Symmetry APIs

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.

Currently users can use symmetry API endpoints to

Create a new Basket

  • Description: Creates a new basket.

  • Endpoint: POST https://api.symmetry.fi/baskets/create

  • Parameters:

    • symbol: Basket Symbol/Ticker (3-10 characters).

    • name: Basket name (3-60 characters).

    • uri: URI containing desired metadata in JSON format (Max 300 characters).

    • hostPlatform: A project integrating Symmetry may receive hostPlatformFees.

    • hostPlatformFees: Fee in bps (0.1% = 10) for host platform wallet.

    • creator: Wallet PublicKey of a user creating a basket.

    • depositFee: Fee charged on deposits for creator (in bps).

    • type: Basket type: 0 = Immutable, 1 = Mutable, 2 = Permissioned.

    • rebalanceInterval: Frequency of rebalance checks in seconds.

    • rebalanceThreshold: Allowed deviation from target weights before rebalancing,

    • slippage: Maximum allowed slippage for rebalance transactions, in bps.

    • lpOffsetThreshold: EXPERIMENTAL: Defines liquidity pool behavior for rebalancing. 0 disables this feature.

    • disableRebalance: Controls automatic rebalancing: 0 = enabled, 1 = disabled.

    • disableLp: Controls liquidity pool functionality: 0 = enabled, 1 = disabled.

    • composition: Array of desired basket composition

Ts Example:

import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Transaction } from "@solana/web3.js";

const wallet = 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
*/
const symmetryHost = "4Vry5hGDmbwGwhjgegHmoitjMHniSotpjBFkRuDYHcDG";
const creator = wallet.publicKey.toBase58();
const basketParameters = {
    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 = await fetch('https://api.symmetry.fi/baskets/create', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(basketParameters),
});
let response = await request.json();

if (response.success) {
    const {
        createTransaction,
        compositionTransaction,
        restructureTransaction
    } = response;

    // Decode the base64 encoded transactions provided by the API.
    const createTx = Transaction.from(Buffer.from(createTransaction, 'base64'));
    const compositionTx = Transaction.from(Buffer.from(compositionTransaction, 'base64'));
    const restructureTx = Transaction.from(Buffer.from(restructureTransaction, 'base64'));

    // Sign and send each transaction to the Solana blockchain.
    let signedCreate = await wallet.signTransaction(createTx);
    let createTxid = await connection.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 = await wallet.signTransaction(compositionTx);
    let compositionTxid = await connection.sendRawTransaction(signedComposition.serialize(), { skipPreflight: true });
    console.log('compositionTxid', compositionTxid);

    let signedRestructure = await wallet.signTransaction(restructureTx);
    let restructureTxid = await connection.sendRawTransaction(signedRestructure.serialize(), { skipPreflight: true });
    console.log('restructureTxid', restructureTxid);

    console.log('Basket created successfully');
} else {
    console.error('Something went wrong', response);
}

Edit Basket

  • Description: Edit a basket.

  • Endpoint: POST https://api.symmetry.fi/baskets/edit

  • Parameters:

    • basket: PublicKey of basket to be edited (string).

    • creator: Wallet PublicKey of the basket creator.

    • depositFee: Fee charged on deposits for creator (in bps).

    • rebalanceInterval: Frequency of rebalance checks in seconds.

    • rebalanceThreshold: Allowed deviation from target weights before rebalancing,

    • slippage: Maximum allowed slippage for rebalance transactions, in bps.

    • lpOffsetThreshold: EXPERIMENTAL: Defines liquidity pool behavior for rebalancing. 0 disables this feature.

    • disableRebalance: Controls automatic rebalancing: 0 = enabled, 1 = disabled.

    • disableLp: Controls liquidity pool functionality: 0 = enabled, 1 = disabled.

    • composition: Array of desired basket composition

Ts Example:

import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Transaction } from "@solana/web3.js";

const wallet = useWallet();
const { connection } = useConnection();

const editParameters = {
    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 = await fetch('https://api.symmetry.fi/baskets/edit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(editParameters),
});
let response = await request.json();

if (response.success) {
    const { editTransaction } = response;

    // Decode the base64 encoded transactions provided by the API.
    const editTx = Transaction.from(Buffer.from(editTransaction, 'base64'));

    // Sign and send transaction to the Solana blockchain.
    let signedEdit = await wallet.signTransaction(editTx);
    let editTxid = await connection.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

  • Endpoint: POST https://api.symmetry.fi/baskets/deposit

  • Parameters:

    • user: PublicKey of the user depositing USDC.

    • basket: PublicKey of the basket on-chain account.

    • amount: amount of USDC to be deposited.

Ts Example:

import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Transaction } from "@solana/web3.js";

const wallet = useWallet();
const { connection } = useConnection();

const depositParameters = {
    user: wallet.publicKey.toBase58(), // string
    basket: "4RofqKG4d6jfUD2HjtWb2F9UkLJvJ7P3kFmyuhX7H88d", // ySOL Basket
    amount: 100 // 100 USDC
};
let request = await fetch('https://api.symmetry.fi/baskets/deposit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(depositParameters),
});
let response = await request.json();

if (response.success) {
    const { transaction } = response;

    // Decode the base64 encoded transactions provided by the API.
    const depositTx = Transaction.from(Buffer.from(transaction, 'base64'));

    // Sign and send transaction to the Solana blockchain.
    let signedDeposit = await wallet.signTransaction(depositTx);
    let dopositTxId = await connection.sendRawTransaction(signedDeposit.serialize(), { skipPreflight: true });
    console.log('depositTxId', dopositTxId);

    console.log('Deposited successfully');
} else {
    console.error('Something went wrong', response);
}

Withdraw and Claim Tokens

  • 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.

  • Withdraw - Endpoint: POST https://api.symmetry.fi/baskets/withdraw

  • Withdraw - Parameters:

    • user: PublicKey of the user depositing USDC.

    • basket: PublicKey of the basket on-chain account.

    • amount: amount of Basket Tokens to be withdrawn.

  • Claim - Endpoint: POST https://api.symmetry.fi/baskets/withdraw

  • Claim - Parameters:

    • user: PublicKey of the user depositing USDC.

    • basket: PublicKey of the on-chain account created during Withdraw.

Ts Example:

import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Transaction } from "@solana/web3.js";

const wallet = useWallet();
const { connection } = useConnection();

const withdrawParameters = {
    user: wallet.publicKey.toBase58(), // string
    basket: "4RofqKG4d6jfUD2HjtWb2F9UkLJvJ7P3kFmyuhX7H88d", // ySOL Basket
    amount: 0.1 // 0.1 ySOL
};
let request = await fetch('https://api.symmetry.fi/baskets/withdraw', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(withdrawParameters),
});
let response = await request.json();

if (response.success) {
    const { transaction } = response;

    // Decode the base64 encoded transactions provided by the API.
    const withdrawTx = Transaction.from(Buffer.from(transaction, 'base64'));

    // Sign and send transaction to the Solana blockchain.
    let signedWithdraw = await wallet.signTransaction(withdrawTx);
    let withdrawTxId = await connection.sendRawTransaction(signedWithdraw.serialize(), { skipPreflight: true });
    console.log('withdrawTxId', withdrawTxId);

    console.log('Withdrawn successfully');
} else {
    console.error('Something went wrong', response);
}
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Transaction } from "@solana/web3.js";

const wallet = useWallet();
const { connection } = useConnection();

const claimParameters = {
    user: wallet.publicKey.toBase58(), // string
    basket: "PublicKey of the account created on the previous step",
};
let request = await fetch('https://api.symmetry.fi/baskets/claim', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(claimParameters),
});
let response = await request.json();

if (response.success) {
    const {
        createATAsTx,
        claimTokensTx
    } = response;

    // User might not have some token accounts from baskets composition
    // First transaction will initialize those accounts.

    const createTx = Transaction.from(Buffer.from(createATAsTx, 'base64'));
    let signedCreate = await wallet.signTransaction(createTx);
    let createTxId = await connection.sendRawTransaction(signedCreate.serialize(), { skipPreflight: true });
    console.log('createTxId', createTxId);

    const claimTx = Transaction.from(Buffer.from(claimTokensTx, 'base64'));
    let signedClaim = await wallet.signTransaction(claimTx);
    let claimTxId = await connection.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.

  • Endpoint: POST https://api.symmetry.fi/baskets/mint

  • Parameters:

    • user: PublicKey of the user depositing asset.

    • basket: PublicKey of the basket on-chain account.

    • 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";

const wallet = useWallet();
const { connection } = useConnection();

// Deposit mSOL tokens and receive ySOL basket tokens
const depositParameters = {
    user: wallet.publicKey.toBase58(), // string
    basket: "4RofqKG4d6jfUD2HjtWb2F9UkLJvJ7P3kFmyuhX7H88d", // ySOL Basket
    tokenMint: "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So", // mSOL
    amount: 0.5 // 0.5 mSOL
};
let request = await fetch('https://api.symmetry.fi/baskets/mint', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(depositParameters),
});
let response = await request.json();

if (response.success) {
    const { transaction } = response;

    // Decode the base64 encoded transactions provided by the API.
    const depositTx = Transaction.from(Buffer.from(transaction, 'base64'));

    // Sign and send transaction to the Solana blockchain.
    let signedDeposit = await wallet.signTransaction(depositTx);
    let dopositTxId = await connection.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.

  • Endpoint: POST https://api.symmetry.fi/baskets/burn

  • Parameters:

    • 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";

const wallet = useWallet();
const { connection } = useConnection();

/* Withdraw ySOL basket tokens and receive mSOL
Make sure to check that there are enough tokens (mSOL in this example)
in the funds current composition.
*/
const withdrawParameters = {
    user: wallet.publicKey.toBase58(), // string
    basket: "4RofqKG4d6jfUD2HjtWb2F9UkLJvJ7P3kFmyuhX7H88d", // ySOL Basket
    tokenMint: "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So", // mSOL
    amount: 0.1 // sell 0.1 ySOL
};
let request = await fetch('https://api.symmetry.fi/baskets/burn', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(withdrawParameters),
});
let response = await request.json();

if (response.success) {
    const { transaction } = response;

    // Decode the base64 encoded transactions provided by the API.
    const withdrawTx = Transaction.from(Buffer.from(transaction, 'base64'));

    // Sign and send transaction to the Solana blockchain.
    let signedWithdraw = await wallet.signTransaction(withdrawTx);
    let withdrawTxId = await connection.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

  • Endpoint: POST https://api.symmetry.fi/baskets/set-metadata

  • Parameters:

    • basket: PublicKey of the basket on-chain account.

    • creator: Wallet PublicKey of the basket creator.

    • symbol: new Symbol/Ticker of Basket Token

    • name: new Name of Basket Token

    • uri: new Symbol/Ticker of Basket Token

Ts Example:

import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { Transaction } from "@solana/web3.js";

const wallet = useWallet();
const { connection } = useConnection();

/* This is an example how ySOL creator could change ySOL token metadata */
const setMetadataParameters = {
    basket: "4RofqKG4d6jfUD2HjtWb2F9UkLJvJ7P3kFmyuhX7H88d", // ySOL Basket
    creator: "EXBMgGA4teyMA161LdfefmKbDBcFufuSQsuHM5Aw5mXL", // ySOL Creator
    symbol: "ySOL", // new symbol
    name: "Solana LSD", // new name,
    // new uri. check the example URI to understand what metadata json should contain
    uri: "https://raw.githubusercontent.com/symmetry-protocol/markets/master/ysol-metadata.json"
};
let request = await fetch('https://api.symmetry.fi/baskets/set-metadata', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(setMetadataParameters),
});
let response = await request.json();
if (response.success) {
    const { transaction } = response;
    const setMetadataTx = Transaction.from(Buffer.from(transaction, 'base64'));
    let signedSetMetadata = await wallet.signTransaction(setMetadataTx);
    let setMetadataTxId = await connection.sendRawTransaction(signedSetMetadata.serialize(), { skipPreflight: true });
    console.log('setMetadataTxId', setMetadataTxId);
    console.log('Metadata Created/Edited successfully');
} else {
    console.error('Something went wrong', response);
}

More API Endpoints are Coming...

If you have any questions or issues, please join our Discord, we're happy to help!

Last updated