diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..257b034 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "zano" + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e07d772..1627fac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,8 @@ "react-dom": "^18.2.0", "react-id-generator": "^3.0.2", "sha256": "^0.2.0", - "web-vitals": "^2.1.4" + "web-vitals": "^2.1.4", + "zano_web3": "^9.2.0" }, "devDependencies": { "@babel/cli": "^7.21.0", @@ -191,6 +192,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.21.4", @@ -1058,6 +1060,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz", "integrity": "sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw==", "dev": true, + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, @@ -1659,6 +1662,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz", "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==", "dev": true, + "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", @@ -3541,6 +3545,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -4124,7 +4129,6 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/@types/big.js/-/big.js-6.2.2.tgz", "integrity": "sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==", - "dev": true, "license": "MIT" }, "node_modules/@types/body-parser": { @@ -4187,6 +4191,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", "dev": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -4393,7 +4398,6 @@ "version": "1.3.11", "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -4531,6 +4535,12 @@ "devOptional": true, "license": "MIT" }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", @@ -4559,6 +4569,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.1.tgz", "integrity": "sha512-1MeobQkQ9tztuleT3v72XmY0XuKXVXusAhryoLuU5YZ+mXoYKZP9SQ7Flulh1NX4DTjpGTc2b/eMu4u7M7dhnQ==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.57.1", @@ -4612,6 +4623,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.57.1.tgz", "integrity": "sha512-hlA0BLeVSA/wBPKdPGxoVr9Pp6GutGoY380FEhbVi0Ph4WNe8kLvqIRx76RSQt1lynZKfrXKs0/XeEk4zZycuA==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.57.1", "@typescript-eslint/types": "5.57.1", @@ -5030,6 +5042,7 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5116,6 +5129,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5494,8 +5508,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/at-least-node": { "version": "1.0.0", @@ -5564,6 +5577,33 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", @@ -5643,6 +5683,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -6188,6 +6229,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -6284,7 +6326,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -6782,7 +6823,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -6988,6 +7028,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -7280,6 +7321,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -7873,7 +7915,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -8145,7 +8186,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -8375,7 +8415,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8385,7 +8424,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8421,7 +8459,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -8434,7 +8471,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -8593,6 +8629,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz", "integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", @@ -8681,6 +8718,7 @@ "integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -8793,6 +8831,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -9097,6 +9136,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -9724,7 +9764,6 @@ "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "dev": true, "funding": [ { "type": "individual", @@ -9953,7 +9992,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10024,7 +10062,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -10064,7 +10101,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -10231,7 +10267,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -10340,7 +10375,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -10353,7 +10387,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -10369,7 +10402,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -11584,6 +11616,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -14309,7 +14342,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -14408,7 +14440,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -14417,7 +14448,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -14479,6 +14509,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -15459,6 +15490,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.1", @@ -16615,6 +16647,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dev": true, + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -16733,6 +16766,7 @@ "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -16869,6 +16903,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -17008,9 +17048,11 @@ } }, "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -17091,6 +17133,7 @@ "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" @@ -17123,6 +17166,7 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -17717,6 +17761,7 @@ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -17881,6 +17926,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.0.tgz", "integrity": "sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==", "dev": true, + "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -19528,6 +19574,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -19641,6 +19688,8 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, + "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -19982,6 +20031,7 @@ "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -20029,6 +20079,7 @@ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -20109,6 +20160,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -20166,6 +20218,7 @@ "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -20225,6 +20278,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -20656,6 +20710,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -21019,6 +21074,67 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zano_web3": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/zano_web3/-/zano_web3-9.2.0.tgz", + "integrity": "sha512-9s6Eo5hXWwC51RXGUpMJUUe4pqZ7INkqJbmEghBEWMG6S8y9L2G50Co20yNIltbvSWar9wfDAVdLuUZ3NoqpFg==", + "license": "ISC", + "dependencies": { + "@types/big.js": "^6.2.2", + "@types/node": "^20.14.12", + "@types/node-forge": "^1.3.11", + "@types/react": "^18.3.3", + "@types/uuid": "^10.0.0", + "axios": "^1.7.2", + "big.js": "^6.2.1", + "decimal.js": "^10.4.3", + "node-forge": "^1.3.1", + "react": "^18.3.1", + "typescript": "^5.5.4", + "uuid": "^10.0.0" + } + }, + "node_modules/zano_web3/node_modules/@types/node": { + "version": "20.19.33", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz", + "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/zano_web3/node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/zano_web3/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/zano_web3/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } } } } diff --git a/package.json b/package.json index ae0d728..8ad4a87 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "react-dom": "^18.2.0", "react-id-generator": "^3.0.2", "sha256": "^0.2.0", - "web-vitals": "^2.1.4" + "web-vitals": "^2.1.4", + "zano_web3": "^9.2.0" }, "scripts": { "start": "react-scripts start", diff --git a/src/app/components/WalletSend/WalletSend.tsx b/src/app/components/WalletSend/WalletSend.tsx index b17e052..1b58f87 100644 --- a/src/app/components/WalletSend/WalletSend.tsx +++ b/src/app/components/WalletSend/WalletSend.tsx @@ -1,5 +1,12 @@ import React, { Dispatch, SetStateAction, useContext, useEffect, useState } from 'react'; import { popToTop } from 'react-chrome-extension-router'; +import Decimal from 'decimal.js'; +import { + validateTokensInput, + // @ts-expect-error - Disabling TS error while importing /shared submodule + // due to global tsconfig "moduleResolution" prop is set to "node" +} from 'zano_web3/shared'; + import failedImage from '../../assets/images/failed-round.png'; import successImage from '../../assets/images/success-round.png'; import { useInput } from '../../hooks/useInput'; @@ -8,7 +15,7 @@ import Button from '../UI/Button/Button'; import MyInput, { inputDataProps } from '../UI/MyInput/MyInput'; import RoutersNav from '../UI/RoutersNav/RoutersNav'; import s from './WalletSend.module.scss'; -import { fetchBackground, validateTokensInput } from '../../utils/utils'; +import { fetchBackground, isPositiveFloatStr } from '../../utils/utils'; import AssetsSelect from './ui/AssetsSelect/AssetsSelect'; import AdditionalDetails from './ui/AdditionalDetails/AdditionalDetails'; @@ -44,14 +51,36 @@ const WalletSend = () => { const [amountValid, setAmountValid] = useState(false); const address = useInput('', { customValidation: true }); - const amount = useInput('', { - isEmpty: true, - isAmountCorrect: true, - }); + const amount = useInput( + '', + { + isEmpty: true, + }, + { + onChangeFactory: + ({ setValue }) => + (event) => { + const newValue = event.target.value; + + if ( + newValue !== '' && + !isPositiveFloatStr(newValue, { allowCommaSeparator: true }) && + newValue !== '' + ) { + return; + } + + setValue(newValue); + }, + }, + ); const comment = useInput('', { isEmpty: true }); const mixin = useInput(10, { isEmpty: true }); const fee = useInput(0.01, { isEmpty: true }); + const amountWithDot = + typeof amount.value === 'string' ? amount.value.replace(',', '.') : amount.value; + const sendTransfer = ( destination: string, amount: string | number, @@ -111,7 +140,14 @@ const WalletSend = () => { }, [address.value]); useEffect(() => { - const isValid = !!validateTokensInput(amount.value, Number(asset.decimalPoint)); + let isValid = false; + + try { + isValid = validateTokensInput(amount.value, Number(asset.decimalPoint)).valid; + } catch { + isValid = false; + } + setAmountValid(isValid); }, [amount.value, asset]); @@ -155,9 +191,8 @@ const WalletSend = () => { setAsset as Dispatch> } /> - +

test

{
@@ -208,7 +243,7 @@ const WalletSend = () => { onClick={async () => { const transferStatus = (await sendTransfer( submitAddress, - amount.value, + new Decimal(amountWithDot).toFixed(), String(comment.value), String(asset.assetId), Number(asset.decimalPoint), diff --git a/src/app/hooks/useInput.ts b/src/app/hooks/useInput.ts index ffd3807..53a17cb 100644 --- a/src/app/hooks/useInput.ts +++ b/src/app/hooks/useInput.ts @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { Dispatch, SetStateAction, useState } from 'react'; import { useValidation } from './useValidation'; type Validations = { @@ -8,14 +8,28 @@ type Validations = { customValidation?: boolean; }; -export const useInput = (initialState: string | number, validations: Validations) => { +export const useInput = ( + initialState: string | number, + validations: Validations, + { + onChangeFactory, + }: { + onChangeFactory?: ({ + setValue, + }: { + setValue: Dispatch>; + }) => (event: React.ChangeEvent) => void; + } = {}, +) => { const [value, setValue] = useState(initialState); const [isDirty, setIsDirty] = useState(false); const valid = useValidation(value, validations); - const onChange = (e: React.ChangeEvent) => { - setValue(e.target.value); - }; + const onChange = onChangeFactory + ? onChangeFactory({ setValue }) + : (e: React.ChangeEvent) => { + setValue(e.target.value); + }; const onInput = (newValue: string | number) => { setValue(newValue); diff --git a/src/app/utils/utils.ts b/src/app/utils/utils.ts index 066055a..988c55c 100644 --- a/src/app/utils/utils.ts +++ b/src/app/utils/utils.ts @@ -7,11 +7,6 @@ interface BackgroundResponse { password: string; } -interface ValidationResult { - valid: boolean; - error?: string; -} - export async function fetchBackground(data: { method: string; password?: string; @@ -67,85 +62,6 @@ export const setSessionPassword = async (password: string): Promise => { await fetchBackground({ method: 'SET_PASSWORD', password }); }; -export function validateTokensInput( - input: string | number, - decimal_point: number, -): ValidationResult { - if (typeof input === 'number') { - input = input.toString(); - } - - if (input === '') { - return { - valid: false, - error: 'Invalid input', - }; - } - - input = input.replace(/[^0-9.,]/g, ''); - - const MAX_NUMBER = new Decimal(2).pow(64).minus(1); - - if (decimal_point < 0 || decimal_point > 18) { - return { - valid: false, - error: 'Invalid decimal point', - }; - } - - const dotInput = input.replace(/,/g, ''); - - const decimalDevider = new Decimal(10).pow(decimal_point); - - const maxAllowedNumber = MAX_NUMBER.div(decimalDevider); - - const minAllowedNumber = new Decimal(1).div(decimalDevider); - - const rounded = (() => { - if (dotInput.replace('.', '').length > 20) { - const decimalParts = dotInput.split('.'); - - if (decimalParts.length === 2 && decimalParts[1].length > 1) { - const roundedInput = new Decimal(dotInput).toFixed(1); - - if (roundedInput.replace(/./g, '').length <= 20) { - return roundedInput; - } - } - - return false; - } - return dotInput; - })(); - - if (rounded === false) { - return { - valid: false, - error: 'Invalid amount - number is too big or has too many decimal points', - }; - } - - const dotInputDecimal = new Decimal(rounded); - - if (dotInputDecimal.gt(maxAllowedNumber)) { - return { - valid: false, - error: 'Invalid amount - number is too big', - }; - } - - if (dotInputDecimal.lt(minAllowedNumber)) { - return { - valid: false, - error: 'Invalid amount - number is too small', - }; - } - - return { - valid: true, - }; -} - export const shortenAddress = (address: string | undefined, startAmount = 5, endAmount = 3) => { if (!address) { return ''; @@ -158,3 +74,11 @@ export function truncateToDecimals(value: string, decimalPoints: number) { return decimal.toDecimalPlaces(decimalPoints, Decimal.ROUND_DOWN).toFixed(); } + +export function isPositiveFloatStr( + input: string, + { allowCommaSeparator }: { allowCommaSeparator?: boolean } = {}, +): boolean { + const regExp = allowCommaSeparator ? /^\d+([.,]\d*)?$/ : /^\d+(\.\d*)?$/; + return regExp.test(input); +} diff --git a/webpack.common.js b/webpack.common.js index 2264e14..0d1d5d7 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -3,6 +3,12 @@ const path = require('path'); module.exports = { module: { rules: [ + { + include: /node_modules[\\/]zano_web3[\\/]/, + resolve: { + fullySpecified: false, + }, + }, { test: /\.(js|jsx)$/, exclude: /node_modules/, @@ -62,6 +68,6 @@ module.exports = { ], }, resolve: { - extensions: ['*', '.js', '.jsx', '.ts', '.tsx'], + extensions: ['.*', '.js', '.jsx', '.ts', '.tsx'], }, };