Symmetry APIs simplifies integration with on-chain programs without the need of installing or interacting with external libraries.
Getting Started
To interact with Symmetry API, you'll need to make POST requests to https://api.symmetry.fi/baskets/XXXX with specific parameters based on the operation you want to perform. Each operation, such as minting, burning, or creating a new basket, has its own command path and required parameters.
import { useConnection, useWallet } from"@solana/wallet-adapter-react";import { Transaction } from"@solana/web3.js";constwallet=useWallet();const { connection } =useConnection();/* By using this publickey as host platform, your basket will be available for public @ https://app.symmetry.fi/explore/ Host platforms can set any address they want to collect fees at*/constsymmetryHost="4Vry5hGDmbwGwhjgegHmoitjMHniSotpjBFkRuDYHcDG";constcreator=wallet.publicKey.toBase58();constbasketParameters= { symbol:"FAVTOKENS",// 3-10 ['a'-'z','A'-'Z','0'-'9'] characters name:"My Portfolio Basket",// 3-60 characters uri:"",// can be left as empty and configured later. hostPlatform: symmetryHost,// publicKey - string. hostPlatformFee:10,// Fee in basis points (bps). 10 bps = 0.1% creator: creator,// wallet publickey of creator (string) . depositFee:50,// Fee on deposits, paid to the basket creator - 0.5% . type:1,// 1 = Mutable, Creator has authority to edit basket. rebalanceInterval:3600,// Rebalance checks are done every hour. rebalanceThreshold: 300, // Rebalance will be triggered when asset weights deviate from their target weights by 3% .
slippage:100,// Maximum allowed slippage for rebalance transactions, in bps 100 = 1%. lpOffsetThreshold:0,// EXPERIMENTAL: Defines liquidity pool behavior for rebalancing. 0 disables this feature. disableRebalance:0,// 0 - Automatic rebalances are enabled. disableLp:1,// 1 - Liquidity pool functionality is disabled. composition: [ { token:"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", weight:40 },// USDC { token:"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263", weight:60 },// BONK ],};let request =awaitfetch('https://api.symmetry.fi/baskets/create', { method:'POST', headers: { 'Content-Type':'application/json' }, body:JSON.stringify(basketParameters),});let response =awaitrequest.json();if (response.success) {const {createTransaction,compositionTransaction,restructureTransaction } = response;// Decode the base64 encoded transactions provided by the API.constcreateTx=Transaction.from(Buffer.from(createTransaction,'base64'));constcompositionTx=Transaction.from(Buffer.from(compositionTransaction,'base64'));constrestructureTx=Transaction.from(Buffer.from(restructureTransaction,'base64'));// Sign and send each transaction to the Solana blockchain.let signedCreate =awaitwallet.signTransaction(createTx);let createTxid =awaitconnection.sendRawTransaction(signedCreate.serialize(), { skipPreflight:true });console.log('createTxid', createTxid); // Transactions need to be executed in the correct order, so make sure each transaction is confirmed before sending the next one.
// Repeat the process for composition and restructure transactions.let signedComposition =awaitwallet.signTransaction(compositionTx);let compositionTxid =awaitconnection.sendRawTransaction(signedComposition.serialize(), { skipPreflight:true });console.log('compositionTxid', compositionTxid);let signedRestructure =awaitwallet.signTransaction(restructureTx);let restructureTxid =awaitconnection.sendRawTransaction(signedRestructure.serialize(), { skipPreflight:true });console.log('restructureTxid', restructureTxid);console.log('Basket created successfully');} else {console.error('Something went wrong', response);}
import { useConnection, useWallet } from"@solana/wallet-adapter-react";import { Transaction } from"@solana/web3.js";constwallet=useWallet();const { connection } =useConnection();consteditParameters= { creator:wallet.publicKey.toBase58(),// string basket:"4RofqKG4d6jfUD2HjtWb2F9UkLJvJ7P3kFmyuhX7H88d",// Publickey of the basket depositFee:40,// Fee on deposits, paid to the basket creator - 0.4% . rebalanceInterval:7200,// Rebalance checks are done every 2 hours. rebalanceThreshold: 500, // Rebalance will be triggered when asset weights deviate from their target weights by 5% .
slippage:100,// Maximum allowed slippage for rebalance transactions, in bps 100 = 1%. lpOffsetThreshold:0,// EXPERIMENTAL: Defines liquidity pool behavior for rebalancing. 0 disables this feature. disableRebalance:0,// 0 - Automatic rebalances are enabled. disableLp:1,// 1 - Liquidity pool functionality is disabled. composition: [ { token:"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", weight:20 },// USDC { token:"So11111111111111111111111111111111111111112", weight:50 },// SOL { token:"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263", weight:30 },// BONK ],};let request =awaitfetch('https://api.symmetry.fi/baskets/edit', { method:'POST', headers: { 'Content-Type':'application/json' }, body:JSON.stringify(editParameters),});let response =awaitrequest.json();if (response.success) {const { editTransaction } = response;// Decode the base64 encoded transactions provided by the API.consteditTx=Transaction.from(Buffer.from(editTransaction,'base64'));// Sign and send transaction to the Solana blockchain.let signedEdit =awaitwallet.signTransaction(editTx);let editTxid =awaitconnection.sendRawTransaction(signedEdit.serialize(), { skipPreflight:true });console.log('createTxid', editTxid);console.log('Basket edited successfully');} else {console.error('Something went wrong', response);}
Deposit into Basket
Description: Deposit USDC to on-chain account. Automation will rebalance USDC to baskets current composition assets and basket tokens will be automatically minted for user within 3 minutes
Description: Burn Basket Tokens and Withdraw underlying assets to the new on-chain account. Underlying assets from the new account can be claimed by using Claim API.
import { useConnection, useWallet } from"@solana/wallet-adapter-react";import { Transaction } from"@solana/web3.js";constwallet=useWallet();const { connection } =useConnection();constclaimParameters= { user:wallet.publicKey.toBase58(),// string basket:"PublicKey of the account created on the previous step",};let request =awaitfetch('https://api.symmetry.fi/baskets/claim', { method:'POST', headers: { 'Content-Type':'application/json' }, body:JSON.stringify(claimParameters),});let response =awaitrequest.json();if (response.success) {const {createATAsTx,claimTokensTx } = response;// User might not have some token accounts from baskets composition// First transaction will initialize those accounts.constcreateTx=Transaction.from(Buffer.from(createATAsTx,'base64'));let signedCreate =awaitwallet.signTransaction(createTx);let createTxId =awaitconnection.sendRawTransaction(signedCreate.serialize(), { skipPreflight:true });console.log('createTxId', createTxId);constclaimTx=Transaction.from(Buffer.from(claimTokensTx,'base64'));let signedClaim =awaitwallet.signTransaction(claimTx);let claimTxId =awaitconnection.sendRawTransaction(signedClaim.serialize(), { skipPreflight:true });console.log('claimTxId', claimTxId);console.log('Claimed successfully');} else {console.error('Something went wrong', response);}
Deposit single Asset
Description: Users also have an option to deposit an arbitrary asset to Buy/Mint Basket tokens. Only constraint is - asset should be in the baskets current composition.
tokenMint: Mint address of the Asset to be deposited.
amount: amount of Asset to be deposited.
Ts Example:
import { useConnection, useWallet } from"@solana/wallet-adapter-react";import { Transaction } from"@solana/web3.js";constwallet=useWallet();const { connection } =useConnection();// Deposit mSOL tokens and receive ySOL basket tokensconstdepositParameters= { user:wallet.publicKey.toBase58(),// string basket:"4RofqKG4d6jfUD2HjtWb2F9UkLJvJ7P3kFmyuhX7H88d",// ySOL Basket tokenMint:"mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So",// mSOL amount:0.5// 0.5 mSOL};let request =awaitfetch('https://api.symmetry.fi/baskets/mint', { method:'POST', headers: { 'Content-Type':'application/json' }, body:JSON.stringify(depositParameters),});let response =awaitrequest.json();if (response.success) {const { transaction } = response;// Decode the base64 encoded transactions provided by the API.constdepositTx=Transaction.from(Buffer.from(transaction,'base64'));// Sign and send transaction to the Solana blockchain.let signedDeposit =awaitwallet.signTransaction(depositTx);let dopositTxId =awaitconnection.sendRawTransaction(signedDeposit.serialize(), { skipPreflight:true });console.log('depositTxId', dopositTxId);console.log('Deposited and Minted successfully');} else {console.error('Something went wrong', response);}
Redeem Single Asset
Description: Users also have an option to sell/burn Basket tokens and withdraw to an arbitrary asset. Only constraint is - asset should be in the baskets current composition.
user: PublicKey of the user selling a basket token.
basket: PublicKey of the basket on-chain account.
tokenMint: Mint address of the Asset to sell Basket Tokens to.
amount: amount of Basket tokens to be withdrawn.
Ts Example:
import { useConnection, useWallet } from"@solana/wallet-adapter-react";import { Transaction } from"@solana/web3.js";constwallet=useWallet();const { connection } =useConnection();/* Withdraw ySOL basket tokens and receive mSOLMake sure to check that there are enough tokens (mSOL in this example)in the funds current composition.*/constwithdrawParameters= { user:wallet.publicKey.toBase58(),// string basket:"4RofqKG4d6jfUD2HjtWb2F9UkLJvJ7P3kFmyuhX7H88d",// ySOL Basket tokenMint:"mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So",// mSOL amount:0.1// sell 0.1 ySOL};let request =awaitfetch('https://api.symmetry.fi/baskets/burn', { method:'POST', headers: { 'Content-Type':'application/json' }, body:JSON.stringify(withdrawParameters),});let response =awaitrequest.json();if (response.success) {const { transaction } = response;// Decode the base64 encoded transactions provided by the API.constwithdrawTx=Transaction.from(Buffer.from(transaction,'base64'));// Sign and send transaction to the Solana blockchain.let signedWithdraw =awaitwallet.signTransaction(withdrawTx);let withdrawTxId =awaitconnection.sendRawTransaction(signedWithdraw.serialize(), { skipPreflight:true });console.log('withdrawTxId', withdrawTxId);console.log('Burned and Withdrawn successfully');} else {console.error('Something went wrong', response);}
Set Basket Metadata
Description: Creators can set metadata for their Basket Token. In that case, token will get easily detected by Wallet Extensions and Solana Blockchain Explorers