@anywalletkit/protocol-staking-ssv-evm

中文文档
0.3.11发布于 2026/11/03Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 2199

A simple package that lets @anywalletkit/wallet-evm wallet accounts stake SSV through SSV Network: stake SSV → cSSV, claim ETH rewards, cooldown unstake and withdraw.

原始使用文档
文档目录8 节
  1. Install
  2. What SSV Network and the SSV token are
  3. Usage
  4. How it maps onto the interface
  5. Why the write path looks the way it does
  6. Configuration
  7. Tests
  8. Activity

@anywalletkit/protocol-staking-ssv-evm

npm

A simple package that lets @anywalletkit/wallet-evm wallet accounts stake through SSV Network: stake SSV → cSSV, claim the ETH rewards, exit through the network's cooldown, and read APR and network stats.

Install

npm install @anywalletkit/protocol-staking-ssv-evm @anywalletkit/core
# or: pnpm add @anywalletkit/protocol-staking-ssv-evm @anywalletkit/core  ·  yarn add @anywalletkit/protocol-staking-ssv-evm @anywalletkit/core

On npm: @anywalletkit/protocol-staking-ssv-evm, published from the release workflow with provenance.

Built as the second implementation of the StakingProtocol type in @anywalletkit/core (the first is @anywalletkit/protocol-staking-lido-evm). The base class lives in @anywalletkit/core (src/staking-protocol.ts here keeps the runtime IStakingProtocol marker and the module's own types). A token-staking protocol with a cooldown exit fitting it unchanged is the point: the interface is not Lido-shaped.

The mechanics are extracted from a production wallet (React Native/Hermes) where every flow is exercised with real funds.

What SSV Network and the SSV token are

SSV Network is distributed validator technology (DVT) for Ethereum: a validator's key is split among several independent operators, so staking keeps running when any one of them is down or misbehaves. A large share of Ethereum liquid staking runs its validators on it. Operators pay the network's fees in ETH.

SSV is the network's ERC-20 token. Since SSV Network v2 (mainnet, 2026) SSV holders can stake it: the network mints cSSV 1:1 — a transferable, non-rebasing receipt token — and cSSV holders receive a pro-rata share of the ETH fees, accrued block by block through an ETH-per-share index and claimable at any time without unstaking. Staked weight also delegates voting power to the network's Effective Balance oracles. Getting the SSV back is a cooldown exit: requestUnstake burns cSSV into a cooldown entry (7 days at launch, DAO-tunable, not cancellable), withdrawUnlocked pays out every entry whose cooldown has ended. There is no slashing for stakers. The APR is ETH-denominated on an SSV-denominated stake, so it moves with SSV's price.

Usage

import WalletManagerEvm from '@anywalletkit/wallet-evm'
import SsvProtocolEvm from '@anywalletkit/protocol-staking-ssv-evm'

const wallet = new WalletManagerEvm(seed, { provider: 'https://rpc.example.org' })
const account = await wallet.getAccount(0)

const ssv = new SsvProtocolEvm(account)

// Stake — approve (awaited) + stake on the first go, one transaction after
const { hash, fee, approveHash } = await ssv.stake({ amount: 10n ** 18n })

// Rewards accrue in ETH; claim any time, the stake stays put
await ssv.getClaimableRewards()            // wei
await ssv.claimRewards()

// Exit, phase 1: burn cSSV into a cooldown entry (irreversible)
await ssv.requestWithdrawal({ amount: 10n ** 18n })

// …after the cooldown — exit, phase 2: withdraw every unlocked entry as SSV
const { claimableIds } = await ssv.getWithdrawalRequests()
if (claimableIds.length) await ssv.claimWithdrawals()

// Views
await ssv.getStakedBalance()   // { balance: cSSV, wrappedBalance: 0n, rate: 1e18, total }
await ssv.getApr()             // 23.8 (percent, from SSV Network's API)

SSV-specific extras beyond the interface:

await ssv.getTokenBalance()          // liquid SSV on the account
await ssv.getClaimableRewards()      // accrued ETH (wei)
await ssv.claimRewards()             // claimEthRewards()
await ssv.getCooldown()              // seconds — read it, never hardcode 7 days
await ssv.getNetworkStats()          // { totalStaked, rewardsPool, accEthPerShare }
await ssv.getAprHistory({ limit: 7 })// daily samples with SSV/ETH prices

How it maps onto the interface

IStakingProtocolSSV Network
stake({ amount })allowance check → approve (awaited to a mined receipt) → stake on the SSVNetwork proxy; cSSV minted 1:1
requestWithdrawal({ amount })requestUnstake — burns cSSV into a cooldown entry; token ignored (single staked form)
getWithdrawalRequests()pendingUnstake → entries with id = position, unlockTime, claimable = unlockTime <= now; amounts are SSV
claimWithdrawals()withdrawUnlocked — pays every unlocked entry; ids are informational
getStakedBalance()cSSV balance, wrappedBalance 0, rate 1e18
getApr()api.ssv.network/…/apr/current — the number stake.ssv.network shows

Two honest differences from Lido are documented on the methods rather than papered over: the exit pays the staked token (SSV), not the chain's native token, and the withdraw call is all-or-nothing on the network side.

Why the write path looks the way it does

  • No permit anywhere: neither SSV nor cSSV implements EIP-2612 (checked: nonces / DOMAIN_SEPARATOR revert on both). The first stake is therefore approve + stake; the approval is awaited to a mined receipt because stake's gas estimate reverts against an unmined allowance. With a standing allowance it is one transaction.
  • Proven before broadcast: every write is simulated with eth_call from the account first. The staking module reverts with bare custom errors — StakeTooLow, UnstakeAmountExceedsBalance, NothingToWithdraw, NothingToClaim, InsufficientBalance… — and describeRevert turns the 4-byte selector back into a named error, wherever the provider (viem) buried it (error.data, info.error.data, cause, or the message text). A user sees "no unstake request has finished its cooldown yet", not "execution reverted", and pays no gas for it.
  • Claim rounding: claimEthRewards pays accrued − accrued % 100000 wei and reverts when that is zero; claimRewards checks previewClaimableEth against ETH_CLAIM_UNIT up front.
  • Unstable ids: cooldown entries are addressed by position and withdrawUnlocked compacts the list — re-read getWithdrawalRequests after every write; nothing here caches ids.
  • Structural account checks: writability is typeof account.sendTransaction === 'function', not instanceof.
  • No AbortSignal.timeout / AbortSignal.any: Hermes ships AbortController without those statics; nothing here depends on them.
  • REST is decoration: APR and APR history come from the same API stake.ssv.network reads (CORS *), overridable via config.endpoints; the on-chain flows never depend on them, and getAprHistory degrades to an empty array.

Configuration

new SsvProtocolEvm(account, {
  provider,   // RPC url or EIP-1193; defaults to the account's provider
  chainId,    // default 1; other chains must supply addresses
  addresses,  // { network, views, ssvToken, cssvToken }
  endpoints   // { apr, aprHistory }
})

Only mainnet ships as a default deployment — deliberately. The Hoodi testnet addresses are listed in src/ssv-address-map.ts for explicit configuration, so nobody stakes against an address a default quietly supplied.

Mainnet contracts (verified on-chain against the live proxy, v2.0.0): SSVNetwork 0xDD9BC35aE942eF0cFa76930954a156B3fF30a4E1, SSVNetworkViews 0xafE830B6Ee262ba11cce5F32fDCd760FFE6a66e4, SSV 0x9D65fF81a3c488d585bBfb0Bfe3c7707c7917f54, cSSV 0xe018D31F120A637828F46aFD6c64EC099d960546.

Tests

pnpm build            # TypeScript → dist/ (tsup: ESM + CJS + d.ts); built on viem
pnpm test             # offline unit tests (vitest, stubbed EIP-1193 provider) + conformance
pnpm verify:live      # read-only checks against mainnet (views, API, eth_call proofs; needs a build)

Activity

describeActivity(tx, { own }) labels SSV staking transactions for a wallet's history, offline and synchronously. A transaction is SSV's when it calls the network proxy the instance is configured with (mainnet by default) on that chain and the selector is stake → stake "Staked SSV", requestUnstake → unstake "Requested unstake", withdrawUnlocked → claim "Withdrew SSV", claimEthRewards → claim "Claimed ETH rewards" (SSV_ACTIONS, selectors computed from the signatures at module load). Operator / cluster management calls on the same proxy, SSV approves and anything else yield null. Subtitle "SSV Network · Ethereum", counterparty the proxy; assetsIn / assetsOut are the wallet's net movements (SSV, cSSV, ETH rewards) labelled by the module.

Fixtures in fixtures/activity/ are the test wallet's funded run (stake, requestUnstake ×2, withdrawUnlocked, claimEthRewards; 2026-09-03 … 10-07); negatives/ holds a Lido submit and a USDT approve.

版本与发布记录

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

版本发布日期距今
0.3.11latest2026/11/035 天前
0.3.102026/10/309 天前
0.3.92026/10/2910 天前
0.3.82026/10/2811 天前
0.3.72026/10/2712 天前
0.3.62026/10/2612 天前

关于 @anywalletkit/protocol-staking-ssv-evm 的常见问题

@anywalletkit/protocol-staking-ssv-evm 是什么?

A simple package that lets @anywalletkit/wallet-evm wallet accounts stake SSV through SSV Network: stake SSV → cSSV, claim ETH rewards, cooldown unstake and withdraw.

如何安装 @anywalletkit/protocol-staking-ssv-evm?

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

@anywalletkit/protocol-staking-ssv-evm 支持 TypeScript 吗?

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

@anywalletkit/protocol-staking-ssv-evm 支持 ESM 还是 CommonJS?

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

@anywalletkit/protocol-staking-ssv-evm 需要什么版本的 Node.js?

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

@anywalletkit/protocol-staking-ssv-evm 可以商用吗?

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

@anywalletkit/protocol-staking-ssv-evm 的下载量有多少?

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

@anywalletkit/protocol-staking-ssv-evm 还在维护吗?

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