Install
npm install @symmetry-hq/sdk @solana/web3.js @coral-xyz/anchor
Initialize the SDK
import { Connection } from "@solana/web3.js";
import { SymmetryCore } from "@symmetry-hq/sdk";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const sdk = new SymmetryCore({
connection,
network: "mainnet",
priorityFee: 50_000,
});
Fetch Vaults
const vaults = await sdk.fetchAllVaults();
console.log(`Found ${vaults.length} vaults`);
const vault = await sdk.fetchVault("<VAULT_PUBKEY>");
console.log(vault.formatted);
Load Prices
Fetching a vault does not include live prices. Call loadVaultPrice to get current oracle prices and compute TVL:
let vault = await sdk.fetchVault("<VAULT_PUBKEY>");
vault = await sdk.loadVaultPrice(vault);
console.log("TVL:", vault.tvl?.toString());
console.log("Token Price:", vault.price?.toString());
for (const asset of vault.formatted!.composition) {
if (!asset.active) continue;
console.log(`${asset.mint}: weight=${asset.weight / 100}%`);
}
Set Up a Wallet
For Node.js environments, create a wallet adapter from a keypair:
import { Keypair } from "@solana/web3.js";
const keypair = Keypair.fromSecretKey(/* your secret key bytes */);
const wallet = {
publicKey: keypair.publicKey,
signTransaction: async <T>(tx: T): Promise<T> => {
(tx as any).sign([keypair]);
return tx;
},
signAllTransactions: async <T>(txs: T[]): Promise<T[]> => {
txs.forEach((tx: any) => tx.sign([keypair]));
return txs;
},
payer: keypair,
};
Never commit private keys to version control. Use environment variables or a secure key management solution.
Create a Vault
const result = await sdk.createVaultTx({
creator: wallet.publicKey.toBase58(),
start_price: "1.0",
name: "My Vault",
symbol: "MV",
metadata_uri: "https://arweave.net/your-metadata-json", // URL to JSON with name, symbol, description, image, cover
});
console.log("Vault mint:", result.mint);
console.log("Vault account:", result.vault);
await sdk.signAndSendTxPayloadBatchSequence({
txPayloadBatchSequence: result,
wallet,
});
The metadata_uri should point to a JSON file containing name, symbol, description, image, and cover fields. See Vaults for the full metadata spec.
After creation, the vault has no tokens. Add tokens with addOrEditTokenTx and set weights with updateWeightsTx. For Pyth oracle price feed IDs, see Pyth Price Feed IDs. See Vaults for the full workflow.
Deposit into a Vault
const tx = await sdk.buyVaultTx({
buyer: wallet.publicKey.toBase58(),
vault_mint: "<VAULT_TOKEN_MINT>",
contributions: [
{ mint: "So11111111111111111111111111111111111111112", amount: 1_000_000_000 },
],
rebalance_slippage_bps: 100,
per_trade_rebalance_slippage_bps: 100,
});
await sdk.signAndSendTxPayloadBatchSequence({
txPayloadBatchSequence: tx,
wallet,
});
const lockTx = await sdk.lockDepositsTx({
buyer: wallet.publicKey.toBase58(),
vault_mint: "<VAULT_TOKEN_MINT>",
});
await sdk.signAndSendTxPayloadBatchSequence({
txPayloadBatchSequence: lockTx,
wallet,
});
After locking, the rebalance is processed: price updates, auctions, and minting. Any wallet may execute these stage methods directly; keeper is an actor role, not a privilege role. See Rebalancing for the full flow.
Common Use Cases
| Use Case | How |
|---|
| Create a multi-token vault | createVaultTx → addOrEditTokenTx → updateWeightsTx |
| Deposit into a vault | buyVaultTx → lockDepositsTx → keeper processes → vault tokens minted |
| Withdraw from a vault | sellVaultTx → keeper processes → underlying tokens redeemed |
| Fast withdrawal | sellVaultTx with all mints in keep_tokens → redeemTokensTx |
| Read vault data | fetchVault → loadVaultPrice → read vault.formatted |
| Run a keeper bot | Create KeeperMonitor and call update() in a loop |
| Claim fees | withdrawVaultFeesTx |
Next Steps