npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@spield/sdk

v0.4.3

Published

TypeScript SDK for Spield Protocol fixed-rate yield on Stellar Testnet.

Readme

@spield/sdk

TypeScript SDK for the Spield Protocol on Stellar: wrap USDC into yield-bearing shares, split them into principal and yield tokens, trade them, and buy a fixed rate — from one typed client.

v0.4.2 · Stellar Testnet · Node ≥ 18 and modern browsers · ESM + CJS + type declarations

Install

npm install @spield/sdk     # or: pnpm add @spield/sdk / yarn add @spield/sdk

@stellar/stellar-sdk v16 ships as a dependency — you do not install it separately.

Quick start

import { FreighterSigner, SpieldClient, testnet } from '@spield/sdk';

// Reads need no wallet. Omit `signer` for a read-only client.
const client = new SpieldClient({
  network: testnet(),              // the default; the SDK ships Testnet only
  signer: new FreighterSigner(),
});

// Read
const health = await client.protocol.getHealth();
const srQuote = await client.sr.previewDeposit({ amount: '100' });   // USDC -> SR
const ptQuote = await client.router.quoteBuyPt({ usdcIn: '100' });   // USDC -> PT

// Write
await client.tokens.ensurePtTrustline();       // once per wallet, before receiving PT
await client.router.buyPt({ usdcIn: '100' });  // 1% slippage floor by default

Every write simulates before it asks for a signature, submits only after wallet approval, and resolves to { hash, status: 'success', explorerUrl } once the network confirms it.

The protocol model

USDC wraps into SR, a yield-bearing share token over a Blend strategy. SR splits into PT (principal, redeems 1:1 at expiry) and YT (the yield until expiry). PT trades against SR on the market, and the fixed-rate vault sells a guaranteed coupon out of its PT inventory.

USDC ──sr.deposit──▶ SR ──yield.mintPy──▶ PT + YT
                     ▲                     │
                     └──yield.redeemPy─────┘

SR is a share token, so one SR is not one USDC — use sr.previewDeposit / sr.previewRedeem, or sr.srToUnderlying / sr.underlyingToSr with the current exchangeRate.

Namespaces

| Namespace | What it does | |---|---| | client.sr | Wrap USDC into SR shares; unwrap fully or partially; previews, exchange rate, deposit cap | | client.strategy | Blend rate guard, position value, withdrawable liquidity, claimable emissions | | client.yield | Mint/redeem PT + YT, read and claim interest, transfer YT, engine solvency | | client.market | PT/SR quotes and trades, YT trades, LP add/remove, reserves and implied APY | | client.vault | Fixed-rate quotes, receipts, deposit, redeem, harvest | | client.router | One-transaction USDC routes for PT, redemption, and yield claims | | client.tokens | USDC/SR/PT/YT balances and the single required PT trustline | | client.portfolio | Wallet-wide balances, interest, LP position, vault receipts, in one call | | client.protocol | Cross-contract health and yield-engine solvency |

Two orchestration helpers live on the client itself: client.buyYtFromUsdc() and client.sellYtToUsdc() (see Two signatures for YT below).

See USAGE.md for a worked example of every flow.

What you need to know

Amounts. Strings and numbers are human amounts; a bigint is already in base units. Every protocol token uses 7 decimals. Prices, APYs and exchange rates use 12-decimal fixed point and come back as exact bigints (plus a …Number / …Pct field where a display value helps).

import { fromBaseUnits, toBaseUnits } from '@spield/sdk';
toBaseUnits('10.25');      // 102500000n
fromBaseUnits(102500000n); // "10.25"

One trustline. PT is the only classic asset, so it is the only trustline a wallet needs. The yield engine contract is the YT token — YT is a contract token and must not get a trustline. Call client.tokens.ensurePtTrustline() once before any flow that delivers PT.

Quotes lag; execution does not. quote_* are views, and a view cannot synchronize SR's stored rate — so a quote can slightly over-state a sale. The router already handles this: leave minOut off and it simulates the real entry point (the same synchronized code path the submission runs) and applies a 1% floor to that, falling back to the quote when simulation cannot run. Pass an explicit minPtOut / minUsdcOut to override, or slippageBps to change the floor.

Two signatures for YT. The deployed Blend-backed stack cannot fit a YT wrap+trade or trade+unwrap into a single Soroban transaction, so client.buyYtFromUsdc() and client.sellYtToUsdc() deliberately use up to two wallet signatures and report progress:

await client.buyYtFromUsdc({
  ytOut: '100',
  onProgress: (step, i, total) => console.log(step, `${i}/${total}`),
});

A deposit cap is in force. SR caps total deposits — currently 200 USDC on Testnet. Read sr.getState() for depositCap, depositHeadroom and depositCapReached rather than assuming; a reached cap blocks new deposits only, never redemptions.

Honest-value reads. sr.exchangeRate is a high-water mark that ratchets up and never falls, so everything built on it can over-report once Blend takes a real loss. These read the venue with no monotonicity guard and keep answering while guarded exits are frozen:

await client.sr.getRealizableRate();                 // what a share is actually worth
await client.sr.getRealizableValue({ shares });      // a holder's actual pro-rata claim
await client.strategy.getPositionValueUnguarded();   // the whole Blend position, live rate
await client.strategy.getClaimableEmissions();       // unclaimed BLND (0 today, see below)

Sitting slightly above the stored rate is normal; only the other direction is interesting. getClaimableEmissions() reads 0 because Blend pays emissions to XLM suppliers and USDC borrowers, not the USDC-supplier side Spield is on — allocations rotate each cycle, so that can change. Claiming is permissionless and pays a destination fixed in contract storage, so an integrator can trigger it but never redirect it.

Errors

Contract reverts are mapped to plain English from the protocol's own error enum, per contract, so Error(Contract, #107) arrives as "The deposit would exceed the SR deposit cap. Check the remaining headroom." The SDK exports SpieldValidationError, SpieldSignerError, SpieldContractError, SpieldRpcError and SpieldConfigurationError, all carrying a code and the original cause.

Confirmation polls RPC for up to two minutes by default, because Testnet can index an accepted transaction well after ledger close. Tune it with confirmationTimeoutMs and confirmationPollIntervalMs in the client options.

Live Testnet deployment

testnet() tracks the 2026-08-30 redeploy, verified live. src/config.ts is the source of truth; these are the addresses it carries:

| | Contract | |---|---| | SR (share token) | CDYAM3NGY5I3SUGPCDQUS25MGCIWT2YOBDSWYT6SJNIPN6A6OOUSSCZY | | Blend strategy | CDPNSWSBVBRF52SED6UD7T2VQH6XODLEHXSCFTZHQP73SNYTKIHP5R2B | | Yield engine (also the YT token) | CDS2Q6L3QCUK4KX633M7QH53GC76EVOUAK7WJ54T3AP3J6IGXIM3LURD | | PT/SR market | CBL7Z3BONITNSWO7NJLT67464HLVVQF5G3REI3XT6KUCK7YNHPICJX5A | | Fixed-rate vault | CDKV7Z7FF3DA57LSO2JA6GFKAIDDIDMZD5XWCMV7G5I3E4ZA3NN2NMH7 | | Router | CDP3VUYH3GEGNOF4XUHKMP5GBTH3SBCL5R3GM5ZTVQAGV7FOAPAQJTGE | | PT (SAC) | CB3T6FOMAH77Z2FMSA2IEVLQEIYOQRRFP7JMJMJGMUCO6HGOOZJZJ7OC | | USDC (SAC) | CAQCFVLOBK5GIULPNZRGATJJMIZL5BSP7X5YJVMGCPTUEPFM4AVSRCJU |

PT trustline asset: SPLDPT7, issuer GDTM2UMJEO6LV5HE2SI56IEWNX5OAF5HV2XNZMVZEDXMMPHZUWXSSLQU.

These contracts carry the full current ABI — keep-alives (bumpHolder / bumpLp / bumpReceipt), caller-bounded LP minting via addLiquidity({ minShares }), resumable vault redemption (getRedeemRemaining, receipt.collected), vault.getSurplus(), and the honest-value reads above. Where an older deployment lacks an entry point the SDK degrades instead of throwing: reads fall back or return null, and addLiquidity uses the three-argument call when minShares is zero.

Scope

Testnet only. There is no mainnet configuration in this SDK. Point it at any other deployment with customNetwork() — see USAGE.md for the full shape.

Development and verification

pnpm install
pnpm run typecheck
pnpm test              # 116 unit + integration tests, no network
pnpm run build
pnpm run test:package  # imports the built ESM and CJS bundles
pnpm run test:e2e:testnet
pnpm run test:all      # typecheck + test + build + test:package + the local-stack suite

The Testnet read suite checks SR, Blend liquidity, yield-engine solvency, PT/SR reserves and prices, vault backing and router quotes against the checked-in live deployment, and cross-checks that the engine, market and vault all agree on one series expiry. The write smoke test is skipped unless a disposable funded SPIELD_E2E_SECRET is provided (copy .env.e2e.example); it only creates and verifies the PT trustline.

Test app and examples

A browser console that exercises every SDK method against Testnet — from the SDK root:

pnpm demo          # vite dev server on http://localhost:5173

On a fresh clone, install the app's own dependencies first: cd examples/sdk-test-app && npm install.

Reads work without a wallet. Writing uses the same multi-wallet connector as the Spield frontend (Freighter, xBull, Rabet, Hana, LOBSTR, Albedo) and needs a disposable funded Testnet account. See the demo README.

examples/ also holds six small runnable programs — amount-utils, protocol-health, market-quotes, portfolio-snapshot, fixed-rate-vault and error-handling. All are read-only, and amount-utils needs no network at all. Each installs and runs from its own directory:

cd examples/protocol-health && npm install && npm start

They are not pnpm workspace members, so a pnpm --filter from the SDK root will not find them.


USAGE.md · CHANGELOG.md · github.com/Suryashish/spield_sdk