⚠️ Development Notice: This SDK is currently under active development and testing. It is not recommended for production use at this time. For updates and documentation, please refer to our official documentation.
The SSV SDK is a TypeScript library for interacting with the SSV network, enabling distributed validator operations on Ethereum.
The SDK consists of five main modules:
- Clusters: Manage validator clusters, handle deposits, and register validators
- DAO: Manage DAO-related actions and values
- Operators: Interact with network operators and manage operator relationships
- API: Access network data, query states, and retrieve operational information
- Utils: Helper functions for keyshare validation, share generation, and other utilities
# Using npm
npm i @ssv-labs/ssv-sdk
# Using yarn
yarn add @ssv-labs/ssv-sdk
# Using pnpm
pnpm install @ssv-labs/ssv-sdkimport { SSVSDK, chains } from '@ssv-labs/ssv-sdk';
import { createPublicClient, createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
const chain = chains.mainnet; // or chains.hoodi
const transport = http();
const publicClient = createPublicClient({
chain,
transport,
});
const account = privateKeyToAccount('0x...');
const walletClient = createWalletClient({
account,
chain,
transport,
});
const sdk = new SSVSDK({
publicClient,
walletClient,
extendedConfig: {
beacon: {
// Optional — only needed for the beacon validator methods below.
endpoint: 'https://your-beacon-node.example',
},
},
});// Query operators
const { operators } = await sdk.api.getOperators({
operatorIds: ['220', '221', '223', '224'],
});
// Get owner nonce
const { nonce } = await sdk.api.getOwnerNonce({
owner: 'your_wallet_address',
});
// Export SDK-generated payloads into a webapp-ready keyshares JSON file (Node.js only)
await sdk.utils.writeKeysharesFile({
path: './keyshares-webapp.json',
shares,
ownerAddress: 'your_wallet_address',
nonce,
});
// Read normalized beacon validator state
const validator = await sdk.api.getBeaconValidatorState({
validatorId: '0xvalidator_public_key',
});
// Wait for a validator to become active
await sdk.api.waitForBeaconValidatorActivation({
validatorId: '0xvalidator_public_key',
pollIntervalMs: 12_000,
timeoutMs: 30 * 60 * 1000,
// failOnNotFound: true, // fail fast instead of treating "not found" as "not yet active"
// requestTimeoutMs: 10_000, // per-attempt timeout, independent of pollIntervalMs (defaults to 10s)
});getClusterSnapshot is the canonical cluster snapshot API.
Snapshot-aware SDK read methods return the queried data together with the subgraph snapshot block number, for example:
sdk.api.getOwnerNonce(...) -> { blockNumber, nonce }sdk.api.getOperators(...) -> { blockNumber, operators }sdk.api.getClusterSnapshot(...) -> { blockNumber, cluster }
| SDK version | Method name |
|---|---|
0.1.x |
sdk.api.getClusterSnapshot({ id }) |
1.x |
sdk.api.getClusterSnapshot({ id }) |
sdk.api.toSolidityCluster is no longer part of the public subgraph API. The internal utility toSolidityCluster(...) in utils/cluster still exists for converting cluster data into the Solidity struct shape used by contract calls.
sdk.utils.writeKeysharesFile(...) is a Node.js utility and relies on filesystem access.
Beacon validator helpers require extendedConfig.beacon.endpoint to be configured; the SDK works normally without it otherwise. sdk.api.getBeaconValidatorState(...) and sdk.api.getBeaconValidatorStates(...) return normalized beacon validator data, and sdk.api.waitForBeaconValidatorActivation(...) polls until a validator becomes active — its requestTimeoutMs option (default 10_000) bounds each individual poll attempt independently of pollIntervalMs, and failOnNotFound (default false) controls whether a not-yet-visible validator fails fast or keeps polling. Failures surface as BeaconHttpError (carries the HTTP status; retried automatically for 408/429/5xx, thrown immediately for other statuses) or BeaconValidationError (a malformed or unexpected response; always thrown immediately, never retried). sdk.api.getBeaconValidator(...) and sdk.api.getBeaconValidators(...) are lower-level reads that only validate the response envelope, not each validator's field-level shape — prefer the ...State/...States variants unless you specifically need the raw shape. sdk.api.getBeaconValidatorLifecycleStage(...) derives a simplified lifecycle stage (pending/active/exited/withdrawal_ready/withdrawn) from a normalized status.
import { parseEther } from 'viem';
// Deposit to cluster
await sdk.clusters.deposit({
id: 'your_cluster_id',
amount: parseEther('30'),
});Note: The current
sdk.clusters.depositpath is payable and does not perform ERC-20 allowance checks orapprovecalls.
To register validators, you'll need to:
- Create shares from your keyshares JSON file
- Register the validator using the created shares
import { parseEther } from 'viem';
// Your keyshares JSON file containing the validator's data
import keyshares from 'path/to/keyshares.json';
// First, validate and create shares from your keyshares
try {
const result = await sdk.utils.validateSharesPreRegistration({
operatorIds: ['220', '221', '223', '224'],
keyshares,
});
// Register validators using the clusters API
const receipt = await sdk.clusters
.registerValidators({
args: {
keyshares: result.available,
depositAmount: parseEther('2'),
},
})
.then((tx) => tx.wait());
} catch (e) {
// something went wrong
}For detailed documentation and examples, visit our official documentation.
