diff --git a/client/package-lock.json b/client/package-lock.json index 3cf61093..9e7cbdc1 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,8 +9,11 @@ "version": "0.0.0", "dependencies": { "axios": "^0.27.2", + "ethereum-cryptography": "^2.1.2", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^6.15.0", + "secp256k1": "^5.0.0" }, "devDependencies": { "@types/react": "^18.0.17", @@ -517,6 +520,72 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@remix-run/router": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.8.0.tgz", + "integrity": "sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "dependencies": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -618,6 +687,11 @@ "node": ">=8" } }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -630,6 +704,11 @@ "node": ">=8" } }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, "node_modules/browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", @@ -787,6 +866,20 @@ "integrity": "sha512-H+mFNKow6gi2P5Gi2d1Fvd3TUEJlB9CF7zYaIV9T83BE3wP1xZ0mRPbNTm0KUjyd1QiVy7iKXuIcjlDtBQMiAQ==", "dev": true }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/esbuild": { "version": "0.15.8", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.8.tgz", @@ -1178,6 +1271,17 @@ "node": ">=0.8.0" } }, + "node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1293,12 +1397,36 @@ "node": ">=4" } }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/immutable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1424,6 +1552,16 @@ "node": ">= 0.6" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1442,6 +1580,21 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node_modules/node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-releases": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", @@ -1537,6 +1690,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.15.0.tgz", + "integrity": "sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg==", + "dependencies": { + "@remix-run/router": "1.8.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.15.0.tgz", + "integrity": "sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ==", + "dependencies": { + "@remix-run/router": "1.8.0", + "react-router": "6.15.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1612,6 +1795,20 @@ "loose-envify": "^1.1.0" } }, + "node_modules/secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2107,6 +2304,48 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "requires": { + "@noble/hashes": "1.3.1" + } + }, + "@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==" + }, + "@remix-run/router": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.8.0.tgz", + "integrity": "sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg==" + }, + "@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==" + }, + "@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "requires": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + } + }, + "@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "requires": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + } + }, "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -2193,6 +2432,11 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -2202,6 +2446,11 @@ "fill-range": "^7.0.1" } }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, "browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", @@ -2305,6 +2554,20 @@ "integrity": "sha512-H+mFNKow6gi2P5Gi2d1Fvd3TUEJlB9CF7zYaIV9T83BE3wP1xZ0mRPbNTm0KUjyd1QiVy7iKXuIcjlDtBQMiAQ==", "dev": true }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "esbuild": { "version": "0.15.8", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.8.tgz", @@ -2497,6 +2760,17 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, + "ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "requires": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2570,12 +2844,36 @@ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "immutable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2662,6 +2960,16 @@ "mime-db": "1.52.0" } }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2674,6 +2982,16 @@ "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", "dev": true }, + "node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" + }, "node-releases": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", @@ -2738,6 +3056,23 @@ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true }, + "react-router": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.15.0.tgz", + "integrity": "sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg==", + "requires": { + "@remix-run/router": "1.8.0" + } + }, + "react-router-dom": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.15.0.tgz", + "integrity": "sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ==", + "requires": { + "@remix-run/router": "1.8.0", + "react-router": "6.15.0" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2792,6 +3127,16 @@ "loose-envify": "^1.1.0" } }, + "secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", diff --git a/client/package.json b/client/package.json index f662261b..a6a9a685 100644 --- a/client/package.json +++ b/client/package.json @@ -10,8 +10,11 @@ }, "dependencies": { "axios": "^0.27.2", + "ethereum-cryptography": "^2.1.2", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^6.15.0", + "secp256k1": "^5.0.0" }, "devDependencies": { "@types/react": "^18.0.17", diff --git a/client/src/App.jsx b/client/src/App.jsx index 7254c1fa..1525bf8c 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -4,18 +4,24 @@ import "./App.scss"; import { useState } from "react"; function App() { - const [balance, setBalance] = useState(0); - const [address, setAddress] = useState(""); + const [loggedInAddress, setLoggedInAddress] = useState(""); + const [loggedInBalance, setLoggedInBalance] = useState(0); + const [publicKey, setPublicKey] = useState(""); + const handleLogin = (address,balance,newPublicKey) => { + setLoggedInAddress(address); + setLoggedInBalance(balance); + setPublicKey(newPublicKey); + }; + const handleAddressChange = (address) => { + setLoggedInAddress(address); + }; return (
- - + + + +
); } diff --git a/client/src/App.scss b/client/src/App.scss index e146bf95..8e08c483 100644 --- a/client/src/App.scss +++ b/client/src/App.scss @@ -1,7 +1,7 @@ body { font-family: "Muli", sans-serif; font-weight: 300; - background-color: #e2e8f0; + background-color: #111; padding: 40px; } @@ -9,9 +9,9 @@ label { display: flex; flex-direction: column; letter-spacing: 0.05rem; - font-size: .8em; + font-size: 0.8em; font-weight: 400; - color: #222; + color: #33ff33; } .app { @@ -25,10 +25,10 @@ label { .container { flex-grow: 1; margin: 0 20px; - background-color: #fff; - border: 1px solid #cbd5e0; - box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); - border-radius: 0.375rem; + background-color: #000; + border: 1px solid #33ff33; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); + border-radius: 10px; padding: 40px; label { @@ -41,26 +41,29 @@ label { } input { - padding: 10px 0; - border-radius: 0.125rem; - border: 1px solid rgb(226, 232, 240); - background-color: #fdfdfe; - padding-inline-start: 0.75rem; - font-size: 0.875rem; + padding: 12px 16px; + border-radius: 6px; + border: 1px solid #33ff33; + background-color: #000; + color: #33ff33; + font-size: 0.9rem; } .button { - background-color: #319795; - border-radius: 0.125rem; - padding: 10px 20px; - color: white; + background-color: #33ff33; + border: none; + border-radius: 6px; + padding: 12px 20px; + color: #000; display: inline-flex; text-transform: uppercase; letter-spacing: 1px; - font-weight: 400; - font-size: .9em; + font-weight: 500; + font-size: 0.9rem; + cursor: pointer; + transition: background-color 0.3s ease-in-out; &:hover { - cursor: pointer; + background-color: #008800; } } @@ -71,16 +74,24 @@ input { .balance { text-transform: uppercase; letter-spacing: 1px; - font-weight: 400; - font-size: .9em; + font-weight: 500; + font-size: 0.9rem; display: inline-flex; margin-top: 10px; - padding: 0.75rem; - background-color: #f4f6f8; + padding: 10px; + background-color: black; + border-radius: 6px; } } .transfer { display: flex; flex-direction: column; + + label { + font-weight: 500; + font-size: 0.9rem; + color: #33ff33; + margin-bottom: 6px; + } } diff --git a/client/src/LogInPage.jsx b/client/src/LogInPage.jsx new file mode 100644 index 00000000..f782766b --- /dev/null +++ b/client/src/LogInPage.jsx @@ -0,0 +1,23 @@ +import React, { useState } from "react"; +import { UsersData } from "../../server/scripts/accounts_array.js"; + +export const LogInComponent = ({ onLogin }) => { + const [address, setAddress] = useState(""); + + const handleLogin = async () => { + try { + const userData = UsersData(); + const generatedAddress = userData.address; + setAddress(generatedAddress); + onLogin(generatedAddress, userData.balance,userData.privatKey,userData.publicKey); + } catch (error) { + console.error("Error generating address:", error); + } + }; + + return ( +
event.preventDefault()}> + +
+ ); +}; diff --git a/client/src/Transfer.jsx b/client/src/Transfer.jsx index 7dac2bef..2f95232f 100644 --- a/client/src/Transfer.jsx +++ b/client/src/Transfer.jsx @@ -1,29 +1,76 @@ -import { useState } from "react"; -import server from "./server"; +import React, { useState,useEffect } from "react"; // Обратите внимание на добавление React +import { arr } from "../../server/scripts/accounts_array.js"; +import Operation from "../../server/scripts/balance_operation.js"; +import { veryfication } from "../../server/scripts/verification.js"; +import { Sign } from "../../server/scripts/Signification.js"; +import { keccak256 } from "ethereum-cryptography/keccak"; +import { utf8ToBytes } from "ethereum-cryptography/utils.js"; +import { toHex } from "ethereum-cryptography/utils.js"; + -function Transfer({ address, setBalance }) { - const [sendAmount, setSendAmount] = useState(""); - const [recipient, setRecipient] = useState(""); + const Transfer = ({ senderAddress,publicKey }) => { + const [sendAmount, setSendAmount] = useState(0); + const [recipient, setRecipient] = useState(""); + const [senderBalance, setBalance] = useState(0); + const [errorMessage, setErrorMessage] = useState(""); + const [isChecked, setIsChecked] = useState(false); + const [privateKey, setPrivateKey] = useState(""); + const setValue = (setter) => (evt) => setter(evt.target.value); async function transfer(evt) { evt.preventDefault(); - + CheckSenderAddressValidity(); + } + const CheckSenderAddressValidity = () => { try { - const { - data: { balance }, - } = await server.post(`send`, { - sender: address, - amount: parseInt(sendAmount), - recipient, - }); - setBalance(balance); - } catch (ex) { - alert(ex.response.data.message); + let validRecipient = false; + for (var i = 0; i < arr.length; i++) { + if (recipient === arr[i].address) { + validRecipient = true; + setBalance(arr[i].balance); + setRecipient(arr[i].address); //встановити адресу яку вводить користувач + setErrorMessage(""); + break; + } + } + if (!validRecipient) { + setErrorMessage("Invalid recipient address"); // Устанавливаем ошибку, если адрес неправильный + } + } catch (error) { + setErrorMessage("Something went wrong: " + error.message); } - } + }; + const CallBalanceChange = (sendAmount, senderAddress, recipient) => { + console.log("CallBalanceChange function called"); + console.log("sendAmount:", sendAmount); + console.log("senderAddress:", senderAddress); + console.log("recipient:", recipient); + const operationInstance = new Operation(); + const recipientObj = operationInstance.RecipientChange(recipient); + const senderObj = operationInstance.SenderChange(senderAddress); + const updatedRecipientBalance = operationInstance.updateBalanceForRecipient(recipientObj, sendAmount); + const updatedSenderBalance = operationInstance.updateBalanceForSender(senderObj, sendAmount); + console.log(updatedRecipientBalance); + console.log(updatedSenderBalance); + }; + const handleOptionChange = (privateKey) => { + if (isChecked) { + return Sign(recipient,senderAddress,sendAmount,privateKey); + } + }; + const verify =()=>{ + const isVeryfied = veryfication(handleOptionChange(privateKey),recipient,senderAddress,sendAmount,publicKey); + return isVeryfied; + } + useEffect(() => { + if (isChecked) { + handleOptionChange(privateKey); + } + + }, [isChecked, privateKey]); return (

Send Transaction

@@ -34,7 +81,7 @@ function Transfer({ address, setBalance }) { placeholder="1, 2, 3..." value={sendAmount} onChange={setValue(setSendAmount)} - > + /> + {errorMessage &&

{errorMessage}

} +
+
+ +
+

Стан чекбокса: {isChecked ? "Обрано" : "Не обрано"}

+
+ CallBalanceChange(sendAmount, senderAddress, recipient)} +/> +
+ +
-
); } diff --git a/client/src/TransferDesign.scss b/client/src/TransferDesign.scss new file mode 100644 index 00000000..87456aa1 --- /dev/null +++ b/client/src/TransferDesign.scss @@ -0,0 +1,154 @@ +// TransferDesign.scss + +$primaryColor: #33ff33; +$backgroundColor: #111; +$textColor: #33ff33; + +.transfer { + background-color: $backgroundColor; + border: 1px solid $primaryColor; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); + border-radius: 10px; + padding: 20px; + + h1 { + color: $primaryColor; + font-size: 1.5rem; + margin-bottom: 20px; + } + + label { + display: flex; + flex-direction: column; + font-size: 0.8em; + font-weight: 400; + color: $textColor; + margin-bottom: 20px; + .private-key-input { + width: 100%; + + input { + padding: 12px 16px; + border-radius: 6px; + border: 1px solid $primaryColor; + background-color: $backgroundColor; + color: $textColor; + font-size: 0.9rem; + } + } +} + + .error-message { + color: red; + margin-top: 10px; + } + + .private-key { + display: flex; + align-items: center; + margin-top: 20px; + + input[type="checkbox"] { + margin-right: 10px; + } + } + + .button { + background-color: $primaryColor; + border: none; + border-radius: 6px; + padding: 12px 20px; + color: $backgroundColor; + display: inline-flex; + text-transform: uppercase; + letter-spacing: 1px; + font-weight: 500; + font-size: 0.9rem; + cursor: pointer; + transition: background-color 0.3s ease-in-out; + + &:hover { + background-color: darken($primaryColor, 10%); + } + } + + .verification { + margin-top: 20px; + + button { + background-color: $primaryColor; + border: none; + border-radius: 6px; + padding: 10px 16px; + color: $backgroundColor; + text-transform: uppercase; + font-weight: 500; + font-size: 0.9rem; + cursor: pointer; + transition: background-color 0.3s ease-in-out; + + &:hover { + background-color: darken($primaryColor, 10%); + .private-key { + display: flex; + align-items: center; + margin-top: 20px; + + .private-key-label { + display: flex; + align-items: center; + cursor: pointer; + + input[type="checkbox"] { + position: absolute; + opacity: 0; + cursor: pointer; + + ~ .checkmark { + position: relative; + border: 1px solid #33ff33; + background-color: $backgroundColor; + width: 18px; + height: 18px; + border-radius: 3px; + margin-right: 8px; + + &:after { + content: ""; + position: absolute; + display: none; + } + } + + &:checked ~ .checkmark { + background-color: $primaryColor; + border: none; + + &:after { + display: block; + left: 5px; + top: 1px; + width: 6px; + height: 11px; + border: solid white; + border-width: 0 2px 2px 0; + transform: rotate(45deg); + } + } + + &:focus ~ .checkmark { + box-shadow: 0 0 1px $primaryColor; + } + } + + .sign-label { + color: $primaryColor; + font-weight: 500; + font-size: 0.9rem; + } + } + } + } + } +} +} \ No newline at end of file diff --git a/client/src/Wallet.jsx b/client/src/Wallet.jsx index 8dde5242..69d8135e 100644 --- a/client/src/Wallet.jsx +++ b/client/src/Wallet.jsx @@ -1,31 +1,113 @@ -import server from "./server"; +// Wallet.jsx +import React, { useState } from "react"; +import { LogInComponent } from "./LogInPage"; +import { arr } from "../../server/scripts/accounts_array.js"; +import { Authentificator } from "../../server/scripts/authentificator.js"; +import { RecipientPubK } from "../../server/scripts/recipient_pub_key.js"; +import "./Wallet.scss"; -function Wallet({ address, setAddress, balance, setBalance }) { - async function onChange(evt) { - const address = evt.target.value; +const Wallet = ({ onLogin }) => { + // State variables for managing user data + const [address, setAddress] = useState(""); + const [balance, setBalance] = useState(0); + const [privateKey, setPrivateKey] = useState(""); + const [publicKey, setPublicKey] = useState(""); + const [recipientAddress, setRecipientAddress] = useState(""); + + // Handles user login and updates state + const handleLogin = (address, balance, newPrivateKey, newPublicKey) => { setAddress(address); - if (address) { - const { - data: { balance }, - } = await server.get(`balance/${address}`); - setBalance(balance); + setBalance(balance); + setPrivateKey(newPrivateKey); + setPublicKey(newPublicKey); + onLogin(address, balance, newPublicKey); + }; + + // Handles changes to user address input field + const handleAddressChange = (evt) => { + setAddress(evt.target.value); + }; + + // Handles changes to public key input field + const handlePublicKeyChange = (evt) => { + const newPublicKey = evt.target.value; + setPublicKey(newPublicKey); + const isAuthorized = Authentificator(address, newPublicKey); + // Do something with isAuthorized + }; + + // Checks and updates user balance + const handleCheckBalance = () => { + const foundUser = findUserByAddress(address); + if (foundUser) { + setBalance(foundUser.balance); } else { setBalance(0); + alert("Address not found"); } - } + }; + + // Finds a user by their address in the accounts array + const findUserByAddress = (address) => { + return arr.find((user) => user.address === address); + }; + + // Handles changes to recipient's public key input field + const handleRecipientPublicKeyChange = (evt) => { + const recipientPK = evt.target.value; + setRecipientAddress(recipientPK); + const foundRecipientPubK = RecipientPubK(recipientPK); + // Do something with foundRecipientPubK + }; + // JSX for the Wallet component return (

Your Wallet

+ - + {/* User address input */} + + {/* User public key input */} + + + {/* Display user balance */}
Balance: {balance}
+ + {/* Button to check user balance */} + + +

Your Data

+

Keep your private key secret!

+ + {/* Display user data */} +
+

Address: {address}

+

Balance: {balance}

+

Public Key: {publicKey}

+

Private Key: {privateKey}

+
+ + {/* Input for recipient's public key */} +
+ + {/* Button to perform recipient public key related action */} +
); -} +}; export default Wallet; diff --git a/client/src/Wallet.scss b/client/src/Wallet.scss new file mode 100644 index 00000000..71afed09 --- /dev/null +++ b/client/src/Wallet.scss @@ -0,0 +1,78 @@ +// Wallet.scss + +$primaryColor: #33ff33; +$backgroundColor: #111; +$textColor: #33ff33; + +.wallet { + background-color: $backgroundColor; + color: $textColor; + padding: 40px; + border-radius: 10px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); + + h1 { + font-size: 24px; + margin-bottom: 20px; + } + + + + .usersData { + margin-top: 20px; + p { + margin: 5px 0; + } + } + + .recipientPublicKey { + margin-top: 30px; + input { + width: 100%; + padding: 10px; + border: none; + background-color: $primaryColor; + color: $backgroundColor; + border-radius: 6px; + margin-right: 10px; + margin-bottom: 10px; + } + .button { + background-color: #33ff33; + border: none; + border-radius: 6px; + padding: 12px 20px; + color: #000; + display: inline-flex; + text-transform: uppercase; + letter-spacing: 1px; + font-weight: 500; + font-size: 0.9rem; + cursor: pointer; + transition: background-color 0.3s ease-in-out; + &:hover { + background-color: #008800; + } + } + +.balance { + background-color: transparent black ; // Set background-color to transparent + padding: 10px 20px; + border-radius: 6px; + margin-top: 10px; + text-transform: uppercase; + font-weight: 500; + font-size: 0.9rem; + position: relative; // Add position relative + z-index: 1; // Add a higher z-index to bring text above the background + &::before { + content: "Balance: "; // Add the text using pseudo-element + position: absolute; + left: 20px; + top: 50%; + transform: translateY(-50%); + color: black; + } +} + } +} diff --git a/client/src/main.jsx b/client/src/main.jsx index a7c77000..68be7b80 100644 --- a/client/src/main.jsx +++ b/client/src/main.jsx @@ -1,6 +1,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; +//import LogInPage from "./LogInPage.jsx"; ReactDOM.createRoot(document.getElementById("root")).render( diff --git a/server/.gitignore b/server/.gitignore index e69f6c6f..0fe94dd2 100644 --- a/server/.gitignore +++ b/server/.gitignore @@ -1,2 +1,4 @@ !.gitignore -node_modules \ No newline at end of file +node_modules +src/package-lock.json +src/package.json diff --git a/server/index.js b/server/index.js index 3dbd053b..63d3a514 100644 --- a/server/index.js +++ b/server/index.js @@ -1,17 +1,13 @@ -const express = require("express"); +import express, { json } from "express"; const app = express(); -const cors = require("cors"); +import cors from "cors"; const port = 3042; +//import {UsersData} from "../../server/scripts/accounts_array.js" app.use(cors()); -app.use(express.json()); - -const balances = { - "0x1": 100, - "0x2": 50, - "0x3": 75, -}; +app.use(json()); +//address = [UsersData.userData]; app.get("/balance/:address", (req, res) => { const { address } = req.params; const balance = balances[address] || 0; diff --git a/server/package-lock.json b/server/package-lock.json index 612c6e2d..11ac581e 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -10,7 +10,76 @@ "license": "ISC", "dependencies": { "cors": "^2.8.5", - "express": "^4.18.1" + "ethereum-cryptography": "^2.1.2", + "express": "^4.18.1", + "react-router-dom": "^6.15.0", + "secp256k1": "^5.0.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@remix-run/router": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.8.0.tgz", + "integrity": "sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "dependencies": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/accepts": { @@ -30,6 +99,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, "node_modules/body-parser": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", @@ -53,6 +127,11 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -147,6 +226,20 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -168,6 +261,17 @@ "node": ">= 0.6" } }, + "node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, "node_modules/express": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", @@ -282,6 +386,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -321,6 +444,24 @@ "node": ">= 0.10" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "peer": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -372,6 +513,16 @@ "node": ">= 0.6" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -385,6 +536,21 @@ "node": ">= 0.6" } }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node_modules/node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -473,6 +639,61 @@ "node": ">= 0.8" } }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-router": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.15.0.tgz", + "integrity": "sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg==", + "dependencies": { + "@remix-run/router": "1.8.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.15.0.tgz", + "integrity": "sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ==", + "dependencies": { + "@remix-run/router": "1.8.0", + "react-router": "6.15.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -497,6 +718,29 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -611,6 +855,48 @@ } }, "dependencies": { + "@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "requires": { + "@noble/hashes": "1.3.1" + } + }, + "@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==" + }, + "@remix-run/router": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.8.0.tgz", + "integrity": "sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg==" + }, + "@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==" + }, + "@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "requires": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + } + }, + "@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "requires": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + } + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -625,6 +911,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, "body-parser": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", @@ -644,6 +935,11 @@ "unpipe": "1.0.0" } }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -713,6 +1009,20 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -728,6 +1038,17 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, + "ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "requires": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, "express": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", @@ -818,6 +1139,25 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -848,6 +1188,21 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "peer": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "peer": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -881,6 +1236,16 @@ "mime-db": "1.52.0" } }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -891,6 +1256,16 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -952,6 +1327,42 @@ "unpipe": "1.0.0" } }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + }, + "react-router": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.15.0.tgz", + "integrity": "sha512-NIytlzvzLwJkCQj2HLefmeakxxWHWAP+02EGqWEZy+DgfHHKQMUoBBjUQLOtFInBMhWtb3hiUy6MfFgwLjXhqg==", + "requires": { + "@remix-run/router": "1.8.0" + } + }, + "react-router-dom": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.15.0.tgz", + "integrity": "sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ==", + "requires": { + "@remix-run/router": "1.8.0", + "react-router": "6.15.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -962,6 +1373,25 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, + "secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + } + }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", diff --git a/server/package.json b/server/package.json index c03b40a9..65e4e511 100644 --- a/server/package.json +++ b/server/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "", "main": "index.js", + "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, @@ -11,6 +12,9 @@ "license": "ISC", "dependencies": { "cors": "^2.8.5", - "express": "^4.18.1" + "ethereum-cryptography": "^2.1.2", + "express": "^4.18.1", + "react-router-dom": "^6.15.0", + "secp256k1": "^5.0.0" } } diff --git a/server/scripts/HashMessage.js b/server/scripts/HashMessage.js new file mode 100644 index 00000000..3eabf40e --- /dev/null +++ b/server/scripts/HashMessage.js @@ -0,0 +1,23 @@ +import { utf8ToBytes } from "ethereum-cryptography/utils.js"; +import { toHex } from "ethereum-cryptography/utils.js"; + +export function HashMessage(recipientAddress, senderAddress, Amount) { + const recipient = recipientAddress; + const address = senderAddress; + const amount = Amount; + // Convert your input strings to Uint8Arrays before concatenating + const recipientBytes = utf8ToBytes(recipient); + const addressBytes = utf8ToBytes(address); + const amountBytes = utf8ToBytes(amount); + + // Concatenate the bytes of recipient, address, and amount + const combinedDataUTF8 = new Uint8Array([ + ...recipientBytes, + ...addressBytes, + ...amountBytes + ]); + + // Hash the combined data using keccak256 + const hash = toHex(combinedDataUTF8); + return hash; +} diff --git a/server/scripts/Signification.js b/server/scripts/Signification.js new file mode 100644 index 00000000..f33d70a1 --- /dev/null +++ b/server/scripts/Signification.js @@ -0,0 +1,10 @@ +import { secp256k1 } from "ethereum-cryptography/secp256k1.js"; +import { HashMessage } from "./HashMessage.js"; + + +export function Sign (recipientAddress,senderAddress,Amount,privateKey){ + const msgHash = HashMessage(recipientAddress,senderAddress,Amount); + const sign = secp256k1.sign(msgHash,privateKey) + + return sign; +} \ No newline at end of file diff --git a/server/scripts/accounts_array.js b/server/scripts/accounts_array.js new file mode 100644 index 00000000..51f49467 --- /dev/null +++ b/server/scripts/accounts_array.js @@ -0,0 +1,18 @@ +import { AddressConfig } from "./logs.js"; + + +export const arr = []; // Оголошуємо масив за межами функції + +export function UsersData() { + const userData = { + id: arr.length + 1, // Використовуємо довжину масиву для визначення нового id + address: AddressConfig.addressGen(), + balance: AddressConfig.balanceLog(), + privatKey: AddressConfig.privatKeyGen(), + publicKey: AddressConfig.publicKeyGen(), + }; + + arr.push(userData); // Додаємо об'єкт userData до масиву + return userData; +} + diff --git a/server/scripts/authentificator.js b/server/scripts/authentificator.js new file mode 100644 index 00000000..6d6fd8ac --- /dev/null +++ b/server/scripts/authentificator.js @@ -0,0 +1,24 @@ +import{ arr} from "./accounts_array.js"; + +export const addressPubKey = []; + +export const Authentificator = async (newAddress, newPublicKey) => { + let pushToAddressPK = arr + .filter(item => item.address === newAddress && item.publicKey === newPublicKey) + .map(item => ({ address: item.address, publicKey: item.publicKey })); + + if (pushToAddressPK.length > 0) { + pushToAddressPK ={ + address: newAddress, + publicKey: newPublicKey + } + console.log(`Public key is valid`); + console.log(pushToAddressPK); + } else { + console.log(`public key is unvalid`); + return []; + } + addressPubKey.push(pushToAddressPK); + console.log(addressPubKey); + return pushToAddressPK; +}; diff --git a/server/scripts/balance_operation.js b/server/scripts/balance_operation.js new file mode 100644 index 00000000..1e08fe40 --- /dev/null +++ b/server/scripts/balance_operation.js @@ -0,0 +1,34 @@ +import { arr } from "../../server/scripts/accounts_array.js"; + + class Operation{ + RecipientChange (recipient){ + const recipientObj = arr.find(item => item.address === recipient); + return recipientObj; + } + + SenderChange (senderAddress) { + const senderObj = arr.find(item => item.address === senderAddress); + return senderObj; + } + + updateBalanceForRecipient(recipient, sendAmount) { + arr.forEach(item => { + if (item.address === recipient.address) { + item.balance += parseInt(sendAmount); + } + }); + return arr; + } + + updateBalanceForSender(senderAddress, sendAmount) { + arr.forEach(item => { + if (item.address === senderAddress.address) { + item.balance -= parseInt(sendAmount); + } + }); + return arr; + } + + } + +export default Operation; \ No newline at end of file diff --git a/server/scripts/logs.js b/server/scripts/logs.js new file mode 100644 index 00000000..1b500ad8 --- /dev/null +++ b/server/scripts/logs.js @@ -0,0 +1,32 @@ +import { secp256k1 } from "ethereum-cryptography/secp256k1.js"; +import { toHex } from "ethereum-cryptography/utils.js"; +import { getRandomBytesSync } from "ethereum-cryptography/random.js"; + +export const AddressConfig = { + privatKeyGen (privateKey){ + return privateKey = toHex(secp256k1.utils.randomPrivateKey()); + + }, + addressGen (address){ + return address = "0x"+toHex(getRandomBytesSync()); + }, + balanceLog (){ + return 100; + }, + publicKeyGen (publicKey){ + return publicKey = toHex(secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey())); + } + +} +export default class bebra{ + constructor(a){ + this.a = a; + } +} + + console.log(AddressConfig.addressGen()); + console.log(AddressConfig.balanceLog()); + console.log(AddressConfig.privatKeyGen()); + console.log(AddressConfig.publicKeyGen()); + + diff --git a/server/scripts/recipient_pub_key.js b/server/scripts/recipient_pub_key.js new file mode 100644 index 00000000..f034d0f1 --- /dev/null +++ b/server/scripts/recipient_pub_key.js @@ -0,0 +1,7 @@ +import { addressPubKey } from "./authentificator.js"; + +export const RecipientPubK = (addressRecipient)=>{ + const recipientPubKeyPairs = addressPubKey.filter(item => item.address === addressRecipient); + console.log(recipientPubKeyPairs); + return recipientPubKeyPairs; +} \ No newline at end of file diff --git a/server/scripts/verification.js b/server/scripts/verification.js new file mode 100644 index 00000000..a66ffe3e --- /dev/null +++ b/server/scripts/verification.js @@ -0,0 +1,19 @@ +import { secp256k1 } from "ethereum-cryptography/secp256k1.js"; +import { HashMessage } from "./HashMessage.js"; +import { keccak256 } from "ethereum-cryptography/keccak.js"; +import { hexToBytes, utf8ToBytes } from "ethereum-cryptography/utils.js"; +import { toHex } from "ethereum-cryptography/utils.js"; + + + +export function veryfication(makeSign,recipientAddress,senderAddress,Amount,publicKey) { + const msgHash = HashMessage(recipientAddress,senderAddress,Amount); + const validation = new secp256k1.Signature(makeSign.r,makeSign.s,makeSign.recovery); + let sign = validation.recoverPublicKey(msgHash,makeSign,makeSign.recovery); + const validity = secp256k1.verify(validation,msgHash,publicKey); + console.log(sign); + console.log(validation) + console.log(validity); + return validity; +} +