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 (
+
+ );
+};
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 (
);
}
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;
+}
+