From e401862d6430a2bd56d4038abbad282deee3e58e Mon Sep 17 00:00:00 2001 From: guy muroch Date: Thu, 29 Jun 2023 14:31:16 +0300 Subject: [PATCH 01/25] change ssv-keys version --- examples/server-worker/index.ts | 2 +- examples/server-worker/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 22c0453..3aff695 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -74,7 +74,7 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { publicKey, operators, encryptedShares, - }, { + },{ ownerAddress: TEST_OWNER_ADDRESS, ownerNonce: TEST_OWNER_NONCE, privateKey diff --git a/examples/server-worker/package.json b/examples/server-worker/package.json index 26441eb..a9746af 100644 --- a/examples/server-worker/package.json +++ b/examples/server-worker/package.json @@ -18,7 +18,7 @@ "@types/body-parser": "^1.19.2", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.14", - "ssv-keys": "https://github.com/bloxapp/ssv-keys.git#v3" + "ssv-keys": "https://github.com/bloxapp/ssv-keys.git" }, "devDependencies": { "body-parser": "^1.20.1", From 4d214b2b8c4650e6726388a82aae551780a71e0e Mon Sep 17 00:00:00 2001 From: guy muroch Date: Thu, 29 Jun 2023 15:08:41 +0300 Subject: [PATCH 02/25] test --- examples/server-worker/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 3aff695..4aac135 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -85,5 +85,6 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { }); app.listen(port, () => { + console.log('works!!!!'); console.log(`⚡️[server]: Server is running at https://localhost:${port}`); }); From 755ce04050195d1611bbeeee801002e58dd658fa Mon Sep 17 00:00:00 2001 From: guy muroch Date: Thu, 29 Jun 2023 15:14:51 +0300 Subject: [PATCH 03/25] test --- examples/server-worker/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/server-worker/package.json b/examples/server-worker/package.json index a9746af..58e3c6a 100644 --- a/examples/server-worker/package.json +++ b/examples/server-worker/package.json @@ -18,7 +18,7 @@ "@types/body-parser": "^1.19.2", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.14", - "ssv-keys": "https://github.com/bloxapp/ssv-keys.git" + "ssv-keys": "https://github.com/bloxapp/ssv-keys.git#hamlet-support" }, "devDependencies": { "body-parser": "^1.20.1", From dd626ed8c80d6cf472574382b0fc5cc531614026 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 13:51:50 +0300 Subject: [PATCH 04/25] adding support for v2 --- src/lib/KeyShares/KeySharesData/KeySharesPayload.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts b/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts index a588150..0cbf253 100644 --- a/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts +++ b/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts @@ -26,6 +26,8 @@ export class KeySharesPayload implements IKeySharesPayload { data.encryptedShares.map((share: EncryptShare) => share.publicKey), data.encryptedShares.map((share: EncryptShare) => share.privateKey) ), + encryptedKeys: data.encryptedShares.map((share: EncryptShare) => share.privateKey), + publicKeys: data.encryptedShares.map((share: EncryptShare) => share.publicKey), amount: 'Amount of SSV tokens to be deposited to your validator\'s cluster balance (mandatory only for 1st validator in a cluster)', cluster: 'The latest cluster snapshot data, obtained using the cluster-scanner tool. If this is the cluster\'s 1st validator then use - {0,0,0,0,true}', }; From f270f8d75e4e054dcd5cc2332e3a3894903db646 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 15:02:24 +0300 Subject: [PATCH 05/25] adding support for v2 --- examples/server-worker/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 4aac135..5fa7881 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -85,6 +85,6 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { }); app.listen(port, () => { - console.log('works!!!!'); + console.log('guy!!!!'); console.log(`⚡️[server]: Server is running at https://localhost:${port}`); }); From 8f9964ebc6cedb8c02957758013da773c8206ce7 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 15:47:21 +0300 Subject: [PATCH 06/25] adding support for v2 --- examples/server-worker/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 5fa7881..da275fd 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -85,6 +85,6 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { }); app.listen(port, () => { - console.log('guy!!!!'); + console.log('!it works!!'); console.log(`⚡️[server]: Server is running at https://localhost:${port}`); }); From efbe3d87af50731bb7bf6aeae7e7802e8e4c3f04 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 16:04:36 +0300 Subject: [PATCH 07/25] adding support for v2 --- examples/server-worker/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index da275fd..95f7185 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -70,7 +70,7 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { // The cluster owner address const TEST_OWNER_ADDRESS = '0x81592c3de184a3e2c0dcb5a261bc107bfa91f494'; - await keyShares.buildPayload({ + const newPayload = await keyShares.buildPayload({ publicKey, operators, encryptedShares, @@ -79,6 +79,8 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { ownerNonce: TEST_OWNER_NONCE, privateKey }); + keyShares.payload = newPayload; + console.log(newPayload); console.log(`Built key shares for operators: ${String(operators_ids)} and public key: ${keystore.pubkey}`); res.json(JSON.parse(keyShares.toJson())); From 50f022884025fc7bccd83ec80c6555fba0068ae6 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 17:09:41 +0300 Subject: [PATCH 08/25] adding support for v2 --- examples/server-worker/index.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 95f7185..d1afc76 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -79,8 +79,11 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { ownerNonce: TEST_OWNER_NONCE, privateKey }); - keyShares.payload = newPayload; - console.log(newPayload); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); + console.log(newPayload.sharesData); + console.log(keyShares.payload.readable); + keyShares.payload.readable.sharesData = newPayload.sharesData; + console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); console.log(`Built key shares for operators: ${String(operators_ids)} and public key: ${keystore.pubkey}`); res.json(JSON.parse(keyShares.toJson())); From ee71ea5082dc2886c78ed068f91d38e95751b2bf Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 17:26:09 +0300 Subject: [PATCH 09/25] adding support for v2 --- examples/server-worker/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index d1afc76..d0512c9 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -80,9 +80,9 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { privateKey }); console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); - console.log(newPayload.sharesData); - console.log(keyShares.payload.readable); - keyShares.payload.readable.sharesData = newPayload.sharesData; + console.log(newPayload); + keyShares.payload.readable.publicKeys = newPayload.publicKeys; + keyShares.payload.readable.encryptedKeys = newPayload.encryptedKeys; console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); console.log(`Built key shares for operators: ${String(operators_ids)} and public key: ${keystore.pubkey}`); From e8598f9fdbdabb29a21882d21b23f408ef47f460 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 17:33:44 +0300 Subject: [PATCH 10/25] adding support for v2 --- examples/server-worker/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index d0512c9..1c11deb 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -81,8 +81,8 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { }); console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); console.log(newPayload); - keyShares.payload.readable.publicKeys = newPayload.publicKeys; keyShares.payload.readable.encryptedKeys = newPayload.encryptedKeys; + keyShares.payload.readable.publicKeys = newPayload.publicKeys; console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); console.log(`Built key shares for operators: ${String(operators_ids)} and public key: ${keystore.pubkey}`); From e2c1a05e768fcfa31cb34516d1ece7e51e41a53d Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 17:56:22 +0300 Subject: [PATCH 11/25] adding support for v2 --- src/lib/KeyShares/KeyShares.ts | 4 ++++ src/lib/KeyShares/KeySharesData/KeySharesPayload.ts | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/lib/KeyShares/KeyShares.ts b/src/lib/KeyShares/KeyShares.ts index c9ba278..9bcd845 100644 --- a/src/lib/KeyShares/KeyShares.ts +++ b/src/lib/KeyShares/KeyShares.ts @@ -86,6 +86,10 @@ export class KeyShares { encryptedShares: metaData.encryptedShares, }); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>') + console.log(payload); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>') + const signature = await web3Helper.buildSignature(`${address}:${ownerNonce}`, privateKey); const signSharesBytes = web3Helper.hexArrayToBytes([signature, payload.sharesData]); diff --git a/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts b/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts index 0cbf253..45339dd 100644 --- a/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts +++ b/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts @@ -31,6 +31,9 @@ export class KeySharesPayload implements IKeySharesPayload { amount: 'Amount of SSV tokens to be deposited to your validator\'s cluster balance (mandatory only for 1st validator in a cluster)', cluster: 'The latest cluster snapshot data, obtained using the cluster-scanner tool. If this is the cluster\'s 1st validator then use - {0,0,0,0,true}', }; + console.log('<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>') + console.log(this.readable); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>') return this.readable; } } From 212f293d09a1bde00f0d7f41b16f06e55e0b018f Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 17:56:34 +0300 Subject: [PATCH 12/25] adding support for v2 --- examples/server-worker/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 1c11deb..ae3e157 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -90,6 +90,6 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { }); app.listen(port, () => { - console.log('!it works!!'); + console.log('!it works2222!!'); console.log(`⚡️[server]: Server is running at https://localhost:${port}`); }); From 126490aa4ef6579757c0cf45abd2816bcdb4d628 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 18:14:19 +0300 Subject: [PATCH 13/25] adding support for v2 --- examples/server-worker/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index ae3e157..a179ed1 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -80,7 +80,6 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { privateKey }); console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); - console.log(newPayload); keyShares.payload.readable.encryptedKeys = newPayload.encryptedKeys; keyShares.payload.readable.publicKeys = newPayload.publicKeys; console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); @@ -90,6 +89,6 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { }); app.listen(port, () => { - console.log('!it works2222!!'); + console.log('brotherit!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); console.log(`⚡️[server]: Server is running at https://localhost:${port}`); }); From 4bf44ed73e6d442037ec2dd343af7206a00a076f Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 18:14:26 +0300 Subject: [PATCH 14/25] adding support for v2 --- examples/server-worker/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/server-worker/package.json b/examples/server-worker/package.json index 58e3c6a..468f05b 100644 --- a/examples/server-worker/package.json +++ b/examples/server-worker/package.json @@ -1,6 +1,6 @@ { "name": "ssv-keys-server-worker", - "version": "1.0.0", + "version": "1.0.1", "description": "Example of expressjs server worker accepting data to build key shares and responding with keyshares json", "main": "./dist/index.js", "scripts": { From b1a1166d28c43586a9ce02a50ba7dea81ff4ba1e Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 18:17:41 +0300 Subject: [PATCH 15/25] adding support for v2 --- examples/server-worker/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/server-worker/package.json b/examples/server-worker/package.json index 468f05b..caad8cc 100644 --- a/examples/server-worker/package.json +++ b/examples/server-worker/package.json @@ -1,6 +1,6 @@ { "name": "ssv-keys-server-worker", - "version": "1.0.1", + "version": "1.0.2", "description": "Example of expressjs server worker accepting data to build key shares and responding with keyshares json", "main": "./dist/index.js", "scripts": { diff --git a/package.json b/package.json index ec161ed..a743e8b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ssv-keys", - "version": "1.0.1", + "version": "1.0.2", "description": "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.", "author": "SSV.Network", "repository": "https://github.com/bloxapp/ssv-keys", From 7febf76a037001b6ad44b85d855d0d3a0eb43037 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 18:40:35 +0300 Subject: [PATCH 16/25] adding support for v2 --- examples/server-worker/index.ts | 12 +++++++----- examples/server-worker/package.json | 2 +- package.json | 2 +- src/lib/KeyShares/KeyShares.ts | 4 ---- src/lib/KeyShares/KeySharesData/KeySharesPayload.ts | 3 --- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index a179ed1..55b1066 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -3,6 +3,7 @@ import { constants } from 'http2'; import bodyParser from 'body-parser'; import { SSVKeys, KeyShares } from 'ssv-keys'; import express, { Express, Request, Response } from 'express'; +import {EncryptShare} from '../../src/lib/Encryption/Encryption'; dotenv.config(); @@ -70,7 +71,7 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { // The cluster owner address const TEST_OWNER_ADDRESS = '0x81592c3de184a3e2c0dcb5a261bc107bfa91f494'; - const newPayload = await keyShares.buildPayload({ + await keyShares.buildPayload({ publicKey, operators, encryptedShares, @@ -79,10 +80,11 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { ownerNonce: TEST_OWNER_NONCE, privateKey }); - console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); - keyShares.payload.readable.encryptedKeys = newPayload.encryptedKeys; - keyShares.payload.readable.publicKeys = newPayload.publicKeys; - console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); + keyShares.payload.readable.encryptedKeys = encryptedShares.map((share: EncryptShare) => share.privateKey); + keyShares.payload.readable.publicKeys = encryptedShares.map((share: EncryptShare) => share.publicKey); + console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); console.log(`Built key shares for operators: ${String(operators_ids)} and public key: ${keystore.pubkey}`); res.json(JSON.parse(keyShares.toJson())); diff --git a/examples/server-worker/package.json b/examples/server-worker/package.json index caad8cc..3159ab8 100644 --- a/examples/server-worker/package.json +++ b/examples/server-worker/package.json @@ -1,6 +1,6 @@ { "name": "ssv-keys-server-worker", - "version": "1.0.2", + "version": "1.0.3", "description": "Example of expressjs server worker accepting data to build key shares and responding with keyshares json", "main": "./dist/index.js", "scripts": { diff --git a/package.json b/package.json index a743e8b..b508a23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ssv-keys", - "version": "1.0.2", + "version": "1.0.3", "description": "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.", "author": "SSV.Network", "repository": "https://github.com/bloxapp/ssv-keys", diff --git a/src/lib/KeyShares/KeyShares.ts b/src/lib/KeyShares/KeyShares.ts index 9bcd845..c9ba278 100644 --- a/src/lib/KeyShares/KeyShares.ts +++ b/src/lib/KeyShares/KeyShares.ts @@ -86,10 +86,6 @@ export class KeyShares { encryptedShares: metaData.encryptedShares, }); - console.log('<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>') - console.log(payload); - console.log('<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>') - const signature = await web3Helper.buildSignature(`${address}:${ownerNonce}`, privateKey); const signSharesBytes = web3Helper.hexArrayToBytes([signature, payload.sharesData]); diff --git a/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts b/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts index 45339dd..0cbf253 100644 --- a/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts +++ b/src/lib/KeyShares/KeySharesData/KeySharesPayload.ts @@ -31,9 +31,6 @@ export class KeySharesPayload implements IKeySharesPayload { amount: 'Amount of SSV tokens to be deposited to your validator\'s cluster balance (mandatory only for 1st validator in a cluster)', cluster: 'The latest cluster snapshot data, obtained using the cluster-scanner tool. If this is the cluster\'s 1st validator then use - {0,0,0,0,true}', }; - console.log('<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>') - console.log(this.readable); - console.log('<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>') return this.readable; } } From a2ed674588b8b6c2ae7e0843aa9fef6627fcec38 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 2 Jul 2023 19:21:39 +0300 Subject: [PATCH 17/25] adding support for v2 --- examples/server-worker/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 55b1066..f671101 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -1,9 +1,8 @@ import dotenv from 'dotenv'; import { constants } from 'http2'; import bodyParser from 'body-parser'; -import { SSVKeys, KeyShares } from 'ssv-keys'; +import { SSVKeys, KeyShares, EncryptShare } from 'ssv-keys'; import express, { Express, Request, Response } from 'express'; -import {EncryptShare} from '../../src/lib/Encryption/Encryption'; dotenv.config(); From 65925cd335d23aca18d8edfc83f734e58a8a5e1a Mon Sep 17 00:00:00 2001 From: guy muroch Date: Mon, 3 Jul 2023 14:37:13 +0300 Subject: [PATCH 18/25] adding support for v2 --- examples/server-worker/index.ts | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index f671101..985531e 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -12,7 +12,7 @@ const ssvKeys = new SSVKeys(); app.use(express.json()); app.use(bodyParser.urlencoded({ extended: true })); - +const nonce = 0; app.post('/key-shares/generate', async (req: Request, res: Response) => { const operators_ids = String(req.body['operators_ids'] || '') .split(',') @@ -25,6 +25,12 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { .json({ message: 'Operator IDs required' }); } + if (!operators_ids.length) { + return res + .status(constants.HTTP_STATUS_BAD_REQUEST) + .json({ message: 'Operator IDs required' }); + } + const operators_keys = String(req.body['operators_keys'] || '') .split(',') .map((key) => key.trim()) @@ -39,11 +45,20 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { const keystore = req.body['keystore']; if (!keystore) { + return res .status(constants.HTTP_STATUS_BAD_REQUEST) .json({ message: 'Keystore is required' }); } + const owner_address = String(req.body['owner_address'] || '') + + if (!owner_address.length) { + return res + .status(constants.HTTP_STATUS_BAD_REQUEST) + .json({ message: 'Owner address is required' }); + } + const password = String(req.body['password'] || ''); if (!password.length) { @@ -65,31 +80,22 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { const keyShares = new KeyShares(); keyShares.update({ operators, publicKey }); - // 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'; - await keyShares.buildPayload({ publicKey, operators, encryptedShares, },{ - ownerAddress: TEST_OWNER_ADDRESS, - ownerNonce: TEST_OWNER_NONCE, + ownerAddress: owner_address, + ownerNonce: nonce, privateKey }); - console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); - console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); keyShares.payload.readable.encryptedKeys = encryptedShares.map((share: EncryptShare) => share.privateKey); keyShares.payload.readable.publicKeys = encryptedShares.map((share: EncryptShare) => share.publicKey); - console.log('<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>'); console.log(`Built key shares for operators: ${String(operators_ids)} and public key: ${keystore.pubkey}`); res.json(JSON.parse(keyShares.toJson())); }); app.listen(port, () => { - console.log('brotherit!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); console.log(`⚡️[server]: Server is running at https://localhost:${port}`); }); From 6ae39c7499d7a8d31b47c924b6d8f41882efa7aa Mon Sep 17 00:00:00 2001 From: guy muroch Date: Mon, 3 Jul 2023 16:18:41 +0300 Subject: [PATCH 19/25] adding support for v2 --- examples/server-worker/index.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 985531e..ddde8f9 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -51,12 +51,13 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { .json({ message: 'Keystore is required' }); } - const owner_address = String(req.body['owner_address'] || '') + // The nonce of the owner within the SSV contract (increments after each validator registration), obtained using the ssv-scanner tool + const nonce = Number(req.body['nonce'] || '') - if (!owner_address.length) { + if (!nonce) { return res .status(constants.HTTP_STATUS_BAD_REQUEST) - .json({ message: 'Owner address is required' }); + .json({ message: 'Nonce is required' }); } const password = String(req.body['password'] || ''); @@ -80,12 +81,15 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { const keyShares = new KeyShares(); keyShares.update({ operators, publicKey }); + // The cluster owner address + const TEST_OWNER_ADDRESS = '0x81592c3de184a3e2c0dcb5a261bc107bfa91f494'; + await keyShares.buildPayload({ publicKey, operators, encryptedShares, },{ - ownerAddress: owner_address, + ownerAddress: TEST_OWNER_ADDRESS, ownerNonce: nonce, privateKey }); @@ -97,5 +101,6 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { }); app.listen(port, () => { + console.log('brotherit!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); console.log(`⚡️[server]: Server is running at https://localhost:${port}`); }); From c617b59932087f3903e127b7d572636c152a2093 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 9 Jul 2023 15:23:32 +0300 Subject: [PATCH 20/25] adding support for v2 --- examples/server-worker/index.ts | 2 -- examples/server-worker/package.json | 4 ++-- package.json | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index ddde8f9..be4ea14 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -12,7 +12,6 @@ const ssvKeys = new SSVKeys(); app.use(express.json()); app.use(bodyParser.urlencoded({ extended: true })); -const nonce = 0; app.post('/key-shares/generate', async (req: Request, res: Response) => { const operators_ids = String(req.body['operators_ids'] || '') .split(',') @@ -101,6 +100,5 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { }); app.listen(port, () => { - console.log('brotherit!!!!!!!!!!!!!!!!!!!!!!!!!!!!'); console.log(`⚡️[server]: Server is running at https://localhost:${port}`); }); diff --git a/examples/server-worker/package.json b/examples/server-worker/package.json index 3159ab8..89a1de6 100644 --- a/examples/server-worker/package.json +++ b/examples/server-worker/package.json @@ -1,6 +1,6 @@ { "name": "ssv-keys-server-worker", - "version": "1.0.3", + "version": "1.0.2", "description": "Example of expressjs server worker accepting data to build key shares and responding with keyshares json", "main": "./dist/index.js", "scripts": { @@ -18,7 +18,7 @@ "@types/body-parser": "^1.19.2", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.14", - "ssv-keys": "https://github.com/bloxapp/ssv-keys.git#hamlet-support" + "ssv-keys": "https://github.com/bloxapp/ssv-keys.git" }, "devDependencies": { "body-parser": "^1.20.1", diff --git a/package.json b/package.json index b508a23..a743e8b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ssv-keys", - "version": "1.0.3", + "version": "1.0.2", "description": "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.", "author": "SSV.Network", "repository": "https://github.com/bloxapp/ssv-keys", From be615b8bc0431adaf1b79e30d29b76709cfb8834 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Sun, 9 Jul 2023 16:35:05 +0300 Subject: [PATCH 21/25] adding support for v2 --- examples/server-worker/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index be4ea14..d731311 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -50,10 +50,10 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { .json({ message: 'Keystore is required' }); } - // The nonce of the owner within the SSV contract (increments after each validator registration), obtained using the ssv-scanner tool - const nonce = Number(req.body['nonce'] || '') +// The nonce of the owner within the SSV contract (increments after each validator registration), obtained using the ssv-scanner tool + const nonce = Number(req.body['nonce']); - if (!nonce) { + if (isNaN(nonce)) { return res .status(constants.HTTP_STATUS_BAD_REQUEST) .json({ message: 'Nonce is required' }); From 04e24ed9287a3a1a2cc324f529de6140ccfe05c3 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Tue, 11 Jul 2023 13:31:50 +0300 Subject: [PATCH 22/25] adding owner_address as an option param to the api --- examples/server-worker/index.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index d731311..0fccf21 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -59,6 +59,15 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { .json({ message: 'Nonce is required' }); } + // The owner address for signing the share payload + const owner_address = String(req.body['owner_address']); + + if (!owner_address) { + return res + .status(constants.HTTP_STATUS_BAD_REQUEST) + .json({ message: 'owner_address is required' }); + } + const password = String(req.body['password'] || ''); if (!password.length) { @@ -81,19 +90,15 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { keyShares.update({ operators, publicKey }); // The cluster owner address - const TEST_OWNER_ADDRESS = '0x81592c3de184a3e2c0dcb5a261bc107bfa91f494'; - await keyShares.buildPayload({ publicKey, operators, encryptedShares, },{ - ownerAddress: TEST_OWNER_ADDRESS, + ownerAddress: owner_address, ownerNonce: nonce, privateKey }); - keyShares.payload.readable.encryptedKeys = encryptedShares.map((share: EncryptShare) => share.privateKey); - keyShares.payload.readable.publicKeys = encryptedShares.map((share: EncryptShare) => share.publicKey); console.log(`Built key shares for operators: ${String(operators_ids)} and public key: ${keystore.pubkey}`); res.json(JSON.parse(keyShares.toJson())); From f7cee205f070cc88b215f3ad364f45a1b52360fa Mon Sep 17 00:00:00 2001 From: guy muroch Date: Tue, 11 Jul 2023 13:37:15 +0300 Subject: [PATCH 23/25] change ssv-keys dependency to use npm and not git --- examples/server-worker/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/server-worker/package.json b/examples/server-worker/package.json index 89a1de6..77216bd 100644 --- a/examples/server-worker/package.json +++ b/examples/server-worker/package.json @@ -18,7 +18,7 @@ "@types/body-parser": "^1.19.2", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.14", - "ssv-keys": "https://github.com/bloxapp/ssv-keys.git" + "ssv-keys": "1.0.1" }, "devDependencies": { "body-parser": "^1.20.1", From 5ff811185d976d91ec4e0acb9a9004112ba91276 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Wed, 12 Jul 2023 13:54:57 +0300 Subject: [PATCH 24/25] code review --- dist/esbuild/main.js | 2 +- dist/tsc/package.json | 2 +- src/lib/KeyShares/KeySharesData/KeySharesPayload.ts | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dist/esbuild/main.js b/dist/esbuild/main.js index 7b8ca25..33ca6e1 100644 --- a/dist/esbuild/main.js +++ b/dist/esbuild/main.js @@ -5481,4 +5481,4 @@ YAHOO.lang = { //# sourceURL=webpack://JSEncrypt/./lib/lib/jsrsasign/yahoo.js?`)},"./lib/version.json":module=>{eval(`module.exports = {"version":"3.2.1"}; -//# sourceURL=webpack://JSEncrypt/./lib/version.json?`)}},__webpack_module_cache__={};function __webpack_require__(t){var n=__webpack_module_cache__[t];if(n!==void 0)return n.exports;var e=__webpack_module_cache__[t]={exports:{}};return __webpack_modules__[t](e,e.exports,__webpack_require__),e.exports}__webpack_require__.d=(t,n)=>{for(var e in n)__webpack_require__.o(n,e)&&!__webpack_require__.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:n[e]})},__webpack_require__.o=(t,n)=>Object.prototype.hasOwnProperty.call(t,n),__webpack_require__.r=t=>{typeof Symbol!="undefined"&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var __webpack_exports__=__webpack_require__("./lib/index.js");return __webpack_exports__=__webpack_exports__.default,__webpack_exports__})()})},{}]},{},[1])(1)})});var rn;try{window.crypto,rn=l("bls-eth-wasm/browser")}catch(t){rn=l("bls-eth-wasm")}var o=rn;var sn=class{constructor(){this.operatorsCount=3}setOperatorsCount(n){this.operatorsCount=n}},dn=t=>!(t<4||t>13||t%3!=1),Vn=new sn;var U=class extends Error{constructor(e,r){super(r);this.data=e}},N=class extends Error{constructor(e,r){super(r);this.data=e}},P=class extends Error{constructor(n){super(n)}},y=class extends Error{constructor(n){super(n)}},k=class extends Error{constructor(e,r){super(r);this.data=e}},T=class extends Error{constructor(e,r){super(r);this.data=e}},A=class extends Error{constructor(e,r){super(r);this.data=e}};var an=class extends Error{constructor(e,r){super(r);this.operators=e}},on=class extends Error{constructor(e,r){super(r);this.operator=e}},pn=class{constructor(){this.shares=[]}static get DEFAULT_THRESHOLD_NUMBER(){return 3}create(n,e){return u(this,null,function*(){if(!n.startsWith("0x"))throw new k(n,"The private key must be provided in the 0x format.");if(e.map(a=>{if(!Number.isInteger(a))throw new on(a,`Operator must be integer. Got: ${a}`)}),!dn(e.length))throw new an(e,"Invalid operators amount. Enter an 3f+1 compatible amount of operator ids.");let r=[],i=[];o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381)),this.privateKey=o.deserializeHexStrToSecretKey(n.replace("0x","")),this.publicKey=this.privateKey.getPublicKey(),r.push(this.privateKey),i.push(this.publicKey);let s=(e.length-1)/3;for(let a=1;a`0${(e&255).toString(16)}`.slice(-2)).join("")}},J=ln;var un;try{window.crypto,un=l("jsencrypt").JSEncrypt}catch(t){un=mn()}var V=un;var I=class extends Error{constructor(e,r){super(r);this.operator=e}},S=class{constructor(n,e){this.operatorPublicKeys=[...n],this.shares=e}encrypt(){let n=[];for(let[e,r]of this.operatorPublicKeys.entries()){let i=new V({});i.setPublicKey(r);let s=i.encrypt(this.shares[e].privateKey),p={operatorPublicKey:r,privateKey:s,publicKey:this.shares[e].publicKey};n.push(p)}return n}};var f=l("class-validator");var G=l("class-validator");var yn=l("js-base64");var En=t=>{try{let n="Invalid operator key format, make sure the operator exists in the network",e=(0,yn.decode)(t);if(t.length<98)throw Error("The length of the operator public key must be at least 98 characters.");if(!e.startsWith("-----BEGIN RSA PUBLIC KEY-----"))throw Error(n);let r=new V({});try{r.setPublicKey(e)}catch(i){throw new I({rsa:e,base64:t},n)}return!0}catch(n){let{message:e}=n;return e}};var H=class extends Error{constructor(e,r){super(r);this.operator=e}},q=class extends Error{constructor(e,r){super(r);this.operator=e}},W=class extends Error{constructor(e,r,i){super(i);this.listOne=e,this.listTwo=r}},F=class extends Error{constructor(e,r){super(r);this.publicKey=e}};var D=class{validate(n){let e=En(n);if(e!==!0)throw new F(n,`${e}`);return!0}defaultMessage(){return"Invalid operator public key"}};D=g([(0,G.ValidatorConstraint)({name:"operatorKey",async:!1})],D);function Sn(t){return function(n,e){(0,G.registerDecorator)({target:n.constructor,propertyName:e,options:t,constraints:[],validator:D})}}var x=class{constructor(n){this.id=n.id,this.operatorKey=n.operatorKey,this.validate()}validate(){(0,f.validateSync)(this)}};g([(0,f.IsNotEmpty)({message:"The operator id is null"}),(0,f.IsDefined)({message:"The operator id is undefined"}),(0,f.IsInt)({message:"The operator id must be an integer"})],x.prototype,"id",2),g([(0,f.IsNotEmpty)({message:"The operator public key is null"}),(0,f.IsDefined)({message:"The operator public key is undefined"}),(0,f.IsString)({message:"The operator public key must be a string"}),Sn()],x.prototype,"operatorKey",2);var E=t=>t.sort((n,e)=>+n.id-+e.id).map(n=>{if(!n.id||!n.operatorKey)throw new W(t,t,"Mismatch amount of operator ids and operator keys.");return new x(n)});var z=class{extractKeys(n,e){return u(this,null,function*(){let r=yield new J(n).getPrivateKey(e);return o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381)),{privateKey:`0x${r}`,publicKey:`0x${o.deserializeHexStrToSecretKey(r).getPublicKey().serializeToHexStr()}`}})}createThreshold(n,e){return u(this,null,function*(){let r=E(e);return this.threshold=yield new M().create(n,r.map(i=>i.id)),this.threshold})}encryptShares(n,e){return u(this,null,function*(){let i=E(n).map(s=>Buffer.from(s.operatorKey,"base64").toString());return new S(i,e).encrypt()})}buildShares(n,e){return u(this,null,function*(){let r=yield this.createThreshold(n,e);return this.encryptShares(e,r.shares)})}getThreshold(){return this.threshold}};z.SHARES_FORMAT_ABI="abi";var B=m(l("ethers")),_n=m(l("semver"));var xn=m(l("web3")),vn=m(l("ethers")),hn=m(l("ethereumjs-util"));var Y=class extends Error{constructor(e,r){super(r);this.publicKey=e}},Z=class extends Error{constructor(e,r){super(r);this.data=e}};var gn=new xn.default;var $=t=>{let n=new Uint8Array(t.map(e=>[...vn.utils.arrayify(e)]).flat());return Buffer.from(n)},Rn=(t,n)=>u(void 0,null,function*(){o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381));let e=o.deserializeHexStrToSecretKey(n.replace("0x","")),r=hn.keccak256(Buffer.from(t));return`0x${e.sign(new Uint8Array(r)).serializeToHexStr()}`}),Tn=(t,n,e)=>u(void 0,null,function*(){o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381));let r=o.deserializeHexStrToPublicKey(e.replace("0x","")),i=o.deserializeHexStrToSignature(n.replace("0x","")),s=hn.keccak256(Buffer.from(t));if(!r.verify(i,new Uint8Array(s)))throw new Z(n,"Single shares signature is invalid")}),An=t=>u(void 0,null,function*(){return o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381)),`0x${o.deserializeHexStrToSecretKey(t.replace("0x","")).getPublicKey().serializeToHexStr()}`});var Q={name:"ssv-keys",version:"1.0.1",description:"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.",author:"SSV.Network",repository:"https://github.com/bloxapp/ssv-keys",license:"MIT",keywords:["ssv","ssv.network","keystore","shares"],main:"./dist/tsc/src/main.js",types:"./dist/tsc/src/main.d.ts",bin:{"ssv-keys":"./dist/tsc/src/cli.js"},engines:{node:">=12"},scripts:{"dev:cli":"ts-node src/cli.ts","dev:icli":"ts-node src/cli-interactive.ts",icli:"node ./dist/tsc/src/cli-interactive.js",cli:"node ./dist/tsc/src/cli.js",lint:"eslint src/ --ext .js,.jsx,.ts,.tsx",test:"jest",clean:"rm -rf dist build package","ts-node":"ts-node",docs:"typedoc",build:"tsc -p tsconfig.json","build-all":"yarn clean && yarn build && yarn esbuild",esbuild:"node ./esbuild.js","pre-commit":"yarn test && yarn lint && yarn build-all","package-linux":"pkg dist/tsc/src/cli-interactive.js --targets node14-linux-x64 --output bin/linux/ssv-keys-lin --compress GZip","package-macos":"pkg dist/tsc/src/cli-interactive.js --targets node14-macos-x64 --output bin/macos/ssv-keys-mac --compress GZip","package-win":"pkg dist/tsc/src/cli-interactive.js --targets node14-win-x64 --output bin/win/ssv-keys.exe --compress GZip","package-all":"yarn package-linux && yarn package-macos && yarn package-win"},devDependencies:{"@testing-library/jest-dom":"^5.16.4","@types/argparse":"^2.0.10","@types/atob":"^2.1.2","@types/btoa":"^1.2.3","@types/jest":"^26.0.24","@types/node":"^15.14.9","@types/prompts":"^2.0.14","@types/semver":"^7.5.0","@typescript-eslint/eslint-plugin":"^4.33.0","@typescript-eslint/parser":"^4.33.0",esbuild:"^0.14.38","esbuild-node-externals":"^1.4.1",eslint:"^7.32.0",husky:"^7.0.4",jest:"^26.6.3","jest-environment-jsdom":"^26.6.2","jest-environment-node":"^26.6.2","jest-environment-uint8array":"^1.0.0","jest-watch-typeahead":"0.6.5",jsdom:"^16.5.3","jsdom-global":"^3.0.2",pkg:"^5.7.0","ts-jest":"^26.5.6","ts-node":"^10.9.1",typedoc:"^0.22.15",typescript:"^4.6.4"},dependencies:{"@types/figlet":"^1.5.4","@types/underscore":"^1.11.4","@types/yargs":"^17.0.12",argparse:"^2.0.1",assert:"^2.0.0",atob:"^2.1.2","bls-eth-wasm":"^1.0.4","bls-signatures":"^0.2.5",btoa:"^1.2.1","class-validator":"^0.13.2",colors:"^1.4.0",crypto:"^1.0.1","eth2-keystore-js":"^1.0.8","ethereumjs-util":"^7.1.5","ethereumjs-wallet":"^1.0.1",ethers:"^5.7.2",events:"^3.3.0",figlet:"^1.5.2","js-base64":"^3.7.2",jsencrypt:"3.2.1",minimist:"^1.2.6",moment:"^2.29.3","node-jsencrypt":"^1.0.0",prompts:"https://github.com/meshin-blox/prompts.git","scrypt-js":"^3.0.1",semver:"^7.5.1",stream:"^0.0.2",underscore:"^1.13.4",web3:"1.7.3",yargs:"^17.5.1"},licenses:[{MIT:"SEE LICENSE IN LICENCE FILE"}]};var b=l("class-validator");var d=l("class-validator");var X=l("class-validator");var O=class{validate(n){let e=new Set,r=new Set;for(let i of n||[]){if(e.has(i.id))throw new H(i,"Operator ID already exists");if(e.add(i.id),r.has(i.operatorKey))throw new q(i,"Operator public key already exists");r.add(i.operatorKey)}return!0}defaultMessage(){return"The list of operators contains duplicate entries"}};O=g([(0,X.ValidatorConstraint)({name:"uniqueList",async:!1})],O);function Dn(t){return function(n,e){(0,X.registerDecorator)({target:n.constructor,propertyName:e,options:t,constraints:[],validator:O})}}var nn=l("class-validator");var w=class{validate(n){return u(this,null,function*(){try{typeof n=="string"?o.deserializeHexStrToPublicKey(n.replace("0x","")):n.forEach(e=>o.deserializeHexStrToPublicKey(e.replace("0x","")))}catch(e){throw new Y(n,"Failed to BLS deserialize validator public key")}return!0})}defaultMessage(){return"Invalid public key"}};w=g([(0,nn.ValidatorConstraint)({name:"publicKey",async:!0})],w);function On(t){return function(n,e){(0,nn.registerDecorator)({target:n.constructor,propertyName:e,options:t,constraints:[],validator:w})}}var v=class{constructor(){this.publicKey=null;this.operators=null}update(n){n.publicKey&&(this.publicKey=n.publicKey),n.operators&&(this.operators=E(n.operators))}validate(){return u(this,null,function*(){(0,d.validateSync)(this)})}get operatorIds(){var n;return(n=this.operators)!=null&&n.length?this.operators.map(e=>parseInt(String(e.id),10)):[]}get operatorPublicKeys(){var n;return(n=this.operators)!=null&&n.length?this.operators.map(e=>String(e.operatorKey)):[]}};g([(0,d.IsOptional)(),(0,d.IsString)(),(0,d.Length)(98,98),On()],v.prototype,"publicKey",2),g([(0,d.IsOptional)(),(0,d.ValidateNested)({each:!0}),Dn()],v.prototype,"operators",2);var en=class{_sharesToBytes(n,e){let r=[...e].map(s=>"0x"+Buffer.from(s,"base64").toString("hex"));return`0x${$([...n,...r]).toString("hex")}`}build(n){return this.readable={publicKey:n.publicKey,operatorIds:n.operatorIds,sharesData:this._sharesToBytes(n.encryptedShares.map(e=>e.publicKey),n.encryptedShares.map(e=>e.privateKey)),amount:"Amount of SSV tokens to be deposited to your validator's cluster balance (mandatory only for 1st validator in a cluster)",cluster:"The latest cluster snapshot data, obtained using the cluster-scanner tool. If this is the cluster's 1st validator then use - {0,0,0,0,true}"},this.readable}};var wn=192,Bn=96,K=class{constructor(){this.data=new v,this.payload=new en}buildPayload(n,e){return u(this,null,function*(){let{ownerAddress:r,ownerNonce:i,privateKey:s}=e;if(!Number.isInteger(i)||i<0)throw new A(i,"Owner nonce is not positive integer");let p;try{p=gn.utils.toChecksumAddress(r)}catch(_){throw new T(r,"Owner address is not a valid Ethereum address")}let a=this.payload.build({publicKey:n.publicKey,operatorIds:E(n.operators).map(_=>_.id),encryptedShares:n.encryptedShares}),c=yield Rn(`${p}:${i}`,s),h=$([c,a.sharesData]);return a.sharesData=`0x${h.toString("hex")}`,yield this.validateSingleShares(a.sharesData,{ownerAddress:r,ownerNonce:i,publicKey:yield An(s)}),a})}validateSingleShares(n,e){return u(this,null,function*(){let{ownerAddress:r,ownerNonce:i,publicKey:s}=e;if(!Number.isInteger(i)||i<0)throw new A(i,"Owner nonce is not positive integer");let p;try{p=gn.utils.toChecksumAddress(r)}catch(c){throw new T(r,"Owner address is not a valid Ethereum address")}let a=n.replace("0x","").substring(0,wn);yield Tn(`${p}:${i}`,`0x${a}`,s)})}buildSharesFromBytes(n,e){let i=n.replace("0x","").substring(wn).substring(0,e*Bn),s=B.utils.arrayify("0x"+i),p=this._splitArray(e,s).map(_=>B.utils.hexlify(_)),a=n.substring(e*Bn),c=B.utils.arrayify("0x"+a),h=this._splitArray(e,c).map(_=>Buffer.from(B.utils.hexlify(_).replace("0x",""),"hex").toString("base64"));return{sharesPublicKeys:p,encryptedKeys:h}}update(n){this.data.update(n),this.validate()}validate(){(0,b.validateSync)(this)}fromJson(n){let e=typeof n=="string"?JSON.parse(n):n,r=_n.default.parse(e.version),i=_n.default.parse(Q.version);if(!r||!i)throw new Error("The file for keyshares must contain a version mark provided by ssv-keys.");if(!r||i.major!==r.major||i.minor!==r.minor)throw new Error(`The keyshares file you are attempting to reuse does not have the same version (v${Q.version}) as supported by ssv-keys`);return this.update(e.data),this}toJson(){return JSON.stringify({version:`v${Q.version}`,createdAt:new Date().toISOString(),data:this.data||null,payload:this.payload.readable||null},null," ")}_splitArray(n,e){let r=Math.floor(e.length/n),i=[];for(let s=0;s{for(var e in n)__webpack_require__.o(n,e)&&!__webpack_require__.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:n[e]})},__webpack_require__.o=(t,n)=>Object.prototype.hasOwnProperty.call(t,n),__webpack_require__.r=t=>{typeof Symbol!="undefined"&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var __webpack_exports__=__webpack_require__("./lib/index.js");return __webpack_exports__=__webpack_exports__.default,__webpack_exports__})()})},{}]},{},[1])(1)})});var rn;try{window.crypto,rn=l("bls-eth-wasm/browser")}catch(t){rn=l("bls-eth-wasm")}var o=rn;var sn=class{constructor(){this.operatorsCount=3}setOperatorsCount(n){this.operatorsCount=n}},dn=t=>!(t<4||t>13||t%3!=1),Vn=new sn;var U=class extends Error{constructor(e,r){super(r);this.data=e}},N=class extends Error{constructor(e,r){super(r);this.data=e}},P=class extends Error{constructor(n){super(n)}},y=class extends Error{constructor(n){super(n)}},k=class extends Error{constructor(e,r){super(r);this.data=e}},T=class extends Error{constructor(e,r){super(r);this.data=e}},A=class extends Error{constructor(e,r){super(r);this.data=e}};var an=class extends Error{constructor(e,r){super(r);this.operators=e}},on=class extends Error{constructor(e,r){super(r);this.operator=e}},pn=class{constructor(){this.shares=[]}static get DEFAULT_THRESHOLD_NUMBER(){return 3}create(n,e){return u(this,null,function*(){if(!n.startsWith("0x"))throw new k(n,"The private key must be provided in the 0x format.");if(e.map(a=>{if(!Number.isInteger(a))throw new on(a,`Operator must be integer. Got: ${a}`)}),!dn(e.length))throw new an(e,"Invalid operators amount. Enter an 3f+1 compatible amount of operator ids.");let r=[],i=[];o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381)),this.privateKey=o.deserializeHexStrToSecretKey(n.replace("0x","")),this.publicKey=this.privateKey.getPublicKey(),r.push(this.privateKey),i.push(this.publicKey);let s=(e.length-1)/3;for(let a=1;a`0${(e&255).toString(16)}`.slice(-2)).join("")}},J=ln;var un;try{window.crypto,un=l("jsencrypt").JSEncrypt}catch(t){un=mn()}var V=un;var I=class extends Error{constructor(e,r){super(r);this.operator=e}},S=class{constructor(n,e){this.operatorPublicKeys=[...n],this.shares=e}encrypt(){let n=[];for(let[e,r]of this.operatorPublicKeys.entries()){let i=new V({});i.setPublicKey(r);let s=i.encrypt(this.shares[e].privateKey),p={operatorPublicKey:r,privateKey:s,publicKey:this.shares[e].publicKey};n.push(p)}return n}};var f=l("class-validator");var G=l("class-validator");var yn=l("js-base64");var En=t=>{try{let n="Invalid operator key format, make sure the operator exists in the network",e=(0,yn.decode)(t);if(t.length<98)throw Error("The length of the operator public key must be at least 98 characters.");if(!e.startsWith("-----BEGIN RSA PUBLIC KEY-----"))throw Error(n);let r=new V({});try{r.setPublicKey(e)}catch(i){throw new I({rsa:e,base64:t},n)}return!0}catch(n){let{message:e}=n;return e}};var H=class extends Error{constructor(e,r){super(r);this.operator=e}},q=class extends Error{constructor(e,r){super(r);this.operator=e}},W=class extends Error{constructor(e,r,i){super(i);this.listOne=e,this.listTwo=r}},F=class extends Error{constructor(e,r){super(r);this.publicKey=e}};var D=class{validate(n){let e=En(n);if(e!==!0)throw new F(n,`${e}`);return!0}defaultMessage(){return"Invalid operator public key"}};D=g([(0,G.ValidatorConstraint)({name:"operatorKey",async:!1})],D);function Sn(t){return function(n,e){(0,G.registerDecorator)({target:n.constructor,propertyName:e,options:t,constraints:[],validator:D})}}var x=class{constructor(n){this.id=n.id,this.operatorKey=n.operatorKey,this.validate()}validate(){(0,f.validateSync)(this)}};g([(0,f.IsNotEmpty)({message:"The operator id is null"}),(0,f.IsDefined)({message:"The operator id is undefined"}),(0,f.IsInt)({message:"The operator id must be an integer"})],x.prototype,"id",2),g([(0,f.IsNotEmpty)({message:"The operator public key is null"}),(0,f.IsDefined)({message:"The operator public key is undefined"}),(0,f.IsString)({message:"The operator public key must be a string"}),Sn()],x.prototype,"operatorKey",2);var E=t=>t.sort((n,e)=>+n.id-+e.id).map(n=>{if(!n.id||!n.operatorKey)throw new W(t,t,"Mismatch amount of operator ids and operator keys.");return new x(n)});var z=class{extractKeys(n,e){return u(this,null,function*(){let r=yield new J(n).getPrivateKey(e);return o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381)),{privateKey:`0x${r}`,publicKey:`0x${o.deserializeHexStrToSecretKey(r).getPublicKey().serializeToHexStr()}`}})}createThreshold(n,e){return u(this,null,function*(){let r=E(e);return this.threshold=yield new M().create(n,r.map(i=>i.id)),this.threshold})}encryptShares(n,e){return u(this,null,function*(){let i=E(n).map(s=>Buffer.from(s.operatorKey,"base64").toString());return new S(i,e).encrypt()})}buildShares(n,e){return u(this,null,function*(){let r=yield this.createThreshold(n,e);return this.encryptShares(e,r.shares)})}getThreshold(){return this.threshold}};z.SHARES_FORMAT_ABI="abi";var B=m(l("ethers")),_n=m(l("semver"));var xn=m(l("web3")),vn=m(l("ethers")),hn=m(l("ethereumjs-util"));var Y=class extends Error{constructor(e,r){super(r);this.publicKey=e}},Z=class extends Error{constructor(e,r){super(r);this.data=e}};var gn=new xn.default;var $=t=>{let n=new Uint8Array(t.map(e=>[...vn.utils.arrayify(e)]).flat());return Buffer.from(n)},Rn=(t,n)=>u(void 0,null,function*(){o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381));let e=o.deserializeHexStrToSecretKey(n.replace("0x","")),r=hn.keccak256(Buffer.from(t));return`0x${e.sign(new Uint8Array(r)).serializeToHexStr()}`}),Tn=(t,n,e)=>u(void 0,null,function*(){o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381));let r=o.deserializeHexStrToPublicKey(e.replace("0x","")),i=o.deserializeHexStrToSignature(n.replace("0x","")),s=hn.keccak256(Buffer.from(t));if(!r.verify(i,new Uint8Array(s)))throw new Z(n,"Single shares signature is invalid")}),An=t=>u(void 0,null,function*(){return o.deserializeHexStrToSecretKey||(yield o.init(o.BLS12_381)),`0x${o.deserializeHexStrToSecretKey(t.replace("0x","")).getPublicKey().serializeToHexStr()}`});var Q={name:"ssv-keys",version:"1.0.2",description:"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.",author:"SSV.Network",repository:"https://github.com/bloxapp/ssv-keys",license:"MIT",keywords:["ssv","ssv.network","keystore","shares"],main:"./dist/tsc/src/main.js",types:"./dist/tsc/src/main.d.ts",bin:{"ssv-keys":"./dist/tsc/src/cli.js"},engines:{node:">=12"},scripts:{"dev:cli":"ts-node src/cli.ts","dev:icli":"ts-node src/cli-interactive.ts",icli:"node ./dist/tsc/src/cli-interactive.js",cli:"node ./dist/tsc/src/cli.js",lint:"eslint src/ --ext .js,.jsx,.ts,.tsx",test:"jest",clean:"rm -rf dist build package","ts-node":"ts-node",docs:"typedoc",build:"tsc -p tsconfig.json","build-all":"yarn clean && yarn build && yarn esbuild",esbuild:"node ./esbuild.js","pre-commit":"yarn test && yarn lint && yarn build-all","package-linux":"pkg dist/tsc/src/cli-interactive.js --targets node14-linux-x64 --output bin/linux/ssv-keys-lin --compress GZip","package-macos":"pkg dist/tsc/src/cli-interactive.js --targets node14-macos-x64 --output bin/macos/ssv-keys-mac --compress GZip","package-win":"pkg dist/tsc/src/cli-interactive.js --targets node14-win-x64 --output bin/win/ssv-keys.exe --compress GZip","package-all":"yarn package-linux && yarn package-macos && yarn package-win"},devDependencies:{"@testing-library/jest-dom":"^5.16.4","@types/argparse":"^2.0.10","@types/atob":"^2.1.2","@types/btoa":"^1.2.3","@types/jest":"^26.0.24","@types/node":"^15.14.9","@types/prompts":"^2.0.14","@types/semver":"^7.5.0","@typescript-eslint/eslint-plugin":"^4.33.0","@typescript-eslint/parser":"^4.33.0",esbuild:"^0.14.38","esbuild-node-externals":"^1.4.1",eslint:"^7.32.0",husky:"^7.0.4",jest:"^26.6.3","jest-environment-jsdom":"^26.6.2","jest-environment-node":"^26.6.2","jest-environment-uint8array":"^1.0.0","jest-watch-typeahead":"0.6.5",jsdom:"^16.5.3","jsdom-global":"^3.0.2",pkg:"^5.7.0","ts-jest":"^26.5.6","ts-node":"^10.9.1",typedoc:"^0.22.15",typescript:"^4.6.4"},dependencies:{"@types/figlet":"^1.5.4","@types/underscore":"^1.11.4","@types/yargs":"^17.0.12",argparse:"^2.0.1",assert:"^2.0.0",atob:"^2.1.2","bls-eth-wasm":"^1.0.4","bls-signatures":"^0.2.5",btoa:"^1.2.1","class-validator":"^0.13.2",colors:"^1.4.0",crypto:"^1.0.1","eth2-keystore-js":"^1.0.8","ethereumjs-util":"^7.1.5","ethereumjs-wallet":"^1.0.1",ethers:"^5.7.2",events:"^3.3.0",figlet:"^1.5.2","js-base64":"^3.7.2",jsencrypt:"3.2.1",minimist:"^1.2.6",moment:"^2.29.3","node-jsencrypt":"^1.0.0",prompts:"https://github.com/meshin-blox/prompts.git","scrypt-js":"^3.0.1",semver:"^7.5.1",stream:"^0.0.2",underscore:"^1.13.4",web3:"1.7.3",yargs:"^17.5.1"},licenses:[{MIT:"SEE LICENSE IN LICENCE FILE"}]};var b=l("class-validator");var d=l("class-validator");var X=l("class-validator");var O=class{validate(n){let e=new Set,r=new Set;for(let i of n||[]){if(e.has(i.id))throw new H(i,"Operator ID already exists");if(e.add(i.id),r.has(i.operatorKey))throw new q(i,"Operator public key already exists");r.add(i.operatorKey)}return!0}defaultMessage(){return"The list of operators contains duplicate entries"}};O=g([(0,X.ValidatorConstraint)({name:"uniqueList",async:!1})],O);function Dn(t){return function(n,e){(0,X.registerDecorator)({target:n.constructor,propertyName:e,options:t,constraints:[],validator:O})}}var nn=l("class-validator");var w=class{validate(n){return u(this,null,function*(){try{typeof n=="string"?o.deserializeHexStrToPublicKey(n.replace("0x","")):n.forEach(e=>o.deserializeHexStrToPublicKey(e.replace("0x","")))}catch(e){throw new Y(n,"Failed to BLS deserialize validator public key")}return!0})}defaultMessage(){return"Invalid public key"}};w=g([(0,nn.ValidatorConstraint)({name:"publicKey",async:!0})],w);function On(t){return function(n,e){(0,nn.registerDecorator)({target:n.constructor,propertyName:e,options:t,constraints:[],validator:w})}}var v=class{constructor(){this.publicKey=null;this.operators=null}update(n){n.publicKey&&(this.publicKey=n.publicKey),n.operators&&(this.operators=E(n.operators))}validate(){return u(this,null,function*(){(0,d.validateSync)(this)})}get operatorIds(){var n;return(n=this.operators)!=null&&n.length?this.operators.map(e=>parseInt(String(e.id),10)):[]}get operatorPublicKeys(){var n;return(n=this.operators)!=null&&n.length?this.operators.map(e=>String(e.operatorKey)):[]}};g([(0,d.IsOptional)(),(0,d.IsString)(),(0,d.Length)(98,98),On()],v.prototype,"publicKey",2),g([(0,d.IsOptional)(),(0,d.ValidateNested)({each:!0}),Dn()],v.prototype,"operators",2);var en=class{_sharesToBytes(n,e){let r=[...e].map(s=>"0x"+Buffer.from(s,"base64").toString("hex"));return`0x${$([...n,...r]).toString("hex")}`}build(n){return this.readable={publicKey:n.publicKey,operatorIds:n.operatorIds,sharesData:this._sharesToBytes(n.encryptedShares.map(e=>e.publicKey),n.encryptedShares.map(e=>e.privateKey)),amount:"Amount of SSV tokens to be deposited to your validator's cluster balance (mandatory only for 1st validator in a cluster)",cluster:"The latest cluster snapshot data, obtained using the cluster-scanner tool. If this is the cluster's 1st validator then use - {0,0,0,0,true}"},this.readable}};var wn=192,Bn=96,K=class{constructor(){this.data=new v,this.payload=new en}buildPayload(n,e){return u(this,null,function*(){let{ownerAddress:r,ownerNonce:i,privateKey:s}=e;if(!Number.isInteger(i)||i<0)throw new A(i,"Owner nonce is not positive integer");let p;try{p=gn.utils.toChecksumAddress(r)}catch(_){throw new T(r,"Owner address is not a valid Ethereum address")}let a=this.payload.build({publicKey:n.publicKey,operatorIds:E(n.operators).map(_=>_.id),encryptedShares:n.encryptedShares}),c=yield Rn(`${p}:${i}`,s),h=$([c,a.sharesData]);return a.sharesData=`0x${h.toString("hex")}`,yield this.validateSingleShares(a.sharesData,{ownerAddress:r,ownerNonce:i,publicKey:yield An(s)}),a})}validateSingleShares(n,e){return u(this,null,function*(){let{ownerAddress:r,ownerNonce:i,publicKey:s}=e;if(!Number.isInteger(i)||i<0)throw new A(i,"Owner nonce is not positive integer");let p;try{p=gn.utils.toChecksumAddress(r)}catch(c){throw new T(r,"Owner address is not a valid Ethereum address")}let a=n.replace("0x","").substring(0,wn);yield Tn(`${p}:${i}`,`0x${a}`,s)})}buildSharesFromBytes(n,e){let i=n.replace("0x","").substring(wn).substring(0,e*Bn),s=B.utils.arrayify("0x"+i),p=this._splitArray(e,s).map(_=>B.utils.hexlify(_)),a=n.substring(e*Bn),c=B.utils.arrayify("0x"+a),h=this._splitArray(e,c).map(_=>Buffer.from(B.utils.hexlify(_).replace("0x",""),"hex").toString("base64"));return{sharesPublicKeys:p,encryptedKeys:h}}update(n){this.data.update(n),this.validate()}validate(){(0,b.validateSync)(this)}fromJson(n){let e=typeof n=="string"?JSON.parse(n):n,r=_n.default.parse(e.version),i=_n.default.parse(Q.version);if(!r||!i)throw new Error("The file for keyshares must contain a version mark provided by ssv-keys.");if(!r||i.major!==r.major||i.minor!==r.minor)throw new Error(`The keyshares file you are attempting to reuse does not have the same version (v${Q.version}) as supported by ssv-keys`);return this.update(e.data),this}toJson(){return JSON.stringify({version:`v${Q.version}`,createdAt:new Date().toISOString(),data:this.data||null,payload:this.payload.readable||null},null," ")}_splitArray(n,e){let r=Math.floor(e.length/n),i=[];for(let s=0;s share.publicKey), data.encryptedShares.map((share: EncryptShare) => share.privateKey) ), - encryptedKeys: data.encryptedShares.map((share: EncryptShare) => share.privateKey), - publicKeys: data.encryptedShares.map((share: EncryptShare) => share.publicKey), amount: 'Amount of SSV tokens to be deposited to your validator\'s cluster balance (mandatory only for 1st validator in a cluster)', cluster: 'The latest cluster snapshot data, obtained using the cluster-scanner tool. If this is the cluster\'s 1st validator then use - {0,0,0,0,true}', }; From 2560dce63656ae039ad5730cfc1e44089a3254b3 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Wed, 12 Jul 2023 14:59:32 +0300 Subject: [PATCH 25/25] change vars names --- examples/server-worker/index.ts | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/examples/server-worker/index.ts b/examples/server-worker/index.ts index 0fccf21..119c007 100644 --- a/examples/server-worker/index.ts +++ b/examples/server-worker/index.ts @@ -13,29 +13,23 @@ const ssvKeys = new SSVKeys(); app.use(express.json()); app.use(bodyParser.urlencoded({ extended: true })); app.post('/key-shares/generate', async (req: Request, res: Response) => { - const operators_ids = String(req.body['operators_ids'] || '') + const operator_ids = String(req.body['operator_ids'] || '') .split(',') .map((id) => Number(id.trim())) .filter(id => !!id); - if (!operators_ids.length) { + if (!operator_ids.length) { return res .status(constants.HTTP_STATUS_BAD_REQUEST) .json({ message: 'Operator IDs required' }); } - if (!operators_ids.length) { - return res - .status(constants.HTTP_STATUS_BAD_REQUEST) - .json({ message: 'Operator IDs required' }); - } - - const operators_keys = String(req.body['operators_keys'] || '') + const operator_keys = String(req.body['operator_keys'] || '') .split(',') .map((key) => key.trim()) .filter(key => !!key); - if (!operators_keys.length) { + if (!operator_keys.length) { return res .status(constants.HTTP_STATUS_BAD_REQUEST) .json({ message: 'Operator keys required' }); @@ -78,8 +72,8 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { const { publicKey, privateKey } = await ssvKeys.extractKeys(keystore, password); - const operators = operators_keys.map((operatorKey, index) => ({ - id: operators_ids[index], + const operators = operator_keys.map((operatorKey, index) => ({ + id: operator_ids[index], operatorKey, })); @@ -100,7 +94,7 @@ app.post('/key-shares/generate', async (req: Request, res: Response) => { privateKey }); - console.log(`Built key shares for operators: ${String(operators_ids)} and public key: ${keystore.pubkey}`); + console.log(`Built key shares for operators: ${String(operator_ids)} and public key: ${keystore.pubkey}`); res.json(JSON.parse(keyShares.toJson())); });