From 5ff811185d976d91ec4e0acb9a9004112ba91276 Mon Sep 17 00:00:00 2001 From: guy muroch Date: Wed, 12 Jul 2023 13:54:57 +0300 Subject: [PATCH] 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}', };