Use Web3 wallet for encryption instead of generated keys

This commit is contained in:
Franck Royer 2021-08-12 15:51:18 +10:00
parent 42ace51f35
commit 1e69811d8d
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
14 changed files with 568 additions and 405 deletions

View File

@ -1,5 +1,5 @@
{
"name": "eth-dm",
"name": "eth-pm-wallet-encryption",
"version": "0.1.0",
"lockfileVersion": 2,
"requires": true,
@ -15,6 +15,7 @@
"@types/jest": "^26.0.15",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"eth-sig-util": "^3.0.1",
"ethers": "^5.2.0",
"fontsource-roboto": "^4.0.0",
"js-waku": "../../build/main",
@ -4174,6 +4175,14 @@
"@babel/types": "^7.3.0"
}
},
"node_modules/@types/bn.js": {
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/eslint": {
"version": "7.2.13",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.13.tgz",
@ -4275,6 +4284,14 @@
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
},
"node_modules/@types/pbkdf2": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
"integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/prettier": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.0.tgz",
@ -4329,6 +4346,14 @@
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
"integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA=="
},
"node_modules/@types/secp256k1": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz",
"integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
@ -5887,6 +5912,14 @@
"node": ">=0.10.0"
}
},
"node_modules/base-x": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz",
"integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/base/node_modules/define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
@ -5967,6 +6000,11 @@
"file-uri-to-path": "1.0.0"
}
},
"node_modules/blakejs": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz",
"integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg=="
},
"node_modules/bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@ -6173,6 +6211,24 @@
"url": "https://opencollective.com/browserslist"
}
},
"node_modules/bs58": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
"dependencies": {
"base-x": "^3.0.2"
}
},
"node_modules/bs58check": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
"integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
"dependencies": {
"bs58": "^4.0.0",
"create-hash": "^1.1.0",
"safe-buffer": "^5.1.2"
}
},
"node_modules/bser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
@ -9676,6 +9732,76 @@
"node": ">= 0.6"
}
},
"node_modules/eth-sig-util": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-3.0.1.tgz",
"integrity": "sha512-0Us50HiGGvZgjtWTyAI/+qTzYPMLy5Q451D0Xy68bxq1QMWdoOddDwGvsqcFT27uohKgalM9z/yxplyt+mY2iQ==",
"dependencies": {
"ethereumjs-abi": "^0.6.8",
"ethereumjs-util": "^5.1.1",
"tweetnacl": "^1.0.3",
"tweetnacl-util": "^0.15.0"
}
},
"node_modules/ethereum-cryptography": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
"integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
"dependencies": {
"@types/pbkdf2": "^3.0.0",
"@types/secp256k1": "^4.0.1",
"blakejs": "^1.1.0",
"browserify-aes": "^1.2.0",
"bs58check": "^2.1.2",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"hash.js": "^1.1.7",
"keccak": "^3.0.0",
"pbkdf2": "^3.0.17",
"randombytes": "^2.1.0",
"safe-buffer": "^5.1.2",
"scrypt-js": "^3.0.0",
"secp256k1": "^4.0.1",
"setimmediate": "^1.0.5"
}
},
"node_modules/ethereumjs-abi": {
"version": "0.6.8",
"resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
"integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
"dependencies": {
"bn.js": "^4.11.8",
"ethereumjs-util": "^6.0.0"
}
},
"node_modules/ethereumjs-abi/node_modules/ethereumjs-util": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
"integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
"dependencies": {
"@types/bn.js": "^4.11.3",
"bn.js": "^4.11.0",
"create-hash": "^1.1.2",
"elliptic": "^6.5.2",
"ethereum-cryptography": "^0.1.3",
"ethjs-util": "0.1.6",
"rlp": "^2.2.3"
}
},
"node_modules/ethereumjs-util": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
"integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
"dependencies": {
"bn.js": "^4.11.0",
"create-hash": "^1.1.2",
"elliptic": "^6.5.2",
"ethereum-cryptography": "^0.1.3",
"ethjs-util": "^0.1.3",
"rlp": "^2.0.0",
"safe-buffer": "^5.1.1"
}
},
"node_modules/ethers": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.3.1.tgz",
@ -9723,6 +9849,19 @@
"@ethersproject/wordlists": "5.3.0"
}
},
"node_modules/ethjs-util": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
"integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
"dependencies": {
"is-hex-prefixed": "1.0.0",
"strip-hex-prefix": "1.0.0"
},
"engines": {
"node": ">=6.5.0",
"npm": ">=3"
}
},
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
@ -12144,6 +12283,15 @@
"node": ">=0.10.0"
}
},
"node_modules/is-hex-prefixed": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
"integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
"engines": {
"node": ">=6.5.0",
"npm": ">=3"
}
},
"node_modules/is-in-browser": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
@ -13643,6 +13791,19 @@
"node": ">=4.0"
}
},
"node_modules/keccak": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz",
"integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==",
"hasInstallScript": true,
"dependencies": {
"node-addon-api": "^2.0.0",
"node-gyp-build": "^4.2.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -14422,6 +14583,11 @@
"tslib": "^2.0.3"
}
},
"node_modules/node-addon-api": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
"integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
},
"node_modules/node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
@ -14430,6 +14596,16 @@
"node": ">= 6.0.0"
}
},
"node_modules/node-gyp-build": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
"integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@ -18371,6 +18547,17 @@
"inherits": "^2.0.1"
}
},
"node_modules/rlp": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz",
"integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==",
"dependencies": {
"bn.js": "^4.11.1"
},
"bin": {
"rlp": "bin/rlp"
}
},
"node_modules/rollup": {
"version": "1.32.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz",
@ -18864,6 +19051,20 @@
"resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
"integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA=="
},
"node_modules/secp256k1": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
"integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
"hasInstallScript": true,
"dependencies": {
"elliptic": "^6.5.2",
"node-addon-api": "^2.0.0",
"node-gyp-build": "^4.2.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@ -19937,6 +20138,18 @@
"node": ">=6"
}
},
"node_modules/strip-hex-prefix": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
"integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
"dependencies": {
"is-hex-prefixed": "1.0.0"
},
"engines": {
"node": ">=6.5.0",
"npm": ">=3"
}
},
"node_modules/strip-indent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
@ -20742,6 +20955,16 @@
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
},
"node_modules/tweetnacl": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
},
"node_modules/tweetnacl-util": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
"integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw=="
},
"node_modules/type": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
@ -25898,6 +26121,14 @@
"@babel/types": "^7.3.0"
}
},
"@types/bn.js": {
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
"requires": {
"@types/node": "*"
}
},
"@types/eslint": {
"version": "7.2.13",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.13.tgz",
@ -25999,6 +26230,14 @@
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
},
"@types/pbkdf2": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz",
"integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==",
"requires": {
"@types/node": "*"
}
},
"@types/prettier": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.0.tgz",
@ -26053,6 +26292,14 @@
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
"integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA=="
},
"@types/secp256k1": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz",
"integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==",
"requires": {
"@types/node": "*"
}
},
"@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
@ -27286,6 +27533,14 @@
}
}
},
"base-x": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz",
"integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@ -27332,6 +27587,11 @@
"file-uri-to-path": "1.0.0"
}
},
"blakejs": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz",
"integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg=="
},
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@ -27522,6 +27782,24 @@
"node-releases": "^1.1.71"
}
},
"bs58": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
"requires": {
"base-x": "^3.0.2"
}
},
"bs58check": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
"integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
"requires": {
"bs58": "^4.0.0",
"create-hash": "^1.1.0",
"safe-buffer": "^5.1.2"
}
},
"bser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
@ -30212,6 +30490,78 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"eth-sig-util": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-3.0.1.tgz",
"integrity": "sha512-0Us50HiGGvZgjtWTyAI/+qTzYPMLy5Q451D0Xy68bxq1QMWdoOddDwGvsqcFT27uohKgalM9z/yxplyt+mY2iQ==",
"requires": {
"ethereumjs-abi": "^0.6.8",
"ethereumjs-util": "^5.1.1",
"tweetnacl": "^1.0.3",
"tweetnacl-util": "^0.15.0"
}
},
"ethereum-cryptography": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz",
"integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==",
"requires": {
"@types/pbkdf2": "^3.0.0",
"@types/secp256k1": "^4.0.1",
"blakejs": "^1.1.0",
"browserify-aes": "^1.2.0",
"bs58check": "^2.1.2",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"hash.js": "^1.1.7",
"keccak": "^3.0.0",
"pbkdf2": "^3.0.17",
"randombytes": "^2.1.0",
"safe-buffer": "^5.1.2",
"scrypt-js": "^3.0.0",
"secp256k1": "^4.0.1",
"setimmediate": "^1.0.5"
}
},
"ethereumjs-abi": {
"version": "0.6.8",
"resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
"integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
"requires": {
"bn.js": "^4.11.8",
"ethereumjs-util": "^6.0.0"
},
"dependencies": {
"ethereumjs-util": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz",
"integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==",
"requires": {
"@types/bn.js": "^4.11.3",
"bn.js": "^4.11.0",
"create-hash": "^1.1.2",
"elliptic": "^6.5.2",
"ethereum-cryptography": "^0.1.3",
"ethjs-util": "0.1.6",
"rlp": "^2.2.3"
}
}
}
},
"ethereumjs-util": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz",
"integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==",
"requires": {
"bn.js": "^4.11.0",
"create-hash": "^1.1.2",
"elliptic": "^6.5.2",
"ethereum-cryptography": "^0.1.3",
"ethjs-util": "^0.1.3",
"rlp": "^2.0.0",
"safe-buffer": "^5.1.1"
}
},
"ethers": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.3.1.tgz",
@ -30249,6 +30599,15 @@
"@ethersproject/wordlists": "5.3.0"
}
},
"ethjs-util": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
"integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
"requires": {
"is-hex-prefixed": "1.0.0",
"strip-hex-prefix": "1.0.0"
}
},
"eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
@ -32150,6 +32509,11 @@
"is-extglob": "^2.1.1"
}
},
"is-hex-prefixed": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
"integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ="
},
"is-in-browser": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
@ -33301,6 +33665,15 @@
"object.assign": "^4.1.2"
}
},
"keccak": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz",
"integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==",
"requires": {
"node-addon-api": "^2.0.0",
"node-gyp-build": "^4.2.0"
}
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -33928,11 +34301,21 @@
"tslib": "^2.0.3"
}
},
"node-addon-api": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz",
"integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA=="
},
"node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
"integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
},
"node-gyp-build": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
"integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg=="
},
"node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@ -37038,6 +37421,14 @@
"inherits": "^2.0.1"
}
},
"rlp": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz",
"integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==",
"requires": {
"bn.js": "^4.11.1"
}
},
"rollup": {
"version": "1.32.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz",
@ -37399,6 +37790,16 @@
"resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
"integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA=="
},
"secp256k1": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz",
"integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==",
"requires": {
"elliptic": "^6.5.2",
"node-addon-api": "^2.0.0",
"node-gyp-build": "^4.2.0"
}
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@ -38312,6 +38713,14 @@
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
},
"strip-hex-prefix": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
"integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
"requires": {
"is-hex-prefixed": "1.0.0"
}
},
"strip-indent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
@ -38937,6 +39346,16 @@
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
},
"tweetnacl": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
},
"tweetnacl-util": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz",
"integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw=="
},
"type": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",

View File

@ -12,6 +12,7 @@
"@types/jest": "^26.0.15",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"eth-sig-util": "^3.0.1",
"ethers": "^5.2.0",
"fontsource-roboto": "^4.0.0",
"js-waku": "../../build/main",

View File

@ -4,17 +4,15 @@ import React, { useEffect, useState } from 'react';
import './App.css';
import { Waku } from 'js-waku';
import { Signer } from '@ethersproject/abstract-signer';
import { KeyPair } from './crypto';
import { Message } from './messaging/Messages';
import 'fontsource-roboto';
import { AppBar, IconButton, Toolbar, Typography } from '@material-ui/core';
import KeyPairHandling from './key_pair_handling/KeyPairHandling';
import {
createMuiTheme,
ThemeProvider,
makeStyles,
} from '@material-ui/core/styles';
import { teal, purple, green } from '@material-ui/core/colors';
import { lightBlue, orange, teal } from '@material-ui/core/colors';
import WifiIcon from '@material-ui/icons/Wifi';
import BroadcastPublicKey from './BroadcastPublicKey';
import Messaging from './messaging/Messaging';
@ -25,15 +23,17 @@ import {
initWaku,
PublicKeyContentTopic,
} from './waku';
import { Web3Provider } from '@ethersproject/providers/src.ts/web3-provider';
import GetEncryptionPublicKey from './GetEncryptionPublicKey';
import ConnectWallet from './ConnectWallet';
const theme = createMuiTheme({
palette: {
primary: {
main: purple[500],
main: orange[500],
},
secondary: {
main: teal[600],
main: lightBlue[600],
},
},
});
@ -68,9 +68,8 @@ const useStyles = makeStyles({
function App() {
const [waku, setWaku] = useState<Waku>();
const [signer, setSigner] = useState<Signer>();
const [EncryptionKeyPair, setEncryptionKeyPair] = useState<
KeyPair | undefined
>();
const [provider, setProvider] = useState<Web3Provider>();
const [encPublicKey, setEncPublicKey] = useState<Uint8Array>();
const [publicKeys, setPublicKeys] = useState<Map<string, Uint8Array>>(
new Map()
);
@ -113,27 +112,14 @@ function App() {
useEffect(() => {
if (!waku) return;
if (!EncryptionKeyPair) return;
waku.relay.addDecryptionKey(EncryptionKeyPair.privateKey);
return function cleanUp() {
if (!waku) return;
if (!EncryptionKeyPair) return;
waku.relay.deleteDecryptionKey(EncryptionKeyPair.privateKey);
};
}, [waku, EncryptionKeyPair]);
useEffect(() => {
if (!waku) return;
if (!EncryptionKeyPair) return;
if (!address) return;
if (!provider?.provider?.request) return;
const observerDirectMessage = handleDirectMessage.bind(
{},
setMessages,
address
address,
provider.provider.request
);
waku.relay.addObserver(observerDirectMessage, [DirectMessageContentTopic]);
@ -145,7 +131,7 @@ function App() {
DirectMessageContentTopic,
]);
};
}, [waku, address, EncryptionKeyPair]);
}, [waku, address, provider?.provider?.request]);
let relayPeers = 0;
let lightPushPeers = 0;
@ -172,7 +158,7 @@ function App() {
>
<WifiIcon
color={waku ? undefined : 'disabled'}
style={waku ? { color: green[500] } : {}}
style={waku ? { color: teal[500] } : {}}
/>
</IconButton>
<Typography className={classes.peers} aria-label="connected-peers">
@ -189,17 +175,23 @@ function App() {
<main className={classes.main}>
<fieldset>
<legend>Wallet</legend>
<ConnectWallet setAddress={setAddress} setSigner={setSigner} />
<ConnectWallet
setProvider={setProvider}
setAddress={setAddress}
setSigner={setSigner}
/>
</fieldset>
<fieldset>
<legend>Encryption Key Pair</legend>
<KeyPairHandling
encryptionKeyPair={EncryptionKeyPair}
setEncryptionKeyPair={setEncryptionKeyPair}
<legend>Encryption Keys</legend>
<GetEncryptionPublicKey
setEncPublicKey={setEncPublicKey}
providerRequest={provider?.provider?.request}
address={address}
/>
<BroadcastPublicKey
signer={signer}
EncryptionKeyPair={EncryptionKeyPair}
address={address}
encryptionPublicKey={encPublicKey}
waku={waku}
/>
</fieldset>

View File

@ -1,62 +1,51 @@
import { Button } from '@material-ui/core';
import React, { useState } from 'react';
import { createPublicKeyMessage, KeyPair } from './crypto';
import React from 'react';
import { createPublicKeyMessage } from './crypto';
import { PublicKeyMessage } from './messaging/wire';
import { WakuMessage, Waku } from 'js-waku';
import { Signer } from '@ethersproject/abstract-signer';
import { PublicKeyContentTopic } from './waku';
interface Props {
EncryptionKeyPair: KeyPair | undefined;
encryptionPublicKey: Uint8Array | undefined;
waku: Waku | undefined;
signer: Signer | undefined;
address: string | undefined;
}
export default function BroadcastPublicKey({
signer,
EncryptionKeyPair,
encryptionPublicKey,
address,
waku,
}: Props) {
const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>();
const broadcastPublicKey = () => {
if (!EncryptionKeyPair) return;
if (!encryptionPublicKey) return;
if (!signer) return;
if (!address) return;
if (!waku) return;
if (publicKeyMsg) {
encodePublicKeyWakuMessage(publicKeyMsg)
.then((wakuMsg) => {
waku.lightPush.push(wakuMsg).catch((e) => {
console.error('Failed to send Public Key Message', e);
console.log('Creating Public Key Message');
createPublicKeyMessage(signer, address, encryptionPublicKey)
.then((msg) => {
console.log('Public Key Message created');
encodePublicKeyWakuMessage(msg)
.then((wakuMsg) => {
console.log('Public Key Message encoded');
waku.lightPush
.push(wakuMsg)
.then((res) => console.log('Public Key Message pushed', res))
.catch((e) => {
console.error('Failed to send Public Key Message', e);
});
})
.catch(() => {
console.log('Failed to encode Public Key Message in Waku Message');
});
})
.catch(() => {
console.log('Failed to encode Public Key Message in Waku Message');
});
} else {
createPublicKeyMessage(signer, EncryptionKeyPair.publicKey)
.then((msg) => {
setPublicKeyMsg(msg);
encodePublicKeyWakuMessage(msg)
.then((wakuMsg) => {
waku.lightPush
.push(wakuMsg)
.then((res) => console.log('Public Key Message pushed', res))
.catch((e) => {
console.error('Failed to send Public Key Message', e);
});
})
.catch(() => {
console.log(
'Failed to encode Public Key Message in Waku Message'
);
});
})
.catch((e) => {
console.error('Failed to create public key message', e);
});
}
})
.catch((e) => {
console.error('Failed to create public key message', e);
});
};
return (
@ -64,7 +53,7 @@ export default function BroadcastPublicKey({
variant="contained"
color="primary"
onClick={broadcastPublicKey}
disabled={!EncryptionKeyPair || !waku}
disabled={!encryptionPublicKey || !waku || !signer}
>
Broadcast Encryption Public Key
</Button>

View File

@ -2,15 +2,21 @@ import { Button } from '@material-ui/core';
import React from 'react';
import { Signer } from '@ethersproject/abstract-signer';
import { ethers } from 'ethers';
import { Web3Provider } from '@ethersproject/providers/src.ts/web3-provider';
declare let window: any;
interface Props {
setAddress: (address: string) => void;
setSigner: (signer: Signer) => void;
setProvider: (provider: Web3Provider) => void;
}
export default function ConnectWallet({ setAddress, setSigner }: Props) {
export default function ConnectWallet({
setAddress,
setSigner,
setProvider,
}: Props) {
const connectWallet = () => {
try {
window.ethereum
@ -18,6 +24,7 @@ export default function ConnectWallet({ setAddress, setSigner }: Props) {
.then((accounts: string[]) => {
const _provider = new ethers.providers.Web3Provider(window.ethereum);
setAddress(accounts[0]);
setProvider(_provider);
setSigner(_provider.getSigner());
});
} catch (e) {

View File

@ -0,0 +1,51 @@
import { Button } from '@material-ui/core';
import React from 'react';
interface Props {
setEncPublicKey: (key: Uint8Array) => void;
providerRequest:
| ((request: { method: string; params?: Array<any> }) => Promise<any>)
| undefined;
address: string | undefined;
}
export default function GetEncryptionPublicKey({
setEncPublicKey,
providerRequest,
address,
}: Props) {
const requestPublicKey = () => {
if (!providerRequest) return;
if (!address) return;
console.log('Getting Encryption Public Key from Wallet');
providerRequest({
method: 'eth_getEncryptionPublicKey',
params: [address],
})
.then((key: string) => {
console.log('Encryption Public key:', key);
setEncPublicKey(Buffer.from(key, 'base64'));
})
.catch((error) => {
if (error.code === 4001) {
// EIP-1193 userRejectedRequest error
console.log("We can't encrypt anything without the key.");
} else {
console.error(error);
}
});
};
return (
<Button
variant="contained"
color="primary"
onClick={requestPublicKey}
disabled={!providerRequest || !address}
>
Get Encryption Public Key from Wallet
</Button>
);
}

View File

@ -4,23 +4,6 @@ import { ethers } from 'ethers';
import { Signer } from '@ethersproject/abstract-signer';
import { PublicKeyMessage } from './messaging/wire';
import { hexToBuf, equalByteArrays, bufToHex } from 'js-waku/lib/utils';
import { generatePrivateKey, getPublicKey } from 'js-waku';
export interface KeyPair {
privateKey: Uint8Array;
publicKey: Uint8Array;
}
/**
* Use the signature of the Salt ("Salt for eth-dm...") as
* the entropy for the EthCrypto keypair. Note that the entropy is hashed with keccak256
* to make the private key.
*/
export async function generateEncryptionKeyPair(): Promise<KeyPair> {
const privateKey = generatePrivateKey();
const publicKey = getPublicKey(privateKey);
return { privateKey, publicKey };
}
/**
* Sign the Eth-DM public key with Web3. This can then be published to let other
@ -29,16 +12,18 @@ export async function generateEncryptionKeyPair(): Promise<KeyPair> {
*/
export async function createPublicKeyMessage(
web3Signer: Signer,
address: string,
encryptionPublicKey: Uint8Array
): Promise<PublicKeyMessage> {
const ethAddress = await web3Signer.getAddress();
console.log('Asking wallet to sign Public Key Message');
const signature = await web3Signer.signMessage(
formatPublicKeyForSignature(encryptionPublicKey)
);
console.log('Public Key Message signed');
return new PublicKeyMessage({
encryptionPublicKey: encryptionPublicKey,
ethAddress: hexToBuf(ethAddress),
ethAddress: hexToBuf(address),
signature: hexToBuf(signature),
});
}

View File

@ -1,90 +0,0 @@
import { Button } from '@material-ui/core';
import { LoadKeyPair } from './LoadKeyPair';
import { SaveKeyPair } from './SaveKeyPair';
import React, { useState } from 'react';
import { generateEncryptionKeyPair, KeyPair } from '../crypto';
import { makeStyles } from '@material-ui/core/styles';
import PasswordInput from './PasswordInput';
const useStyles = makeStyles({
root: {
textAlign: 'center',
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
margin: '5px',
},
generate: { margin: '5px' },
storage: {
margin: '5px',
},
loadSave: {
display: 'flex',
flexDirection: 'row',
margin: '5px',
},
loadSaveButton: {
margin: '5px',
},
});
export interface Props {
encryptionKeyPair: KeyPair | undefined;
setEncryptionKeyPair: (keyPair: KeyPair) => void;
}
export default function KeyPairHandling({
encryptionKeyPair,
setEncryptionKeyPair,
}: Props) {
const classes = useStyles();
const [password, setPassword] = useState<string>();
const generateKeyPair = () => {
if (encryptionKeyPair) return;
generateEncryptionKeyPair()
.then((keyPair) => {
setEncryptionKeyPair(keyPair);
})
.catch((e) => {
console.error('Failed to generate Key Pair', e);
});
};
return (
<div className={classes.root}>
<Button
className={classes.generate}
variant="contained"
color="primary"
onClick={generateKeyPair}
disabled={!!encryptionKeyPair}
>
Generate Encryption Key Pair
</Button>
<div className={classes.storage}>
<PasswordInput
password={password}
setPassword={(p) => setPassword(p)}
/>
<div className={classes.loadSave}>
<div className={classes.loadSaveButton}>
<LoadKeyPair
setEncryptionKeyPair={(keyPair) => setEncryptionKeyPair(keyPair)}
disabled={!!encryptionKeyPair}
password={password}
/>
</div>
<div className={classes.loadSaveButton}>
<SaveKeyPair
EncryptionKeyPair={encryptionKeyPair}
password={password}
/>
</div>
</div>
</div>
</div>
);
}

View File

@ -1,37 +0,0 @@
import { Button } from '@material-ui/core';
import React from 'react';
import { loadKeyPairFromStorage } from './key_pair_storage';
import { KeyPair } from '../crypto';
export interface Props {
setEncryptionKeyPair: (keyPair: KeyPair) => void;
disabled: boolean;
password: string | undefined;
}
export function LoadKeyPair({
password,
disabled,
setEncryptionKeyPair,
}: Props) {
const loadKeyPair = () => {
if (disabled) return;
if (!password) return;
loadKeyPairFromStorage(password).then((keyPair: KeyPair | undefined) => {
if (!keyPair) return;
console.log('Encryption KeyPair loaded from storage');
setEncryptionKeyPair(keyPair);
});
};
return (
<Button
variant="contained"
color="primary"
onClick={loadKeyPair}
disabled={!password || disabled}
>
Load Encryption Key Pair from storage
</Button>
);
}

View File

@ -1,24 +0,0 @@
import { TextField } from '@material-ui/core';
import React, { ChangeEvent } from 'react';
interface Props {
password: string | undefined;
setPassword: (password: string) => void;
}
export default function PasswordInput({ password, setPassword }: Props) {
const handlePasswordChange = (event: ChangeEvent<HTMLInputElement>) => {
setPassword(event.target.value);
};
return (
<TextField
id="password-input"
label="Password"
variant="filled"
type="password"
onChange={handlePasswordChange}
value={password}
/>
);
}

View File

@ -1,30 +0,0 @@
import { Button } from '@material-ui/core';
import React from 'react';
import { KeyPair } from '../crypto';
import { saveKeyPairToStorage } from './key_pair_storage';
export interface Props {
EncryptionKeyPair: KeyPair | undefined;
password: string | undefined;
}
export function SaveKeyPair({ password, EncryptionKeyPair }: Props) {
const saveKeyPair = () => {
if (!EncryptionKeyPair) return;
if (!password) return;
saveKeyPairToStorage(EncryptionKeyPair, password).then(() => {
console.log('Encryption KeyPair saved to storage');
});
};
return (
<Button
variant="contained"
color="primary"
onClick={saveKeyPair}
disabled={!password || !EncryptionKeyPair}
>
Save Encryption Key Pair to storage
</Button>
);
}

View File

@ -1,122 +0,0 @@
import { KeyPair } from '../crypto';
import { bufToHex, hexToBuf } from 'js-waku/lib/utils';
/**
* Save keypair to storage, encrypted with password
*/
export async function saveKeyPairToStorage(
EncryptionKeyPair: KeyPair,
password: string
) {
const { salt, iv, cipher } = await encryptKey(EncryptionKeyPair, password);
const data = {
salt: bufToHex(salt),
iv: bufToHex(iv),
cipher: bufToHex(cipher),
};
localStorage.setItem('cipherEncryptionKeyPair', JSON.stringify(data));
}
/**
* Load keypair from storage, decrypted using password
*/
export async function loadKeyPairFromStorage(
password: string
): Promise<KeyPair | undefined> {
const str = localStorage.getItem('cipherEncryptionKeyPair');
if (!str) return;
const data = JSON.parse(str);
const salt = hexToBuf(data.salt);
const iv = hexToBuf(data.iv);
const cipher = hexToBuf(data.cipher);
return await decryptKey(salt, iv, cipher, password);
}
/**
* Use password user as key material for wrap key.
*/
function getKeyMaterial(password: string): Promise<CryptoKey> {
const enc = new TextEncoder();
return window.crypto.subtle.importKey(
'raw',
enc.encode(password),
{ name: 'PBKDF2' },
false,
['deriveBits', 'deriveKey']
);
}
/**
* get key to store password
*/
function getWrapKey(keyMaterial: CryptoKey, salt: Uint8Array) {
return window.crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: salt,
iterations: 100000,
hash: 'SHA-256',
},
keyMaterial,
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
}
/**
* Encrypt Eth-DM KeyPair using provided password
*/
async function encryptKey(encryptionKeyPair: KeyPair, password: string) {
const keyMaterial = await getKeyMaterial(password);
const salt = window.crypto.getRandomValues(new Uint8Array(16));
const wrappingKey = await getWrapKey(keyMaterial, salt);
const enc = new TextEncoder();
const encodedKeyPair = enc.encode(JSON.stringify(encryptionKeyPair));
const iv = window.crypto.getRandomValues(new Uint8Array(12));
const cipher = await window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: iv,
},
wrappingKey,
encodedKeyPair
);
return { salt, iv, cipher };
}
/**
* Derive a key from a password, and use the key to decrypt the cipher key pair.
*/
async function decryptKey(
salt: Buffer,
iv: Buffer,
cipherKeyPair: Buffer,
password: string
): Promise<KeyPair | undefined> {
const keyMaterial = await getKeyMaterial(password);
const key = await getWrapKey(keyMaterial, salt);
try {
let decrypted = await window.crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv: iv,
},
key,
cipherKeyPair
);
let dec = new TextDecoder();
return JSON.parse(dec.decode(decrypted));
} catch (e) {
return;
}
}

View File

@ -8,9 +8,10 @@ import {
} from '@material-ui/core';
import React, { ChangeEvent, useState, KeyboardEvent } from 'react';
import { Waku, WakuMessage } from 'js-waku';
import { hexToBuf } from 'js-waku/lib/utils';
import { bufToHex, hexToBuf } from 'js-waku/lib/utils';
import { DirectMessage } from './wire';
import { DirectMessageContentTopic } from '../waku';
import * as sigUtil from 'eth-sig-util';
const useStyles = makeStyles((theme) => ({
formControl: {
@ -115,9 +116,15 @@ async function encodeEncryptedWakuMessage(
});
const payload = directMsg.encode();
return WakuMessage.fromBytes(payload, DirectMessageContentTopic, {
encPublicKey: publicKey,
});
const encObj = sigUtil.encrypt(
Buffer.from(publicKey).toString('base64'),
{ data: bufToHex(payload) },
'x25519-xsalsa20-poly1305'
);
const encryptedPayload = Buffer.from(JSON.stringify(encObj), 'utf8');
return WakuMessage.fromBytes(encryptedPayload, DirectMessageContentTopic);
}
function sendMessage(

View File

@ -5,8 +5,10 @@ import { validatePublicKeyMessage } from './crypto';
import { Message } from './messaging/Messages';
import { bufToHex, equalByteArrays } from 'js-waku/lib/utils';
export const PublicKeyContentTopic = '/eth-dm/1/public-key/proto';
export const DirectMessageContentTopic = '/eth-dm/1/direct-message/proto';
export const PublicKeyContentTopic =
'/eth-pm-wallet/1/encryption-public-key/proto';
export const DirectMessageContentTopic =
'/eth-pm-wallet/1/direct-message/proto';
export async function initWaku(): Promise<Waku> {
const waku = await Waku.create({});
@ -34,7 +36,7 @@ export async function initWaku(): Promise<Waku> {
export function handlePublicKeyMessage(
myAddress: string | undefined,
setter: Dispatch<SetStateAction<Map<string, Uint8Array>>>,
setPublicKeys: Dispatch<SetStateAction<Map<string, Uint8Array>>>,
msg: WakuMessage
) {
console.log('Public Key Message received:', msg);
@ -47,7 +49,7 @@ export function handlePublicKeyMessage(
console.log('Is Public Key Message valid?', res);
if (res) {
setter((prevPks: Map<string, Uint8Array>) => {
setPublicKeys((prevPks: Map<string, Uint8Array>) => {
prevPks.set(
bufToHex(publicKeyMsg.ethAddress),
publicKeyMsg.encryptionPublicKey
@ -60,11 +62,24 @@ export function handlePublicKeyMessage(
export async function handleDirectMessage(
setter: Dispatch<SetStateAction<Message[]>>,
address: string,
providerRequest: (request: {
method: string;
params?: Array<any>;
}) => Promise<any>,
wakuMsg: WakuMessage
) {
console.log('Direct Message received:', wakuMsg);
if (!wakuMsg.payload) return;
const directMessage = DirectMessage.decode(wakuMsg.payload);
const decryptedPayload = await providerRequest({
method: 'eth_decrypt',
params: [wakuMsg.payloadAsUtf8, address],
}).catch((error) => console.log(error.message));
console.log('Decrypted Payload:', decryptedPayload);
const directMessage = DirectMessage.decode(
Buffer.from(decryptedPayload, 'hex')
);
if (!directMessage) {
console.log('Failed to decode Direct Message');
return;