@anywalletkit/protocol-staking-spl-stake-pool-solana

中文文档
0.2.12发布于 2026/11/03Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 2235

A simple package that lets @anywalletkit/wallet-solana wallet accounts stake through SPL stake pools (Jito by default): stake SOL → JitoSOL, exit instantly from the reserve or through a stake account, claim, read rates, APY and earnings.

原始使用文档
文档目录9 节
  1. Install
  2. What an SPL stake pool and JitoSOL are
  3. Usage
  4. Configuration
  5. Fail-closed rules
  6. Why the instructions are hand-encoded
  7. Tests
  8. License
  9. Activity

@anywalletkit/protocol-staking-spl-stake-pool-solana

npm

A simple package that lets @anywalletkit/wallet-solana wallet accounts stake through pools on the SPL Stake Pool program — Jito by default: stake SOL → JitoSOL, exit instantly from the reserve or through a stake account, claim, read rates, APY and earnings.

Install

npm install @anywalletkit/protocol-staking-spl-stake-pool-solana @anywalletkit/core
# or: pnpm add @anywalletkit/protocol-staking-spl-stake-pool-solana @anywalletkit/core  ·  yarn add @anywalletkit/protocol-staking-spl-stake-pool-solana @anywalletkit/core

On npm: @anywalletkit/protocol-staking-spl-stake-pool-solana, published from the release workflow with provenance.

Built as the fourth implementation of the StakingProtocol type in @anywalletkit/core — after Lido (ETH liquid staking), SSV (token staking with a cooldown) and Tonstakers (GRAM liquid staking) — and the second one off EVM. The base class in src/staking-protocol.js is the same file, byte-identical: the type is chain-agnostic, and Solana's two-shape exit (instant vs. stake account + epoch boundary) fits its request → queue → claim contract.

The mechanics are extracted from a production wallet (React Native/Hermes). Verification status (2026-09-07, mainnet): stake and instant exit ran with real funds from the wallet (four transactions, amounts matched the module's quotes to the lamport); the delayed exit (stake account + deactivate) is verified by simulateTransaction as a large holder, and the claim only by its instruction layout — a funded delayed → claim cycle needs a position of ≥ 1 SOL worth and is still to be run. scripts/verify-live.mjs re-checks every shape the account can afford, keys never involved.

What an SPL stake pool and JitoSOL are

An SPL stake pool holds stake accounts on many validators plus a reserve. The pool token (JitoSOL for Jito; bSOL and most validator LSTs use the same program) is the non-rebasing receipt whose SOL value is total_lamports / pool_token_supply, moved once per epoch (~2 days) when the pool's crank applies the epoch's rewards. Jito adds MEV tips on top of inflation rewards.

  • Stake is one DepositSol instruction: SOL goes to the reserve, tokens are minted at the rate (Jito: no deposit fee).
  • Instant exit — WithdrawSol: burn tokens, SOL is paid from the reserve at once, minus the pool's SOL withdrawal fee (Jito: 0.1 %). Only while the reserve holds enough (typically ~1 000 SOL).
  • Delayed exit — WithdrawStake: burn tokens, the pool splits a validator stake account to a fresh stake account owned by the wallet (Jito: 0.1 % fee); this module deactivates it in the same transaction. After the epoch boundary the account is inactive and claim sweeps the SOL (and the account's rent) back to the wallet. The stake program's minimum delegation (1 SOL + rent) is the floor for this path.

The wallet's stake accounts are derived with seeds (createWithSeed(wallet, "<pool>-unstake:<i>", StakeProgram), 8 slots), so the queue is recoverable from the wallet alone and no ephemeral keypair ever signs. A slot address someone pre-funded (SOL sent to the predictable seed address, where CreateAccountWithSeed would fail) is still used: the exit first moves that SOL back to the wallet with System TransferWithSeed, then creates the stake account there.

Usage

import WalletManagerSolana from '@anywalletkit/wallet-solana'
import SplStakePoolProtocolSolana from '@anywalletkit/protocol-staking-spl-stake-pool-solana'

const wallet = new WalletManagerSolana(seed, { provider: 'https://api.mainnet-beta.solana.com' })
const account = await wallet.getAccount(0)

const jito = new SplStakePoolProtocolSolana(account) // pool: 'jito' by default; reads ride the account's RPC

// Stake 1 SOL — JitoSOL lands at the pool rate (DepositSolWithSlippage, 0.5 % floor)
const { hash, fee } = await jito.stake({ amount: 10n ** 9n })
await jito.awaitConfirmation(hash)

// Exit: delayed (default — stake account, claim after the epoch boundary) or instant (reserve)
await jito.requestWithdrawal({ amount: 10n ** 9n })                    // ≥ 1 SOL worth
await jito.requestWithdrawal({ amount: 5n * 10n ** 7n, mode: 'instant' })

// The queue, then the claim
const { requests, claimableIds } = await jito.getWithdrawalRequests()
if (claimableIds.length) await jito.claimWithdrawals({ ids: claimableIds })

// Views
await jito.getStakedBalance()   // { balance: JitoSOL, rate: lamports per JitoSOL (1e9), total: lamports }
await jito.getPoolData()        // rate, previousRate, updated, instantLiquidity, fees, minimumStakeLamports…
await jito.getApr()             // percent — on-chain estimate, or your provider's figure via the `apr` hook
await jito.getRewards()         // { earned, entryRate, deposited, minted, firstStakeAt } from the account's own deposits

Configuration

new SplStakePoolProtocolSolana(account, {
  pool: 'jito',                        // or { name, pool, mint, symbol } for any pool on the program
  provider: [url1, url2],              // JSON-RPC URL(s), a @solana/rpc client, or { request(method, params) }
  commitment: 'confirmed',
  slippageBps: 50,                     // floor on quoted amounts (..WithSlippage instructions)
  computeUnitLimit: 300_000,
  computeUnitPrice: 50_000n,           // micro-lamports per unit — ≈ 0.000015 SOL priority fee
  unstakeSlots: 8,                     // delayed exits tracked per wallet
  apr: async () => fetchJitoApy()      // provider APY hook (Jito's stats include MEV); default: epoch-over-epoch estimate
})

A read-only account ({ getAddress }) is enough for every view; writes need an account with sendTransaction. The module hands the account a bare { version: 0, instructions } message — @anywalletkit/wallet-solana sets the blockhash lifetime and the fee-payer signer, signs and broadcasts; the key never enters the module.

Fail-closed rules

Checked before any transaction is built:

  • the configured mint must equal the on-chain pool's mint; the pool account must be owned by the SPL Stake Pool program;
  • the pool must be updated for the current epoch (last_update_epoch == epoch) — the program rejects every deposit and withdrawal otherwise;
  • a delayed exit must yield at least rent + minimum delegation and leave the split-from validator account the same minimum (checked against the live balance, not only the last-update list), else the stake program's Split fails;
  • an instant exit must fit the reserve minus its rent;
  • every amount goes out with a ..WithSlippage floor (default 0.5 %);
  • a pool that restricts SOL deposits or withdrawals to an authority is refused for that path rather than sent to fail.

Why the instructions are hand-encoded

@anywalletkit/wallet-solana is built on @solana/* 3.x. The published stake-pool client wants web3.js v1 and @solana-program/stake wants kit ≥ 5; either would put a second Solana stack into the consumer's bundle. The six instructions this module needs have stable, documented layouts (Stake Pool DepositSol 14 / WithdrawStake 10 / WithdrawSol 16 and their ..WithSlippage variants 25 / 24 / 26, System CreateAccountWithSeed 3, Stake Deactivate 5 / Withdraw 4), verified against the program sources and by simulation — src/spl-stake-pool-codec.js encodes them with @solana/addresses and @solana/instructions only.

Tests

npm test               # unit tests over mainnet fixtures (pool state, validator list, stake account)
npm run verify:live    # reads + simulateTransaction of every shape on mainnet, no keys

License

Apache-2.0

Activity

describeActivity(tx, { own }) labels SPL Stake Pool transactions for a wallet's history, offline and synchronously. A transaction is this module's when the Stake Pool program SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy is among the programs it invoked (call.programs / call.to). The instruction tag — first byte of the stake-pool instruction's base58 call.data when the source passes it — picks the kind: DepositSol 14 / DepositSolWithSlippage 25 → stake "Staked SOL"; WithdrawSol 16 / 26 → unstake "Unstaked JitoSOL" (instant); WithdrawStake 10 / 24 → unstake "Requested unstake of JitoSOL" (delayed). Without data, the pool-token movement decides (minted to the wallet → stake, burned → unstake, with SOL arriving → instant). Pool tokens of every preset (SPL_STAKE_POOL_ADDRESS_MAP) and of the instance's pool are labelled and name the subtitle ("Jito · Solana"); an unknown pool on the same program is still recognized as "SPL Stake Pool · Solana". counterparty is the pool account. Sweeping a finished delayed unstake (a Stake-program withdraw from a derived account) is not recognized — it carries no stake-pool instruction. own should contain the wallet and its token accounts: sources normalize SPL movements to owners, but a source that keeps token-account addresses still nets correctly when the ATA is in own.

Fixtures in fixtures/activity/ are the test wallet's funded Jito run (DepositSol ×2, WithdrawSol ×3; 2026-09-07 … 10-07, from getTransaction jsonParsed); negatives/ holds a plain SOL transfer and a plain JitoSOL SPL transfer (shapes only).

版本与发布记录

@anywalletkit/protocol-staking-spl-stake-pool-solana 共发布 12 个版本,首次发布于 2026/10/25;过去 12 个月发布了 12 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.2.12latest2026/11/035 天前
0.2.112026/10/308 天前
0.2.102026/10/309 天前
0.2.92026/10/2811 天前
0.2.82026/10/2712 天前
0.2.72026/10/2612 天前

关于 @anywalletkit/protocol-staking-spl-stake-pool-solana 的常见问题

@anywalletkit/protocol-staking-spl-stake-pool-solana 是什么?

A simple package that lets @anywalletkit/wallet-solana wallet accounts stake through SPL stake pools (Jito by default): stake SOL → JitoSOL, exit instantly from the reserve or through a stake account, claim, read rates, APY and earnings.

如何安装 @anywalletkit/protocol-staking-spl-stake-pool-solana?

在项目目录运行 npm install @anywalletkit/protocol-staking-spl-stake-pool-solana,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@anywalletkit/core(0.8.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@anywalletkit/protocol-staking-spl-stake-pool-solana 支持 TypeScript 吗?

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

@anywalletkit/protocol-staking-spl-stake-pool-solana 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@anywalletkit/protocol-staking-spl-stake-pool-solana 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@anywalletkit/protocol-staking-spl-stake-pool-solana 可以商用吗?

@anywalletkit/protocol-staking-spl-stake-pool-solana 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@anywalletkit/protocol-staking-spl-stake-pool-solana 的下载量有多少?

根据 npm 官方下载统计,@anywalletkit/protocol-staking-spl-stake-pool-solana 在 2026/10/06 – 2026/11/04 这 30 天内被下载 2,235 次,日均约 75 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@anywalletkit/protocol-staking-spl-stake-pool-solana 还在维护吗?

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