StockwovenDocs
    AppLaunch app

    SDK.

    @stockwoven/sdk is a TypeScript SDK for neobanks and fintechs. It reads the swSPCX vault and your customers' positions, prices deposits and redemptions, and builds the transactions. It never holds keys: you sign with your own custody, whether that is a backend key, an MPC or wallet-as-a-service provider, or the customer's wallet in your app.

    Devnet only for now. The preset vault is swSPCX: the three issuers' SpaceX tokens (xStocks SPCXx, Backpack SPCX, Ondo SPCXon, as mocks with their real decimals), USDC and SOL, across four Meteora DAMM v2 pools.

    Install

    The SDK is in the repository's sdk/ folder. Until it is on npm, install the tarball that npm pack builds there:

    npm install @solana/web3.js @solana/spl-token ./stockwoven-sdk-0.2.0.tgz
    

    It runs in Node 20+ and in browsers.

    Deposit for a customer

    import { Connection } from "@solana/web3.js";
    import { Stockwoven, toRaw } from "@stockwoven/sdk";
    
    const sw = new Stockwoven({ connection: new Connection("https://api.devnet.solana.com", "confirmed") });
    
    const quote = await sw.quoteDeposit({ pay: "USDC", amount: toRaw("20", 6) });
    const built = await sw.buildDeposit(quote, { owner: customer.publicKey, feePayer: treasury.publicKey });
    await sw.sendAll(built, [treasury, customer]);
    

    feePayer is optional. When it is your key, you pay the network fees and token-account rent, and the customer needs no SOL unless they pay with SOL.

    What a customer can pay with

    payTransactionsWhat happens
    "mix" with shares1Every asset in the vault's current proportions, for an exact number of shares. Unused amounts are refunded.
    "SPCXx", "SPCX" or "SPCXon" with amount1The vault takes the issuer token alone and counts it 1:1 as one SpaceX share, less a dynamic fee (route: "single"). If the token is at its cap or outside its 1:1 band, the vault converts it into an underweight issuer token in the same instruction.
    "USDC" or "SOL" with amount1The vault converts it into the issuer token furthest below its target weight, then counts that token 1:1. SOL is swapped to USDC first when no pool pairs it with that token.

    The vault keeps a target weight and a cap for each token (for example, at most 40% in one issuer). Its fee depends on how a deposit moves that token's weight: a token above its target costs more, one below costs less or earns a small discount. The fee stays in the vault, for holders. The quote returns feeBps (negative for a discount), the token the deposit became (into), and minShares, the least the transaction will mint.

    1:1 only holds inside a band of ±2%. If an issuer token's market price leaves the band, the vault stops taking it alone. If the keeper's prices are out of date, or a vault pool trades outside the band around them, every single-token deposit pauses. When that happens, the quote falls back to the older route (route: "swap", two transactions that swap the token into the vault's mix and deposit it), and fallbackReason says why.

    Redemptions pay a slice of every asset in kind by default, and that never needs a price. With { receive: "SPCXon" } (any issuer token), the vault pays that token alone, less the dynamic fee: taking out a token below its target costs more. With { receive: "USDC" }, the vault pays whichever issuer token sells for the most USDC, and the same transaction sells it. The vault never pauses in-kind redemptions.

    Reading the vault

    getVault() returns the value of one swSPCX in USD, the vault's total value, its exposure (the share of value in SpaceX tokens, USDC and SOL), each pool's value and target weight, the idle reserves and the pause flag. Its basket field shows each token's weight, target and cap, whether it is inside its band, the fee on a small deposit or redemption, the age of the keeper's prices, and whether the breaker is on (status). getPosition(owner) returns a customer's swSPCX, its USD value and what redeeming it in kind would pay. getActivity(owner) lists their latest deposits, redemptions and swaps.

    Limits

    • Quotes are refused when their swaps would lose more than maxLossBps of the value (default 3%). The devnet SOL pools are small, so keep SOL deposits under about 0.05 SOL.
    • Every deposit and redemption closes the owner's wrapped-SOL account at the end and returns it as SOL.
    • Backpack's SpaceX token is called SPCX, like swSPCX's ticker. Show the issuer next to it.

    Errors

    parseError(error) turns a failed transaction into a kind you can branch on (DepositsPaused, SlippageExceeded, AssetAtCap, TokenDepegged, PricesStale, PoolOutOfBand, InsufficientFunds, TooManyInstructions, BlockhashExpired, RateLimited, Rejected) and a sentence for your own copy.

    The full reference, with every method and option, is in sdk/README.md; a custodial backend example is in sdk/examples/custodial-backend.ts.