Getting Started
Prerequisites
| Requirement | Version |
|---|---|
| Node.js | ≥ 18 |
| Solana CLI | ≥ 1.18 |
| Rust + cargo | stable (for building the program) |
@solana/web3.js | ^1.98 |
Installation
Install the Veil TypeScript SDK from the monorepo lib/veil directory, or copy it directly into your project.
npm
npm install @solana/web3.js @solana/spl-tokenThen copy lib/veil/ from the Veil monorepo into your project:
your-project/
└── lib/
└── veil/
├── constants.ts ← program ID, seeds, WAD
├── instructions.ts ← all instruction builders
├── pda.ts ← PDA derivation helpers
├── state.ts ← on-chain account decoders
└── index.ts ← re-exportsEnvironment Setup
Set the program ID in your environment after deploying:
# .env.local
NEXT_PUBLIC_VEIL_PROGRAM_ID=<deployed-program-id>Deploy the Program
# Clone the repo
git clone https://github.com/esharma3/veil
cd veil/programs
# Build (requires Solana platform-tools)
cargo build-sbf
# Deploy to devnet
solana program deploy \
target/deploy/veil_lending.so \
--url devnet \
--keypair ~/.config/solana/id.jsonThe program uses Pinocchio 0.11.1 and targets the sbpf-solana-solana target. Make sure cargo build-sbf is available via the Solana CLI toolchain.
Your First Transaction
The following example initialises a lending pool for a given SPL token mint.
import {
Connection,
Keypair,
PublicKey,
sendAndConfirmTransaction,
Transaction,
} from '@solana/web3.js';
import {
findPoolAddress,
findPoolAuthorityAddress,
findVaultAddress,
} from './lib/veil/pda';
import { initializePoolIx } from './lib/veil/instructions';
import { PROGRAM_ID } from './lib/veil/constants';
const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
const payer = Keypair.generate(); // fund this keypair before use
const authority = payer;
const tokenMint = new PublicKey('<your-spl-mint>');
async function initPool() {
const [pool, poolBump] = findPoolAddress(tokenMint);
const [poolAuthority, authorityBump] = findPoolAuthorityAddress(pool);
// Vault is the ATA of poolAuthority for the mint (allowOwnerOffCurve = true).
// Pre-create it via createAssociatedTokenAccountInstruction in the same tx,
// or in a previous tx — the program does not create it.
const vault = findVaultAddress(tokenMint, poolAuthority);
const ix = initializePoolIx(
payer.publicKey,
authority.publicKey,
pool,
tokenMint,
vault,
poolBump,
authorityBump,
0, // vaultBump — passed-through, derivation is checked by address comparison
);
const tx = new Transaction().add(ix);
const sig = await sendAndConfirmTransaction(connection, tx, [payer, authority]);
console.log('Pool initialised:', sig);
}
initPool();Next Steps
- Program Reference — complete instruction API
- TypeScript SDK — all builders, PDAs, and state decoders
- Architecture — understand the account model
Last updated on