UNPKG

ssv-keys

Version:

CLI Tool for splitting a validator key into a predefined threshold of shares via Shamir-Secret-Sharing (SSS), and encrypt them with a set of operator keys.

85 lines (68 loc) 3.27 kB
import { KeyShares, KeySharesItem, SSVKeys, SSVKeysException } from "@ssv-labs/ssv-sdk"; const path = require('path'); const fsp = require('fs').promises; const operatorKeys = require('./operators.json'); const keystore = require('./test.keystore.json'); const operatorIds = require('./operatorIds.json'); const keystorePassword = 'testtest'; // The nonce of the owner within the SSV contract (increments after each validator registration), obtained using the ssv-scanner tool const TEST_OWNER_NONCE = 1; // The cluster owner address const TEST_OWNER_ADDRESS = '0x81592c3de184a3e2c0dcb5a261bc107bfa91f494'; const getKeySharesFilePath = (step: any) => { return `${path.join(process.cwd(), 'data')}${path.sep}keyshares-step-${step}.json`; }; /** * This is more complex example demonstrating usage of SSVKeys SDK together with * KeyShares file which can be useful in a different flows for solo staker, staking provider or web developer. */ async function main() { // Initialize SSVKeys SDK const ssvKeys = new SSVKeys(); const { publicKey, privateKey } = await ssvKeys.extractKeys(keystore, keystorePassword); // At some point we get operator IDs and public keys and want to save them too const operators = operatorKeys.map((operatorKey: any, index: number) => ({ id: operatorIds[index], operatorKey, })); const keySharesItem = new KeySharesItem(); // Save it with version only and with no any data. await fsp.writeFile(getKeySharesFilePath(1), keySharesItem.toJson(), { encoding: 'utf-8' }); await keySharesItem.update({ operators }); await fsp.writeFile(getKeySharesFilePath(2), keySharesItem.toJson(), { encoding: 'utf-8' }); // Now save to key shares file encrypted shares and validator public key await keySharesItem.update({ ownerAddress: TEST_OWNER_ADDRESS, ownerNonce: TEST_OWNER_NONCE, publicKey }); await fsp.writeFile(getKeySharesFilePath(3), keySharesItem.toJson(), { encoding: 'utf-8' }); // Build shares from operator IDs and public keys const encryptedShares = await ssvKeys.buildShares(privateKey, operators); // Build final web3 transaction payload and update keyshares file with payload data await keySharesItem.buildPayload({ publicKey, operators, encryptedShares, }, { ownerAddress: TEST_OWNER_ADDRESS, ownerNonce: TEST_OWNER_NONCE, privateKey }); const keyShares = new KeyShares(); keyShares.add(keySharesItem); await fsp.writeFile(getKeySharesFilePath(4), keyShares.toJson(), { encoding: 'utf-8' }); // example to work with keyshares from file const jsonKeyShares = await fsp.readFile('./data/test-error.json', { encoding: 'utf-8' }); const keyShares2 = await KeyShares.fromJson(jsonKeyShares); for (const keySharesItem of keyShares2.list()) { if (keySharesItem.error) { if (keySharesItem.error instanceof SSVKeysException) { console.log('SSVKeys Error name:', keySharesItem.error.name); console.log('SSVKeys Error message:', keySharesItem.error.message); console.log('SSVKeys Error trace:', keySharesItem.error.trace); } else { // Handle other types of errors console.log('Other Error caught:', keySharesItem.error); } } console.log(keySharesItem.toJson()); } } void main();