JSPM

  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q68924F
  • License ISC

Software Development Kit for interacting with Symmetry Funds Program

Package Exports

  • @symmetry-hq/funds-sdk
  • @symmetry-hq/funds-sdk/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@symmetry-hq/funds-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Funds Sdk

Software Development Kit for interacting with Symmetry Funds Program

Init

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();

// 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({
  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)

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
  .findFunds([{
    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);

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%

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

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

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

  • Fund has 1 rule:

  • Select TOP 3 assets by 1 week average MarketCap,

  • Weight chosen assets by square root of 1 day performance

import {
  FundsSDK,
  Fund,
  BuyState,
  FilterType,
  FilterTime,
  SortBy,
  WeightType,
  WeightTime
} from "@symmetry-hq/funds-sdk";

/*  init funds sdk */
let fundsSDK: FundsSDK = await FundsSDK.init(
   connection,
   wallet
);

/*  Create a fund (CreateFund + SetRules + Refilter&Reweight) */
let fund: Fund = await fundsSdk.createFund({
  hostPlatform: wallet.publicKey,
  hostPlatformFee: 0,
  manager: wallet.publicKey,
  managerFee: 10,                    // fee in bps: 10 = 0.1%
  activelyManaged: true,             // actively managed
  assetPool: [0, 1, 2, 26],          // 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 funds.buyFund(fund, 50);
let txsRebalanceBuyState1 = await funds.rebalanceBuyState(buyState1);
let txMintFund1 = await funds.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 funds.buyFund(fund, 50);
let txMintFund2 = await funds.mintFund(buyState2);


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

/*  1. sell a fund without rebalancing
    2. claim tokens (all tokens in a fund) */
let sellState2: Fund = await funds.sellFund(fund, 0.4, false);
let txsClaimTokens2 = await funds.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 funds.refilterFund(fund);
let txReweight: TransactionSignature = await funds.reweightFund(fund);
let txsRebalance = await funds.rebalanceFund(fund);