TypeScript icon, indicating that this package has built-in type declarations

0.1.34 • Public • Published

Funds Sdk

Software Development Kit for interacting with Symmetry Funds Program


Loads FundsProgram, TekenInfos supported in funds, and Prism Aggregator

import { FundsSDK } from "@symmetry-hq/funds-sdk";

let fundsSDK: FundsSDK = await FundsSDK.init(
    // rpc connection
    connection: Connection,
    // wallet (optional | can be provided later, using funds.setWallet
    wallet: Wallet,

// load list of supported tokens
let tokens: TokenInfoData[] = fundsSdk.getTokenInfoData();

// get tokenId(tokenId in symmetry supported tokens) from mint
let tokenId = fundsSdk.tokenIdFromMint("So11111111111111111111111111111111111111112");

// set wallet
fundsSdk.setWallet(wallet: Wallet);

Create/Edit/Close Fund

Create Fund with specific settings and rules

let fund: Fund = await fundsSdk.createFund(params: CreateFundParams);
let fund: Fund = await fundsSdk.createFund({
  name: string,
  symbol: string,
  description: string,
  hostPlatform: PublicKey,
  hostPlatformFee: number,
  manager: PublicKey,
  managerFee: number,
  activelyManaged: boolean,
  assetPool: number[],
  refilterInterval: number,
  reweightInterval: number,
  rebalanceInterval: number,
  rebalanceThreshold: number,
  rebalanceSlippage: number,
  lpOffsetThreshold: number,
  rules: {
    filterBy: FilterType,
    filterDays: FilterTime,
    sortBy: SortBy,
    totalWeight: number,
    fixedAsset: number,
    numAssets: number,
    weightBy: WeightType,
    weightDays: WeightTime,
    weightExpo: number,
    excludeAssets: number[]

Edit Fund (Only for actively managed funds)

Fund name and symbol can not be changed.

await fundsSdk
  .editFund(fund: Fund, params: CreateFundParams);

Close Fund (Fund TVL == 0 & no active BuyStates)

await fundsSdk.closeFund(fund: Fund);

Load Fund(s)

Load specific fund from pubkey

let fund: Fund = await fundsSDK.loadFromPubkey(pubkey: PublicKey);

Load funds array based on filters (manager/host platform pubkey)

let funds: Fund[] = await fundsSDK.findFunds(filters: FilterOption[]);
let funds: Fund[] = await fundsSDK
    filterType: "manager"|"host",
    filterPubkey: PublicKey

Buy Fund

Step 1: Contribute USDC and create BuyState

let buyState: BuyState = await fundsSdk
  .buyFund(fund: Fund, amountUsdc: number);

Step 2: Rebalance BuyState: Buy underlying assets in a fund. (Optional)

let txs: TransactionSignature[] = await fundsSdk
  .rebalanceBuyState(buyState: BuyState);

Step 3: Mint Fund Tokens & Close Buy State

let tx: TransactionSignature = await fundsSdk
  .mintFund(buyState: BuyState);

Helper: Find active BuyStates for user that have been created after Step 1

let buyStates: BuyState[] = await fundsSdk
  .findActiveBuyStates(user: PublicKey);

Sell Fund

Step 1: Burn Fund Tokens and create SellState

(Create new Fund where user has authority to claim all tokens)

let sellState: Fund = await fundsSdk
  .sellFund(fund: Fund, amount: number, rebalance: boolean);

Step 2: Rebalance SellState(Fund): Rebalance underlying assets to USDC

(Optional, only when rebalance == true)

let txs: TransactionSignature[] = await fundsSdk
  .rebalanceFund(sellState: Fund);

Step 3: Claim underlying toknes from SellState

let txs: TransactionSignature[] = await fundsSdk
  .claimTokens(sellState: Fund);

Helper: Find active SellStates for user that have been created after Step 1

let sellStates: Fund[] = await fundsSdk
  .findActiveSellStates(user: PublicKey);


Automation on all funds (Refilter/Reweight/Rebalance), as well as monitoring

active Buy/Sell states and rebalancing them is done by Symmetry.

Platforms and Developers can run their own automation for their funds by using example bellow

Swap using Symmetry Funds Liquidity

Users can swap and check available swap liquidity for a specific fund

Find out more at @symmetry-hq/liquidity-sdk

Full Example

Example shows how to create/buy/sell/rebalance/refilter/reweight a fund

Creating fund with following settings:

  • Manager fee : 0.1% - Users pay 0.1% to fund manager on fund buy

  • Is actively managed - Manager can edit fund settings and rules

  • Asset Pool consists of 4 tokens - [USDC, SOL, BTC, ETH]

  • Fund refilters underlying assets every week

  • Fund reweights underlying assets every day

  • Fund rebalances every 2 hours

  • Fund rebalances when target and current weights differ by at least 5%

  • Maximum allowed slippage on rebalance is 3% (compared to pyth price)

  • Fund provides swap liquidity for a token if current weight is within

    5% (rebalance) 50%(lpOffset) = 2.5% of target weight

  • Fund earns 0.05% of swap amount on liquidity providing

  • Fund has 1 rule:

  • Select TOP 3 assets by 1 week average MarketCap,

  • Weight chosen assets by square root of 1 day performance

import {
} from "@symmetry-hq/funds-sdk";

/*  init funds sdk */
let fundsSDK: FundsSDK = await FundsSDK.init(

/*  Create a fund (CreateFund + SetRules + Refilter&Reweight) */
let fund: Fund = await fundsSdk.createFund({
  name: "Solana Bitcoin Etherium",
  symbol: "SOLBTCETH",
  description: "Actively Managed Fund with SOL BTC ETH" +
               "weighted by square root of 1 day performance",
  hostPlatform: wallet.publicKey,
  hostPlatformFee: 0,
  manager: wallet.publicKey,
  managerFee: 10,                    // fee in bps: 10 = 0.1%
  activelyManaged: true,             // actively managed
  assetPool: [0, 1, 2, 3],           // USDC, SOL, BTC, ETH
  refilterInterval: 7 * 24 * 3600,   // 1 week
  reweightInterval: 24 * 3600,       // 1 day
  rebalanceInterval: 2 * 3600,       // 2 hours
  rebalanceThreshold: 500,           // 5%
  rebalanceSlippage: 300,            // 3%
  lpOffsetThreshold: 5000,           // 50% of rebalance threshold
  rules: [{
    filterBy: FilterType.MarketCap,  // filter assets by marketcap
    filterDays: FilterTime.Week,     // 1 week average of marketcap
    sortBy: SortBy.DescendingOrder,  // select top coins by marketcap
    totalWeight: 100,
    fixedAsset: 0,
    numAssets: 3,                     // select 3 assets
    weightBy: WeightType.Performance, // weight by performance
    weightDays: WeightTime.Day,       // 1 day performance
    weightExpo: 0.5,                  // square root of performance
    excludeAssets: [0],               // Exclude USDC

/*  1. buy a fund with 50 USDC
    2. rebalance buyState (buy underlying assets)
    3. mint fund tokens */
let buyState1: BuyState = await fundsSdk.buyFund(fund, 50);
let txsRebalanceBuyState1 = await fundsSdk.rebalanceBuyState(buyState1);
let txMintFund1 = await fundsSdk.mintFund(buyState1);

/*  1. buy a fund with 50 USDC without rebalancing
      unspent amount will have *penalty* and counted as if rebalance
      happend with maximum slippage (rebalanceSlippage = 3%)
    2. mint fund tokens */
let buyState2: BuyState = await fundsSdk.buyFund(fund, 50);
let txMintFund2 = await fundsSdk.mintFund(buyState2);

/*  1. sell a fund
    2. rebalance fund (to USDC)
    3. claim tokens (USDC + tokens for which rebalance failed) */
let sellState1: Fund = await fundsSdk.sellFund(fund, 0.4, true);
let txsRebalanceSellState = await fundsSdk.rebalanceFund(sellState1);
let txsClaimTokens1 = await fundsSdk.claimTokens(sellState);

/*  1. sell a fund without rebalancing
    2. claim tokens (all tokens in a fund) */
let sellState2: Fund = await fundsSdk.sellFund(fund, 0.4, false);
let txsClaimTokens2 = await fundsSdk.claimTokens(sellState2);

/*  1. Refilter Fund (RefilterInterval seconds since last refilter)
    2. Reweight Fund (ReweightInterval seconds since last reweight)
    3. Rebalance Fund (RebalanceInterval seconds since last rebalanace) */
let txRefilter: TransactionSignature = await fundsSdk.refilterFund(fund);
let txReweight: TransactionSignature = await fundsSdk.reweightFund(fund);
let txsRebalance = await fundsSdk.rebalanceFund(fund);

/* In some cases, when fund decides to remove token after refiltering,
   and rebalance function sells it to USDC, fund might end up with 
   small amount of that token, for which it is unable to rebalance and
   sell the full amount. Although it's possible to remove the "dust"
   if user swaps equivalent amount of usdc (based on pyth price) for 
   the token, which is stuck in a fund. Meaning that fund will receive
   USDC and user will receive token. RemoveDust will be triggered for
   tokens with equivalent USD value < 0.005.
   Amount of usdc to be swapped is computed in a following way:
   max(tokenAmount * tokenPrice * 1.1 (for slippage purposes), 0.000001) */
let txsRemoveDust = await fund.removeDust();


npm i @symmetry-hq/funds-sdk

DownloadsWeekly Downloads






Unpacked Size

497 kB

Total Files


Last publish


  • effarigesrever
  • prism-ag
  • ubermenschsym
  • symmetry_fi