@etherfuse/stablebond-sdk

中文文档
3.0.21发布于 2026/11/12MITTypeScriptESM + CJS近 30 天下载 3901

JavaScript client for the stablebond program

原始使用文档
文档目录8 节
  1. Usage
  2. Instance Methods
  3. Static Methods
  4. On chain bond prices
  5. Oracle Updates
  6. Checking Oracle Staleness
  7. Updating the Oracle
  8. API Reference

Etherfuse Stablebond Program SDK

The StablebondProgram class provides a set of methods to interact with the Stablebond program on the Solana blockchain.

We're currently using this ourselves at app.etherfuse.com.

We also have a sandbox version of the program running at sandbox.etherfuse.com. This is useful for testing and development, reach out to us for play-money and we'll transfer you some fake tokens to use.

A users's bond lifecycle is as follows:

  1. User is granted/airdropped a bond, indicating they have been given access to the platform.
  2. User leverages the bond to gain access to the platform by calling grantAccess.
  3. User purchases and mints new bonds by calling mintBond.
  4. User lets bonds mature for a period of time, ideally a year or more, but can do so immediately after purchasing.
  5. User redeems bonds by calling redeemBonds, getting an NFT that will store the user's bonds in a vault until the next issuance, similar to unstaking solana.
  6. User redeems the NFT by calling redeemNFT, getting the payment stablecoin for the bonds they redeemed, the same token used to pay for the bond.

Usage

Though the SDK includes all autogenerated code and types from the program, we recommend interacting with the program through the StablebondProgram class. There are exported types to enable faster development and better type safety.

The pattern for interacting with the class is that static methods reveal catalog information about availible bonds, while instance methods are used to interact with the context of a user's wallet. This way, catalog infomation can be refreshed independently of the user's wallet state.

First, import the StablebondProgram class:

import { StablebondProgram } from "@etherfuse/stablebond-sdk";

Collect the static stablebond information

const bonds = await StablebondProgram.getBonds(rpcEndpoint);

Then, once a user has authenticated, create an instance of the StablebondProgram class:

const stablebondProgram = new StablebondProgram(rpcEndpoint, wallet);

Instance Methods

getUserBondBalances

async getUserBondBalances(): Promise<Map<string, Decimal>>

Fetches the user's bond balances in the Stablebond program.

getUserTokens

async getUserTokens(): Promise<Stablebond[]>

Fetches the user's tokens in the Stablebond program, combining getBonds and getUserBondBalances. We don't call this in our code, but it's available for you to use.

getUserNFTs

async getUserNFTs(): Promise<PartialNFT[]>

Fetches the user's NFTs in the Stablebond program. For the sake of effiency, catalog information about the bond is excluded. This information can be patched back in to complete a full NFT object using the static mapper method mapToCompleteNFT.

hasAccess

async hasAccess(): Promise<boolean>

Checks if the user has access to the Stablebond program.

grantAccess

async grantAccess(bondAddress: string, bondMint: string): Promise<Uint8Array>

Grants access to the user by leveraging a bond in their wallet, proving they have sought out and requsted access to the platform.

hasKYC

async hasKYC(): Promise<boolean>

Checks if the user has completed KYC (Know Your Customer) verification in the Stablebond program.

mintBond

async mintBond(stablebondAddress: Address, uiAmount: Decimal): Promise<Uint8Array>

Mints new bonds for the user matching the specified amount. Amount is in the payment token of the bond, without specifying the amount of bonds to purchase.

Oracle freshness: This operation requires up-to-date oracle price data. See Oracle Updates below.

instantRedeemBonds

async instantRedeemBonds(stablebondAddress: Address, passedUIAmount?: Decimal): Promise<Uint8Array>

Instantly redeems bonds in the Stablebond program. This results in a user getting paid out in the payment token of the bond, minus a fee. The fee and available liquidity are determined by the bond's instant redeem configuration.

Oracle freshness: This operation requires up-to-date oracle price data. See Oracle Updates below.

createPurchaseOrder

async createPurchaseOrder(stablebondAddress: Address, paymentAmount: Decimal): Promise<Uint8Array>

Creates a purchase order for the user to reserve bonds in the upcoming issuance within the Stablebond program. The amount is in the payment token of the bond, without specifying the amount of bonds to purchase.

Oracle freshness: This operation requires up-to-date oracle price data. See Oracle Updates below.

redeemPurchaseOrder

async redeemPurchaseOrder(nftMintString: Address): Promise<Uint8Array>

Redeems a purchase order for the user to claim bonds previously paid for within the Stablebond program.

redeemBonds

async redeemBonds(stablebondAddress: Address, passedUIAmount?: Decimal): Promise<Uint8Array>

Redeems bonds in the Stablebond program. This results in a user receiving an NFT that will mature at the end of the current issuance.

redeemNFT

async redeemNFT(nftMintString: Address): Promise<Uint8Array>

Redeems an NFT in the Stablebond program. This results in a user receiving the underlying asset of the NFT.

Static Methods

getBonds

static async getBonds(rpcEndpoint: string): Promise<Stablebond[]>

Fetches the bonds in the Stablebond program.

getBond

static async getBond(rpcEndpoint: string, bondAddress: string): Promise<Stablebond>

Fetches a bond in the Stablebond program.

getBondPrices

static async getBondPrices(host = StablebondProgram.etherfuseHost): Promise<{ [mint: string]: PriceData }>

Fetches current prices for active bonds, keyed by bond mint. This defaults to using the etherfuse production host.

getBondPrice

static async getBondPrice(mint: Address, host = StablebondProgram.etherfuseHost): Promise<PriceData>

Fetches the current price for a bond in its payment token. This defaults to using the etherfuse production host.

On chain bond prices

The BondPrice account at ["bond_price", mint] is the price source for a bond once a delegate has run InitializeBondPrice; before that the token 2022 interest bearing extension is. These helpers read either source directly from the chain instead of the Etherfuse host.

import {
  bondPriceAt,
  bondRateBps,
  fetchBondPriceSource,
  fetchBondPriceSources,
  getBondPriceAddress,
  parseBondPriceSource,
} from '@etherfuse/stablebond-sdk';

const source = await fetchBondPriceSource(connection, mint);
const price = bondPriceAt(source);
const rateBps = bondRateBps(source);
  • getBondPriceAddress(mint) derives the BondPrice PDA.
  • fetchBondPriceSource(rpc, mint) and fetchBondPriceSources(rpc, mints) fetch the mint and its BondPrice account together and pick the source the program would use. Any object with getMultipleAccountsInfo, such as a web3.js Connection, works as the rpc.
  • parseBondPriceSource(mint, priceAccount, mintAccount) does the same from already fetched account data.
  • bondPriceAt(source, unixTimestamp?) returns the price as a Decimal at the given time (default now), and bondRateBps(source) the current rate in basis points.

Every generated instruction builder that prices a bond (startIssuance, setInterestRateToZero, delegateMintBondFromCurrencyAmount, burnBondFromTokenAmount, burnBondFromCurrencyAmount, purchaseBondV3, instantBondRedemptionV2) fills its bondPriceAccount from the mint when the caller leaves it out.

mapToCompleteNFT

static mapToCompleteNFT({ ...nft }: PartialNFT, bond: Stablebond): NFT

Maps a PartialNFT and a Stablebond to a complete NFT.

For more details, refer to the StablebondProgram class in the source code.

getInterestOverTime

static getInterestOverTime(basisPoints: number, secondsPast: number): Decimal

Calculates the interest accrued over a period of time given a rate in basis points. This is used internally to calculate bond values but may be useful for external calculations.

Parameters:

  • basisPoints: The interest rate in basis points (1/100th of a percent)
  • secondsPast: The number of seconds that have passed

Returns a Decimal representing the multiplier to apply to the principal amount.

Oracle Updates

Some stablebond operations (mintBond, createPurchaseOrder, instantRedeemBonds) require up-to-date Switchboard on-demand oracle price data. If the oracle is stale (typically more than 1 hour), these operations will fail on-chain with a StaleOracle error.

The SDK exports utilities to check oracle freshness and fetch update instructions so you can update the oracle yourself before submitting a stablebond transaction.

Checking Oracle Staleness

import {
  createStablebondProgram,
  fetchBond,
  fetchPaymentFeedBrute,
  isSwitchboardOnDemand,
  isOracleStale,
} from "@etherfuse/stablebond-sdk";
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
import { publicKey } from "@metaplex-foundation/umi";

const umi = createUmi(rpcEndpoint);
umi.programs.add(createStablebondProgram(), false);

const bond = await fetchBond(umi, publicKey(bondAddress));
const paymentFeed = await fetchPaymentFeedBrute(umi, bond.paymentFeedType);

// Check if this bond uses Switchboard on-demand oracles
if (isSwitchboardOnDemand(paymentFeed.paymentFeedType)) {
  // Check if the quote price feed is stale (e.g., older than 20 minutes)
  const stale = await isOracleStale(umi, paymentFeed.quotePriceFeed, 1200);
  console.log("Oracle stale:", stale);
}

Updating the Oracle

If the oracle is stale, use fetchOracleUpdateIxForBond to get update instructions. Submit these in a separate transaction before your stablebond operation.

import {
  fetchOracleUpdateIxForBond,
  isOracleStale,
} from "@etherfuse/stablebond-sdk";
import {
  Connection,
  TransactionMessage,
  VersionedTransaction,
} from "@solana/web3.js";

// Check staleness first to avoid unnecessary oracle update calls
const stale = await isOracleStale(umi, paymentFeed.quotePriceFeed, 1200);

if (stale) {
  const { instructions, lookupTables } = await fetchOracleUpdateIxForBond(
    umi,
    bondAddress, // Same address you pass to mintBond
    wallet.publicKey.toBase58(),
    "mainnet-beta" // or 'devnet'
  );

  if (instructions.length > 0) {
    // Each feed returns 2 instructions (keccak verify + pullFeedSubmit).
    // Submit each feed's instructions in a separate transaction to avoid
    // checksum mismatches between independently-fetched oracle responses.
    const connection = new Connection(rpcEndpoint);

    for (let i = 0; i < instructions.length; i += 2) {
      const feedIxs = instructions.slice(i, i + 2);
      const { blockhash } = await connection.getLatestBlockhash();
      const message = new TransactionMessage({
        payerKey: wallet.publicKey,
        recentBlockhash: blockhash,
        instructions: feedIxs,
      }).compileToV0Message(lookupTables.length ? lookupTables : undefined);

      const tx = new VersionedTransaction(message);
      // Sign and send...
    }
  }
}

// Now the oracle is fresh — proceed with your stablebond operation
const sig = await stablebondProgram.mintBond(bondAddress, amount);

API Reference

isSwitchboardOnDemand(feedType: PaymentFeedType): boolean

Returns true if the given payment feed type uses Switchboard on-demand oracles that may need manual updating.

isOracleStale(umi: Umi, feedPubkey: PublicKey, stalenessThresholdSecs: number): Promise<boolean>

Reads the oracle's lastUpdateTimestamp from on-chain data and returns true if it's older than the specified threshold.

fetchOracleUpdateIxForBond(umi, bondAddress, payerPubkey, network?): Promise<{ instructions, lookupTables }>

Fetches Switchboard oracle update instructions for a bond's price feeds using the @switchboard-xyz/on-demand SDK (PullFeed.fetchUpdateIx). Pass the same bond address you use for mintBond(). Returns TransactionInstruction[] and AddressLookupTableAccount[] for building a V0 transaction. Returns empty arrays if the bond doesn't use Switchboard on-demand or if the fetch fails.

版本与发布记录

@etherfuse/stablebond-sdk 共发布 210 个版本,首次发布于 2024/03/26;过去 12 个月发布了 34 个版本。

版本发布日期距今
3.0.21latest2026/11/122 天前
3.0.202026/11/077 天前
3.0.192026/10/2321 天前
3.0.182026/09/251 个月前
3.0.172026/09/251 个月前
3.0.162026/09/251 个月前

关于 @etherfuse/stablebond-sdk 的常见问题

@etherfuse/stablebond-sdk 是什么?

JavaScript client for the stablebond program

如何安装 @etherfuse/stablebond-sdk?

在项目目录运行 npm install @etherfuse/stablebond-sdk,或使用 pnpm add / yarn add / bun add。

@etherfuse/stablebond-sdk 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@etherfuse/stablebond-sdk 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@etherfuse/stablebond-sdk 可以商用吗?

@etherfuse/stablebond-sdk 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@etherfuse/stablebond-sdk 的下载量有多少?

根据 npm 官方下载统计,@etherfuse/stablebond-sdk 在 2026/10/14 – 2026/11/12 这 30 天内被下载 3,901 次,日均约 130 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@etherfuse/stablebond-sdk 还在维护吗?

最新版本 3.0.21 发布于 2026/11/12(2 天前);至今共发布 210 个版本,其中过去 12 个月发布了 34 个;首次发布于 2024/03/26。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。