Generate and Validate Keyshares
This part of the SSV SDK lets you generate validator keyshares by splitting validator keys into threshold shares with Shamir Secret Sharing (SSS) and encrypting them with operator public keys.
The resulting shares and signatures are packaged as sharesData, which is used during validator registration through the SSV smart contracts to distribute keyshares from stakers to operators.
The SDK can also validate keyshares before registration to help ensure the validator can be registered successfully.
Prerequisites
Before using this example, make sure you have:
Install dependencies
Install the SSV SDK and required dependencies:
npm install @ssv-labs/ssv-sdk viem
Initialize the SDK
Create an SDK instance to interact with the SSV Network:
import { SSVSDK, chains } from '@ssv-labs/ssv-sdk'import { createPublicClient, http } from 'viem'
// Use chains.mainnet for mainnetconst publicClient = createPublicClient({ chain: chains.hoodi, transport: http('https://ethereum-hoodi-rpc.publicnode.com'),})
const sdk = new SSVSDK({ publicClient,})Generate Keyshares
Use generateKeyShares to create keyshares from a validator keystore and encrypt them with the selected operator public keys.
Operator public keys are required to encrypt keyshares. These can be retrieved using the SDK based on operator IDs.
const ownerAddress = "0xA4831B989972605A62141a667578d742927Cbef9"const nonce = Number(await sdk.api.getOwnerNonce({ owner: ownerAddress }))const operatorIds = ["1", "2", "3", "4"]
// Fetch operator metadata from the SDK APIconst operators = await sdk.api.getOperators({ operatorIds })if (operators.length !== operatorIds.length) { throw new Error('One or more operator IDs were not found')}
// Build operator public keys in the same order as operatorIds.const operatorKeys = operatorIds.map((id) => { const op = operators.find((o) => o.id === id) if (!op) throw new Error(`Operator ${id} not found`) return op.publicKey})
// Generate encrypted keyshares from keystore(s).const keysharesPayload = await sdk.utils.generateKeyShares({ keystore: JSON.stringify(keystoresObject), // or string[] keystorePassword: "INSERT_PASSWORD", operatorKeys, operatorIds: operatorIds.map(Number), ownerAddress, nonce,})Validate Keyshares
Use validateSharesPreRegistration to verify that the generated keyshares and operator IDs are valid before registering the validator.
const ownerAddress = "0xA4831B989972605A62141a667578d742927Cbef9"const operatorIds = ["1", "2", "3", "4"]
// Validate keyshares and operator set before registration.const validatedShares = await sdk.utils.validateSharesPreRegistration({ keyshares: keysharesPayload, operatorIds, ownerAddress, // required if no walletClient in sdk init})
console.log(validatedShares)A valid keyshare can then be used to register a validator.