From 06622d89171f36a52693cd2eff0928fff74c7d7d Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Wed, 13 Mar 2024 22:46:54 +0700 Subject: [PATCH 01/73] feat: initial commit --- utilities/wallet-connector/.gitignore | 24 + utilities/wallet-connector/Earthfile | 0 utilities/wallet-connector/index.html | 14 + utilities/wallet-connector/nginx.conf | 23 + utilities/wallet-connector/package-lock.json | 6916 +++++++++++++++++ utilities/wallet-connector/package.json | 62 + utilities/wallet-connector/postcss.config.js | 6 + utilities/wallet-connector/src/App.tsx | 49 + utilities/wallet-connector/src/main.tsx | 7 + .../wallet-connector/src/styles/global.css | 26 + .../wallet-connector/src/types/global.d.ts | 1 + utilities/wallet-connector/tailwind.config.js | 19 + utilities/wallet-connector/tsconfig.json | 24 + utilities/wallet-connector/tsconfig.node.json | 8 + utilities/wallet-connector/vite.config.ts | 18 + 15 files changed, 7197 insertions(+) create mode 100644 utilities/wallet-connector/.gitignore create mode 100644 utilities/wallet-connector/Earthfile create mode 100644 utilities/wallet-connector/index.html create mode 100644 utilities/wallet-connector/nginx.conf create mode 100644 utilities/wallet-connector/package-lock.json create mode 100644 utilities/wallet-connector/package.json create mode 100644 utilities/wallet-connector/postcss.config.js create mode 100644 utilities/wallet-connector/src/App.tsx create mode 100644 utilities/wallet-connector/src/main.tsx create mode 100644 utilities/wallet-connector/src/styles/global.css create mode 100644 utilities/wallet-connector/src/types/global.d.ts create mode 100644 utilities/wallet-connector/tailwind.config.js create mode 100644 utilities/wallet-connector/tsconfig.json create mode 100644 utilities/wallet-connector/tsconfig.node.json create mode 100644 utilities/wallet-connector/vite.config.ts diff --git a/utilities/wallet-connector/.gitignore b/utilities/wallet-connector/.gitignore new file mode 100644 index 00000000000..54f07af58b4 --- /dev/null +++ b/utilities/wallet-connector/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? \ No newline at end of file diff --git a/utilities/wallet-connector/Earthfile b/utilities/wallet-connector/Earthfile new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utilities/wallet-connector/index.html b/utilities/wallet-connector/index.html new file mode 100644 index 00000000000..10f741ec8ff --- /dev/null +++ b/utilities/wallet-connector/index.html @@ -0,0 +1,14 @@ + + + + + + + + + Hermes Wallet Connector + + +
+ + diff --git a/utilities/wallet-connector/nginx.conf b/utilities/wallet-connector/nginx.conf new file mode 100644 index 00000000000..ee0a8bd814b --- /dev/null +++ b/utilities/wallet-connector/nginx.conf @@ -0,0 +1,23 @@ +server { + listen 80; + server_name _; + server_tokens off; + + # timeout + client_body_timeout 12; + client_header_timeout 12; + keepalive_timeout 15; + send_timeout 10; + + location / { + root /usr/share/nginx/html; + index index.html; + try_files $uri $uri/ /index.html; + } + + location ~ ^/(.+)$ { + root /usr/share/nginx/html; + index index.html; + try_files $uri $uri/ /index.html; + } +} diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json new file mode 100644 index 00000000000..474e9b514c5 --- /dev/null +++ b/utilities/wallet-connector/package-lock.json @@ -0,0 +1,6916 @@ +{ + "name": "hermes-wallet-connector", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hermes-wallet-connector", + "version": "0.0.0", + "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@headlessui/react": "^1.7.17", + "@mui/icons-material": "^5.15.0", + "@mui/material": "^5.15.0", + "clsx": "^2.0.0", + "dayjs": "^1.11.10", + "lodash-es": "^4.17.21", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-dropzone": "^14.2.3", + "react-hook-form": "^7.49.1", + "react-query": "^3.39.3", + "react-router-dom": "^6.20.1", + "react-textarea-autosize": "^8.5.3", + "react-toastify": "^9.1.3", + "tailwind-merge": "^2.2.1" + }, + "devDependencies": { + "@types/lodash-es": "^4.17.12", + "@types/node": "^20.10.4", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.17", + "@vitejs/plugin-react-swc": "^3.5.0", + "autoprefixer": "^10.4.18", + "postcss": "^8.4.35", + "tailwindcss": "^3.4.1", + "typescript": "^5.3.3", + "vite": "^5.0.8", + "vite-tsconfig-paths": "^4.2.2" + }, + "optionalDependencies": { + "@tanstack/eslint-plugin-query": "^5.12.1", + "@typescript-eslint/eslint-plugin": "^6.14.0", + "@typescript-eslint/parser": "^6.14.0", + "eslint": "^8.55.0", + "eslint-plugin-i18next": "^6.0.3", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-jsx-a11y": "^6.8.0", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "eslint-plugin-yml": "^1.10.0", + "prettier": "^3.1.1" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "optional": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "optional": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "optional": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "optional": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@headlessui/react": { + "version": "1.7.18", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.18.tgz", + "integrity": "sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ==", + "dependencies": { + "@tanstack/react-virtual": "^3.0.0-beta.60", + "client-only": "^0.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "optional": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "optional": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "optional": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.39.tgz", + "integrity": "sha512-puyUptF7VJ+9/dMIRLF+DLR21cWfvejsA6OnatfJfqFp8aMhya7xQtvYLEfCch6ahvFZvNC9FFEGGR+qkgFjUg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.13", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.15.13", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.13.tgz", + "integrity": "sha512-ERsk9EWpiitSiKnmUdFJGshtFk647l4p7r+mjRWe/F1l5kT1NTTKkaeDLcK3/lsy0udXjMgcG0bNwzbYBdDdhQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.15.13", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.13.tgz", + "integrity": "sha512-I7CioMQKBPaKyGgcE9i8+1dgzAmox5a/0wZ0E9sIxm7PzG5KJZRRJkdK4oDT4HfYRGv61KjcHEeqH48pht1dvQ==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.15.13", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.13.tgz", + "integrity": "sha512-E+QisOJcIzTTyeJ0o3lgYMcyrmCydb2S4cn9vTtGpIB9uR6fQ6La3dIGsXgYEGyeOB9YkWzQbNzYzvyODGEWKA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.39", + "@mui/core-downloads-tracker": "^5.15.13", + "@mui/system": "^5.15.13", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.13", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.15.13", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.13.tgz", + "integrity": "sha512-j5Z2pRi6talCunIRIzpQERSaHwLd5EPdHMwIKDVCszro1RAzRZl7WmH68IMCgQmJMeglr+FalqNuq048qptGAg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.13", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.11.tgz", + "integrity": "sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.15.13", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.13.tgz", + "integrity": "sha512-eHaX3sniZXNWkxX0lmcLxROhQ5La0HkOuF7zxbSdAoHUOk07gboQYmF6hSJ/VBFx/GLanIw67FMTn88vc8niLg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.13", + "@mui/styled-engine": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.13", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.15.13", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.13.tgz", + "integrity": "sha512-qNlR9FLEhORC4zVZ3fzF48213EhP/92N71AcFbhHN73lPJjAbq9lUv+71P7uEdRHdrrOlm8+1zE8/OBy6MUqdg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "devOptional": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "devOptional": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "devOptional": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@remix-run/router": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", + "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@swc/core": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.7.tgz", + "integrity": "sha512-I7a9sUxB+z+UCf6KudqrQH/RgLal/S+E+t4uBdbggycLyJe7WvBgPrQlcN5UpEuD9YC2PJ0CN6kgD6ARStg+pg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@swc/counter": "^0.1.2", + "@swc/types": "^0.1.5" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.4.7", + "@swc/core-darwin-x64": "1.4.7", + "@swc/core-linux-arm-gnueabihf": "1.4.7", + "@swc/core-linux-arm64-gnu": "1.4.7", + "@swc/core-linux-arm64-musl": "1.4.7", + "@swc/core-linux-x64-gnu": "1.4.7", + "@swc/core-linux-x64-musl": "1.4.7", + "@swc/core-win32-arm64-msvc": "1.4.7", + "@swc/core-win32-ia32-msvc": "1.4.7", + "@swc/core-win32-x64-msvc": "1.4.7" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.7.tgz", + "integrity": "sha512-IhfP2Mrrh9WcdlBJQbPNBhfdOhW/SC910SiuzvxaLgJmzq1tw6TVDNUz4Zf85TbK5uzgR0emtPc9hTGxynl57A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.7.tgz", + "integrity": "sha512-MO01pnxJDS6st5IiqyTnAOz9kpAPP/O4lzEUH9E80XdXBzwptS5hNTM0egBlqueWDFrPM26RI81JLtyTU7kR8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.7.tgz", + "integrity": "sha512-+cDaXW6PZqGhXIq9C4xE+/QuyUsLkXf8d8uSXep+rZYDl4YHS9Fi7HpZQnqLX6al/iVhwe3VnxHMGw50gxcr/g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.7.tgz", + "integrity": "sha512-RNnVHRKhEtA3pM34wgb3Vumf5M6/XlWzFdkHEMZIkOKyNSUhZiv8X3tsEK+n1rZQWIDkvlw4YyHtB8vK18WdCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.7.tgz", + "integrity": "sha512-p7Xm4Pib02d1SFS9XXMoOcCTDIkFWMspspptPX00VcjAdZYnXWujWGuD2W+KN1gq5syHB1g3TsYs9LP2dGsKqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.7.tgz", + "integrity": "sha512-ViI5jy03cFYPETsye1J+oPbHE4v8oIDN34qebzvgHUlNKOXfc1ig0Zha5oQnKp3zj1rmjcSLIMqK++WR021G5A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.7.tgz", + "integrity": "sha512-Nf3Axcx/ILl7XE44eidNNPF39rg/KIeqg2545vrOXJG02iu7pEjZuu8wm6w+23BpP4COjZJymlg9LzPT1ZBD5Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.7.tgz", + "integrity": "sha512-MFkJEaC59AO2HpndmHhCkaj8NJus5etjMtBphOe9em7jmmfdQ7mLenKHbZ/CspHNl8yNPO9Qzpa/at2838x+RQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.7.tgz", + "integrity": "sha512-nwrfERocUei9sxqd6URrWcEC3KDcTBD+beMerB9idvuzy4rcm5k1O1ClUlZ9pJOZn+vMN1tqZjLze4hJMT9STQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.7.tgz", + "integrity": "sha512-d5T8Z/axAml8FTA+T9RS2mwJDNIbSSz5jcEiWaGuKVDIoSZib2HpMvnMydOGsIrmjfS1Z4ZhdAawivPhAZ3M8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true + }, + "node_modules/@swc/types": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz", + "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", + "dev": true + }, + "node_modules/@tanstack/eslint-plugin-query": { + "version": "5.27.7", + "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.27.7.tgz", + "integrity": "sha512-I0bQGypBu7gmbjHhRPglZRnYZObiXu7JotDxqRJfjr8sP5YiCx2zm+qbQClrgUGER++Hx4EA4suL7hSiBMWgJg==", + "optional": true, + "dependencies": { + "@typescript-eslint/utils": "^6.20.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "eslint": "^8.0.0" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.1.3.tgz", + "integrity": "sha512-YCzcbF/Ws/uZ0q3Z6fagH+JVhx4JLvbSflgldMgLsuvB8aXjZLLb3HvrEVxY480F9wFlBiXlvQxOyXb5ENPrNA==", + "dependencies": { + "@tanstack/virtual-core": "3.1.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.1.3.tgz", + "integrity": "sha512-Y5B4EYyv1j9V8LzeAoOVeTg0LI7Fo5InYKgAjkY1Pu9GjtUwX/EKxNcU7ng3sKr99WEf+bPTcktAeybyMOYo+g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "optional": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "optional": true + }, + "node_modules/@types/lodash": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", + "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", + "dev": true + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/node": { + "version": "20.11.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.27.tgz", + "integrity": "sha512-qyUZfMnCg1KEz57r7pzFtSGt49f6RPkPBis3Vo4PbS7roQEDn22hiHzl/Lo1q4i4hDEgBJmBF/NTNg2XR0HbFg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/react": { + "version": "18.2.65", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.65.tgz", + "integrity": "sha512-98TsY0aW4jqx/3RqsUXwMDZSWR1Z4CUlJNue8ueS2/wcxZOsz4xmW1X8ieaWVRHcmmQM3R8xVA4XWB3dJnWwDQ==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.22", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.22.tgz", + "integrity": "sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "optional": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "optional": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "optional": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "optional": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "optional": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "optional": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "optional": true + }, + "node_modules/@vitejs/plugin-react-swc": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.6.0.tgz", + "integrity": "sha512-XFRbsGgpGxGzEV5i5+vRiro1bwcIaZDIdBRP16qwm+jP68ue/S8FJTBEgOeojtVDYrbSua3XFp71kC8VJE6v+g==", + "dev": true, + "dependencies": { + "@swc/core": "^1.3.107" + }, + "peerDependencies": { + "vite": "^4 || ^5" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "optional": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "optional": true + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "optional": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.filter": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", + "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.4.tgz", + "integrity": "sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", + "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "optional": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "optional": true + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "optional": true, + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/attr-accept": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", + "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.18", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz", + "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001591", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "optional": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "optional": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "devOptional": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "devOptional": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/broadcast-channel": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz", + "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "detect-node": "^2.1.0", + "js-sha3": "0.8.0", + "microseconds": "0.2.0", + "nano-time": "1.0.0", + "oblivious-set": "1.0.0", + "rimraf": "3.0.2", + "unload": "2.2.0" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001597", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", + "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "optional": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "devOptional": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "optional": true + }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "devOptional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "optional": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "optional": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "optional": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.703", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.703.tgz", + "integrity": "sha512-094ZZC4nHXPKl/OwPinSMtLN9+hoFkdfQGKnvXbY+3WEAYtVDpz9UhJIViiY6Zb8agvqxiaJzNG9M+pRZWvSZw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "devOptional": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", + "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "optional": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "optional": true + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "optional": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", + "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", + "optional": true, + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.4", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "optional": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "optional": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "optional": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "optional": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.4.1.tgz", + "integrity": "sha512-5N7ZaJG5pZxUeNNJfUchurLVrunD1xJvyg5kYOIVF8kg1f3ajTikmAu/5fZ9w100omNPOoMjngRszh/Q/uFGMg==", + "optional": true, + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "optional": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "optional": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-i18next": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-i18next/-/eslint-plugin-i18next-6.0.3.tgz", + "integrity": "sha512-RtQXYfg6PZCjejIQ/YG+dUj/x15jPhufJ9hUDGH0kCpJ6CkVMAWOQ9exU1CrbPmzeykxLjrXkjAaOZF/V7+DOA==", + "optional": true, + "dependencies": { + "lodash": "^4.17.21", + "requireindex": "~1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "optional": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "optional": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "optional": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.34.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.0.tgz", + "integrity": "sha512-MeVXdReleBTdkz/bvcQMSnCXGi+c9kvy51IpinjnJgutl3YTHWsDdke7Z1ufZpGfDG8xduBDKyjtB9JH1eBKIQ==", + "optional": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.17", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.10" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "optional": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.6.tgz", + "integrity": "sha512-NjGXdm7zgcKRkKMua34qVO9doI7VOxZ6ancSvBELJSSoX97jyndXcSoa8XBh69JoB31dNz3EEzlMcizZl7LaMA==", + "optional": true, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "optional": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "optional": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-yml": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.12.2.tgz", + "integrity": "sha512-hvS9p08FhPT7i/ynwl7/Wt7ke7Rf4P2D6fT8lZlL43peZDTsHtH2A0SIFQ7Kt7+mJ6if6P+FX3iJhMkdnxQwpg==", + "optional": true, + "dependencies": { + "debug": "^4.3.2", + "eslint-compat-utils": "^0.4.0", + "lodash": "^4.17.21", + "natural-compare": "^1.4.0", + "yaml-eslint-parser": "^1.2.1" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "optional": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "optional": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "optional": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "optional": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "optional": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "optional": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "optional": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "devOptional": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "optional": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "optional": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "devOptional": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "optional": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-selector": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", + "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "devOptional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "optional": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "optional": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "optional": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "optional": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "optional": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "devOptional": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "optional": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "optional": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "optional": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "optional": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "optional": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "optional": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "optional": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "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/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "optional": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "optional": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "optional": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "optional": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "optional": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "optional": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "optional": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "optional": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "optional": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "optional": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "devOptional": true + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "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==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "optional": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "optional": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "optional": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "optional": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "optional": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "optional": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "optional": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "optional": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "optional": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "optional": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "optional": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "optional": true + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "optional": 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==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/match-sorter": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz", + "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "remove-accents": "0.5.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "devOptional": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "devOptional": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/microseconds": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", + "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "devOptional": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nano-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", + "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", + "dependencies": { + "big-integer": "^1.6.16" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "optional": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", + "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "optional": true, + "dependencies": { + "array.prototype.filter": "^1.0.3", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "optional": true, + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/oblivious-set": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz", + "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "optional": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "optional": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "optional": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "devOptional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "optional": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "optional": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "devOptional": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "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==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-dropzone": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz", + "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==", + "dependencies": { + "attr-accept": "^2.2.2", + "file-selector": "^0.6.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8 || 18.0.0" + } + }, + "node_modules/react-hook-form": { + "version": "7.51.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.0.tgz", + "integrity": "sha512-BggOy5j58RdhdMzzRUHGOYhSz1oeylFAv6jUSG86OvCIvlAvS7KvnRY7yoAf2pfEiPN7BesnR0xx73nEk3qIiw==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/react-query": { + "version": "3.39.3", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", + "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "broadcast-channel": "^3.4.1", + "match-sorter": "^6.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz", + "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==", + "dependencies": { + "@remix-run/router": "1.15.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz", + "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==", + "dependencies": { + "@remix-run/router": "1.15.3", + "react-router": "6.22.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-textarea-autosize": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz", + "integrity": "sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-toastify": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", + "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/react-toastify/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", + "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "get-intrinsic": "^1.2.3", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/remove-accents": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" + }, + "node_modules/requireindex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", + "integrity": "sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==", + "optional": true, + "engines": { + "node": ">=0.10.5" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "devOptional": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "devOptional": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "optional": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "optional": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "devOptional": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "optional": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.1.tgz", + "integrity": "sha512-o+2GTLkthfa5YUt4JxPfzMIpQzZ3adD1vLVkvKE1Twl9UAhGsEbIZhHHZVRttyW177S8PDJI3bTQNaebyofK3Q==", + "dependencies": { + "@babel/runtime": "^7.23.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", + "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "optional": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "optional": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/tsconfck": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.3.tgz", + "integrity": "sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==", + "dev": true, + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "optional": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "optional": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "optional": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "devOptional": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "optional": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unload": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz", + "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==", + "dependencies": { + "@babel/runtime": "^7.6.2", + "detect-node": "^2.0.4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "optional": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-composed-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", + "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", + "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "dependencies": { + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vite": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", + "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", + "dev": true, + "dependencies": { + "esbuild": "^0.19.3", + "postcss": "^8.4.35", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-tsconfig-paths": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.1.tgz", + "integrity": "sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.1" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "devOptional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "optional": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "optional": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "optional": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "optional": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yaml-eslint-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz", + "integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==", + "optional": true, + "dependencies": { + "eslint-visitor-keys": "^3.0.0", + "lodash": "^4.17.21", + "yaml": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/yaml-eslint-parser/node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "optional": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json new file mode 100644 index 00000000000..49d441e352c --- /dev/null +++ b/utilities/wallet-connector/package.json @@ -0,0 +1,62 @@ +{ + "name": "hermes-wallet-connector", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "check": "tsc --noEmit", + "lint": "eslint './src/**/*.{ts,tsx}'", + "lintfix": "eslint './src/**/*.{ts,tsx}' --fix", + "prettier": "prettier --write './src/**/*.{ts,tsx}'", + "fmt": "npm run prettier && npm run fix:scripts", + "preview": "vite preview" + }, + "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@headlessui/react": "^1.7.17", + "@mui/icons-material": "^5.15.0", + "@mui/material": "^5.15.0", + "clsx": "^2.0.0", + "dayjs": "^1.11.10", + "lodash-es": "^4.17.21", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-dropzone": "^14.2.3", + "react-hook-form": "^7.49.1", + "react-query": "^3.39.3", + "react-router-dom": "^6.20.1", + "react-textarea-autosize": "^8.5.3", + "react-toastify": "^9.1.3", + "tailwind-merge": "^2.2.1" + }, + "devDependencies": { + "@types/lodash-es": "^4.17.12", + "@types/node": "^20.10.4", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.17", + "@vitejs/plugin-react-swc": "^3.5.0", + "autoprefixer": "^10.4.18", + "postcss": "^8.4.35", + "tailwindcss": "^3.4.1", + "typescript": "^5.3.3", + "vite": "^5.0.8", + "vite-tsconfig-paths": "^4.2.2" + }, + "optionalDependencies": { + "@tanstack/eslint-plugin-query": "^5.12.1", + "@typescript-eslint/eslint-plugin": "^6.14.0", + "@typescript-eslint/parser": "^6.14.0", + "eslint": "^8.55.0", + "eslint-plugin-i18next": "^6.0.3", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-jsx-a11y": "^6.8.0", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "eslint-plugin-yml": "^1.10.0", + "prettier": "^3.1.1" + } +} diff --git a/utilities/wallet-connector/postcss.config.js b/utilities/wallet-connector/postcss.config.js new file mode 100644 index 00000000000..2e7af2b7f1a --- /dev/null +++ b/utilities/wallet-connector/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx new file mode 100644 index 00000000000..16ac3f00ad8 --- /dev/null +++ b/utilities/wallet-connector/src/App.tsx @@ -0,0 +1,49 @@ +import { QueryClient, QueryClientProvider } from "react-query"; +import { ToastContainer } from "react-toastify"; + +import "react-toastify/dist/ReactToastify.css"; + +import "./styles/global.css"; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + refetchOnWindowFocus: false + }, + mutations: { + retry: false + } + } +}); + +function App() { + console.log(globalThis.cardano); + + const isCardanoActivated = typeof globalThis.cardano !== "undefined"; + + return ( + + +
+
+
+
+ {isCardanoActivated ? ( +
+
hello world
+
+ ) : ( +
+
Cardano extension is not activated!
+
+ )} +
+
+
+
+
+ ); +} + +export default App; diff --git a/utilities/wallet-connector/src/main.tsx b/utilities/wallet-connector/src/main.tsx new file mode 100644 index 00000000000..198fc023a73 --- /dev/null +++ b/utilities/wallet-connector/src/main.tsx @@ -0,0 +1,7 @@ +import ReactDOM from "react-dom/client"; + +import App from "./App.jsx"; + +ReactDOM.createRoot(document.getElementById("root")).render( + +); diff --git a/utilities/wallet-connector/src/styles/global.css b/utilities/wallet-connector/src/styles/global.css new file mode 100644 index 00000000000..bfa7a939943 --- /dev/null +++ b/utilities/wallet-connector/src/styles/global.css @@ -0,0 +1,26 @@ +@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); +@import "tailwindcss/base"; +@import "tailwindcss/components"; +@import "tailwindcss/utilities"; + +h1, h2, h3, h4, h5, h6 { + margin: 0; +} + +fieldset { + all: initial; + width: 100%; +} + +html * { + font-family: Poppins, sans-serif; +} + +button { + display: block; + padding: 0; + margin: 0; + cursor: pointer; + background-color: transparent; + border: 0; +} diff --git a/utilities/wallet-connector/src/types/global.d.ts b/utilities/wallet-connector/src/types/global.d.ts new file mode 100644 index 00000000000..11f02fe2a00 --- /dev/null +++ b/utilities/wallet-connector/src/types/global.d.ts @@ -0,0 +1 @@ +/// diff --git a/utilities/wallet-connector/tailwind.config.js b/utilities/wallet-connector/tailwind.config.js new file mode 100644 index 00000000000..3f302a55415 --- /dev/null +++ b/utilities/wallet-connector/tailwind.config.js @@ -0,0 +1,19 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./index.html", + "./src/**/*.{js,ts,jsx,tsx}", + ], + theme: { + extend: { + colors: { + primary: "#35cac1", + secondary: "#8caee1", + background: "#f9fdfd", + text: "#051111", + accent: "#6775d7" + } + }, + }, + plugins: [], +} diff --git a/utilities/wallet-connector/tsconfig.json b/utilities/wallet-connector/tsconfig.json new file mode 100644 index 00000000000..1c8a0ba7062 --- /dev/null +++ b/utilities/wallet-connector/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2018", + "useDefineForClassFields": true, + "lib": ["DOM", "ESNext"], + "baseUrl": "./src", + "allowJs": false, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "types": ["vite/client", "react", "react-dom", "@modyfi/vite-plugin-yaml/modules"], + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} \ No newline at end of file diff --git a/utilities/wallet-connector/tsconfig.node.json b/utilities/wallet-connector/tsconfig.node.json new file mode 100644 index 00000000000..9c820015548 --- /dev/null +++ b/utilities/wallet-connector/tsconfig.node.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "composite": true, + "module": "esnext", + "moduleResolution": "node", + }, + "include": ["vite.config.ts"] +} \ No newline at end of file diff --git a/utilities/wallet-connector/vite.config.ts b/utilities/wallet-connector/vite.config.ts new file mode 100644 index 00000000000..733f86d6a1b --- /dev/null +++ b/utilities/wallet-connector/vite.config.ts @@ -0,0 +1,18 @@ +import react from "@vitejs/plugin-react-swc"; +import { defineConfig } from "vite"; +import tsconfigPaths from "vite-tsconfig-paths"; + +// https://vitejs.dev/config/ +export default defineConfig(({ mode }) => { + return { + server: { + host: process.env["HOST"] || "127.0.0.1", + port: Number(process.env["PORT"] || 3000), + strictPort: true + }, + plugins: [ + tsconfigPaths(), + react() + ], + }; +}); From fee9cba9df15e3dbd98f8835a95ff4d0ace0ad7e Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 14 Mar 2024 00:09:28 +0700 Subject: [PATCH 02/73] feat: wallet card --- utilities/wallet-connector/package-lock.json | 385 +++++++++++++++--- utilities/wallet-connector/package.json | 48 +-- utilities/wallet-connector/src/App.tsx | 52 ++- .../src/components/WalletCard.tsx | 27 ++ utilities/wallet-connector/tsconfig.json | 2 +- 5 files changed, 427 insertions(+), 87 deletions(-) create mode 100644 utilities/wallet-connector/src/components/WalletCard.tsx diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index 474e9b514c5..7ba7ea6a8bb 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -8,50 +8,50 @@ "name": "hermes-wallet-connector", "version": "0.0.0", "dependencies": { - "@emotion/react": "^11.11.1", + "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", - "@headlessui/react": "^1.7.17", - "@mui/icons-material": "^5.15.0", - "@mui/material": "^5.15.0", - "clsx": "^2.0.0", + "@headlessui/react": "^1.7.18", + "@mui/icons-material": "^5.15.13", + "@mui/material": "^5.15.13", + "clsx": "^2.1.0", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", "react": "^18.2.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", - "react-hook-form": "^7.49.1", + "react-hook-form": "^7.51.0", "react-query": "^3.39.3", - "react-router-dom": "^6.20.1", + "react-router-dom": "^6.22.3", "react-textarea-autosize": "^8.5.3", - "react-toastify": "^9.1.3", + "react-toastify": "^10.0.4", "tailwind-merge": "^2.2.1" }, "devDependencies": { "@types/lodash-es": "^4.17.12", - "@types/node": "^20.10.4", - "@types/react": "^18.2.45", - "@types/react-dom": "^18.2.17", - "@vitejs/plugin-react-swc": "^3.5.0", + "@types/node": "^20.11.27", + "@types/react": "^18.2.65", + "@types/react-dom": "^18.2.22", + "@vitejs/plugin-react-swc": "^3.6.0", "autoprefixer": "^10.4.18", "postcss": "^8.4.35", "tailwindcss": "^3.4.1", - "typescript": "^5.3.3", - "vite": "^5.0.8", - "vite-tsconfig-paths": "^4.2.2" + "typescript": "^5.4.2", + "vite": "^5.1.6", + "vite-tsconfig-paths": "^4.3.1" }, "optionalDependencies": { - "@tanstack/eslint-plugin-query": "^5.12.1", - "@typescript-eslint/eslint-plugin": "^6.14.0", - "@typescript-eslint/parser": "^6.14.0", - "eslint": "^8.55.0", + "@tanstack/eslint-plugin-query": "^5.27.7", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.2.0", + "eslint": "^8.57.0", "eslint-plugin-i18next": "^6.0.3", - "eslint-plugin-import": "^2.29.0", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react": "^7.34.0", "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.5", - "eslint-plugin-yml": "^1.10.0", - "prettier": "^3.1.1" + "eslint-plugin-react-refresh": "^0.4.6", + "eslint-plugin-yml": "^1.12.2", + "prettier": "^3.2.5" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1873,16 +1873,16 @@ "optional": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz", + "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==", "optional": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/type-utils": "7.2.0", + "@typescript-eslint/utils": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1898,8 +1898,66 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "optional": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { "typescript": { @@ -1907,16 +1965,58 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "optional": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", + "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", "optional": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", "debug": "^4.3.4" }, "engines": { @@ -1927,7 +2027,65 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "optional": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { "typescript": { @@ -1935,6 +2093,23 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", @@ -1953,13 +2128,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz", + "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==", "optional": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/utils": "7.2.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1971,7 +2146,65 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "optional": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { "typescript": { @@ -1979,6 +2212,48 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "optional": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "optional": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", @@ -5586,25 +5861,17 @@ } }, "node_modules/react-toastify": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", - "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.4.tgz", + "integrity": "sha512-etR3RgueY8pe88SA67wLm8rJmL1h+CLqUGHuAoNsseW35oTGJEri6eBTyaXnFKNQ80v/eO10hBYLgz036XRGgA==", "dependencies": { - "clsx": "^1.1.1" + "clsx": "^2.1.0" }, "peerDependencies": { "react": ">=16", "react-dom": ">=16" } }, - "node_modules/react-toastify/node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "engines": { - "node": ">=6" - } - }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index 49d441e352c..b1ec31ebb50 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -14,49 +14,49 @@ "preview": "vite preview" }, "dependencies": { - "@emotion/react": "^11.11.1", + "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", - "@headlessui/react": "^1.7.17", - "@mui/icons-material": "^5.15.0", - "@mui/material": "^5.15.0", - "clsx": "^2.0.0", + "@headlessui/react": "^1.7.18", + "@mui/icons-material": "^5.15.13", + "@mui/material": "^5.15.13", + "clsx": "^2.1.0", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", "react": "^18.2.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", - "react-hook-form": "^7.49.1", + "react-hook-form": "^7.51.0", "react-query": "^3.39.3", - "react-router-dom": "^6.20.1", + "react-router-dom": "^6.22.3", "react-textarea-autosize": "^8.5.3", - "react-toastify": "^9.1.3", + "react-toastify": "^10.0.4", "tailwind-merge": "^2.2.1" }, "devDependencies": { "@types/lodash-es": "^4.17.12", - "@types/node": "^20.10.4", - "@types/react": "^18.2.45", - "@types/react-dom": "^18.2.17", - "@vitejs/plugin-react-swc": "^3.5.0", + "@types/node": "^20.11.27", + "@types/react": "^18.2.65", + "@types/react-dom": "^18.2.22", + "@vitejs/plugin-react-swc": "^3.6.0", "autoprefixer": "^10.4.18", "postcss": "^8.4.35", "tailwindcss": "^3.4.1", - "typescript": "^5.3.3", - "vite": "^5.0.8", - "vite-tsconfig-paths": "^4.2.2" + "typescript": "^5.4.2", + "vite": "^5.1.6", + "vite-tsconfig-paths": "^4.3.1" }, "optionalDependencies": { - "@tanstack/eslint-plugin-query": "^5.12.1", - "@typescript-eslint/eslint-plugin": "^6.14.0", - "@typescript-eslint/parser": "^6.14.0", - "eslint": "^8.55.0", + "@tanstack/eslint-plugin-query": "^5.27.7", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.2.0", + "eslint": "^8.57.0", "eslint-plugin-i18next": "^6.0.3", - "eslint-plugin-import": "^2.29.0", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", - "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react": "^7.34.0", "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.5", - "eslint-plugin-yml": "^1.10.0", - "prettier": "^3.1.1" + "eslint-plugin-react-refresh": "^0.4.6", + "eslint-plugin-yml": "^1.12.2", + "prettier": "^3.2.5" } } diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 16ac3f00ad8..a65ea777703 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -1,9 +1,12 @@ import { QueryClient, QueryClientProvider } from "react-query"; import { ToastContainer } from "react-toastify"; +import { xor } from "lodash-es"; import "react-toastify/dist/ReactToastify.css"; import "./styles/global.css"; +import WalletCard from "components/WalletCard"; +import { useEffect, useState } from "react"; const queryClient = new QueryClient({ defaultOptions: { @@ -18,10 +21,42 @@ const queryClient = new QueryClient({ }); function App() { + const [isInit, setIsInit] = useState(false); + const [walletApis, setWalletApis] = useState({}); + const [enablingWallets, setEnablingWallets] = useState([]); + const [selectingWallets, setSelectingWallets] = useState([]); + console.log(globalThis.cardano); + useEffect(() => { + init(); + }, []); + const isCardanoActivated = typeof globalThis.cardano !== "undefined"; + async function init() { + console.log("testing") + + const walletApis = await Promise.all(Object.entries(globalThis.cardano).map(async ([walletName, walletProps]: any) => { + const api = await walletProps.enable({ cip: 30 }) + + return [walletName, api] + })); + + console.log("apis", walletApis) + + setIsInit(true); + setWalletApis(Object.fromEntries(walletApis)); + } + + function handleWalletCardClick(walletName: string) { + setSelectingWallets((prev) => xor(prev, [ walletName ])) + } + + if (!isInit) { + return
Loading
+ } + return ( @@ -30,11 +65,22 @@ function App() {
{isCardanoActivated ? ( -
-
hello world
+
+

Select available wallets:

+
+ {Object.keys(globalThis.cardano).map((walletName) => ( + handleWalletCardClick(walletName)} + /> + ))} +
) : ( -
+
Cardano extension is not activated!
)} diff --git a/utilities/wallet-connector/src/components/WalletCard.tsx b/utilities/wallet-connector/src/components/WalletCard.tsx new file mode 100644 index 00000000000..7f8a6a099f3 --- /dev/null +++ b/utilities/wallet-connector/src/components/WalletCard.tsx @@ -0,0 +1,27 @@ +import { noop } from "lodash-es"; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import { twMerge } from "tailwind-merge"; + +type Props = { + isChecked: boolean; + isEnabled: boolean; + name: string; + onClick?: () => void; +} + +function WalletCard({ isChecked, isEnabled, name, onClick = noop }: Props) { + return ( + + ) +} + +export default WalletCard; \ No newline at end of file diff --git a/utilities/wallet-connector/tsconfig.json b/utilities/wallet-connector/tsconfig.json index 1c8a0ba7062..1262c50fbb7 100644 --- a/utilities/wallet-connector/tsconfig.json +++ b/utilities/wallet-connector/tsconfig.json @@ -17,7 +17,7 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", - "types": ["vite/client", "react", "react-dom", "@modyfi/vite-plugin-yaml/modules"], + "types": ["vite/client", "react", "react-dom"], }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] From a39822a78ed20fcad945f908f13a779710e4ee12 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 14 Mar 2024 01:58:14 +0700 Subject: [PATCH 03/73] feat: cardano types --- utilities/wallet-connector/package-lock.json | 282 +++++++++++++++++- utilities/wallet-connector/package.json | 1 + utilities/wallet-connector/src/App.tsx | 153 +++++++--- .../src/common/helpers/getCardano.ts | 11 + 4 files changed, 401 insertions(+), 46 deletions(-) create mode 100644 utilities/wallet-connector/src/common/helpers/getCardano.ts diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index 7ba7ea6a8bb..608b93a6ea1 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -27,6 +27,7 @@ "tailwind-merge": "^2.2.1" }, "devDependencies": { + "@cardano-sdk/cip30": "^0.5.0", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.27", "@types/react": "^18.2.65", @@ -279,6 +280,108 @@ "node": ">=6.9.0" } }, + "node_modules/@cardano-sdk/cip30": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@cardano-sdk/cip30/-/cip30-0.5.0.tgz", + "integrity": "sha512-78o4VSMZhKJfD9V96eaJeOilTJO3RaaFkHGwKe4uBg4jFMI7zDAxYJgtuWJyJ+9UNC+20AfYAP1GitCn9Z85Lg==", + "dev": true, + "dependencies": { + "@cardano-sdk/core": "^0.5.0", + "ts-custom-error": "^3.2.0", + "ts-log": "^2.2.3", + "webextension-polyfill": "^0.8.0" + }, + "engines": { + "node": "^14" + } + }, + "node_modules/@cardano-sdk/cip30/node_modules/@cardano-ogmios/client": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@cardano-ogmios/client/-/client-5.5.2.tgz", + "integrity": "sha512-PvXMimCDZLTqG4VLmvus5PvYpzCrHx3NxNLLxM3L+6ltT9qggwBw36UehSottLn+HPEFBsVqIOySgxM8oGVK0g==", + "dev": true, + "dependencies": { + "@cardano-ogmios/schema": "5.5.2", + "@cardanosolutions/json-bigint": "^1.0.0", + "@types/json-bigint": "^1.0.1", + "cross-fetch": "^3.1.4", + "fastq": "^1.11.0", + "isomorphic-ws": "^4.0.1", + "nanoid": "^3.1.31", + "ts-custom-error": "^3.2.0", + "ws": "^7.4.6" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@cardano-sdk/cip30/node_modules/@cardano-ogmios/schema": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@cardano-ogmios/schema/-/schema-5.5.2.tgz", + "integrity": "sha512-0+vlT13y+/hXYCHoX8Fvd1O+8mRoPJ0ajc/NMtFgZr6aIRm7zu8Jpa8gWjNJJqAp8f3F2vj4eIeB7F9suIfmaQ==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@cardano-sdk/cip30/node_modules/@cardano-sdk/core": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@cardano-sdk/core/-/core-0.5.0.tgz", + "integrity": "sha512-MGN7GRwrU8hJjjZrUWYm/4V2TLVJgMOqu7yN0rQTU7Wh72CvYID/Xl8TtZE3UydBO0wYSy3nR000uxIULInvJg==", + "dev": true, + "dependencies": { + "@cardano-ogmios/client": "5.5.2", + "@cardano-sdk/util": "^0.5.0", + "@emurgo/cardano-serialization-lib-browser": "11.0.0-rc.6", + "@emurgo/cardano-serialization-lib-nodejs": "11.0.0-rc.6", + "bech32": "^2.0.0", + "lodash": "^4.17.21", + "ts-custom-error": "^3.2.0" + }, + "engines": { + "node": "^14" + } + }, + "node_modules/@cardano-sdk/cip30/node_modules/@cardano-sdk/util": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@cardano-sdk/util/-/util-0.5.0.tgz", + "integrity": "sha512-8wEDcV/kwtoH8cifNhUgIo24ACszum0S05MQRz6yzyA2e+I7i4zZaOktgXmts/xA+i7ppTk2eunDK8Rok197cw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21", + "serialize-error": "^8" + }, + "engines": { + "node": "^14" + } + }, + "node_modules/@cardano-sdk/cip30/node_modules/@emurgo/cardano-serialization-lib-browser": { + "version": "11.0.0-rc.6", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-11.0.0-rc.6.tgz", + "integrity": "sha512-EWqknJqmJf+Tnsn5s05CvKRPCC0ncGcDHjqf9pjty/FKRo2oC6CzmLk3CciRhucmD78cxSiHlhMl8dqROivxPg==", + "dev": true + }, + "node_modules/@cardano-sdk/cip30/node_modules/@emurgo/cardano-serialization-lib-nodejs": { + "version": "11.0.0-rc.6", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-11.0.0-rc.6.tgz", + "integrity": "sha512-OXakMlp9sgB8kX+pwPY8z9REHcXG93dmIfSqHHLNq/CzwxCDa1lr/zg/3BtJL4Di6LzBBo8X+kUd9ehdX5diHA==", + "dev": true + }, + "node_modules/@cardano-sdk/cip30/node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", + "dev": true + }, + "node_modules/@cardanosolutions/json-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cardanosolutions/json-bigint/-/json-bigint-1.0.1.tgz", + "integrity": "sha512-mbYL6jtHqMFCZnTFhmkmoeDzHMBino0gMiGQnOJE7CwzZzkK2HCpH0MTBk+84QDadMEGX7iFt7uB+levm1a+bQ==", + "dev": true, + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", @@ -1788,6 +1891,12 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/json-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/json-bigint/-/json-bigint-1.0.4.tgz", + "integrity": "sha512-ydHooXLbOmxBbubnA7Eh+RpBzuaIiQjh8WGJYQB50JFGFrdxW7JzVlyEV7fAXw0T2sqJ1ysTneJbiyNLqZRAag==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -2760,6 +2869,15 @@ "node": ">=0.6" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2837,6 +2955,21 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -3010,6 +3143,15 @@ "node": ">=10" } }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4814,6 +4956,15 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "devOptional": true }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "dev": true, + "peerDependencies": { + "ws": "*" + } + }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -4999,7 +5150,7 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "optional": true + "devOptional": true }, "node_modules/lodash-es": { "version": "4.17.21", @@ -5153,6 +5304,39 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "optional": true }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "dev": true, + "optional": true, + "peer": true, + "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.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", @@ -6127,6 +6311,21 @@ "node": ">=10" } }, + "node_modules/serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -6580,6 +6779,12 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -6592,12 +6797,27 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-custom-error": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz", + "integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true }, + "node_modules/ts-log": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.5.tgz", + "integrity": "sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==", + "dev": true + }, "node_modules/tsconfck": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.3.tgz", @@ -6651,7 +6871,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "optional": true, + "devOptional": true, "engines": { "node": ">=10" }, @@ -6851,6 +7071,21 @@ } } }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -6931,6 +7166,28 @@ } } }, + "node_modules/webextension-polyfill": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.8.0.tgz", + "integrity": "sha512-a19+DzlT6Kp9/UI+mF9XQopeZ+n2ussjhxHJ4/pmIGge9ijCDz7Gn93mNnjpZAk95T4Tae8iHZ6sSf869txqiQ==", + "dev": true + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7124,6 +7381,27 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index b1ec31ebb50..366b41bf3d9 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -33,6 +33,7 @@ "tailwind-merge": "^2.2.1" }, "devDependencies": { + "@cardano-sdk/cip30": "^0.5.0", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.27", "@types/react": "^18.2.65", diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index a65ea777703..fa26c70bd46 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -1,12 +1,17 @@ +import { WalletApi } from "@cardano-sdk/cip30"; +import { Tab } from "@headlessui/react"; +import ArrowRightIcon from '@mui/icons-material/ArrowRight'; +import getCardano from "common/helpers/getCardano"; +import WalletCard from "components/WalletCard"; +import { xor } from "lodash-es"; +import { Fragment, useState } from "react"; import { QueryClient, QueryClientProvider } from "react-query"; import { ToastContainer } from "react-toastify"; -import { xor } from "lodash-es"; +import { twMerge } from "tailwind-merge"; import "react-toastify/dist/ReactToastify.css"; import "./styles/global.css"; -import WalletCard from "components/WalletCard"; -import { useEffect, useState } from "react"; const queryClient = new QueryClient({ defaultOptions: { @@ -21,40 +26,37 @@ const queryClient = new QueryClient({ }); function App() { - const [isInit, setIsInit] = useState(false); - const [walletApis, setWalletApis] = useState({}); - const [enablingWallets, setEnablingWallets] = useState([]); - const [selectingWallets, setSelectingWallets] = useState([]); + const [walletApis, setWalletApis] = useState>({}); + const [enablingWallets, setEnablingWallets] = useState([]); + const [selectedWallets, setSelectedWallets] = useState([]); - console.log(globalThis.cardano); + console.log(getCardano()); - useEffect(() => { - init(); - }, []); + const isCardanoActivated = typeof getCardano() !== "undefined"; - const isCardanoActivated = typeof globalThis.cardano !== "undefined"; - - async function init() { - console.log("testing") + function handleWalletCardClick(walletName: string) { + setSelectedWallets((prev) => xor(prev, [walletName])) + } - const walletApis = await Promise.all(Object.entries(globalThis.cardano).map(async ([walletName, walletProps]: any) => { - const api = await walletProps.enable({ cip: 30 }) + async function enableWallet(walletName: string) { + setEnablingWallets((prev) => [...prev, walletName]); - return [walletName, api] - })); + const api = await getCardano(walletName).enable(); - console.log("apis", walletApis) + console.log(walletName, "api", api); - setIsInit(true); - setWalletApis(Object.fromEntries(walletApis)); + setWalletApis((prev) => ({ ...prev, [walletName]: api })); + setEnablingWallets((prev) => prev.filter((w) => w !== walletName)); } - function handleWalletCardClick(walletName: string) { - setSelectingWallets((prev) => xor(prev, [ walletName ])) - } + async function enableAllWallets(walletNames: string[]) { + /* const walletApis = await Promise.all(Object.entries(getCardano()).map(async ([walletName, walletProps]: any) => { + const api = await walletProps.enable({ cip: 30 }) - if (!isInit) { - return
Loading
+ return [walletName, api] + })); */ + + // setWalletApis(Object.fromEntries(walletApis)); } return ( @@ -62,26 +64,89 @@ function App() {
-
-
+
+
{isCardanoActivated ? ( -
-

Select available wallets:

-
- {Object.keys(globalThis.cardano).map((walletName) => ( - handleWalletCardClick(walletName)} - /> - ))} -
-
+ <> +
+

Select available wallets:

+
+ {Object.keys(getCardano()).map((walletName) => ( + handleWalletCardClick(walletName)} + /> + ))} +
+
+
+

Wallet Informatmion:

+ {selectedWallets.length ? ( +
+
+
+
+

Selected wallets: {selectedWallets.length}

+
+
+ +
+
+
+ + + {selectedWallets.map((wallet) => ( + + {({ selected }) => ( +
+ icon +

{wallet}

+ {selected && } +
+ )} +
+ ))} +
+ + {selectedWallets.map((wallet) => ( + + {walletApis[wallet] ? ( +
+
+

+
+
{wallet}
+
+ ) : ( +
+ +
+ )} +
+ ))} +
+
+
+ ) : ( +
+

Please select at least one wallet to view the information.

+
+ )} +
+
+

Wallet Actions:

+
+ ) : (
-
Cardano extension is not activated!
+

Cardano extension is not activated!

)}
diff --git a/utilities/wallet-connector/src/common/helpers/getCardano.ts b/utilities/wallet-connector/src/common/helpers/getCardano.ts new file mode 100644 index 00000000000..928995cf6ad --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/getCardano.ts @@ -0,0 +1,11 @@ +import { Cip30Wallet } from "@cardano-sdk/cip30"; + +type WalletCollections = { + [k: string]: Cip30Wallet; +}; + +export default function getCardano(walletName?: T): T extends string ? Cip30Wallet : WalletCollections { + return walletName + ? globalThis.cardano[walletName] + : globalThis.cardano; +} \ No newline at end of file From b6ab6d6d64056549fb7a23ddd39d4190b59bd347 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 14 Mar 2024 03:01:17 +0700 Subject: [PATCH 04/73] feat: wallet info view --- utilities/wallet-connector/src/App.tsx | 49 +++++++++++++++---- .../src/common/helpers/extractApiData.ts | 18 +++++++ .../wallet-connector/src/styles/global.css | 4 ++ .../wallet-connector/src/types/cardano.ts | 17 +++++++ 4 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 utilities/wallet-connector/src/common/helpers/extractApiData.ts create mode 100644 utilities/wallet-connector/src/types/cardano.ts diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index fa26c70bd46..31e5a3183c0 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -1,4 +1,3 @@ -import { WalletApi } from "@cardano-sdk/cip30"; import { Tab } from "@headlessui/react"; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import getCardano from "common/helpers/getCardano"; @@ -11,6 +10,8 @@ import { twMerge } from "tailwind-merge"; import "react-toastify/dist/ReactToastify.css"; +import extractApiData from "common/helpers/extractApiData"; +import { ExtractedWalletApi } from "types/cardano"; import "./styles/global.css"; const queryClient = new QueryClient({ @@ -26,7 +27,7 @@ const queryClient = new QueryClient({ }); function App() { - const [walletApis, setWalletApis] = useState>({}); + const [walletApis, setWalletApis] = useState>({}); const [enablingWallets, setEnablingWallets] = useState([]); const [selectedWallets, setSelectedWallets] = useState([]); @@ -43,9 +44,11 @@ function App() { const api = await getCardano(walletName).enable(); - console.log(walletName, "api", api); + const extractedApi = await extractApiData(api); - setWalletApis((prev) => ({ ...prev, [walletName]: api })); + console.log("api", extractedApi); + + setWalletApis((prev) => ({ ...prev, [walletName]: extractedApi })); setEnablingWallets((prev) => prev.filter((w) => w !== walletName)); } @@ -112,15 +115,43 @@ function App() { ))} - + {selectedWallets.map((wallet) => ( {walletApis[wallet] ? ( -
-
-

+
+
+

Balance Lovelace:

+

{walletApis[wallet]?.balance || "-"}

+
+
+

UTXOs:

+

{walletApis[wallet]?.utxos.join(", ") || "-"}

+
+
+

Network ID (0 = testnet; 1 = mainnet):

+

{walletApis[wallet]?.networkId || "-"}

+
+
+

Collateral:

+

{walletApis[wallet]?.collateral?.join(", ") || "-"}

+
+
+

Used Addresses:

+

{walletApis[wallet]?.usedAddresses?.join(", ") || "-"}

+
+
+

Unused Addresses:

+

{walletApis[wallet]?.unusedAddresses?.join(", ") || "-"}

+
+
+

Change Address:

+

{walletApis[wallet]?.changeAddress || "-"}

+
+
+

Reward Address:

+

{walletApis[wallet]?.rewardAddresses || "-"}

-
{wallet}
) : (
diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts new file mode 100644 index 00000000000..f202a0a18d2 --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -0,0 +1,18 @@ +import { WalletApi } from "@cardano-sdk/cip30"; +import { ExtractedWalletApi } from "types/cardano"; + +export default async function extractApiData(api: WalletApi): Promise { + return { + networkId: await api.getNetworkId(), + utxos: await api.getUtxos(), + balance: await api.getBalance(), + collateral: await api.getCollateral(), + usedAddresses: await api.getUsedAddresses(), + unusedAddresses: await api.getUnusedAddresses(), + changeAddress: await api.getChangeAddress(), + rewardAddresses: await api.getRewardAddresses(), + signTx: api.signTx, + signData: api.signData, + submitTx: api.submitTx, + }; +} \ No newline at end of file diff --git a/utilities/wallet-connector/src/styles/global.css b/utilities/wallet-connector/src/styles/global.css index bfa7a939943..3e9efec6ea9 100644 --- a/utilities/wallet-connector/src/styles/global.css +++ b/utilities/wallet-connector/src/styles/global.css @@ -24,3 +24,7 @@ button { background-color: transparent; border: 0; } + +button:disabled { + opacity: 0.6; +} diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts new file mode 100644 index 00000000000..c0807af9f2e --- /dev/null +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -0,0 +1,17 @@ +import * as cip30 from "@cardano-sdk/cip30"; + +type Extracted any> = Awaited>; + +export type ExtractedWalletApi = { + networkId: Extracted; + utxos: Extracted; + balance: Extracted; + collateral: Extracted; + usedAddresses: Extracted; + unusedAddresses: Extracted; + changeAddress: Extracted; + rewardAddresses: Extracted; + signTx: cip30.SignTx; + signData: cip30.SignData; + submitTx: cip30.SubmitTx; +} \ No newline at end of file From e598d98097f5d9e611cbeea319fda5c6c46894b4 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 14 Mar 2024 18:42:27 +0700 Subject: [PATCH 05/73] feat: secitons --- utilities/wallet-connector/package-lock.json | 9 +++ utilities/wallet-connector/package.json | 1 + utilities/wallet-connector/src/App.tsx | 70 +++++++++---------- .../src/components/InfoItem.tsx | 33 +++++++++ .../src/modules/WalletActionsSection.tsx | 13 ++++ .../src/modules/WalletInfoSection.tsx | 13 ++++ 6 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 utilities/wallet-connector/src/components/InfoItem.tsx create mode 100644 utilities/wallet-connector/src/modules/WalletActionsSection.tsx create mode 100644 utilities/wallet-connector/src/modules/WalletInfoSection.tsx diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index 608b93a6ea1..0abf106ec01 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -13,6 +13,7 @@ "@headlessui/react": "^1.7.18", "@mui/icons-material": "^5.15.13", "@mui/material": "^5.15.13", + "cborg": "^4.1.1", "clsx": "^2.1.0", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", @@ -3026,6 +3027,14 @@ } ] }, + "node_modules/cborg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.1.1.tgz", + "integrity": "sha512-XBEXWdr1N0pjAX0l2a+BKmWGIMDYoLrrqgAWWETtaqn3HC4zn0dZoNO8vC+8oDZfDLMyVRfRD3kMuoYgT67KBQ==", + "bin": { + "cborg": "lib/bin.js" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index 366b41bf3d9..b4715de2a4d 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -19,6 +19,7 @@ "@headlessui/react": "^1.7.18", "@mui/icons-material": "^5.15.13", "@mui/material": "^5.15.13", + "cborg": "^4.1.1", "clsx": "^2.1.0", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 31e5a3183c0..d4f3065736a 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -13,6 +13,8 @@ import "react-toastify/dist/ReactToastify.css"; import extractApiData from "common/helpers/extractApiData"; import { ExtractedWalletApi } from "types/cardano"; import "./styles/global.css"; +import InfoItem from "components/InfoItem"; +import WalletActionsSection from "modules/WalletActionsSection"; const queryClient = new QueryClient({ defaultOptions: { @@ -120,38 +122,38 @@ function App() { {walletApis[wallet] ? (
-
-

Balance Lovelace:

-

{walletApis[wallet]?.balance || "-"}

-
-
-

UTXOs:

-

{walletApis[wallet]?.utxos.join(", ") || "-"}

-
-
-

Network ID (0 = testnet; 1 = mainnet):

-

{walletApis[wallet]?.networkId || "-"}

-
-
-

Collateral:

-

{walletApis[wallet]?.collateral?.join(", ") || "-"}

-
-
-

Used Addresses:

-

{walletApis[wallet]?.usedAddresses?.join(", ") || "-"}

-
-
-

Unused Addresses:

-

{walletApis[wallet]?.unusedAddresses?.join(", ") || "-"}

-
-
-

Change Address:

-

{walletApis[wallet]?.changeAddress || "-"}

-
-
-

Reward Address:

-

{walletApis[wallet]?.rewardAddresses || "-"}

-
+ + + + + + + +
) : (
@@ -171,9 +173,7 @@ function App() {
)}
-
-

Wallet Actions:

-
+ ) : (
diff --git a/utilities/wallet-connector/src/components/InfoItem.tsx b/utilities/wallet-connector/src/components/InfoItem.tsx new file mode 100644 index 00000000000..0e8681de01e --- /dev/null +++ b/utilities/wallet-connector/src/components/InfoItem.tsx @@ -0,0 +1,33 @@ +import { toast } from "react-toastify"; + +type Props = { + heading: string; + value: string | string[] | null; +} + +function InfoItem({ heading, value }: Props) { + async function handleCopy(value: string) { + await navigator.clipboard.writeText(value); + + toast.success("Value coppied."); + } + + return ( +
+

{heading}:

+ {typeof value === "string" ? ( +

handleCopy(value)}>{value || "-"}

+ ) : Array.isArray(value) && value.length ? ( +
    + {value.map((v) => ( +
  1. handleCopy(v)}>{v || "-"}
  2. + ))} +
+ ) : ( +

{String(value) || "-"}

+ )} +
+ ) +} + +export default InfoItem; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx new file mode 100644 index 00000000000..854094afc68 --- /dev/null +++ b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx @@ -0,0 +1,13 @@ +type Props = { + +} + +function WalletActionsSection({ }: Props) { + return ( +
+

Wallet Actions:

+
+ ) +} + +export default WalletActionsSection; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx new file mode 100644 index 00000000000..b8907518711 --- /dev/null +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -0,0 +1,13 @@ +type Props = { + +} + +function WalletInfoSection({ }: Props) { + return ( +
+ +
+ ) +} + +export default WalletInfoSection; \ No newline at end of file From 4ca2825f5588da8ea44c5deb9a873c1f77c723a3 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 14 Mar 2024 18:48:45 +0700 Subject: [PATCH 06/73] refactor: move wallet info section --- utilities/wallet-connector/src/App.tsx | 112 +++--------------- .../src/modules/WalletInfoSection.tsx | 112 +++++++++++++++++- 2 files changed, 123 insertions(+), 101 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index d4f3065736a..2715aadc803 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -1,20 +1,18 @@ -import { Tab } from "@headlessui/react"; -import ArrowRightIcon from '@mui/icons-material/ArrowRight'; +import "react-toastify/dist/ReactToastify.css"; + +import "./styles/global.css"; + import getCardano from "common/helpers/getCardano"; import WalletCard from "components/WalletCard"; import { xor } from "lodash-es"; -import { Fragment, useState } from "react"; +import { useState } from "react"; import { QueryClient, QueryClientProvider } from "react-query"; import { ToastContainer } from "react-toastify"; -import { twMerge } from "tailwind-merge"; - -import "react-toastify/dist/ReactToastify.css"; import extractApiData from "common/helpers/extractApiData"; -import { ExtractedWalletApi } from "types/cardano"; -import "./styles/global.css"; -import InfoItem from "components/InfoItem"; import WalletActionsSection from "modules/WalletActionsSection"; +import WalletInfoSection from "modules/WalletInfoSection"; +import { ExtractedWalletApi } from "types/cardano"; const queryClient = new QueryClient({ defaultOptions: { @@ -87,93 +85,15 @@ function App() { ))}
-
-

Wallet Informatmion:

- {selectedWallets.length ? ( -
-
-
-
-

Selected wallets: {selectedWallets.length}

-
-
- -
-
-
- - - {selectedWallets.map((wallet) => ( - - {({ selected }) => ( -
- icon -

{wallet}

- {selected && } -
- )} -
- ))} -
- - {selectedWallets.map((wallet) => ( - - {walletApis[wallet] ? ( -
- - - - - - - - -
- ) : ( -
- -
- )} -
- ))} -
-
-
- ) : ( -
-

Please select at least one wallet to view the information.

-
- )} -
- + + ) : (
diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index b8907518711..a97a3c31d7d 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -1,12 +1,114 @@ +import { Tab } from "@headlessui/react"; +import getCardano from "common/helpers/getCardano"; +import { noop } from "lodash-es"; +import { Fragment } from "react/jsx-runtime"; +import { twMerge } from "tailwind-merge"; +import ArrowRightIcon from '@mui/icons-material/ArrowRight'; +import InfoItem from "components/InfoItem"; +import { ExtractedWalletApi } from "types/cardano"; + type Props = { - + selectedWallets: string[]; + enablingWallets: string[]; + walletApis: Record; + onEnable?: (walletName: string) => void; + onEnableAll?: (walletNames: string[]) => void; } -function WalletInfoSection({ }: Props) { +function WalletInfoSection({ + selectedWallets, + enablingWallets, + walletApis, + onEnable = noop, + onEnableAll = noop, +}: Props) { return ( -
- -
+
+

Wallet Informatmion:

+ {selectedWallets.length ? ( +
+
+
+
+

Selected wallets: {selectedWallets.length}

+
+
+ +
+
+
+ + + {selectedWallets.map((wallet) => ( + + {({ selected }) => ( +
+ icon +

{wallet}

+ {selected && } +
+ )} +
+ ))} +
+ + {selectedWallets.map((wallet) => ( + + {walletApis[wallet] ? ( +
+ + + + + + + + +
+ ) : ( +
+ +
+ )} +
+ ))} +
+
+
+ ) : ( +
+

Please select at least one wallet to view the information.

+
+ )} +
) } From 6676b91b729830fb7bd4eb656ea5d20336d3c341 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 14 Mar 2024 18:55:35 +0700 Subject: [PATCH 07/73] feat: stricter checks --- utilities/wallet-connector/src/App.tsx | 2 +- .../src/common/helpers/extractApiData.ts | 4 +-- .../src/modules/WalletInfoSection.tsx | 22 ++++++------- utilities/wallet-connector/tsconfig.json | 31 ++++++++++++++----- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 2715aadc803..11a8a56bd79 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -12,7 +12,7 @@ import { ToastContainer } from "react-toastify"; import extractApiData from "common/helpers/extractApiData"; import WalletActionsSection from "modules/WalletActionsSection"; import WalletInfoSection from "modules/WalletInfoSection"; -import { ExtractedWalletApi } from "types/cardano"; +import type { ExtractedWalletApi } from "types/cardano"; const queryClient = new QueryClient({ defaultOptions: { diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index f202a0a18d2..c32194d6bd9 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -1,5 +1,5 @@ -import { WalletApi } from "@cardano-sdk/cip30"; -import { ExtractedWalletApi } from "types/cardano"; +import type { WalletApi } from "@cardano-sdk/cip30"; +import type { ExtractedWalletApi } from "types/cardano"; export default async function extractApiData(api: WalletApi): Promise { return { diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index a97a3c31d7d..11713171304 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -5,14 +5,14 @@ import { Fragment } from "react/jsx-runtime"; import { twMerge } from "tailwind-merge"; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import InfoItem from "components/InfoItem"; -import { ExtractedWalletApi } from "types/cardano"; +import type { ExtractedWalletApi } from "types/cardano"; type Props = { selectedWallets: string[]; enablingWallets: string[]; walletApis: Record; onEnable?: (walletName: string) => void; - onEnableAll?: (walletNames: string[]) => void; + onEnableAll?: () => void; } function WalletInfoSection({ @@ -33,7 +33,7 @@ function WalletInfoSection({

Selected wallets: {selectedWallets.length}

-
@@ -60,35 +60,35 @@ function WalletInfoSection({
) : ( diff --git a/utilities/wallet-connector/tsconfig.json b/utilities/wallet-connector/tsconfig.json index 1262c50fbb7..08d50a3b9fa 100644 --- a/utilities/wallet-connector/tsconfig.json +++ b/utilities/wallet-connector/tsconfig.json @@ -1,22 +1,39 @@ { "compilerOptions": { + // Basic Configuration "target": "ES2018", - "useDefineForClassFields": true, + "module": "ESNext", "lib": ["DOM", "ESNext"], - "baseUrl": "./src", "allowJs": false, - "skipLibCheck": true, - "skipDefaultLibCheck": true, + "jsx": "react-jsx", + "baseUrl": "./src", + + // Advanced Configuration "esModuleInterop": false, "allowSyntheticDefaultImports": true, - "downlevelIteration": true, "forceConsistentCasingInFileNames": true, - "module": "ESNext", + "downlevelIteration": true, "moduleResolution": "Node", "resolveJsonModule": true, "isolatedModules": true, + "verbatimModuleSyntax": true, + + // Type Checking Configuration + "skipLibCheck": true, + "skipDefaultLibCheck": true, "noEmit": true, - "jsx": "react-jsx", + + // Strict + "strict": true, + "noUncheckedIndexedAccess": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "exactOptionalPropertyTypes": true, + "strictNullChecks": true, + + // Type Definitions Configuration "types": ["vite/client", "react", "react-dom"], }, "include": ["src"], From 3f07caebe6fdea5e011f2328584d5951b3410a5e Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 14 Mar 2024 21:33:47 +0700 Subject: [PATCH 08/73] feat: panels --- utilities/wallet-connector/src/App.tsx | 2 +- .../src/components/CBOREditor.tsx | 18 ++++++ .../src/components/CheckBox.tsx | 24 ++++++++ .../src/components/InputBlock.tsx | 25 ++++++++ .../src/modules/SignDataPanel.tsx | 13 +++++ .../src/modules/SignTxnPanel.tsx | 58 +++++++++++++++++++ .../src/modules/SubmitTxnPanel.tsx | 13 +++++ .../src/modules/WalletActionsSection.tsx | 47 +++++++++++++++ .../src/modules/WalletInfoSection.tsx | 2 +- 9 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 utilities/wallet-connector/src/components/CBOREditor.tsx create mode 100644 utilities/wallet-connector/src/components/CheckBox.tsx create mode 100644 utilities/wallet-connector/src/components/InputBlock.tsx create mode 100644 utilities/wallet-connector/src/modules/SignDataPanel.tsx create mode 100644 utilities/wallet-connector/src/modules/SignTxnPanel.tsx create mode 100644 utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 11a8a56bd79..413b0ce92a2 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -67,7 +67,7 @@ function App() {
-
+
{isCardanoActivated ? ( <> diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/components/CBOREditor.tsx new file mode 100644 index 00000000000..96d7cb8cafa --- /dev/null +++ b/utilities/wallet-connector/src/components/CBOREditor.tsx @@ -0,0 +1,18 @@ +import { noop } from "lodash-es"; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import { twMerge } from "tailwind-merge"; + +type Props = { + +} + +function CBOREditor({ }: Props) { + return ( +
+ +
+ ) +} + +export default CBOREditor; \ No newline at end of file diff --git a/utilities/wallet-connector/src/components/CheckBox.tsx b/utilities/wallet-connector/src/components/CheckBox.tsx new file mode 100644 index 00000000000..d409a3788f9 --- /dev/null +++ b/utilities/wallet-connector/src/components/CheckBox.tsx @@ -0,0 +1,24 @@ +import { noop } from "lodash-es"; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import { twMerge } from "tailwind-merge"; + +type Props = { + variant?: "radio" | "checkbox", + value: boolean; + label?: string; + onChange?: (value: boolean) => void; +} + +function CheckBox({ variant = "checkbox", value, label, onChange = noop }: Props) { + return ( + + ) +} + +export default CheckBox; \ No newline at end of file diff --git a/utilities/wallet-connector/src/components/InputBlock.tsx b/utilities/wallet-connector/src/components/InputBlock.tsx new file mode 100644 index 00000000000..36bdea7d5bc --- /dev/null +++ b/utilities/wallet-connector/src/components/InputBlock.tsx @@ -0,0 +1,25 @@ +import InputIcon from "@mui/icons-material/Input"; +import type { ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; + +type Props = { + variant: "inline" | "block", + name: string, + children: ReactNode +} + +function InputBlock({ variant, name, children }: Props) { + return ( +
+
+ +

{name}:

+
+
+ {children} +
+
+ ) +} + +export default InputBlock; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/SignDataPanel.tsx b/utilities/wallet-connector/src/modules/SignDataPanel.tsx new file mode 100644 index 00000000000..f7410e4b90f --- /dev/null +++ b/utilities/wallet-connector/src/modules/SignDataPanel.tsx @@ -0,0 +1,13 @@ +type Props = { + +} + +function SignDataPanel({ }: Props) { + return ( +
+ +
+ ) +} + +export default SignDataPanel; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx new file mode 100644 index 00000000000..144053a3a98 --- /dev/null +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -0,0 +1,58 @@ +import InputIcon from "@mui/icons-material/Input"; +import CBOREditor from "components/CBOREditor"; +import CheckBox from "components/CheckBox"; +import InputBlock from "components/InputBlock"; +import { Controller, useForm } from "react-hook-form"; + +type Props = { + +} + +type FormValues = { + partialSign: boolean; + tx: string; +} + +function SignTxnPanel({ }: Props) { + const actionForm = useForm({ + defaultValues: { + partialSign: false, + tx: "" + } + }); + + return ( +
+
+
+ Requests that a user sign the unsigned portions of the supplied transaction. + The wallet should ask the user for permission, and if given, try to sign the supplied body and return a signed transaction. + If partialSign is true, the wallet only tries to sign what it can. + If partialSign is false and the wallet could not sign the entire transaction, TxSignError shall be returned with the ProofGeneration code. + Likewise if the user declined in either case it shall return the UserDeclined code. + Only the portions of the witness set that were signed as a result of this call are returned to encourage dApps to verify the contents returned by this endpoint while building the final transaction. +
+

Payload:

+ + ( + + )} + /> + + + + +
+
+ +
+
+ ) +} + +export default SignTxnPanel; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx new file mode 100644 index 00000000000..c1dd3eaa2ae --- /dev/null +++ b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx @@ -0,0 +1,13 @@ +type Props = { + +} + +function SubmitTxnPanel({ }: Props) { + return ( +
+ +
+ ) +} + +export default SubmitTxnPanel; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx index 854094afc68..8d9aa7e61e7 100644 --- a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx @@ -1,3 +1,17 @@ +import { Tab } from "@headlessui/react"; +import ArrowRightIcon from '@mui/icons-material/ArrowRight'; +import { Fragment } from "react/jsx-runtime"; +import { twMerge } from "tailwind-merge"; +import SignDataPanel from "./SignDataPanel"; +import SignTxnPanel from "./SignTxnPanel"; +import SubmitTxnPanel from "./SubmitTxnPanel"; + +const ACTIONS = [ + "Sign Transaction", + "Sign Data", + "Submit Transaction" +]; + type Props = { } @@ -6,6 +20,39 @@ function WalletActionsSection({ }: Props) { return (

Wallet Actions:

+
+ + + {ACTIONS.map((action) => ( + + {({ selected }) => ( +
+

{action}

+ {selected && } +
+ )} +
+ ))} +
+ + + + + + + + + + + +
+
) } diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index 11713171304..e5b2f6afef9 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -44,7 +44,7 @@ function WalletInfoSection({ {selectedWallets.map((wallet) => ( {({ selected }) => ( -
+
icon

{wallet}

{selected && } From f9571e08f559077fbf8da59be58fed7201920112 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 01:05:22 +0700 Subject: [PATCH 09/73] feat: cbor editor --- utilities/wallet-connector/package-lock.json | 77 +++++++++---------- utilities/wallet-connector/package.json | 4 +- .../src/common/helpers/hex2bin.ts | 16 ++++ .../src/components/Button.tsx | 16 ++++ .../src/components/CBOREditor.tsx | 77 +++++++++++++++++-- .../src/components/InputBlock.tsx | 2 +- .../src/modules/SignTxnPanel.tsx | 22 +++++- .../src/modules/WalletInfoSection.tsx | 11 +-- .../wallet-connector/src/styles/global.css | 3 +- utilities/wallet-connector/tsconfig.json | 2 +- 10 files changed, 170 insertions(+), 60 deletions(-) create mode 100644 utilities/wallet-connector/src/common/helpers/hex2bin.ts create mode 100644 utilities/wallet-connector/src/components/Button.tsx diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index 0abf106ec01..41415d9b7a4 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -13,16 +13,17 @@ "@headlessui/react": "^1.7.18", "@mui/icons-material": "^5.15.13", "@mui/material": "^5.15.13", + "ace-builds": "^1.32.7", "cborg": "^4.1.1", "clsx": "^2.1.0", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", "react": "^18.2.0", + "react-ace": "^10.1.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-hook-form": "^7.51.0", "react-query": "^3.39.3", - "react-router-dom": "^6.22.3", "react-textarea-autosize": "^8.5.3", "react-toastify": "^10.0.4", "tailwind-merge": "^2.2.1" @@ -1458,14 +1459,6 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@remix-run/router": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", - "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.13.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", @@ -2465,6 +2458,11 @@ "vite": "^4 || ^5" } }, + "node_modules/ace-builds": { + "version": "1.32.7", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.32.7.tgz", + "integrity": "sha512-ziv35kaYELFw4suWlotz/Xsl1/1LhWAbwFoD3zIgCgP9gXGECEsAM4GhiB0T0xZdmQjyv6hmAzO280g0+n4vGw==" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -3280,6 +3278,11 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true }, + "node_modules/diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", + "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -5166,6 +5169,16 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5934,6 +5947,22 @@ "node": ">=0.10.0" } }, + "node_modules/react-ace": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-10.1.0.tgz", + "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==", + "dependencies": { + "ace-builds": "^1.4.14", + "diff-match-patch": "^1.0.5", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -6007,36 +6036,6 @@ } } }, - "node_modules/react-router": { - "version": "6.22.3", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz", - "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==", - "dependencies": { - "@remix-run/router": "1.15.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/react-router-dom": { - "version": "6.22.3", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz", - "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==", - "dependencies": { - "@remix-run/router": "1.15.3", - "react-router": "6.22.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, "node_modules/react-textarea-autosize": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index b4715de2a4d..6fd9fa93330 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -19,16 +19,16 @@ "@headlessui/react": "^1.7.18", "@mui/icons-material": "^5.15.13", "@mui/material": "^5.15.13", + "ace-builds": "^1.32.7", "cborg": "^4.1.1", - "clsx": "^2.1.0", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", "react": "^18.2.0", + "react-ace": "^10.1.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-hook-form": "^7.51.0", "react-query": "^3.39.3", - "react-router-dom": "^6.22.3", "react-textarea-autosize": "^8.5.3", "react-toastify": "^10.0.4", "tailwind-merge": "^2.2.1" diff --git a/utilities/wallet-connector/src/common/helpers/hex2bin.ts b/utilities/wallet-connector/src/common/helpers/hex2bin.ts new file mode 100644 index 00000000000..133e5eea539 --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/hex2bin.ts @@ -0,0 +1,16 @@ +export default function hex2bin(hexString: string): Uint8Array { + // Remove spaces and convert to uppercase + const cleanedHexString = hexString.replace(/\s/g, '').toUpperCase(); + + // Check if the cleaned string is a valid hex string + if (!/^[0-9a-fA-F]*$/.test(cleanedHexString)) { + throw new Error('Invalid hex string'); + } + + // Convert the hex string to a Uint8Array + const uint8Array = Array.from(cleanedHexString.match(/.{1,2}/g) || []).map((byte) => + parseInt(byte, 16) + ); + + return new Uint8Array(uint8Array); +} \ No newline at end of file diff --git a/utilities/wallet-connector/src/components/Button.tsx b/utilities/wallet-connector/src/components/Button.tsx new file mode 100644 index 00000000000..754e35a7053 --- /dev/null +++ b/utilities/wallet-connector/src/components/Button.tsx @@ -0,0 +1,16 @@ +import type { ButtonHTMLAttributes, ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; + +type Props = { + children: ReactNode; +} & ButtonHTMLAttributes; + +function Button({ children, className = "", type = "button", ...props }: Props) { + return ( + + ) +} + +export default Button; \ No newline at end of file diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/components/CBOREditor.tsx index 96d7cb8cafa..00fc34b4dfa 100644 --- a/utilities/wallet-connector/src/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/components/CBOREditor.tsx @@ -1,16 +1,79 @@ +import { useState, type CSSProperties } from "react"; +import AceEditor from "react-ace"; +import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; +import { encode, decode } from "cborg"; import { noop } from "lodash-es"; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; -import CheckBoxIcon from '@mui/icons-material/CheckBox'; -import { twMerge } from "tailwind-merge"; +import hex2bin from "common/helpers/hex2bin"; + +import "ace-builds/src-noconflict/mode-text"; +import "ace-builds/src-noconflict/ext-language_tools"; type Props = { - + value: string; + isReadOnly?: boolean; + onChange?: (value: string) => void; } -function CBOREditor({ }: Props) { - return ( -
+const EDITOR_STYLE: CSSProperties = { + width: "100%", + fontFamily: "Fira Code, monospace", + fontSize: 12, + height: "240px" +} as const; + +// bg-gray-100 font-mono text-xs h-[240px] overflow-y-auto + +function CBOREditor({ + value, + isReadOnly = false, + onChange = noop +}: Props) { + const [prevValue, setPrevValue] = useState(""); + + function handleBinChange(value: string) { + + } + function handleDiagChange(value: string) { + + } + + const tmp = decode(hex2bin("a16474686973a26269736543424f522163796179f5"), { }) + + // console.log(tokensToDiagnostic(hex2bin("a16474686973a26269736543424f522163796179f5"))); + + return ( +
+
+

+ CBOR Editor + | + + | + +

+

+ bin + + diag +

+
+
+ + +
) } diff --git a/utilities/wallet-connector/src/components/InputBlock.tsx b/utilities/wallet-connector/src/components/InputBlock.tsx index 36bdea7d5bc..30b0c18c6f4 100644 --- a/utilities/wallet-connector/src/components/InputBlock.tsx +++ b/utilities/wallet-connector/src/components/InputBlock.tsx @@ -10,7 +10,7 @@ type Props = { function InputBlock({ variant, name, children }: Props) { return ( -
+

{name}:

diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index 144053a3a98..9a6638482df 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -1,4 +1,5 @@ import InputIcon from "@mui/icons-material/Input"; +import Button from "components/Button"; import CBOREditor from "components/CBOREditor"; import CheckBox from "components/CheckBox"; import InputBlock from "components/InputBlock"; @@ -14,13 +15,17 @@ type FormValues = { } function SignTxnPanel({ }: Props) { - const actionForm = useForm({ + const payloadForm = useForm({ defaultValues: { partialSign: false, tx: "" } }); + function handleExecute() { + + } + return (
@@ -35,7 +40,7 @@ function SignTxnPanel({ }: Props) {

Payload:

( @@ -43,10 +48,19 @@ function SignTxnPanel({ }: Props) { /> - ( + + )} /> +
+ +
diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index e5b2f6afef9..f44e4a250ed 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -6,6 +6,7 @@ import { twMerge } from "tailwind-merge"; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import InfoItem from "components/InfoItem"; import type { ExtractedWalletApi } from "types/cardano"; +import Button from "components/Button"; type Props = { selectedWallets: string[]; @@ -24,7 +25,7 @@ function WalletInfoSection({ }: Props) { return (
-

Wallet Informatmion:

+

Wallet Information:

{selectedWallets.length ? (
@@ -33,9 +34,9 @@ function WalletInfoSection({

Selected wallets: {selectedWallets.length}

- +
@@ -93,9 +94,9 @@ function WalletInfoSection({
) : (
- +
)} diff --git a/utilities/wallet-connector/src/styles/global.css b/utilities/wallet-connector/src/styles/global.css index 3e9efec6ea9..6ce4efa1100 100644 --- a/utilities/wallet-connector/src/styles/global.css +++ b/utilities/wallet-connector/src/styles/global.css @@ -1,4 +1,5 @@ @import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&display=swap"); @import "tailwindcss/base"; @import "tailwindcss/components"; @import "tailwindcss/utilities"; @@ -12,7 +13,7 @@ fieldset { width: 100%; } -html * { +html { font-family: Poppins, sans-serif; } diff --git a/utilities/wallet-connector/tsconfig.json b/utilities/wallet-connector/tsconfig.json index 08d50a3b9fa..ce330381ec2 100644 --- a/utilities/wallet-connector/tsconfig.json +++ b/utilities/wallet-connector/tsconfig.json @@ -4,7 +4,7 @@ "target": "ES2018", "module": "ESNext", "lib": ["DOM", "ESNext"], - "allowJs": false, + "allowJs": true, "jsx": "react-jsx", "baseUrl": "./src", From 592268b93b41fce004be51907699457eeafb1789 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 02:13:28 +0700 Subject: [PATCH 10/73] feat: hex2diag --- .../src/common/helpers/hex2bin.ts | 2 +- .../src/common/helpers/hex2diag.ts | 15 +++++++++++++++ .../src/components/CBOREditor.tsx | 19 ++++++++----------- utilities/wallet-connector/vite.config.ts | 5 +++++ 4 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 utilities/wallet-connector/src/common/helpers/hex2diag.ts diff --git a/utilities/wallet-connector/src/common/helpers/hex2bin.ts b/utilities/wallet-connector/src/common/helpers/hex2bin.ts index 133e5eea539..9054eaf5060 100644 --- a/utilities/wallet-connector/src/common/helpers/hex2bin.ts +++ b/utilities/wallet-connector/src/common/helpers/hex2bin.ts @@ -1,6 +1,6 @@ export default function hex2bin(hexString: string): Uint8Array { // Remove spaces and convert to uppercase - const cleanedHexString = hexString.replace(/\s/g, '').toUpperCase(); + const cleanedHexString = hexString.replace(/\s/gm, '').toUpperCase(); // Check if the cleaned string is a valid hex string if (!/^[0-9a-fA-F]*$/.test(cleanedHexString)) { diff --git a/utilities/wallet-connector/src/common/helpers/hex2diag.ts b/utilities/wallet-connector/src/common/helpers/hex2diag.ts new file mode 100644 index 00000000000..4249fc61177 --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/hex2diag.ts @@ -0,0 +1,15 @@ +import { tokensToDiagnostic } from "cborg/lib/diagnostic"; +import hex2bin from "./hex2bin"; + +export default function hex2diag(hexString: string): string { + try { + const result: string[] = []; + for (const line of tokensToDiagnostic(hex2bin(hexString), 48)) { + result.push(line); + } + + return result.join("\n").replace(/#\s+/gm, "# "); + } catch (err: unknown) { + return String(err); + } +} diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/components/CBOREditor.tsx index 00fc34b4dfa..f3a064567f2 100644 --- a/utilities/wallet-connector/src/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/components/CBOREditor.tsx @@ -1,12 +1,11 @@ -import { useState, type CSSProperties } from "react"; -import AceEditor from "react-ace"; import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; -import { encode, decode } from "cborg"; import { noop } from "lodash-es"; -import hex2bin from "common/helpers/hex2bin"; +import { useState, type CSSProperties } from "react"; +import AceEditor from "react-ace"; +import hex2diag from "common/helpers/hex2diag"; -import "ace-builds/src-noconflict/mode-text"; import "ace-builds/src-noconflict/ext-language_tools"; +import "ace-builds/src-noconflict/mode-text"; type Props = { value: string; @@ -31,16 +30,14 @@ function CBOREditor({ const [prevValue, setPrevValue] = useState(""); function handleBinChange(value: string) { - + onChange(value); } function handleDiagChange(value: string) { } - const tmp = decode(hex2bin("a16474686973a26269736543424f522163796179f5"), { }) - - // console.log(tokensToDiagnostic(hex2bin("a16474686973a26269736543424f522163796179f5"))); + console.log(hex2diag("a16474686973a26269736543424f522163796179f5")); return (
@@ -60,14 +57,14 @@ function CBOREditor({
{ return { + resolve: { + alias: { + "cborg/lib/diagnostic": "../../node_modules/cborg/lib/diagnostic" + } + }, server: { host: process.env["HOST"] || "127.0.0.1", port: Number(process.env["PORT"] || 3000), From 8fb36c927004812dc31a27c30e42a3904f345e2e Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 03:10:56 +0700 Subject: [PATCH 11/73] feat: reactive cbor editor --- .../src/common/helpers/diag2hex.ts | 13 ++++++ .../src/components/CBOREditor.tsx | 44 ++++++++++++++++--- .../src/modules/SignTxnPanel.tsx | 2 +- 3 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 utilities/wallet-connector/src/common/helpers/diag2hex.ts diff --git a/utilities/wallet-connector/src/common/helpers/diag2hex.ts b/utilities/wallet-connector/src/common/helpers/diag2hex.ts new file mode 100644 index 00000000000..612e97b09eb --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/diag2hex.ts @@ -0,0 +1,13 @@ +import { fromDiag } from "cborg/lib/diagnostic"; + +export default function diag2hex(diagString: string): string { + try { + const result = fromDiag(diagString); + + return Array.from(result, byte => { + return ("0" + byte.toString(16)).slice(-2); + }).join(" "); + } catch (err: unknown) { + return String(err); + } +} diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/components/CBOREditor.tsx index f3a064567f2..6c6bbd9c525 100644 --- a/utilities/wallet-connector/src/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/components/CBOREditor.tsx @@ -1,11 +1,12 @@ import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; import { noop } from "lodash-es"; -import { useState, type CSSProperties } from "react"; +import { useState, type CSSProperties, useEffect } from "react"; import AceEditor from "react-ace"; import hex2diag from "common/helpers/hex2diag"; import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/mode-text"; +import diag2hex from 'common/helpers/diag2hex'; type Props = { value: string; @@ -27,17 +28,44 @@ function CBOREditor({ isReadOnly = false, onChange = noop }: Props) { - const [prevValue, setPrevValue] = useState(""); + const [shouldRefresh, setShouldRefresh] = useState(true); + const [focusingSide, setFocusingSide] = useState<"bin" | "diag">("bin"); + const [binValue, setBinValue] = useState(""); + const [diagValue, setDiagValue] = useState(""); + + useEffect(() => { + if (shouldRefresh) { + setDiagValue(hex2diag(value)); + setBinValue(value); + setShouldRefresh(false); + } + }, [ value, shouldRefresh ]); function handleBinChange(value: string) { - onChange(value); + setBinValue(value); + + const result = hex2diag(value); + + result.includes("Error:") + ? setDiagValue(hex2diag(value)) + : ( + onChange(value), + setShouldRefresh(true) + ); } function handleDiagChange(value: string) { + setDiagValue(value); - } + const result = diag2hex(value); - console.log(hex2diag("a16474686973a26269736543424f522163796179f5")); + result.includes("Error:") + ? setBinValue(result) + : ( + onChange(result), + setShouldRefresh(true) + ); + } return (
@@ -57,17 +85,19 @@ function CBOREditor({
setFocusingSide("bin")} editorProps={{ $blockScrolling: true }} /> setFocusingSide("diag")} editorProps={{ $blockScrolling: true }} />
diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index 9a6638482df..7a54005d47d 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -51,7 +51,7 @@ function SignTxnPanel({ }: Props) { ( + render={({ field: { value, onChange } }) => ( )} /> From 80e21ecee564dc83b7b92b874587c6047a107d7e Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 16:40:17 +0700 Subject: [PATCH 12/73] feat: response --- utilities/wallet-connector/src/App.tsx | 3 +- .../src/common/helpers/diag2hex.ts | 4 +- .../src/components/CBOREditor.tsx | 12 +++-- .../src/modules/SignTxnPanel.tsx | 48 +++++++++++++++---- .../src/modules/WalletActionsSection.tsx | 12 +++-- 5 files changed, 60 insertions(+), 19 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 413b0ce92a2..bb35c45ab6d 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -92,7 +92,8 @@ function App() { onEnable={enableWallet} /> ) : ( diff --git a/utilities/wallet-connector/src/common/helpers/diag2hex.ts b/utilities/wallet-connector/src/common/helpers/diag2hex.ts index 612e97b09eb..bf72d8ada07 100644 --- a/utilities/wallet-connector/src/common/helpers/diag2hex.ts +++ b/utilities/wallet-connector/src/common/helpers/diag2hex.ts @@ -4,9 +4,7 @@ export default function diag2hex(diagString: string): string { try { const result = fromDiag(diagString); - return Array.from(result, byte => { - return ("0" + byte.toString(16)).slice(-2); - }).join(" "); + return Array.from(result, (byte) => byte.toString(16).padStart(2, "0")).join(" "); } catch (err: unknown) { return String(err); } diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/components/CBOREditor.tsx index 6c6bbd9c525..410bde4c550 100644 --- a/utilities/wallet-connector/src/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/components/CBOREditor.tsx @@ -39,7 +39,7 @@ function CBOREditor({ setBinValue(value); setShouldRefresh(false); } - }, [ value, shouldRefresh ]); + }, [value, shouldRefresh]); function handleBinChange(value: string) { setBinValue(value); @@ -72,8 +72,12 @@ function CBOREditor({

CBOR Editor - | - + {!isReadOnly && ( + <> + | + + + )} |

@@ -87,6 +91,7 @@ function CBOREditor({ setFocusingSide("bin")} @@ -95,6 +100,7 @@ function CBOREditor({ setFocusingSide("diag")} diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index 7a54005d47d..e1438ec6890 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -1,12 +1,15 @@ -import InputIcon from "@mui/icons-material/Input"; +import RefreshIcon from '@mui/icons-material/Refresh'; import Button from "components/Button"; import CBOREditor from "components/CBOREditor"; import CheckBox from "components/CheckBox"; import InputBlock from "components/InputBlock"; import { Controller, useForm } from "react-hook-form"; +import { useMutation } from "react-query"; +import type { ExtractedWalletApi } from 'types/cardano'; type Props = { - + selectedWallets: string[]; + walletApis: Record; } type FormValues = { @@ -14,7 +17,18 @@ type FormValues = { tx: string; } -function SignTxnPanel({ }: Props) { +function SignTxnPanel({ + selectedWallets, + walletApis +}: Props) { + const { isLoading, mutateAsync, data } = useMutation({ + mutationFn: mutateFn + }); + + async function mutateFn() { + + } + const payloadForm = useForm({ defaultValues: { partialSign: false, @@ -57,14 +71,30 @@ function SignTxnPanel({ }: Props) { />
- -
-
-
+
+ + {isLoading && } +
+
+
+
+ {true && ( + <> +
+
+

Response:

+ null} + isReadOnly={true} + /> +
+ + )}
) } diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx index 8d9aa7e61e7..e3729b37ea4 100644 --- a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx @@ -5,6 +5,7 @@ import { twMerge } from "tailwind-merge"; import SignDataPanel from "./SignDataPanel"; import SignTxnPanel from "./SignTxnPanel"; import SubmitTxnPanel from "./SubmitTxnPanel"; +import type { ExtractedWalletApi } from "types/cardano"; const ACTIONS = [ "Sign Transaction", @@ -13,10 +14,14 @@ const ACTIONS = [ ]; type Props = { - + selectedWallets: string[]; + walletApis: Record; } -function WalletActionsSection({ }: Props) { +function WalletActionsSection({ + walletApis, + selectedWallets +}: Props) { return (

Wallet Actions:

@@ -37,7 +42,8 @@ function WalletActionsSection({ }: Props) { From 4c3f313b318b1a9b0dd6a7f22f8f4db962d34e3f Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 18:03:29 +0700 Subject: [PATCH 13/73] feat: submit tx function --- utilities/wallet-connector/src/App.tsx | 1 + .../src/components/CheckBox.tsx | 26 ++++++++---- .../src/components/WalletCard.tsx | 39 ++++++++++++----- .../components/WalletResponseSelection.tsx | 33 +++++++++++++++ .../src/modules/SignTxnPanel.tsx | 42 +++++++++++++++---- 5 files changed, 116 insertions(+), 25 deletions(-) create mode 100644 utilities/wallet-connector/src/components/WalletResponseSelection.tsx diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index bb35c45ab6d..fe0584f705e 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -80,6 +80,7 @@ function App() { isChecked={selectedWallets.includes(walletName)} isEnabled={Boolean(walletApis[walletName])} name={walletName} + isEnabledStatusDisplayed={true} onClick={() => handleWalletCardClick(walletName)} /> ))} diff --git a/utilities/wallet-connector/src/components/CheckBox.tsx b/utilities/wallet-connector/src/components/CheckBox.tsx index d409a3788f9..a1f270acd0a 100644 --- a/utilities/wallet-connector/src/components/CheckBox.tsx +++ b/utilities/wallet-connector/src/components/CheckBox.tsx @@ -1,7 +1,8 @@ -import { noop } from "lodash-es"; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; -import { twMerge } from "tailwind-merge"; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; +import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; +import { noop } from "lodash-es"; type Props = { variant?: "radio" | "checkbox", @@ -10,12 +11,23 @@ type Props = { onChange?: (value: boolean) => void; } -function CheckBox({ variant = "checkbox", value, label, onChange = noop }: Props) { +function CheckBox({ + variant = "checkbox", + value, + label = "", + onChange = noop +}: Props) { return ( ) diff --git a/utilities/wallet-connector/src/components/WalletCard.tsx b/utilities/wallet-connector/src/components/WalletCard.tsx index 7f8a6a099f3..8cf15786fce 100644 --- a/utilities/wallet-connector/src/components/WalletCard.tsx +++ b/utilities/wallet-connector/src/components/WalletCard.tsx @@ -1,25 +1,44 @@ -import { noop } from "lodash-es"; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; +import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; +import { noop } from "lodash-es"; import { twMerge } from "tailwind-merge"; type Props = { isChecked: boolean; isEnabled: boolean; name: string; + isEnabledStatusDisplayed?: boolean; + variant?: "checkbox" | "radio" onClick?: () => void; } -function WalletCard({ isChecked, isEnabled, name, onClick = noop }: Props) { +function WalletCard({ + isChecked, + isEnabled, + name, + variant = "checkbox", + isEnabledStatusDisplayed = false, + onClick = noop +}: Props) { return ( - ) } diff --git a/utilities/wallet-connector/src/components/WalletResponseSelection.tsx b/utilities/wallet-connector/src/components/WalletResponseSelection.tsx new file mode 100644 index 00000000000..ee6ff18f674 --- /dev/null +++ b/utilities/wallet-connector/src/components/WalletResponseSelection.tsx @@ -0,0 +1,33 @@ +import type { ButtonHTMLAttributes, ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; +import WalletCard from "./WalletCard"; +import { noop } from "lodash-es"; + +type Props = { + selectedWallet: string; + wallets: string[], + onSelect: (wallet: string) => void; +}; + +function WalletResponseSelection({ wallets, selectedWallet, onSelect = noop }: Props) { + if (!wallets.length) { + return null; + } + + return ( +
+ {wallets.map((wallet) => ( + onSelect(wallet)} + /> + ))} +
+ ) +} + +export default WalletResponseSelection; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index e1438ec6890..34a099c0daf 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -1,10 +1,14 @@ +import type { SignTx } from '@cardano-sdk/cip30'; import RefreshIcon from '@mui/icons-material/Refresh'; import Button from "components/Button"; import CBOREditor from "components/CBOREditor"; import CheckBox from "components/CheckBox"; import InputBlock from "components/InputBlock"; +import WalletResponseSelection from 'components/WalletResponseSelection'; +import { useState } from 'react'; import { Controller, useForm } from "react-hook-form"; import { useMutation } from "react-query"; +import { toast } from 'react-toastify'; import type { ExtractedWalletApi } from 'types/cardano'; type Props = { @@ -21,14 +25,13 @@ function SignTxnPanel({ selectedWallets, walletApis }: Props) { + const [selectedResponseWallet, setSelectedResponseWallet] = useState(""); + const { isLoading, mutateAsync, data } = useMutation({ + onError: (err) => void toast.error(String(err)), mutationFn: mutateFn }); - async function mutateFn() { - - } - const payloadForm = useForm({ defaultValues: { partialSign: false, @@ -36,8 +39,27 @@ function SignTxnPanel({ } }); - function handleExecute() { + async function mutateFn(args: Parameters): Promise> { + const responses = await Promise.all(selectedWallets.map(async (wallet) => [ + wallet, + await walletApis[wallet]?.signTx(...args) + ])); + + setSelectedResponseWallet(responses[0]?.[0] ?? ""); + + return Object.fromEntries(responses); + } + function handleResponseWalletSelect(wallet: string) { + setSelectedResponseWallet(wallet); + } + + async function handleExecute(formValues: FormValues) { + if (!selectedWallets.length) { + return toast.error("Please select at least one wallet to execute.") + } + + await mutateAsync([formValues.tx, formValues.partialSign]); } return ( @@ -72,7 +94,7 @@ function SignTxnPanel({
- {isLoading && } @@ -86,10 +108,14 @@ function SignTxnPanel({ <>
+

Response:

null} + value={data?.[selectedResponseWallet] ?? ""} isReadOnly={true} />
From c8c2517df37fa558c2f8176dddb55b94c7073e2e Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 18:23:22 +0700 Subject: [PATCH 14/73] feat: clean hex --- utilities/wallet-connector/package-lock.json | 1 - .../wallet-connector/src/common/helpers/cleanHex.ts | 11 +++++++++++ .../wallet-connector/src/common/helpers/hex2bin.ts | 11 +++-------- .../wallet-connector/src/modules/SignTxnPanel.tsx | 3 ++- utilities/wallet-connector/vite.config.ts | 2 +- 5 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 utilities/wallet-connector/src/common/helpers/cleanHex.ts diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index 41415d9b7a4..7ff870b0de6 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -15,7 +15,6 @@ "@mui/material": "^5.15.13", "ace-builds": "^1.32.7", "cborg": "^4.1.1", - "clsx": "^2.1.0", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", "react": "^18.2.0", diff --git a/utilities/wallet-connector/src/common/helpers/cleanHex.ts b/utilities/wallet-connector/src/common/helpers/cleanHex.ts new file mode 100644 index 00000000000..4d345a07ff7 --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/cleanHex.ts @@ -0,0 +1,11 @@ +export default function cleanHex(hexString: string): string { + // Remove spaces and convert to uppercase + const cleanedHexString = hexString.replace(/\s/gm, '').toUpperCase(); + + // Check if the cleaned string is a valid hex string + if (!/^[0-9a-fA-F]*$/.test(cleanedHexString)) { + throw new Error('Invalid hex string'); + } + + return cleanedHexString; +} \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/helpers/hex2bin.ts b/utilities/wallet-connector/src/common/helpers/hex2bin.ts index 9054eaf5060..bd6031be194 100644 --- a/utilities/wallet-connector/src/common/helpers/hex2bin.ts +++ b/utilities/wallet-connector/src/common/helpers/hex2bin.ts @@ -1,13 +1,8 @@ -export default function hex2bin(hexString: string): Uint8Array { - // Remove spaces and convert to uppercase - const cleanedHexString = hexString.replace(/\s/gm, '').toUpperCase(); +import cleanHex from "./cleanHex"; - // Check if the cleaned string is a valid hex string - if (!/^[0-9a-fA-F]*$/.test(cleanedHexString)) { - throw new Error('Invalid hex string'); - } +export default function hex2bin(hexString: string): Uint8Array { + const cleanedHexString = cleanHex(hexString); - // Convert the hex string to a Uint8Array const uint8Array = Array.from(cleanedHexString.match(/.{1,2}/g) || []).map((byte) => parseInt(byte, 16) ); diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index 34a099c0daf..16402eda77f 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -1,5 +1,6 @@ import type { SignTx } from '@cardano-sdk/cip30'; import RefreshIcon from '@mui/icons-material/Refresh'; +import cleanHex from 'common/helpers/cleanHex'; import Button from "components/Button"; import CBOREditor from "components/CBOREditor"; import CheckBox from "components/CheckBox"; @@ -59,7 +60,7 @@ function SignTxnPanel({ return toast.error("Please select at least one wallet to execute.") } - await mutateAsync([formValues.tx, formValues.partialSign]); + await mutateAsync([cleanHex(formValues.tx), formValues.partialSign]); } return ( diff --git a/utilities/wallet-connector/vite.config.ts b/utilities/wallet-connector/vite.config.ts index 83749143b66..ef13f05520d 100644 --- a/utilities/wallet-connector/vite.config.ts +++ b/utilities/wallet-connector/vite.config.ts @@ -7,7 +7,7 @@ export default defineConfig(({ mode }) => { return { resolve: { alias: { - "cborg/lib/diagnostic": "../../node_modules/cborg/lib/diagnostic" + "cborg/lib/diagnostic": "../../../node_modules/cborg/lib/diagnostic" } }, server: { From 3f8ac979a366d5d8ac2bd6fc5122877faaed2b99 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 18:39:47 +0700 Subject: [PATCH 15/73] feat: to be implemented --- utilities/wallet-connector/package-lock.json | 6 ++++++ utilities/wallet-connector/package.json | 1 + utilities/wallet-connector/src/App.tsx | 13 +++++++++---- .../wallet-connector/src/modules/SignDataPanel.tsx | 6 ++++-- .../wallet-connector/src/modules/SignTxnPanel.tsx | 2 +- .../wallet-connector/src/modules/SubmitTxnPanel.tsx | 6 ++++-- 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index 7ff870b0de6..c3edc889f95 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", + "@emurgo/cardano-serialization-lib-asmjs": "^11.5.0", "@headlessui/react": "^1.7.18", "@mui/icons-material": "^5.15.13", "@mui/material": "^5.15.13", @@ -516,6 +517,11 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, + "node_modules/@emurgo/cardano-serialization-lib-asmjs": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-asmjs/-/cardano-serialization-lib-asmjs-11.5.0.tgz", + "integrity": "sha512-QQkavjEug/EmBFg02bmSg0eLYiOaRa1lmRG8q6fGRkx3O9BX1iZQDZJmirPDBTkTO3CpNB0q9se8DQFFcjREIw==" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.19.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index 6fd9fa93330..2229f75f305 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -16,6 +16,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", + "@emurgo/cardano-serialization-lib-asmjs": "^11.5.0", "@headlessui/react": "^1.7.18", "@mui/icons-material": "^5.15.13", "@mui/material": "^5.15.13", diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index fe0584f705e..2a0a951a16f 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -53,20 +53,22 @@ function App() { } async function enableAllWallets(walletNames: string[]) { - /* const walletApis = await Promise.all(Object.entries(getCardano()).map(async ([walletName, walletProps]: any) => { + // const toBeEnabledWallets = walletNames.filter((wallet) => ) + + const walletApis = await Promise.all(Object.entries(getCardano()).map(async ([walletName, walletProps]: any) => { const api = await walletProps.enable({ cip: 30 }) return [walletName, api] - })); */ + })); - // setWalletApis(Object.fromEntries(walletApis)); + setWalletApis(Object.fromEntries(walletApis)); } return (
-
+
{isCardanoActivated ? ( @@ -104,6 +106,9 @@ function App() { )}
+
+
© 2024 Input Output Global · All Rights Reserved
+
diff --git a/utilities/wallet-connector/src/modules/SignDataPanel.tsx b/utilities/wallet-connector/src/modules/SignDataPanel.tsx index f7410e4b90f..24373ccb786 100644 --- a/utilities/wallet-connector/src/modules/SignDataPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignDataPanel.tsx @@ -4,8 +4,10 @@ type Props = { function SignDataPanel({ }: Props) { return ( -
- +
+
+

Not Implemented.

+
) } diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index 16402eda77f..8353db8c8b0 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -105,7 +105,7 @@ function SignTxnPanel({
- {true && ( + {data && ( <>
diff --git a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx index c1dd3eaa2ae..cf3055efa54 100644 --- a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx @@ -4,8 +4,10 @@ type Props = { function SubmitTxnPanel({ }: Props) { return ( -
- +
+
+

Not Implemented.

+
) } From 2e7bed0a377b659a081ddbdb97e0c30a45fa1bd2 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 18:58:55 +0700 Subject: [PATCH 16/73] feat: enable all wallets --- utilities/wallet-connector/src/App.tsx | 48 ++++++++++--------- .../src/modules/SignTxnPanel.tsx | 6 +-- .../src/modules/WalletActionsSection.tsx | 6 +-- .../src/modules/WalletInfoSection.tsx | 26 +++++----- 4 files changed, 46 insertions(+), 40 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 2a0a951a16f..a39aff22c8c 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -4,7 +4,7 @@ import "./styles/global.css"; import getCardano from "common/helpers/getCardano"; import WalletCard from "components/WalletCard"; -import { xor } from "lodash-es"; +import { pickBy, xor } from "lodash-es"; import { useState } from "react"; import { QueryClient, QueryClientProvider } from "react-query"; import { ToastContainer } from "react-toastify"; @@ -13,6 +13,7 @@ import extractApiData from "common/helpers/extractApiData"; import WalletActionsSection from "modules/WalletActionsSection"; import WalletInfoSection from "modules/WalletInfoSection"; import type { ExtractedWalletApi } from "types/cardano"; +import type { Cip30Wallet } from "@cardano-sdk/cip30"; const queryClient = new QueryClient({ defaultOptions: { @@ -27,8 +28,11 @@ const queryClient = new QueryClient({ }); function App() { - const [walletApis, setWalletApis] = useState>({}); + // enabled wallets with the API object + const [walletApi, setWalletApi] = useState>({}); + // list of wallet names that is being enabled const [enablingWallets, setEnablingWallets] = useState([]); + // wallet name selections const [selectedWallets, setSelectedWallets] = useState([]); console.log(getCardano()); @@ -39,29 +43,28 @@ function App() { setSelectedWallets((prev) => xor(prev, [walletName])) } - async function enableWallet(walletName: string) { - setEnablingWallets((prev) => [...prev, walletName]); - - const api = await getCardano(walletName).enable(); + async function handleEnableWallet(walletName: string) { + await handleEnableAllWallets([ walletName ]); + } - const extractedApi = await extractApiData(api); + async function handleEnableAllWallets(wallets?: string[]) { + const toBeEnabledWallets = (wallets ?? selectedWallets).filter((wallet) => !walletApi[wallet]); + const mappedWalletProp = pickBy(getCardano(), (v, k) => toBeEnabledWallets.includes(k)) as Record; - console.log("api", extractedApi); + setEnablingWallets((prev) => [...prev, ...toBeEnabledWallets]); - setWalletApis((prev) => ({ ...prev, [walletName]: extractedApi })); - setEnablingWallets((prev) => prev.filter((w) => w !== walletName)); - } + const walletApis = await Promise.all(Object.entries(mappedWalletProp).map(async ([walletName, walletProps]) => { + const api = await walletProps.enable(/* { cip: 30 } */); - async function enableAllWallets(walletNames: string[]) { - // const toBeEnabledWallets = walletNames.filter((wallet) => ) + const extractedApi = await extractApiData(api); - const walletApis = await Promise.all(Object.entries(getCardano()).map(async ([walletName, walletProps]: any) => { - const api = await walletProps.enable({ cip: 30 }) - - return [walletName, api] + return [walletName, extractedApi] })); - setWalletApis(Object.fromEntries(walletApis)); + console.log("api", walletApis); + + setWalletApi((prev) => ({ ...prev, ...Object.fromEntries(walletApis) })); + setEnablingWallets((prev) => prev.filter((wallet) => !toBeEnabledWallets.includes(wallet))); } return ( @@ -80,7 +83,7 @@ function App() { handleWalletCardClick(walletName)} @@ -91,12 +94,13 @@ function App() { ) : ( diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index 8353db8c8b0..4ba7d8491fb 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -14,7 +14,7 @@ import type { ExtractedWalletApi } from 'types/cardano'; type Props = { selectedWallets: string[]; - walletApis: Record; + walletApi: Record; } type FormValues = { @@ -24,7 +24,7 @@ type FormValues = { function SignTxnPanel({ selectedWallets, - walletApis + walletApi }: Props) { const [selectedResponseWallet, setSelectedResponseWallet] = useState(""); @@ -43,7 +43,7 @@ function SignTxnPanel({ async function mutateFn(args: Parameters): Promise> { const responses = await Promise.all(selectedWallets.map(async (wallet) => [ wallet, - await walletApis[wallet]?.signTx(...args) + await walletApi[wallet]?.signTx(...args) ])); setSelectedResponseWallet(responses[0]?.[0] ?? ""); diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx index e3729b37ea4..ec09b28932d 100644 --- a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx @@ -15,11 +15,11 @@ const ACTIONS = [ type Props = { selectedWallets: string[]; - walletApis: Record; + walletApi: Record; } function WalletActionsSection({ - walletApis, + walletApi, selectedWallets }: Props) { return ( @@ -43,7 +43,7 @@ function WalletActionsSection({ diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index f44e4a250ed..f612866dae0 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -11,7 +11,7 @@ import Button from "components/Button"; type Props = { selectedWallets: string[]; enablingWallets: string[]; - walletApis: Record; + walletApi: Record; onEnable?: (walletName: string) => void; onEnableAll?: () => void; } @@ -19,10 +19,12 @@ type Props = { function WalletInfoSection({ selectedWallets, enablingWallets, - walletApis, + walletApi, onEnable = noop, onEnableAll = noop, }: Props) { + const allEnabled = selectedWallets.every((wallet) => walletApi[wallet]); + return (

Wallet Information:

@@ -34,7 +36,7 @@ function WalletInfoSection({

Selected wallets: {selectedWallets.length}

-
@@ -57,39 +59,39 @@ function WalletInfoSection({ {selectedWallets.map((wallet) => ( - {walletApis[wallet] ? ( + {walletApi[wallet] ? (
) : ( From 1aef0c545ff8bd41455f8fac8e7705628b332fbd Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 15 Mar 2024 23:12:38 +0700 Subject: [PATCH 17/73] feat: json mode --- utilities/wallet-connector/Earthfile | 20 +++++ utilities/wallet-connector/package-lock.json | 26 ++++-- utilities/wallet-connector/package.json | 1 + utilities/wallet-connector/src/App.tsx | 2 +- .../src/common/helpers/bin2hex.ts | 3 + .../src/common/helpers/diag2hex.ts | 5 +- .../src/components/CBOREditor.tsx | 81 +++++++++++++------ 7 files changed, 102 insertions(+), 36 deletions(-) create mode 100644 utilities/wallet-connector/src/common/helpers/bin2hex.ts diff --git a/utilities/wallet-connector/Earthfile b/utilities/wallet-connector/Earthfile index e69de29bb2d..7ed33f26e62 100644 --- a/utilities/wallet-connector/Earthfile +++ b/utilities/wallet-connector/Earthfile @@ -0,0 +1,20 @@ +VERSION --try --global-cache 0.7 + +builder: + FROM node:20-alpine + WORKDIR /app + COPY package.json package-lock.json . + COPY index.html postcss.config.js tailwind.config.js tsconfig* vite.config.ts . + COPY src ./src + + RUN npm i + +check: + FROM +builder + + RUN npx tsc --noEmit + +build: + FROM +builder + + RUN npm run build \ No newline at end of file diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index c3edc889f95..5c6919e28dc 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -17,6 +17,7 @@ "ace-builds": "^1.32.7", "cborg": "^4.1.1", "dayjs": "^1.11.10", + "json5": "^2.2.3", "lodash-es": "^4.17.21", "react": "^18.2.0", "react-ace": "^10.1.0", @@ -5068,15 +5069,14 @@ "optional": true }, "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "optional": true, - "dependencies": { - "minimist": "^1.2.0" - }, + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/jsx-ast-utils": { @@ -6863,6 +6863,18 @@ "strip-bom": "^3.0.0" } }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "optional": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index 2229f75f305..f7a08e2676b 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -23,6 +23,7 @@ "ace-builds": "^1.32.7", "cborg": "^4.1.1", "dayjs": "^1.11.10", + "json5": "^2.2.3", "lodash-es": "^4.17.21", "react": "^18.2.0", "react-ace": "^10.1.0", diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index a39aff22c8c..60b51fb988d 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -111,7 +111,7 @@ function App() {
-
© 2024 Input Output Global · All Rights Reserved
+
Created by Catalyst Team
diff --git a/utilities/wallet-connector/src/common/helpers/bin2hex.ts b/utilities/wallet-connector/src/common/helpers/bin2hex.ts new file mode 100644 index 00000000000..b5e5eca1d1f --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/bin2hex.ts @@ -0,0 +1,3 @@ +export default function bin2hex(bin: Uint8Array, sep = " "): string { + return Array.from(bin, (byte) => byte.toString(16).padStart(2, "0")).join(sep); +} diff --git a/utilities/wallet-connector/src/common/helpers/diag2hex.ts b/utilities/wallet-connector/src/common/helpers/diag2hex.ts index bf72d8ada07..29c690d9bc4 100644 --- a/utilities/wallet-connector/src/common/helpers/diag2hex.ts +++ b/utilities/wallet-connector/src/common/helpers/diag2hex.ts @@ -1,10 +1,9 @@ import { fromDiag } from "cborg/lib/diagnostic"; +import bin2hex from "./bin2hex"; export default function diag2hex(diagString: string): string { try { - const result = fromDiag(diagString); - - return Array.from(result, (byte) => byte.toString(16).padStart(2, "0")).join(" "); + return bin2hex(fromDiag(diagString)); } catch (err: unknown) { return String(err); } diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/components/CBOREditor.tsx index 410bde4c550..b1a06003833 100644 --- a/utilities/wallet-connector/src/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/components/CBOREditor.tsx @@ -2,11 +2,18 @@ import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; import { noop } from "lodash-es"; import { useState, type CSSProperties, useEffect } from "react"; import AceEditor from "react-ace"; +import JSON5 from "json5"; import hex2diag from "common/helpers/hex2diag"; import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/mode-text"; import diag2hex from 'common/helpers/diag2hex'; +import { decode, encode } from 'cborg'; +import hex2bin from 'common/helpers/hex2bin'; +import bin2hex from 'common/helpers/bin2hex'; + +type Side = "lhs" | "rhs"; +type Mode = "bin2diag" | "bin2json"; type Props = { value: string; @@ -29,42 +36,64 @@ function CBOREditor({ onChange = noop }: Props) { const [shouldRefresh, setShouldRefresh] = useState(true); - const [focusingSide, setFocusingSide] = useState<"bin" | "diag">("bin"); - const [binValue, setBinValue] = useState(""); - const [diagValue, setDiagValue] = useState(""); + const [mode, setMode] = useState("bin2diag"); + const [focusingSide, setFocusingSide] = useState("lhs"); + const [lhsValue, setLhsValue] = useState(""); + const [rhsValue, setRhsValue] = useState(""); useEffect(() => { if (shouldRefresh) { - setDiagValue(hex2diag(value)); - setBinValue(value); + try { + const rhsValue = mode === "bin2diag" + ? hex2diag(value) + : JSON5.stringify(decode(hex2bin(value)), null, 2); + + setRhsValue(rhsValue); + } catch (e) { + setRhsValue(String(e)); + } + + setLhsValue(value); setShouldRefresh(false); } }, [value, shouldRefresh]); - function handleBinChange(value: string) { - setBinValue(value); + function handleLhsChange(value: string) { + setLhsValue(value); const result = hex2diag(value); result.includes("Error:") - ? setDiagValue(hex2diag(value)) + ? setRhsValue(hex2diag(value)) : ( onChange(value), setShouldRefresh(true) ); } - function handleDiagChange(value: string) { - setDiagValue(value); + function handleRhsChange(value: string) { + setRhsValue(value); - const result = diag2hex(value); + try { + const result = mode === "bin2diag" + ? diag2hex(value) + : bin2hex(encode(JSON5.parse(value))); - result.includes("Error:") - ? setBinValue(result) - : ( - onChange(result), - setShouldRefresh(true) - ); + result.includes("Error:") + ? setLhsValue(result) + : ( + onChange(result), + setShouldRefresh(true) + ); + } catch (e) { + setLhsValue(String(e)); + } + } + + function switchMode() { + setFocusingSide("lhs"); + setMode((prev) => prev === "bin2diag" ? "bin2json" : "bin2diag"); + setShouldRefresh(true); } return ( @@ -83,27 +112,29 @@ function CBOREditor({

bin - - diag + + {mode === "bin2diag" ? "diag" : "json5"}

setFocusingSide("bin")} + onChange={handleLhsChange} + onFocus={() => setFocusingSide("lhs")} editorProps={{ $blockScrolling: true }} /> setFocusingSide("diag")} + onChange={handleRhsChange} + onFocus={() => setFocusingSide("rhs")} editorProps={{ $blockScrolling: true }} />
From a1e61baffdccff00bc1e486b6c829ae6f109a33d Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Sat, 16 Mar 2024 00:51:12 +0700 Subject: [PATCH 18/73] feat: json editor --- utilities/wallet-connector/package-lock.json | 12 ---------- utilities/wallet-connector/package.json | 1 - .../src/components/CBOREditor.tsx | 22 +++++++++---------- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index 5c6919e28dc..f730cb3f064 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -17,7 +17,6 @@ "ace-builds": "^1.32.7", "cborg": "^4.1.1", "dayjs": "^1.11.10", - "json5": "^2.2.3", "lodash-es": "^4.17.21", "react": "^18.2.0", "react-ace": "^10.1.0", @@ -5068,17 +5067,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "optional": true }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index f7a08e2676b..2229f75f305 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -23,7 +23,6 @@ "ace-builds": "^1.32.7", "cborg": "^4.1.1", "dayjs": "^1.11.10", - "json5": "^2.2.3", "lodash-es": "^4.17.21", "react": "^18.2.0", "react-ace": "^10.1.0", diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/components/CBOREditor.tsx index b1a06003833..44b5c18158a 100644 --- a/utilities/wallet-connector/src/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/components/CBOREditor.tsx @@ -1,16 +1,16 @@ import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; +import { decode, encode } from 'cborg'; +import bin2hex from 'common/helpers/bin2hex'; +import diag2hex from 'common/helpers/diag2hex'; +import hex2bin from 'common/helpers/hex2bin'; +import hex2diag from "common/helpers/hex2diag"; import { noop } from "lodash-es"; -import { useState, type CSSProperties, useEffect } from "react"; +import { useEffect, useState, type CSSProperties } from "react"; import AceEditor from "react-ace"; -import JSON5 from "json5"; -import hex2diag from "common/helpers/hex2diag"; import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/mode-text"; -import diag2hex from 'common/helpers/diag2hex'; -import { decode, encode } from 'cborg'; -import hex2bin from 'common/helpers/hex2bin'; -import bin2hex from 'common/helpers/bin2hex'; +import "ace-builds/src-noconflict/mode-json"; type Side = "lhs" | "rhs"; type Mode = "bin2diag" | "bin2json"; @@ -46,7 +46,7 @@ function CBOREditor({ try { const rhsValue = mode === "bin2diag" ? hex2diag(value) - : JSON5.stringify(decode(hex2bin(value)), null, 2); + : JSON.stringify(decode(hex2bin(value)), null, 2); setRhsValue(rhsValue); } catch (e) { @@ -77,7 +77,7 @@ function CBOREditor({ try { const result = mode === "bin2diag" ? diag2hex(value) - : bin2hex(encode(JSON5.parse(value))); + : bin2hex(encode(JSON.parse(value))); result.includes("Error:") ? setLhsValue(result) @@ -115,7 +115,7 @@ function CBOREditor({ - {mode === "bin2diag" ? "diag" : "json5"} + {mode === "bin2diag" ? "diag" : "json"}

@@ -132,7 +132,7 @@ function CBOREditor({ value={focusingSide === "rhs" ? undefined : rhsValue} style={EDITOR_STYLE} readOnly={isReadOnly} - mode="text" + mode={mode === "bin2diag" ? "text" : "json"} onChange={handleRhsChange} onFocus={() => setFocusingSide("rhs")} editorProps={{ $blockScrolling: true }} From 7ccb117ff7f0aba25fc7ec3d73e286ab82234a7d Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Sat, 16 Mar 2024 01:57:13 +0700 Subject: [PATCH 19/73] fix: extract api data handling --- .../src/common/helpers/extractApiData.ts | 24 ++++++++++++------- .../src/components/CBOREditor.tsx | 4 +--- .../src/modules/WalletInfoSection.tsx | 2 +- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index c32194d6bd9..58c019452e8 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -2,15 +2,23 @@ import type { WalletApi } from "@cardano-sdk/cip30"; import type { ExtractedWalletApi } from "types/cardano"; export default async function extractApiData(api: WalletApi): Promise { + const safeTry = async (fn: () => Promise): Promise => { + try { + return await fn(); + } catch (err) { + return `Failed: ${String(err)}` as T; + } + } + return { - networkId: await api.getNetworkId(), - utxos: await api.getUtxos(), - balance: await api.getBalance(), - collateral: await api.getCollateral(), - usedAddresses: await api.getUsedAddresses(), - unusedAddresses: await api.getUnusedAddresses(), - changeAddress: await api.getChangeAddress(), - rewardAddresses: await api.getRewardAddresses(), + networkId: await safeTry(api.getNetworkId), + utxos: await safeTry(api.getUtxos), + balance: await safeTry(api.getBalance), + collateral: await safeTry(api.getCollateral), + usedAddresses: await safeTry(api.getUsedAddresses), + unusedAddresses: await safeTry(api.getUnusedAddresses), + changeAddress: await safeTry(api.getChangeAddress), + rewardAddresses: await safeTry(api.getRewardAddresses), signTx: api.signTx, signData: api.signData, submitTx: api.submitTx, diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/components/CBOREditor.tsx index 44b5c18158a..94f35218eb1 100644 --- a/utilities/wallet-connector/src/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/components/CBOREditor.tsx @@ -46,7 +46,7 @@ function CBOREditor({ try { const rhsValue = mode === "bin2diag" ? hex2diag(value) - : JSON.stringify(decode(hex2bin(value)), null, 2); + : JSON.stringify(value ? decode(hex2bin(value)) : undefined, null, 2); setRhsValue(rhsValue); } catch (e) { @@ -107,8 +107,6 @@ function CBOREditor({ )} - | -

bin diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index f612866dae0..6911ffc63b7 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -90,7 +90,7 @@ function WalletInfoSection({ value={walletApi[wallet]?.changeAddress ?? null} />

From e818cc507d848a320431fa061652ca1ada00b924 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Sat, 16 Mar 2024 01:57:56 +0700 Subject: [PATCH 20/73] refactor: move components to common --- utilities/wallet-connector/src/App.tsx | 2 +- .../src/{ => common}/components/Button.tsx | 0 .../src/{ => common}/components/CBOREditor.tsx | 0 .../src/{ => common}/components/CheckBox.tsx | 0 .../src/{ => common}/components/InfoItem.tsx | 0 .../src/{ => common}/components/InputBlock.tsx | 0 .../src/{ => common}/components/WalletCard.tsx | 0 .../components/WalletResponseSelection.tsx | 0 .../wallet-connector/src/modules/SignTxnPanel.tsx | 10 +++++----- .../wallet-connector/src/modules/WalletInfoSection.tsx | 4 ++-- 10 files changed, 8 insertions(+), 8 deletions(-) rename utilities/wallet-connector/src/{ => common}/components/Button.tsx (100%) rename utilities/wallet-connector/src/{ => common}/components/CBOREditor.tsx (100%) rename utilities/wallet-connector/src/{ => common}/components/CheckBox.tsx (100%) rename utilities/wallet-connector/src/{ => common}/components/InfoItem.tsx (100%) rename utilities/wallet-connector/src/{ => common}/components/InputBlock.tsx (100%) rename utilities/wallet-connector/src/{ => common}/components/WalletCard.tsx (100%) rename utilities/wallet-connector/src/{ => common}/components/WalletResponseSelection.tsx (100%) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 60b51fb988d..f5a9c6be2d9 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -3,7 +3,7 @@ import "react-toastify/dist/ReactToastify.css"; import "./styles/global.css"; import getCardano from "common/helpers/getCardano"; -import WalletCard from "components/WalletCard"; +import WalletCard from "common/components/WalletCard"; import { pickBy, xor } from "lodash-es"; import { useState } from "react"; import { QueryClient, QueryClientProvider } from "react-query"; diff --git a/utilities/wallet-connector/src/components/Button.tsx b/utilities/wallet-connector/src/common/components/Button.tsx similarity index 100% rename from utilities/wallet-connector/src/components/Button.tsx rename to utilities/wallet-connector/src/common/components/Button.tsx diff --git a/utilities/wallet-connector/src/components/CBOREditor.tsx b/utilities/wallet-connector/src/common/components/CBOREditor.tsx similarity index 100% rename from utilities/wallet-connector/src/components/CBOREditor.tsx rename to utilities/wallet-connector/src/common/components/CBOREditor.tsx diff --git a/utilities/wallet-connector/src/components/CheckBox.tsx b/utilities/wallet-connector/src/common/components/CheckBox.tsx similarity index 100% rename from utilities/wallet-connector/src/components/CheckBox.tsx rename to utilities/wallet-connector/src/common/components/CheckBox.tsx diff --git a/utilities/wallet-connector/src/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx similarity index 100% rename from utilities/wallet-connector/src/components/InfoItem.tsx rename to utilities/wallet-connector/src/common/components/InfoItem.tsx diff --git a/utilities/wallet-connector/src/components/InputBlock.tsx b/utilities/wallet-connector/src/common/components/InputBlock.tsx similarity index 100% rename from utilities/wallet-connector/src/components/InputBlock.tsx rename to utilities/wallet-connector/src/common/components/InputBlock.tsx diff --git a/utilities/wallet-connector/src/components/WalletCard.tsx b/utilities/wallet-connector/src/common/components/WalletCard.tsx similarity index 100% rename from utilities/wallet-connector/src/components/WalletCard.tsx rename to utilities/wallet-connector/src/common/components/WalletCard.tsx diff --git a/utilities/wallet-connector/src/components/WalletResponseSelection.tsx b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx similarity index 100% rename from utilities/wallet-connector/src/components/WalletResponseSelection.tsx rename to utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index 4ba7d8491fb..5c65e632561 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -1,11 +1,11 @@ import type { SignTx } from '@cardano-sdk/cip30'; import RefreshIcon from '@mui/icons-material/Refresh'; import cleanHex from 'common/helpers/cleanHex'; -import Button from "components/Button"; -import CBOREditor from "components/CBOREditor"; -import CheckBox from "components/CheckBox"; -import InputBlock from "components/InputBlock"; -import WalletResponseSelection from 'components/WalletResponseSelection'; +import Button from "common/components/Button"; +import CBOREditor from "common/components/CBOREditor"; +import CheckBox from "common/components/CheckBox"; +import InputBlock from "common/components/InputBlock"; +import WalletResponseSelection from 'common/components/WalletResponseSelection'; import { useState } from 'react'; import { Controller, useForm } from "react-hook-form"; import { useMutation } from "react-query"; diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index 6911ffc63b7..f04ddc7b717 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -4,9 +4,9 @@ import { noop } from "lodash-es"; import { Fragment } from "react/jsx-runtime"; import { twMerge } from "tailwind-merge"; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; -import InfoItem from "components/InfoItem"; +import InfoItem from "common/components/InfoItem"; import type { ExtractedWalletApi } from "types/cardano"; -import Button from "components/Button"; +import Button from "common/components/Button"; type Props = { selectedWallets: string[]; From 6ee8c1ef2b54ffd61f27ff1c294fef8998804e30 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Sat, 16 Mar 2024 03:05:04 +0700 Subject: [PATCH 21/73] feat: file upload --- .../src/common/components/CBOREditor.tsx | 55 +++++++++++++++++-- .../src/common/helpers/readFile.ts | 21 +++++++ 2 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 utilities/wallet-connector/src/common/helpers/readFile.ts diff --git a/utilities/wallet-connector/src/common/components/CBOREditor.tsx b/utilities/wallet-connector/src/common/components/CBOREditor.tsx index 94f35218eb1..118535941eb 100644 --- a/utilities/wallet-connector/src/common/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/common/components/CBOREditor.tsx @@ -1,16 +1,21 @@ import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; import { decode, encode } from 'cborg'; import bin2hex from 'common/helpers/bin2hex'; +import cleanHex from "common/helpers/cleanHex"; import diag2hex from 'common/helpers/diag2hex'; import hex2bin from 'common/helpers/hex2bin'; import hex2diag from "common/helpers/hex2diag"; +import readFile from "common/helpers/readFile"; import { noop } from "lodash-es"; import { useEffect, useState, type CSSProperties } from "react"; import AceEditor from "react-ace"; +import { useDropzone } from "react-dropzone"; +import { toast } from "react-toastify"; +import { twMerge } from "tailwind-merge"; import "ace-builds/src-noconflict/ext-language_tools"; -import "ace-builds/src-noconflict/mode-text"; import "ace-builds/src-noconflict/mode-json"; +import "ace-builds/src-noconflict/mode-text"; type Side = "lhs" | "rhs"; type Mode = "bin2diag" | "bin2json"; @@ -37,10 +42,47 @@ function CBOREditor({ }: Props) { const [shouldRefresh, setShouldRefresh] = useState(true); const [mode, setMode] = useState("bin2diag"); - const [focusingSide, setFocusingSide] = useState("lhs"); + const [focusingSide, setFocusingSide] = useState(null); const [lhsValue, setLhsValue] = useState(""); const [rhsValue, setRhsValue] = useState(""); + const {getRootProps, getInputProps, isDragActive, open} = useDropzone({ + accept: { + "text/plain": [".txt"], + "application/json": [".json"], + "application/octet-stream": [".bin"], + }, + multiple: false, + disabled: isReadOnly, + noClick: true, + onDrop: async ([ acceptedFile ]: File[]) => { + if (!acceptedFile) { + return void toast.error("Invalid file."); + } + + if (acceptedFile.type === "application/octet-stream") { + const result = await readFile(acceptedFile, "buffer") as ArrayBuffer; + onChange(bin2hex(new Uint8Array(result))) + } else if (acceptedFile.type === "application/json") { + const result = await readFile(acceptedFile, "text") as string; + try { + const finalResult = bin2hex(encode(JSON.parse(result))) + onChange(finalResult); + } catch (err) { + toast.error("Failed to read a JSON file.") + } + } else if (acceptedFile.type === "text/plain") { + const result = await readFile(acceptedFile, "text") as string; + onChange(bin2hex(hex2bin(result))) + } else { + toast.error(`The uploaded file type is unacceptable (${acceptedFile.type}).`); + } + + setShouldRefresh(true) + setFocusingSide(null) + } + }) + useEffect(() => { if (shouldRefresh) { try { @@ -97,14 +139,19 @@ function CBOREditor({ } return ( -
+
+ +

CBOR Editor {!isReadOnly && ( <> | - + )}

diff --git a/utilities/wallet-connector/src/common/helpers/readFile.ts b/utilities/wallet-connector/src/common/helpers/readFile.ts new file mode 100644 index 00000000000..2c6106cae1f --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/readFile.ts @@ -0,0 +1,21 @@ +type ReadAs = "buffer" | "data-url" | "text"; + +export default function readFile(blob: Blob, readAs: ReadAs): Promise { + return new Promise((resolve, reject) => { + const reader = new FileReader() + + reader.onabort = () => reject(Error("file reading was aborted")) + reader.onerror = () => reject(Error("file reading has failed")) + reader.onload = () => resolve(reader.result) + + if (readAs === "buffer") { + reader.readAsArrayBuffer(blob) + } else if (readAs === "data-url") { + reader.readAsDataURL(blob) + } else if (readAs === "text") { + reader.readAsText(blob) + } else { + reject(Error("invalid reading scheme")) + } + }) +} From bb63a66b4a8d72958152f921900ec674cb303c62 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 15:55:32 +0700 Subject: [PATCH 22/73] feat: extension field --- utilities/wallet-connector/src/App.tsx | 12 +++++---- .../src/common/components/CBOREditor.tsx | 3 --- .../src/common/components/InfoItem.tsx | 8 ++++-- .../src/modules/WalletInfoSection.tsx | 27 ++++++++++++++++--- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index f5a9c6be2d9..0946afde20c 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -71,7 +71,7 @@ function App() {
-
+
{isCardanoActivated ? ( @@ -98,10 +98,12 @@ function App() { onEnable={handleEnableWallet} onEnableAll={handleEnableAllWallets} /> - + {Boolean(selectedWallets.length) && ( + + )} ) : (
diff --git a/utilities/wallet-connector/src/common/components/CBOREditor.tsx b/utilities/wallet-connector/src/common/components/CBOREditor.tsx index 118535941eb..b5f65e90b22 100644 --- a/utilities/wallet-connector/src/common/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/common/components/CBOREditor.tsx @@ -1,7 +1,6 @@ import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; import { decode, encode } from 'cborg'; import bin2hex from 'common/helpers/bin2hex'; -import cleanHex from "common/helpers/cleanHex"; import diag2hex from 'common/helpers/diag2hex'; import hex2bin from 'common/helpers/hex2bin'; import hex2diag from "common/helpers/hex2diag"; @@ -33,8 +32,6 @@ const EDITOR_STYLE: CSSProperties = { height: "240px" } as const; -// bg-gray-100 font-mono text-xs h-[240px] overflow-y-auto - function CBOREditor({ value, isReadOnly = false, diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index 0e8681de01e..42d74b6a026 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -16,11 +16,15 @@ function InfoItem({ heading, value }: Props) {

{heading}:

{typeof value === "string" ? ( -

handleCopy(value)}>{value || "-"}

+

handleCopy(value)}> + {value || "-"} +

) : Array.isArray(value) && value.length ? (
    {value.map((v) => ( -
  1. handleCopy(v)}>{v || "-"}
  2. +
  3. handleCopy(v)}> + {(typeof v === "object" ? JSON.stringify(v) : v) || "-"} +
  4. ))}
) : ( diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index f04ddc7b717..932ccbc75a3 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -7,6 +7,7 @@ import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import InfoItem from "common/components/InfoItem"; import type { ExtractedWalletApi } from "types/cardano"; import Button from "common/components/Button"; +import WarningIcon from '@mui/icons-material/Warning'; type Props = { selectedWallets: string[]; @@ -59,6 +60,16 @@ function WalletInfoSection({ {selectedWallets.map((wallet) => ( +
+ + +
{walletApi[wallet] ? (
) : ( -
+
+

Extension (optional)

+
)} @@ -107,8 +125,11 @@ function WalletInfoSection({
) : ( -
-

Please select at least one wallet to view the information.

+
+
+ +

Please select at least one wallet to view the information.

+
)}
From 67c77e76eab6bf37c066e7d9bcde6a969374381a Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 17:05:41 +0700 Subject: [PATCH 23/73] fix: types --- utilities/wallet-connector/src/App.tsx | 45 +++++++++++-------- .../src/common/components/InfoItem.tsx | 13 +++--- .../src/common/helpers/getCardano.ts | 8 +--- utilities/wallet-connector/src/main.tsx | 2 +- .../src/modules/SignTxnPanel.tsx | 2 +- .../src/modules/WalletInfoSection.tsx | 36 ++++++++++----- .../wallet-connector/src/types/cardano.ts | 11 +++++ .../wallet-connector/src/types/global.d.ts | 6 +++ 8 files changed, 80 insertions(+), 43 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 0946afde20c..f9985cbd6ae 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -4,15 +4,15 @@ import "./styles/global.css"; import getCardano from "common/helpers/getCardano"; import WalletCard from "common/components/WalletCard"; -import { pickBy, xor } from "lodash-es"; +import { isEmpty, pickBy, xor } from "lodash-es"; import { useState } from "react"; import { QueryClient, QueryClientProvider } from "react-query"; -import { ToastContainer } from "react-toastify"; +import { ToastContainer, toast } from "react-toastify"; import extractApiData from "common/helpers/extractApiData"; import WalletActionsSection from "modules/WalletActionsSection"; import WalletInfoSection from "modules/WalletInfoSection"; -import type { ExtractedWalletApi } from "types/cardano"; +import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; import type { Cip30Wallet } from "@cardano-sdk/cip30"; const queryClient = new QueryClient({ @@ -43,28 +43,35 @@ function App() { setSelectedWallets((prev) => xor(prev, [walletName])) } - async function handleEnableWallet(walletName: string) { - await handleEnableAllWallets([ walletName ]); + async function handleEnableWallet(walletName: string, extArg: ExtensionArguments) { + await handleEnableAllWallets([ walletName ], { [walletName]: extArg }); } - async function handleEnableAllWallets(wallets?: string[]) { + async function handleEnableAllWallets(wallets: string[], walletExtArg: Record) { const toBeEnabledWallets = (wallets ?? selectedWallets).filter((wallet) => !walletApi[wallet]); - const mappedWalletProp = pickBy(getCardano(), (v, k) => toBeEnabledWallets.includes(k)) as Record; + const mappedWalletProp = pickBy(getCardano(), (v, k) => toBeEnabledWallets.includes(k)); setEnablingWallets((prev) => [...prev, ...toBeEnabledWallets]); - const walletApis = await Promise.all(Object.entries(mappedWalletProp).map(async ([walletName, walletProps]) => { - const api = await walletProps.enable(/* { cip: 30 } */); - - const extractedApi = await extractApiData(api); - - return [walletName, extractedApi] - })); - - console.log("api", walletApis); - - setWalletApi((prev) => ({ ...prev, ...Object.fromEntries(walletApis) })); - setEnablingWallets((prev) => prev.filter((wallet) => !toBeEnabledWallets.includes(wallet))); + try { + const walletApis = await Promise.all(Object.entries(mappedWalletProp).map(async ([walletName, walletProps]) => { + const api = isEmpty(walletExtArg[walletName]) + ? await walletProps.enable() + : await walletProps.enable({ extensions: [walletExtArg[walletName]] }); + + const extractedApi = await extractApiData(api); + + return [walletName, extractedApi] + })); + + console.log("api", walletApis); + + setWalletApi((prev) => ({ ...prev, ...Object.fromEntries(walletApis) })); + } catch (err) { + toast.error(String(err)) + } finally { + setEnablingWallets((prev) => prev.filter((wallet) => !toBeEnabledWallets.includes(wallet))); + } } return ( diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index 42d74b6a026..c914e8eeb23 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -1,8 +1,9 @@ import { toast } from "react-toastify"; +import type { ExtensionArguments } from "types/cardano"; type Props = { heading: string; - value: string | string[] | null; + value: string | string[] | null | ExtensionArguments[]; } function InfoItem({ heading, value }: Props) { @@ -16,19 +17,19 @@ function InfoItem({ heading, value }: Props) {

{heading}:

{typeof value === "string" ? ( -

handleCopy(value)}> +

handleCopy(value)}> {value || "-"}

) : Array.isArray(value) && value.length ? (
    - {value.map((v) => ( -
  1. handleCopy(v)}> - {(typeof v === "object" ? JSON.stringify(v) : v) || "-"} + {value.map((v) => typeof v === "object" ? JSON.stringify(v) : v).map((v) => ( +
  2. handleCopy(v)}> + {v || "-"}
  3. ))}
) : ( -

{String(value) || "-"}

+

{String(value) || "-"}

)}
) diff --git a/utilities/wallet-connector/src/common/helpers/getCardano.ts b/utilities/wallet-connector/src/common/helpers/getCardano.ts index 928995cf6ad..8a81ecc1997 100644 --- a/utilities/wallet-connector/src/common/helpers/getCardano.ts +++ b/utilities/wallet-connector/src/common/helpers/getCardano.ts @@ -1,10 +1,6 @@ -import { Cip30Wallet } from "@cardano-sdk/cip30"; +import type { WalletCollections } from "types/cardano"; -type WalletCollections = { - [k: string]: Cip30Wallet; -}; - -export default function getCardano(walletName?: T): T extends string ? Cip30Wallet : WalletCollections { +export default function getCardano(walletName?: T): T extends string ? WalletCollections[string] : WalletCollections { return walletName ? globalThis.cardano[walletName] : globalThis.cardano; diff --git a/utilities/wallet-connector/src/main.tsx b/utilities/wallet-connector/src/main.tsx index 198fc023a73..71592e8e0c7 100644 --- a/utilities/wallet-connector/src/main.tsx +++ b/utilities/wallet-connector/src/main.tsx @@ -2,6 +2,6 @@ import ReactDOM from "react-dom/client"; import App from "./App.jsx"; -ReactDOM.createRoot(document.getElementById("root")).render( +ReactDOM.createRoot(document.getElementById("root")!).render( ); diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index 5c65e632561..a37815b6a88 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -57,7 +57,7 @@ function SignTxnPanel({ async function handleExecute(formValues: FormValues) { if (!selectedWallets.length) { - return toast.error("Please select at least one wallet to execute.") + return void toast.error("Please select at least one wallet to execute.") } await mutateAsync([cleanHex(formValues.tx), formValues.partialSign]); diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index 932ccbc75a3..d8a5cde6f0f 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -1,20 +1,25 @@ import { Tab } from "@headlessui/react"; import getCardano from "common/helpers/getCardano"; -import { noop } from "lodash-es"; +import { noop, pickBy } from "lodash-es"; import { Fragment } from "react/jsx-runtime"; import { twMerge } from "tailwind-merge"; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import InfoItem from "common/components/InfoItem"; -import type { ExtractedWalletApi } from "types/cardano"; +import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; import Button from "common/components/Button"; import WarningIcon from '@mui/icons-material/Warning'; +import { useForm } from "react-hook-form"; type Props = { selectedWallets: string[]; enablingWallets: string[]; walletApi: Record; - onEnable?: (walletName: string) => void; - onEnableAll?: () => void; + onEnable?: (walletName: string, extArg: ExtensionArguments) => void; + onEnableAll?: (walletNames: string[], walletExtArg: Record) => void; +} + +type FormValues = { + [walletName: string]: ExtensionArguments; } function WalletInfoSection({ @@ -24,7 +29,18 @@ function WalletInfoSection({ onEnable = noop, onEnableAll = noop, }: Props) { - const allEnabled = selectedWallets.every((wallet) => walletApi[wallet]); + const { register, getValues } = useForm(); + + const disabledWallets = selectedWallets.filter((wallet) => !walletApi[wallet]); + const allEnabled = !disabledWallets.length; + + function handleEnableWallet(wallet: string) { + const arg = getValues(wallet); + + console.log(arg); + + onEnable(wallet, pickBy(arg, Boolean)) + } return (
@@ -37,7 +53,7 @@ function WalletInfoSection({

Selected wallets: {selectedWallets.length}

-
@@ -107,15 +123,15 @@ function WalletInfoSection({
) : (
- -

Extension (optional)

+

Extension

)} diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index c0807af9f2e..7d3341b1147 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -2,6 +2,17 @@ import * as cip30 from "@cardano-sdk/cip30"; type Extracted any> = Awaited>; +export type WalletCollections = { + [k: string]: Omit & { + enable(args: { extensions: { cip: number }[] }): Promise; + supportedExtensions: { cip: number }[]; + } +}; + +export type ExtensionArguments = { + cip?: number +} + export type ExtractedWalletApi = { networkId: Extracted; utxos: Extracted; diff --git a/utilities/wallet-connector/src/types/global.d.ts b/utilities/wallet-connector/src/types/global.d.ts index 11f02fe2a00..6568235dddc 100644 --- a/utilities/wallet-connector/src/types/global.d.ts +++ b/utilities/wallet-connector/src/types/global.d.ts @@ -1 +1,7 @@ /// +/// + +declare module globalThis { + const cardano: Record + export { cardano } +} From 836d98b6375fd3eaa785a1f767c258e1030e1bdc Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 17:20:45 +0700 Subject: [PATCH 24/73] feat: linters --- utilities/wallet-connector/.eslintrc.yaml | 83 +++++++++++++++++++++ utilities/wallet-connector/.prettierrc.yaml | 5 ++ utilities/wallet-connector/src/App.tsx | 3 +- 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 utilities/wallet-connector/.eslintrc.yaml create mode 100644 utilities/wallet-connector/.prettierrc.yaml diff --git a/utilities/wallet-connector/.eslintrc.yaml b/utilities/wallet-connector/.eslintrc.yaml new file mode 100644 index 00000000000..4ad671ff6c9 --- /dev/null +++ b/utilities/wallet-connector/.eslintrc.yaml @@ -0,0 +1,83 @@ +parser: "@typescript-eslint/parser" +root: true +env: + es2021: true + browser: true + node: true +extends: + - plugin:@typescript-eslint/eslint-recommended + - plugin:@typescript-eslint/recommended + - plugin:react/recommended + - plugin:react/jsx-runtime + - plugin:react-hooks/recommended + - plugin:@tanstack/eslint-plugin-query/recommended + - plugin:jsx-a11y/strict +parserOptions: + ecmaFeatures: + jsx: true + ecmaVersion: latest + sourceType: module + tsconfigRootDir: ./ + project: + - ./tsconfig.json + - ./tsconfig.node.json +plugins: + - "@typescript-eslint" + - react + - react-hooks + - jsx-a11y + - import + - react-refresh + - i18next + - "@tanstack/query" +overrides: + - files: + - "*.yaml" + - "*.yml" + parser: yaml-eslint-parser + extends: + - plugin:yml/standard +settings: + react: + version: detect +ignorePatterns: + - node_modules +rules: + # import + import/order: + - warn + - newlines-between: always + alphabetize: + order: asc + caseInsensitive: false + pathGroups: + # internal + - pattern: "common/**" + group: parent + - pattern: "modules/**" + group: parent + - pattern: "styles/**" + group: parent + - pattern: "types/**" + group: parent + # sibling + - pattern: "../**" + group: sibling + # styles + - pattern: "./*.css" + group: sibling + position: after + pathGroupsExcludedImportTypes: [] + + # vanilla js + quotes: + - error + - double + + # react-refresh + react-refresh/only-export-components: + - error + - allowConstantExport: true + + # vanilla + "@typescript-eslint/semi": error \ No newline at end of file diff --git a/utilities/wallet-connector/.prettierrc.yaml b/utilities/wallet-connector/.prettierrc.yaml new file mode 100644 index 00000000000..cd750021760 --- /dev/null +++ b/utilities/wallet-connector/.prettierrc.yaml @@ -0,0 +1,5 @@ +trailingComma: es5 +useTabs: false +tabWidth: 2 +semi: true +singleQuote: false \ No newline at end of file diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index f9985cbd6ae..bd6adb1dc42 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -2,8 +2,8 @@ import "react-toastify/dist/ReactToastify.css"; import "./styles/global.css"; -import getCardano from "common/helpers/getCardano"; import WalletCard from "common/components/WalletCard"; +import getCardano from "common/helpers/getCardano"; import { isEmpty, pickBy, xor } from "lodash-es"; import { useState } from "react"; import { QueryClient, QueryClientProvider } from "react-query"; @@ -13,7 +13,6 @@ import extractApiData from "common/helpers/extractApiData"; import WalletActionsSection from "modules/WalletActionsSection"; import WalletInfoSection from "modules/WalletInfoSection"; import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; -import type { Cip30Wallet } from "@cardano-sdk/cip30"; const queryClient = new QueryClient({ defaultOptions: { From ccd917a8048cde6035d41ff1b35c99f576ac7744 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 17:22:10 +0700 Subject: [PATCH 25/73] chore: lintfix --- utilities/wallet-connector/src/App.tsx | 10 +++--- .../src/common/components/Button.tsx | 2 +- .../src/common/components/CBOREditor.tsx | 33 ++++++++++--------- .../src/common/components/CheckBox.tsx | 12 +++---- .../src/common/components/InfoItem.tsx | 5 +-- .../src/common/components/InputBlock.tsx | 4 +-- .../src/common/components/WalletCard.tsx | 12 +++---- .../components/WalletResponseSelection.tsx | 5 +-- .../src/common/helpers/cleanHex.ts | 4 +-- .../src/common/helpers/diag2hex.ts | 1 + .../src/common/helpers/extractApiData.ts | 3 +- .../src/common/helpers/hex2diag.ts | 1 + .../src/common/helpers/readFile.ts | 18 +++++----- .../src/modules/SignDataPanel.tsx | 4 +-- .../src/modules/SignTxnPanel.tsx | 27 +++++++-------- .../src/modules/SubmitTxnPanel.tsx | 4 +-- .../src/modules/WalletActionsSection.tsx | 10 +++--- .../src/modules/WalletInfoSection.tsx | 19 ++++++----- .../wallet-connector/src/types/cardano.ts | 4 +-- .../wallet-connector/src/types/global.d.ts | 4 +-- 20 files changed, 96 insertions(+), 86 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index bd6adb1dc42..d463798a64b 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -2,14 +2,14 @@ import "react-toastify/dist/ReactToastify.css"; import "./styles/global.css"; -import WalletCard from "common/components/WalletCard"; -import getCardano from "common/helpers/getCardano"; import { isEmpty, pickBy, xor } from "lodash-es"; import { useState } from "react"; import { QueryClient, QueryClientProvider } from "react-query"; import { ToastContainer, toast } from "react-toastify"; +import WalletCard from "common/components/WalletCard"; import extractApiData from "common/helpers/extractApiData"; +import getCardano from "common/helpers/getCardano"; import WalletActionsSection from "modules/WalletActionsSection"; import WalletInfoSection from "modules/WalletInfoSection"; import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; @@ -39,7 +39,7 @@ function App() { const isCardanoActivated = typeof getCardano() !== "undefined"; function handleWalletCardClick(walletName: string) { - setSelectedWallets((prev) => xor(prev, [walletName])) + setSelectedWallets((prev) => xor(prev, [walletName])); } async function handleEnableWallet(walletName: string, extArg: ExtensionArguments) { @@ -60,14 +60,14 @@ function App() { const extractedApi = await extractApiData(api); - return [walletName, extractedApi] + return [walletName, extractedApi]; })); console.log("api", walletApis); setWalletApi((prev) => ({ ...prev, ...Object.fromEntries(walletApis) })); } catch (err) { - toast.error(String(err)) + toast.error(String(err)); } finally { setEnablingWallets((prev) => prev.filter((wallet) => !toBeEnabledWallets.includes(wallet))); } diff --git a/utilities/wallet-connector/src/common/components/Button.tsx b/utilities/wallet-connector/src/common/components/Button.tsx index 754e35a7053..27821d070e0 100644 --- a/utilities/wallet-connector/src/common/components/Button.tsx +++ b/utilities/wallet-connector/src/common/components/Button.tsx @@ -10,7 +10,7 @@ function Button({ children, className = "", type = "button", ...props }: Props) - ) + ); } export default Button; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/CBOREditor.tsx b/utilities/wallet-connector/src/common/components/CBOREditor.tsx index b5f65e90b22..32fd38a8578 100644 --- a/utilities/wallet-connector/src/common/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/common/components/CBOREditor.tsx @@ -1,10 +1,5 @@ -import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; -import { decode, encode } from 'cborg'; -import bin2hex from 'common/helpers/bin2hex'; -import diag2hex from 'common/helpers/diag2hex'; -import hex2bin from 'common/helpers/hex2bin'; -import hex2diag from "common/helpers/hex2diag"; -import readFile from "common/helpers/readFile"; +import SwapHorizIcon from "@mui/icons-material/SwapHoriz"; +import { decode, encode } from "cborg"; import { noop } from "lodash-es"; import { useEffect, useState, type CSSProperties } from "react"; import AceEditor from "react-ace"; @@ -12,6 +7,12 @@ import { useDropzone } from "react-dropzone"; import { toast } from "react-toastify"; import { twMerge } from "tailwind-merge"; +import bin2hex from "common/helpers/bin2hex"; +import diag2hex from "common/helpers/diag2hex"; +import hex2bin from "common/helpers/hex2bin"; +import hex2diag from "common/helpers/hex2diag"; +import readFile from "common/helpers/readFile"; + import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/mode-json"; import "ace-builds/src-noconflict/mode-text"; @@ -23,7 +24,7 @@ type Props = { value: string; isReadOnly?: boolean; onChange?: (value: string) => void; -} +}; const EDITOR_STYLE: CSSProperties = { width: "100%", @@ -59,26 +60,26 @@ function CBOREditor({ if (acceptedFile.type === "application/octet-stream") { const result = await readFile(acceptedFile, "buffer") as ArrayBuffer; - onChange(bin2hex(new Uint8Array(result))) + onChange(bin2hex(new Uint8Array(result))); } else if (acceptedFile.type === "application/json") { const result = await readFile(acceptedFile, "text") as string; try { - const finalResult = bin2hex(encode(JSON.parse(result))) + const finalResult = bin2hex(encode(JSON.parse(result))); onChange(finalResult); } catch (err) { - toast.error("Failed to read a JSON file.") + toast.error("Failed to read a JSON file."); } } else if (acceptedFile.type === "text/plain") { const result = await readFile(acceptedFile, "text") as string; - onChange(bin2hex(hex2bin(result))) + onChange(bin2hex(hex2bin(result))); } else { toast.error(`The uploaded file type is unacceptable (${acceptedFile.type}).`); } - setShouldRefresh(true) - setFocusingSide(null) + setShouldRefresh(true); + setFocusingSide(null); } - }) + }); useEffect(() => { if (shouldRefresh) { @@ -181,7 +182,7 @@ function CBOREditor({ />
- ) + ); } export default CBOREditor; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/CheckBox.tsx b/utilities/wallet-connector/src/common/components/CheckBox.tsx index a1f270acd0a..3ba8a522eb1 100644 --- a/utilities/wallet-connector/src/common/components/CheckBox.tsx +++ b/utilities/wallet-connector/src/common/components/CheckBox.tsx @@ -1,7 +1,7 @@ -import CheckBoxIcon from '@mui/icons-material/CheckBox'; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; -import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; -import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; +import CheckBoxIcon from "@mui/icons-material/CheckBox"; +import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; +import RadioButtonCheckedIcon from "@mui/icons-material/RadioButtonChecked"; +import RadioButtonUncheckedIcon from "@mui/icons-material/RadioButtonUnchecked"; import { noop } from "lodash-es"; type Props = { @@ -9,7 +9,7 @@ type Props = { value: boolean; label?: string; onChange?: (value: boolean) => void; -} +}; function CheckBox({ variant = "checkbox", @@ -30,7 +30,7 @@ function CheckBox({ )} {label &&
{label}
} - ) + ); } export default CheckBox; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index c914e8eeb23..93689c97834 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -1,10 +1,11 @@ import { toast } from "react-toastify"; + import type { ExtensionArguments } from "types/cardano"; type Props = { heading: string; value: string | string[] | null | ExtensionArguments[]; -} +}; function InfoItem({ heading, value }: Props) { async function handleCopy(value: string) { @@ -32,7 +33,7 @@ function InfoItem({ heading, value }: Props) {

{String(value) || "-"}

)}
- ) + ); } export default InfoItem; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/InputBlock.tsx b/utilities/wallet-connector/src/common/components/InputBlock.tsx index 30b0c18c6f4..e3ee943de8b 100644 --- a/utilities/wallet-connector/src/common/components/InputBlock.tsx +++ b/utilities/wallet-connector/src/common/components/InputBlock.tsx @@ -6,7 +6,7 @@ type Props = { variant: "inline" | "block", name: string, children: ReactNode -} +}; function InputBlock({ variant, name, children }: Props) { return ( @@ -19,7 +19,7 @@ function InputBlock({ variant, name, children }: Props) { {children}
- ) + ); } export default InputBlock; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/WalletCard.tsx b/utilities/wallet-connector/src/common/components/WalletCard.tsx index 8cf15786fce..dd8da2bed0b 100644 --- a/utilities/wallet-connector/src/common/components/WalletCard.tsx +++ b/utilities/wallet-connector/src/common/components/WalletCard.tsx @@ -1,7 +1,7 @@ -import CheckBoxIcon from '@mui/icons-material/CheckBox'; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; -import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; -import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; +import CheckBoxIcon from "@mui/icons-material/CheckBox"; +import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; +import RadioButtonCheckedIcon from "@mui/icons-material/RadioButtonChecked"; +import RadioButtonUncheckedIcon from "@mui/icons-material/RadioButtonUnchecked"; import { noop } from "lodash-es"; import { twMerge } from "tailwind-merge"; @@ -12,7 +12,7 @@ type Props = { isEnabledStatusDisplayed?: boolean; variant?: "checkbox" | "radio" onClick?: () => void; -} +}; function WalletCard({ isChecked, @@ -40,7 +40,7 @@ function WalletCard({ )} - ) + ); } export default WalletCard; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx index ee6ff18f674..480de2f8385 100644 --- a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx +++ b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx @@ -1,7 +1,8 @@ +import { noop } from "lodash-es"; import type { ButtonHTMLAttributes, ReactNode } from "react"; import { twMerge } from "tailwind-merge"; + import WalletCard from "./WalletCard"; -import { noop } from "lodash-es"; type Props = { selectedWallet: string; @@ -27,7 +28,7 @@ function WalletResponseSelection({ wallets, selectedWallet, onSelect = noop }: P /> ))} - ) + ); } export default WalletResponseSelection; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/helpers/cleanHex.ts b/utilities/wallet-connector/src/common/helpers/cleanHex.ts index 4d345a07ff7..82bd2e2c6fd 100644 --- a/utilities/wallet-connector/src/common/helpers/cleanHex.ts +++ b/utilities/wallet-connector/src/common/helpers/cleanHex.ts @@ -1,10 +1,10 @@ export default function cleanHex(hexString: string): string { // Remove spaces and convert to uppercase - const cleanedHexString = hexString.replace(/\s/gm, '').toUpperCase(); + const cleanedHexString = hexString.replace(/\s/gm, "").toUpperCase(); // Check if the cleaned string is a valid hex string if (!/^[0-9a-fA-F]*$/.test(cleanedHexString)) { - throw new Error('Invalid hex string'); + throw new Error("Invalid hex string"); } return cleanedHexString; diff --git a/utilities/wallet-connector/src/common/helpers/diag2hex.ts b/utilities/wallet-connector/src/common/helpers/diag2hex.ts index 29c690d9bc4..dd65beb2b2f 100644 --- a/utilities/wallet-connector/src/common/helpers/diag2hex.ts +++ b/utilities/wallet-connector/src/common/helpers/diag2hex.ts @@ -1,4 +1,5 @@ import { fromDiag } from "cborg/lib/diagnostic"; + import bin2hex from "./bin2hex"; export default function diag2hex(diagString: string): string { diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index 58c019452e8..b530a6504c0 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -1,4 +1,5 @@ import type { WalletApi } from "@cardano-sdk/cip30"; + import type { ExtractedWalletApi } from "types/cardano"; export default async function extractApiData(api: WalletApi): Promise { @@ -8,7 +9,7 @@ export default async function extractApiData(api: WalletApi): Promise { return new Promise((resolve, reject) => { - const reader = new FileReader() + const reader = new FileReader(); - reader.onabort = () => reject(Error("file reading was aborted")) - reader.onerror = () => reject(Error("file reading has failed")) - reader.onload = () => resolve(reader.result) + reader.onabort = () => reject(Error("file reading was aborted")); + reader.onerror = () => reject(Error("file reading has failed")); + reader.onload = () => resolve(reader.result); if (readAs === "buffer") { - reader.readAsArrayBuffer(blob) + reader.readAsArrayBuffer(blob); } else if (readAs === "data-url") { - reader.readAsDataURL(blob) + reader.readAsDataURL(blob); } else if (readAs === "text") { - reader.readAsText(blob) + reader.readAsText(blob); } else { - reject(Error("invalid reading scheme")) + reject(Error("invalid reading scheme")); } - }) + }); } diff --git a/utilities/wallet-connector/src/modules/SignDataPanel.tsx b/utilities/wallet-connector/src/modules/SignDataPanel.tsx index 24373ccb786..bc8be7a1e07 100644 --- a/utilities/wallet-connector/src/modules/SignDataPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignDataPanel.tsx @@ -1,6 +1,6 @@ type Props = { -} +}; function SignDataPanel({ }: Props) { return ( @@ -9,7 +9,7 @@ function SignDataPanel({ }: Props) {

Not Implemented.

- ) + ); } export default SignDataPanel; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index a37815b6a88..dc7f8d21642 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -1,26 +1,27 @@ -import type { SignTx } from '@cardano-sdk/cip30'; -import RefreshIcon from '@mui/icons-material/Refresh'; -import cleanHex from 'common/helpers/cleanHex'; +import type { SignTx } from "@cardano-sdk/cip30"; +import RefreshIcon from "@mui/icons-material/Refresh"; +import { useState } from "react"; +import { Controller, useForm } from "react-hook-form"; +import { useMutation } from "react-query"; +import { toast } from "react-toastify"; + import Button from "common/components/Button"; import CBOREditor from "common/components/CBOREditor"; import CheckBox from "common/components/CheckBox"; import InputBlock from "common/components/InputBlock"; -import WalletResponseSelection from 'common/components/WalletResponseSelection'; -import { useState } from 'react'; -import { Controller, useForm } from "react-hook-form"; -import { useMutation } from "react-query"; -import { toast } from 'react-toastify'; -import type { ExtractedWalletApi } from 'types/cardano'; +import WalletResponseSelection from "common/components/WalletResponseSelection"; +import cleanHex from "common/helpers/cleanHex"; +import type { ExtractedWalletApi } from "types/cardano"; type Props = { selectedWallets: string[]; walletApi: Record; -} +}; type FormValues = { partialSign: boolean; tx: string; -} +}; function SignTxnPanel({ selectedWallets, @@ -57,7 +58,7 @@ function SignTxnPanel({ async function handleExecute(formValues: FormValues) { if (!selectedWallets.length) { - return void toast.error("Please select at least one wallet to execute.") + return void toast.error("Please select at least one wallet to execute."); } await mutateAsync([cleanHex(formValues.tx), formValues.partialSign]); @@ -123,7 +124,7 @@ function SignTxnPanel({ )} - ) + ); } export default SignTxnPanel; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx index cf3055efa54..ea502fde97a 100644 --- a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx @@ -1,6 +1,6 @@ type Props = { -} +}; function SubmitTxnPanel({ }: Props) { return ( @@ -9,7 +9,7 @@ function SubmitTxnPanel({ }: Props) {

Not Implemented.

- ) + ); } export default SubmitTxnPanel; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx index ec09b28932d..bb2a0d8a1f8 100644 --- a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx @@ -1,11 +1,13 @@ import { Tab } from "@headlessui/react"; -import ArrowRightIcon from '@mui/icons-material/ArrowRight'; +import ArrowRightIcon from "@mui/icons-material/ArrowRight"; import { Fragment } from "react/jsx-runtime"; import { twMerge } from "tailwind-merge"; + +import type { ExtractedWalletApi } from "types/cardano"; + import SignDataPanel from "./SignDataPanel"; import SignTxnPanel from "./SignTxnPanel"; import SubmitTxnPanel from "./SubmitTxnPanel"; -import type { ExtractedWalletApi } from "types/cardano"; const ACTIONS = [ "Sign Transaction", @@ -16,7 +18,7 @@ const ACTIONS = [ type Props = { selectedWallets: string[]; walletApi: Record; -} +}; function WalletActionsSection({ walletApi, @@ -60,7 +62,7 @@ function WalletActionsSection({
- ) + ); } export default WalletActionsSection; \ No newline at end of file diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index d8a5cde6f0f..f4e4a7df4db 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -1,14 +1,15 @@ import { Tab } from "@headlessui/react"; -import getCardano from "common/helpers/getCardano"; +import ArrowRightIcon from "@mui/icons-material/ArrowRight"; +import WarningIcon from "@mui/icons-material/Warning"; import { noop, pickBy } from "lodash-es"; import { Fragment } from "react/jsx-runtime"; +import { useForm } from "react-hook-form"; import { twMerge } from "tailwind-merge"; -import ArrowRightIcon from '@mui/icons-material/ArrowRight'; + +import Button from "common/components/Button"; import InfoItem from "common/components/InfoItem"; +import getCardano from "common/helpers/getCardano"; import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; -import Button from "common/components/Button"; -import WarningIcon from '@mui/icons-material/Warning'; -import { useForm } from "react-hook-form"; type Props = { selectedWallets: string[]; @@ -16,11 +17,11 @@ type Props = { walletApi: Record; onEnable?: (walletName: string, extArg: ExtensionArguments) => void; onEnableAll?: (walletNames: string[], walletExtArg: Record) => void; -} +}; type FormValues = { [walletName: string]: ExtensionArguments; -} +}; function WalletInfoSection({ selectedWallets, @@ -39,7 +40,7 @@ function WalletInfoSection({ console.log(arg); - onEnable(wallet, pickBy(arg, Boolean)) + onEnable(wallet, pickBy(arg, Boolean)); } return ( @@ -149,7 +150,7 @@ function WalletInfoSection({ )} - ) + ); } export default WalletInfoSection; \ No newline at end of file diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index 7d3341b1147..337aa947f81 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -11,7 +11,7 @@ export type WalletCollections = { export type ExtensionArguments = { cip?: number -} +}; export type ExtractedWalletApi = { networkId: Extracted; @@ -25,4 +25,4 @@ export type ExtractedWalletApi = { signTx: cip30.SignTx; signData: cip30.SignData; submitTx: cip30.SubmitTx; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/utilities/wallet-connector/src/types/global.d.ts b/utilities/wallet-connector/src/types/global.d.ts index 6568235dddc..9f637ac89fa 100644 --- a/utilities/wallet-connector/src/types/global.d.ts +++ b/utilities/wallet-connector/src/types/global.d.ts @@ -2,6 +2,6 @@ /// declare module globalThis { - const cardano: Record - export { cardano } + const cardano: Record; + export { cardano }; } From 37eccb15d49041ca77a7f8e7e817d0ec3bea431a Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 17:25:19 +0700 Subject: [PATCH 26/73] chore: lintfix --- utilities/wallet-connector/.eslintrc.yaml | 8 ++++++-- .../wallet-connector/src/common/components/CheckBox.tsx | 2 +- .../wallet-connector/src/common/components/InputBlock.tsx | 6 +++--- .../wallet-connector/src/common/components/WalletCard.tsx | 2 +- .../src/common/components/WalletResponseSelection.tsx | 2 +- utilities/wallet-connector/src/types/cardano.ts | 8 ++++---- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/utilities/wallet-connector/.eslintrc.yaml b/utilities/wallet-connector/.eslintrc.yaml index 4ad671ff6c9..b975a528131 100644 --- a/utilities/wallet-connector/.eslintrc.yaml +++ b/utilities/wallet-connector/.eslintrc.yaml @@ -79,5 +79,9 @@ rules: - error - allowConstantExport: true - # vanilla - "@typescript-eslint/semi": error \ No newline at end of file + # typescript + "@typescript-eslint/semi": error + "@typescript-eslint/member-delimiter-style": + - error + - singleline: + requireLast: true \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/CheckBox.tsx b/utilities/wallet-connector/src/common/components/CheckBox.tsx index 3ba8a522eb1..eabb734cea3 100644 --- a/utilities/wallet-connector/src/common/components/CheckBox.tsx +++ b/utilities/wallet-connector/src/common/components/CheckBox.tsx @@ -5,7 +5,7 @@ import RadioButtonUncheckedIcon from "@mui/icons-material/RadioButtonUnchecked"; import { noop } from "lodash-es"; type Props = { - variant?: "radio" | "checkbox", + variant?: "radio" | "checkbox"; value: boolean; label?: string; onChange?: (value: boolean) => void; diff --git a/utilities/wallet-connector/src/common/components/InputBlock.tsx b/utilities/wallet-connector/src/common/components/InputBlock.tsx index e3ee943de8b..86e6a763bca 100644 --- a/utilities/wallet-connector/src/common/components/InputBlock.tsx +++ b/utilities/wallet-connector/src/common/components/InputBlock.tsx @@ -3,9 +3,9 @@ import type { ReactNode } from "react"; import { twMerge } from "tailwind-merge"; type Props = { - variant: "inline" | "block", - name: string, - children: ReactNode + variant: "inline" | "block"; + name: string; + children: ReactNode; }; function InputBlock({ variant, name, children }: Props) { diff --git a/utilities/wallet-connector/src/common/components/WalletCard.tsx b/utilities/wallet-connector/src/common/components/WalletCard.tsx index dd8da2bed0b..ab0c7bd7991 100644 --- a/utilities/wallet-connector/src/common/components/WalletCard.tsx +++ b/utilities/wallet-connector/src/common/components/WalletCard.tsx @@ -10,7 +10,7 @@ type Props = { isEnabled: boolean; name: string; isEnabledStatusDisplayed?: boolean; - variant?: "checkbox" | "radio" + variant?: "checkbox" | "radio"; onClick?: () => void; }; diff --git a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx index 480de2f8385..3bf4ca82624 100644 --- a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx +++ b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx @@ -6,7 +6,7 @@ import WalletCard from "./WalletCard"; type Props = { selectedWallet: string; - wallets: string[], + wallets: string[]; onSelect: (wallet: string) => void; }; diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index 337aa947f81..128d2412579 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -4,13 +4,13 @@ type Extracted any> = Awaited>; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number }[] }): Promise; - supportedExtensions: { cip: number }[]; - } + enable(args: { extensions: { cip: number; }[]; }): Promise; + supportedExtensions: { cip: number; }[]; + }; }; export type ExtensionArguments = { - cip?: number + cip?: number; }; export type ExtractedWalletApi = { From f25c506bb5e9865353dbc2daa279a8959bd91004 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 17:35:02 +0700 Subject: [PATCH 27/73] chore: remove lint issues --- .../src/common/components/CBOREditor.tsx | 2 +- .../src/common/components/InfoItem.tsx | 14 ++++++++------ .../common/components/WalletResponseSelection.tsx | 2 -- .../wallet-connector/src/modules/SignDataPanel.tsx | 5 ++++- .../src/modules/SubmitTxnPanel.tsx | 5 ++++- .../src/modules/WalletActionsSection.tsx | 6 ++++-- utilities/wallet-connector/src/types/cardano.ts | 1 + utilities/wallet-connector/src/types/global.d.ts | 3 +-- 8 files changed, 23 insertions(+), 15 deletions(-) diff --git a/utilities/wallet-connector/src/common/components/CBOREditor.tsx b/utilities/wallet-connector/src/common/components/CBOREditor.tsx index 32fd38a8578..0822ecc925d 100644 --- a/utilities/wallet-connector/src/common/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/common/components/CBOREditor.tsx @@ -96,7 +96,7 @@ function CBOREditor({ setLhsValue(value); setShouldRefresh(false); } - }, [value, shouldRefresh]); + }, [value, shouldRefresh]); // eslint-disable-line react-hooks/exhaustive-deps function handleLhsChange(value: string) { setLhsValue(value); diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index 93689c97834..0a770622aa4 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -18,15 +18,17 @@ function InfoItem({ heading, value }: Props) {

{heading}:

{typeof value === "string" ? ( -

handleCopy(value)}> - {value || "-"} -

+ ) : Array.isArray(value) && value.length ? (
    {value.map((v) => typeof v === "object" ? JSON.stringify(v) : v).map((v) => ( -
  1. handleCopy(v)}> - {v || "-"} -
  2. +
      + +
    ))}
) : ( diff --git a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx index 3bf4ca82624..1a37fbcd347 100644 --- a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx +++ b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx @@ -1,6 +1,4 @@ import { noop } from "lodash-es"; -import type { ButtonHTMLAttributes, ReactNode } from "react"; -import { twMerge } from "tailwind-merge"; import WalletCard from "./WalletCard"; diff --git a/utilities/wallet-connector/src/modules/SignDataPanel.tsx b/utilities/wallet-connector/src/modules/SignDataPanel.tsx index bc8be7a1e07..3979cde9c27 100644 --- a/utilities/wallet-connector/src/modules/SignDataPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignDataPanel.tsx @@ -1,5 +1,8 @@ -type Props = { +import type { ExtractedWalletApi } from "types/cardano"; +type Props = { + selectedWallets: string[]; + walletApi: Record; }; function SignDataPanel({ }: Props) { diff --git a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx index ea502fde97a..86db8268803 100644 --- a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx @@ -1,5 +1,8 @@ -type Props = { +import type { ExtractedWalletApi } from "types/cardano"; +type Props = { + selectedWallets: string[]; + walletApi: Record; }; function SubmitTxnPanel({ }: Props) { diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx index bb2a0d8a1f8..168bbcd4573 100644 --- a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx @@ -50,12 +50,14 @@ function WalletActionsSection({ diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index 128d2412579..b27fd7b81e3 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -1,5 +1,6 @@ import * as cip30 from "@cardano-sdk/cip30"; +// eslint-disable-next-line @typescript-eslint/no-explicit-any type Extracted any> = Awaited>; export type WalletCollections = { diff --git a/utilities/wallet-connector/src/types/global.d.ts b/utilities/wallet-connector/src/types/global.d.ts index 9f637ac89fa..cfbbfe09509 100644 --- a/utilities/wallet-connector/src/types/global.d.ts +++ b/utilities/wallet-connector/src/types/global.d.ts @@ -1,7 +1,6 @@ /// -/// declare module globalThis { - const cardano: Record; + const cardano: Record; export { cardano }; } From 5f4d9ddc9aa11f82217cbb49832c039e8a039511 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 17:41:48 +0700 Subject: [PATCH 28/73] chore: fmt --- utilities/wallet-connector/.prettierrc.yaml | 1 + utilities/wallet-connector/src/App.tsx | 40 +++++------ .../src/common/components/Button.tsx | 8 ++- .../src/common/components/CBOREditor.tsx | 67 +++++++++---------- .../src/common/components/CheckBox.tsx | 17 ++--- .../src/common/components/InfoItem.tsx | 28 +++++--- .../src/common/components/InputBlock.tsx | 6 +- .../src/common/components/WalletCard.tsx | 25 ++++--- .../components/WalletResponseSelection.tsx | 2 +- .../src/common/helpers/cleanHex.ts | 2 +- .../src/common/helpers/extractApiData.ts | 4 +- .../src/common/helpers/getCardano.ts | 10 +-- .../src/common/helpers/hex2bin.ts | 2 +- utilities/wallet-connector/src/main.tsx | 4 +- .../src/modules/SignDataPanel.tsx | 4 +- .../src/modules/SignTxnPanel.tsx | 43 +++++------- .../src/modules/SubmitTxnPanel.tsx | 4 +- .../src/modules/WalletActionsSection.tsx | 35 ++++------ .../src/modules/WalletInfoSection.tsx | 29 ++++---- .../wallet-connector/src/types/cardano.ts | 6 +- 20 files changed, 165 insertions(+), 172 deletions(-) diff --git a/utilities/wallet-connector/.prettierrc.yaml b/utilities/wallet-connector/.prettierrc.yaml index cd750021760..c4018fc2ab4 100644 --- a/utilities/wallet-connector/.prettierrc.yaml +++ b/utilities/wallet-connector/.prettierrc.yaml @@ -1,3 +1,4 @@ +printWidth: 100 trailingComma: es5 useTabs: false tabWidth: 2 diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index d463798a64b..61bec6caee0 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -18,12 +18,12 @@ const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, - refetchOnWindowFocus: false + refetchOnWindowFocus: false, }, mutations: { - retry: false - } - } + retry: false, + }, + }, }); function App() { @@ -43,25 +43,30 @@ function App() { } async function handleEnableWallet(walletName: string, extArg: ExtensionArguments) { - await handleEnableAllWallets([ walletName ], { [walletName]: extArg }); + await handleEnableAllWallets([walletName], { [walletName]: extArg }); } - async function handleEnableAllWallets(wallets: string[], walletExtArg: Record) { + async function handleEnableAllWallets( + wallets: string[], + walletExtArg: Record + ) { const toBeEnabledWallets = (wallets ?? selectedWallets).filter((wallet) => !walletApi[wallet]); const mappedWalletProp = pickBy(getCardano(), (v, k) => toBeEnabledWallets.includes(k)); setEnablingWallets((prev) => [...prev, ...toBeEnabledWallets]); try { - const walletApis = await Promise.all(Object.entries(mappedWalletProp).map(async ([walletName, walletProps]) => { - const api = isEmpty(walletExtArg[walletName]) - ? await walletProps.enable() - : await walletProps.enable({ extensions: [walletExtArg[walletName]] }); - - const extractedApi = await extractApiData(api); - - return [walletName, extractedApi]; - })); + const walletApis = await Promise.all( + Object.entries(mappedWalletProp).map(async ([walletName, walletProps]) => { + const api = isEmpty(walletExtArg[walletName]) + ? await walletProps.enable() + : await walletProps.enable({ extensions: [walletExtArg[walletName]] }); + + const extractedApi = await extractApiData(api); + + return [walletName, extractedApi]; + }) + ); console.log("api", walletApis); @@ -105,10 +110,7 @@ function App() { onEnableAll={handleEnableAllWallets} /> {Boolean(selectedWallets.length) && ( - + )} ) : ( diff --git a/utilities/wallet-connector/src/common/components/Button.tsx b/utilities/wallet-connector/src/common/components/Button.tsx index 27821d070e0..b18f29fdb43 100644 --- a/utilities/wallet-connector/src/common/components/Button.tsx +++ b/utilities/wallet-connector/src/common/components/Button.tsx @@ -7,10 +7,14 @@ type Props = { function Button({ children, className = "", type = "button", ...props }: Props) { return ( - ); } -export default Button; \ No newline at end of file +export default Button; diff --git a/utilities/wallet-connector/src/common/components/CBOREditor.tsx b/utilities/wallet-connector/src/common/components/CBOREditor.tsx index 0822ecc925d..6dbc71fc8fd 100644 --- a/utilities/wallet-connector/src/common/components/CBOREditor.tsx +++ b/utilities/wallet-connector/src/common/components/CBOREditor.tsx @@ -30,21 +30,17 @@ const EDITOR_STYLE: CSSProperties = { width: "100%", fontFamily: "Fira Code, monospace", fontSize: 12, - height: "240px" + height: "240px", } as const; -function CBOREditor({ - value, - isReadOnly = false, - onChange = noop -}: Props) { +function CBOREditor({ value, isReadOnly = false, onChange = noop }: Props) { const [shouldRefresh, setShouldRefresh] = useState(true); const [mode, setMode] = useState("bin2diag"); const [focusingSide, setFocusingSide] = useState(null); const [lhsValue, setLhsValue] = useState(""); const [rhsValue, setRhsValue] = useState(""); - const {getRootProps, getInputProps, isDragActive, open} = useDropzone({ + const { getRootProps, getInputProps, isDragActive, open } = useDropzone({ accept: { "text/plain": [".txt"], "application/json": [".json"], @@ -53,16 +49,16 @@ function CBOREditor({ multiple: false, disabled: isReadOnly, noClick: true, - onDrop: async ([ acceptedFile ]: File[]) => { + onDrop: async ([acceptedFile]: File[]) => { if (!acceptedFile) { return void toast.error("Invalid file."); } if (acceptedFile.type === "application/octet-stream") { - const result = await readFile(acceptedFile, "buffer") as ArrayBuffer; + const result = (await readFile(acceptedFile, "buffer")) as ArrayBuffer; onChange(bin2hex(new Uint8Array(result))); } else if (acceptedFile.type === "application/json") { - const result = await readFile(acceptedFile, "text") as string; + const result = (await readFile(acceptedFile, "text")) as string; try { const finalResult = bin2hex(encode(JSON.parse(result))); onChange(finalResult); @@ -70,7 +66,7 @@ function CBOREditor({ toast.error("Failed to read a JSON file."); } } else if (acceptedFile.type === "text/plain") { - const result = await readFile(acceptedFile, "text") as string; + const result = (await readFile(acceptedFile, "text")) as string; onChange(bin2hex(hex2bin(result))); } else { toast.error(`The uploaded file type is unacceptable (${acceptedFile.type}).`); @@ -78,21 +74,22 @@ function CBOREditor({ setShouldRefresh(true); setFocusingSide(null); - } + }, }); useEffect(() => { if (shouldRefresh) { try { - const rhsValue = mode === "bin2diag" - ? hex2diag(value) - : JSON.stringify(value ? decode(hex2bin(value)) : undefined, null, 2); + const rhsValue = + mode === "bin2diag" + ? hex2diag(value) + : JSON.stringify(value ? decode(hex2bin(value)) : undefined, null, 2); setRhsValue(rhsValue); } catch (e) { setRhsValue(String(e)); } - + setLhsValue(value); setShouldRefresh(false); } @@ -105,26 +102,16 @@ function CBOREditor({ result.includes("Error:") ? setRhsValue(hex2diag(value)) - : ( - onChange(value), - setShouldRefresh(true) - ); + : (onChange(value), setShouldRefresh(true)); } function handleRhsChange(value: string) { setRhsValue(value); try { - const result = mode === "bin2diag" - ? diag2hex(value) - : bin2hex(encode(JSON.parse(value))); - - result.includes("Error:") - ? setLhsValue(result) - : ( - onChange(result), - setShouldRefresh(true) - ); + const result = mode === "bin2diag" ? diag2hex(value) : bin2hex(encode(JSON.parse(value))); + + result.includes("Error:") ? setLhsValue(result) : (onChange(result), setShouldRefresh(true)); } catch (e) { setLhsValue(String(e)); } @@ -132,24 +119,34 @@ function CBOREditor({ function switchMode() { setFocusingSide("lhs"); - setMode((prev) => prev === "bin2diag" ? "bin2json" : "bin2diag"); + setMode((prev) => (prev === "bin2diag" ? "bin2json" : "bin2diag")); setShouldRefresh(true); } return (
-
+

CBOR Editor {!isReadOnly && ( <> | - + )}

@@ -185,4 +182,4 @@ function CBOREditor({ ); } -export default CBOREditor; \ No newline at end of file +export default CBOREditor; diff --git a/utilities/wallet-connector/src/common/components/CheckBox.tsx b/utilities/wallet-connector/src/common/components/CheckBox.tsx index eabb734cea3..1d8c02c0960 100644 --- a/utilities/wallet-connector/src/common/components/CheckBox.tsx +++ b/utilities/wallet-connector/src/common/components/CheckBox.tsx @@ -11,26 +11,17 @@ type Props = { onChange?: (value: boolean) => void; }; -function CheckBox({ - variant = "checkbox", - value, - label = "", - onChange = noop -}: Props) { +function CheckBox({ variant = "checkbox", value, label = "", onChange = noop }: Props) { return ( ); } -export default CheckBox; \ No newline at end of file +export default CheckBox; diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index 0a770622aa4..cbb08d1b557 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -18,18 +18,28 @@ function InfoItem({ heading, value }: Props) {

{heading}:

{typeof value === "string" ? ( - ) : Array.isArray(value) && value.length ? (
    - {value.map((v) => typeof v === "object" ? JSON.stringify(v) : v).map((v) => ( -
      - -
    - ))} + {value + .map((v) => (typeof v === "object" ? JSON.stringify(v) : v)) + .map((v) => ( +
      + +
    + ))}
) : (

{String(value) || "-"}

@@ -38,4 +48,4 @@ function InfoItem({ heading, value }: Props) { ); } -export default InfoItem; \ No newline at end of file +export default InfoItem; diff --git a/utilities/wallet-connector/src/common/components/InputBlock.tsx b/utilities/wallet-connector/src/common/components/InputBlock.tsx index 86e6a763bca..7b82d8058e6 100644 --- a/utilities/wallet-connector/src/common/components/InputBlock.tsx +++ b/utilities/wallet-connector/src/common/components/InputBlock.tsx @@ -15,11 +15,9 @@ function InputBlock({ variant, name, children }: Props) {

{name}:

-
- {children} -
+
{children}
); } -export default InputBlock; \ No newline at end of file +export default InputBlock; diff --git a/utilities/wallet-connector/src/common/components/WalletCard.tsx b/utilities/wallet-connector/src/common/components/WalletCard.tsx index ab0c7bd7991..4adab89db9a 100644 --- a/utilities/wallet-connector/src/common/components/WalletCard.tsx +++ b/utilities/wallet-connector/src/common/components/WalletCard.tsx @@ -20,27 +20,32 @@ function WalletCard({ name, variant = "checkbox", isEnabledStatusDisplayed = false, - onClick = noop + onClick = noop, }: Props) { return ( - ); } -export default WalletCard; \ No newline at end of file +export default WalletCard; diff --git a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx index 1a37fbcd347..d7b69cd4c77 100644 --- a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx +++ b/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx @@ -29,4 +29,4 @@ function WalletResponseSelection({ wallets, selectedWallet, onSelect = noop }: P ); } -export default WalletResponseSelection; \ No newline at end of file +export default WalletResponseSelection; diff --git a/utilities/wallet-connector/src/common/helpers/cleanHex.ts b/utilities/wallet-connector/src/common/helpers/cleanHex.ts index 82bd2e2c6fd..dcca4b5e4d9 100644 --- a/utilities/wallet-connector/src/common/helpers/cleanHex.ts +++ b/utilities/wallet-connector/src/common/helpers/cleanHex.ts @@ -8,4 +8,4 @@ export default function cleanHex(hexString: string): string { } return cleanedHexString; -} \ No newline at end of file +} diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index b530a6504c0..35aea8d706b 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -10,7 +10,7 @@ export default async function extractApiData(api: WalletApi): Promise(walletName?: T): T extends string ? WalletCollections[string] : WalletCollections { - return walletName - ? globalThis.cardano[walletName] - : globalThis.cardano; -} \ No newline at end of file +export default function getCardano( + walletName?: T +): T extends string ? WalletCollections[string] : WalletCollections { + return walletName ? globalThis.cardano[walletName] : globalThis.cardano; +} diff --git a/utilities/wallet-connector/src/common/helpers/hex2bin.ts b/utilities/wallet-connector/src/common/helpers/hex2bin.ts index bd6031be194..af8906ae4ea 100644 --- a/utilities/wallet-connector/src/common/helpers/hex2bin.ts +++ b/utilities/wallet-connector/src/common/helpers/hex2bin.ts @@ -8,4 +8,4 @@ export default function hex2bin(hexString: string): Uint8Array { ); return new Uint8Array(uint8Array); -} \ No newline at end of file +} diff --git a/utilities/wallet-connector/src/main.tsx b/utilities/wallet-connector/src/main.tsx index 71592e8e0c7..df6f44bde2e 100644 --- a/utilities/wallet-connector/src/main.tsx +++ b/utilities/wallet-connector/src/main.tsx @@ -2,6 +2,4 @@ import ReactDOM from "react-dom/client"; import App from "./App.jsx"; -ReactDOM.createRoot(document.getElementById("root")!).render( - -); +ReactDOM.createRoot(document.getElementById("root")!).render(); diff --git a/utilities/wallet-connector/src/modules/SignDataPanel.tsx b/utilities/wallet-connector/src/modules/SignDataPanel.tsx index 3979cde9c27..6c1b1dc1aa2 100644 --- a/utilities/wallet-connector/src/modules/SignDataPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignDataPanel.tsx @@ -5,7 +5,7 @@ type Props = { walletApi: Record; }; -function SignDataPanel({ }: Props) { +function SignDataPanel({}: Props) { return (
@@ -15,4 +15,4 @@ function SignDataPanel({ }: Props) { ); } -export default SignDataPanel; \ No newline at end of file +export default SignDataPanel; diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx index dc7f8d21642..19fbc96a7d0 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxnPanel.tsx @@ -23,29 +23,25 @@ type FormValues = { tx: string; }; -function SignTxnPanel({ - selectedWallets, - walletApi -}: Props) { +function SignTxnPanel({ selectedWallets, walletApi }: Props) { const [selectedResponseWallet, setSelectedResponseWallet] = useState(""); const { isLoading, mutateAsync, data } = useMutation({ onError: (err) => void toast.error(String(err)), - mutationFn: mutateFn + mutationFn: mutateFn, }); const payloadForm = useForm({ defaultValues: { partialSign: false, - tx: "" - } + tx: "", + }, }); async function mutateFn(args: Parameters): Promise> { - const responses = await Promise.all(selectedWallets.map(async (wallet) => [ - wallet, - await walletApi[wallet]?.signTx(...args) - ])); + const responses = await Promise.all( + selectedWallets.map(async (wallet) => [wallet, await walletApi[wallet]?.signTx(...args)]) + ); setSelectedResponseWallet(responses[0]?.[0] ?? ""); @@ -68,12 +64,14 @@ function SignTxnPanel({
- Requests that a user sign the unsigned portions of the supplied transaction. - The wallet should ask the user for permission, and if given, try to sign the supplied body and return a signed transaction. - If partialSign is true, the wallet only tries to sign what it can. - If partialSign is false and the wallet could not sign the entire transaction, TxSignError shall be returned with the ProofGeneration code. - Likewise if the user declined in either case it shall return the UserDeclined code. - Only the portions of the witness set that were signed as a result of this call are returned to encourage dApps to verify the contents returned by this endpoint while building the final transaction. + Requests that a user sign the unsigned portions of the supplied transaction. The wallet + should ask the user for permission, and if given, try to sign the supplied body and return + a signed transaction. If partialSign is true, the wallet only tries to sign what it can. + If partialSign is false and the wallet could not sign the entire transaction, TxSignError + shall be returned with the ProofGeneration code. Likewise if the user declined in either + case it shall return the UserDeclined code. Only the portions of the witness set that were + signed as a result of this call are returned to encourage dApps to verify the contents + returned by this endpoint while building the final transaction.

Payload:

@@ -101,9 +99,7 @@ function SignTxnPanel({ {isLoading && }
-
- -
+
{data && ( @@ -116,10 +112,7 @@ function SignTxnPanel({ onSelect={handleResponseWalletSelect} />

Response:

- +
)} @@ -127,4 +120,4 @@ function SignTxnPanel({ ); } -export default SignTxnPanel; \ No newline at end of file +export default SignTxnPanel; diff --git a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx index 86db8268803..c394455392a 100644 --- a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx @@ -5,7 +5,7 @@ type Props = { walletApi: Record; }; -function SubmitTxnPanel({ }: Props) { +function SubmitTxnPanel({}: Props) { return (
@@ -15,4 +15,4 @@ function SubmitTxnPanel({ }: Props) { ); } -export default SubmitTxnPanel; \ No newline at end of file +export default SubmitTxnPanel; diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx index 168bbcd4573..86a33b6bec0 100644 --- a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx @@ -9,21 +9,14 @@ import SignDataPanel from "./SignDataPanel"; import SignTxnPanel from "./SignTxnPanel"; import SubmitTxnPanel from "./SubmitTxnPanel"; -const ACTIONS = [ - "Sign Transaction", - "Sign Data", - "Submit Transaction" -]; +const ACTIONS = ["Sign Transaction", "Sign Data", "Submit Transaction"]; type Props = { selectedWallets: string[]; walletApi: Record; }; -function WalletActionsSection({ - walletApi, - selectedWallets -}: Props) { +function WalletActionsSection({ walletApi, selectedWallets }: Props) { return (

Wallet Actions:

@@ -33,7 +26,12 @@ function WalletActionsSection({ {ACTIONS.map((action) => ( {({ selected }) => ( -
+

{action}

{selected && }
@@ -43,22 +41,13 @@ function WalletActionsSection({ - + - + - + @@ -67,4 +56,4 @@ function WalletActionsSection({ ); } -export default WalletActionsSection; \ No newline at end of file +export default WalletActionsSection; diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index f4e4a7df4db..c3363343c89 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -54,7 +54,10 @@ function WalletInfoSection({

Selected wallets: {selectedWallets.length}

-
@@ -65,7 +68,12 @@ function WalletInfoSection({ {selectedWallets.map((wallet) => ( {({ selected }) => ( -
+
icon

{wallet}

{selected && } @@ -78,10 +86,7 @@ function WalletInfoSection({ {selectedWallets.map((wallet) => (
- + - + ) : (
-

Extension

@@ -153,4 +158,4 @@ function WalletInfoSection({ ); } -export default WalletInfoSection; \ No newline at end of file +export default WalletInfoSection; diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index b27fd7b81e3..758dc87811f 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -5,8 +5,8 @@ type Extracted any> = Awaited>; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number; }[]; }): Promise; - supportedExtensions: { cip: number; }[]; + enable(args: { extensions: { cip: number }[] }): Promise; + supportedExtensions: { cip: number }[]; }; }; @@ -26,4 +26,4 @@ export type ExtractedWalletApi = { signTx: cip30.SignTx; signData: cip30.SignData; submitTx: cip30.SubmitTx; -}; \ No newline at end of file +}; From 77ef29bcd209076aab4a2dd3696133b8b6e0b9eb Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 17:47:51 +0700 Subject: [PATCH 29/73] chore: lintfix --- utilities/wallet-connector/Earthfile | 5 +++-- utilities/wallet-connector/src/types/cardano.ts | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/utilities/wallet-connector/Earthfile b/utilities/wallet-connector/Earthfile index 7ed33f26e62..74b751a4fc2 100644 --- a/utilities/wallet-connector/Earthfile +++ b/utilities/wallet-connector/Earthfile @@ -4,7 +4,7 @@ builder: FROM node:20-alpine WORKDIR /app COPY package.json package-lock.json . - COPY index.html postcss.config.js tailwind.config.js tsconfig* vite.config.ts . + COPY index.html postcss.config.js tailwind.config.js tsconfig* vite.config.ts .eslintrc.yaml .prettierrc.yaml . COPY src ./src RUN npm i @@ -12,7 +12,8 @@ builder: check: FROM +builder - RUN npx tsc --noEmit + RUN npm run check \ + && npm run lint build: FROM +builder diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index 758dc87811f..e4e2ac41950 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -5,8 +5,8 @@ type Extracted any> = Awaited>; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number }[] }): Promise; - supportedExtensions: { cip: number }[]; + enable(args: { extensions: { cip: number; }[]; }): Promise; + supportedExtensions: { cip: number; }[]; }; }; From 3f5f2253b4ecc431548268628fa73ed994fdb50f Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 18:00:08 +0700 Subject: [PATCH 30/73] ci: build local --- utilities/wallet-connector/Earthfile | 15 ++++++++++++++- utilities/wallet-connector/nginx.conf | 23 ----------------------- 2 files changed, 14 insertions(+), 24 deletions(-) delete mode 100644 utilities/wallet-connector/nginx.conf diff --git a/utilities/wallet-connector/Earthfile b/utilities/wallet-connector/Earthfile index 74b751a4fc2..2ebc83d0bcf 100644 --- a/utilities/wallet-connector/Earthfile +++ b/utilities/wallet-connector/Earthfile @@ -18,4 +18,17 @@ check: build: FROM +builder - RUN npm run build \ No newline at end of file + RUN npm run build + + SAVE ARTIFACT dist + +local: + FROM nginx:1.25-alpine + + COPY +build/dist /usr/share/nginx/html + + EXPOSE 80 + + CMD ["nginx", "-g", "daemon off;"] + + SAVE IMAGE cat-wallet-connector:latest \ No newline at end of file diff --git a/utilities/wallet-connector/nginx.conf b/utilities/wallet-connector/nginx.conf deleted file mode 100644 index ee0a8bd814b..00000000000 --- a/utilities/wallet-connector/nginx.conf +++ /dev/null @@ -1,23 +0,0 @@ -server { - listen 80; - server_name _; - server_tokens off; - - # timeout - client_body_timeout 12; - client_header_timeout 12; - keepalive_timeout 15; - send_timeout 10; - - location / { - root /usr/share/nginx/html; - index index.html; - try_files $uri $uri/ /index.html; - } - - location ~ ^/(.+)$ { - root /usr/share/nginx/html; - index index.html; - try_files $uri $uri/ /index.html; - } -} From 3e50875509c421c7bdb0d6a1411788145591b984 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 18:04:38 +0700 Subject: [PATCH 31/73] docs: earthfile --- utilities/wallet-connector/Earthfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utilities/wallet-connector/Earthfile b/utilities/wallet-connector/Earthfile index 2ebc83d0bcf..2436613d20e 100644 --- a/utilities/wallet-connector/Earthfile +++ b/utilities/wallet-connector/Earthfile @@ -1,5 +1,6 @@ VERSION --try --global-cache 0.7 +# builder - Installs node packages. builder: FROM node:20-alpine WORKDIR /app @@ -9,12 +10,14 @@ builder: RUN npm i +# check - Runs checks against the source code including type checks and linting. check: FROM +builder RUN npm run check \ && npm run lint +# build - Builds the source code for deployment build: FROM +builder @@ -22,6 +25,7 @@ build: SAVE ARTIFACT dist +# local - Makes a docker image that can serve the docs for development purposes. local: FROM nginx:1.25-alpine From 0ca95b89746877d5066292d17aef872d188d4310 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 18:08:32 +0700 Subject: [PATCH 32/73] fix: copied --- utilities/wallet-connector/src/common/components/InfoItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index cbb08d1b557..0624e04768d 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -11,7 +11,7 @@ function InfoItem({ heading, value }: Props) { async function handleCopy(value: string) { await navigator.clipboard.writeText(value); - toast.success("Value coppied."); + toast.success("Value copied."); } return ( From 4d377fe7b5417dec9e42e3cea3fd7d810a96b272 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 18 Mar 2024 18:18:33 +0700 Subject: [PATCH 33/73] feat: re-enable --- utilities/wallet-connector/src/App.tsx | 7 ++-- .../src/common/components/InfoItem.tsx | 4 +- .../src/modules/WalletInfoSection.tsx | 42 +++++++++---------- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 61bec6caee0..d7e97d79df0 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -50,10 +50,9 @@ function App() { wallets: string[], walletExtArg: Record ) { - const toBeEnabledWallets = (wallets ?? selectedWallets).filter((wallet) => !walletApi[wallet]); - const mappedWalletProp = pickBy(getCardano(), (v, k) => toBeEnabledWallets.includes(k)); + const mappedWalletProp = pickBy(getCardano(), (v, k) => wallets.includes(k)); - setEnablingWallets((prev) => [...prev, ...toBeEnabledWallets]); + setEnablingWallets((prev) => [...prev, ...wallets]); try { const walletApis = await Promise.all( @@ -74,7 +73,7 @@ function App() { } catch (err) { toast.error(String(err)); } finally { - setEnablingWallets((prev) => prev.filter((wallet) => !toBeEnabledWallets.includes(wallet))); + setEnablingWallets((prev) => prev.filter((wallet) => !wallets.includes(wallet))); } } diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index 0624e04768d..efad096f595 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -20,7 +20,7 @@ function InfoItem({ heading, value }: Props) { {typeof value === "string" ? ( -

Extension

- -
)} +
+
+ +

Extension

+ +
))} From ce7bdf66da2e6a3258dd2dd25906638d51becdf1 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Tue, 19 Mar 2024 00:40:54 +0700 Subject: [PATCH 34/73] chore: remove console.log --- utilities/wallet-connector/src/App.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index d7e97d79df0..2af1698aaf6 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -34,8 +34,6 @@ function App() { // wallet name selections const [selectedWallets, setSelectedWallets] = useState([]); - console.log(getCardano()); - const isCardanoActivated = typeof getCardano() !== "undefined"; function handleWalletCardClick(walletName: string) { @@ -67,8 +65,6 @@ function App() { }) ); - console.log("api", walletApis); - setWalletApi((prev) => ({ ...prev, ...Object.fromEntries(walletApis) })); } catch (err) { toast.error(String(err)); From 8e08fab5bc5662b5052a3837ed1db2787529a956 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Wed, 20 Mar 2024 20:56:21 +0700 Subject: [PATCH 35/73] docs: readme --- utilities/wallet-connector/README.md | 39 +++++++++++++++ utilities/wallet-connector/src/App.tsx | 4 +- .../src/common/components/InfoItem.tsx | 8 +++- .../src/common/helpers/extractApiData.ts | 47 +++++++++++++------ .../src/modules/SignTxnPanel.tsx | 5 +- .../src/modules/WalletInfoSection.tsx | 45 +++++------------- .../wallet-connector/src/types/cardano.ts | 1 + 7 files changed, 99 insertions(+), 50 deletions(-) create mode 100644 utilities/wallet-connector/README.md diff --git a/utilities/wallet-connector/README.md b/utilities/wallet-connector/README.md new file mode 100644 index 00000000000..9cf712a64db --- /dev/null +++ b/utilities/wallet-connector/README.md @@ -0,0 +1,39 @@ +# Cardano Utility Wallet Connector + +## Setup Project + +1. Make sure you have the version of Node.js 18 or 20 on your current machine as the requirement to run Vite. +2. Install all dependencies via `npm i`. +3. Done. You can develop the project via the `npm run dev` command, and build the project by running the `npm run build` command. See more scripts in `package.json`. + +Runs the app in the development mode.\ +Open [http://localhost:3000](http://localhost:3000) to view it in your browser. + +## Tools + +- **Scripting**: TypeScript 5 +- **UI Framework**: React 18 +- **Styling**: Tailwind CSS +- **Async State Management**: Tanstack Query +- **UI Components**: Headless UI +- **Utilities**: Lodash +- **Icons**: Material UI Icons +- **Build Tool**: Vite + +## Runs with Earthly + +Type command `earthly +local` to build the app with Nginx wrapped as a web server. + +And run with docker: + +```sh +docker run -p ...:80 -t cat-wallet-connector +``` + +## What it can do: +First step, the tool will scan all accessible wallets installed as browser extensions. +It executes fundamental wallet actions as outlined in [CIP30](https://cips.cardano.org/cip/CIP-30/) including: +- Retrieving wallet details +- Simultaneously signing transactions using multiple wallets +- (WIP) Simultaneously signing data with multiple wallets +- (WIP) Simultaneously submitting transactions using multiple wallets diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 2af1698aaf6..300ea9e99a4 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -59,12 +59,14 @@ function App() { ? await walletProps.enable() : await walletProps.enable({ extensions: [walletExtArg[walletName]] }); - const extractedApi = await extractApiData(api); + const extractedApi = await extractApiData(api, walletExtArg[walletName]?.cip ?? undefined); return [walletName, extractedApi]; }) ); + console.log(walletApis); + setWalletApi((prev) => ({ ...prev, ...Object.fromEntries(walletApis) })); } catch (err) { toast.error(String(err)); diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index efad096f595..ce0cb53d40e 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -5,9 +5,10 @@ import type { ExtensionArguments } from "types/cardano"; type Props = { heading: string; value: string | string[] | null | ExtensionArguments[]; + from?: string; }; -function InfoItem({ heading, value }: Props) { +function InfoItem({ heading, value, from }: Props) { async function handleCopy(value: string) { await navigator.clipboard.writeText(value); @@ -16,7 +17,10 @@ function InfoItem({ heading, value }: Props) { return (
-

{heading}:

+
+
{from?.toUpperCase()}
+

{heading}:

+
{typeof value === "string" ? (
); diff --git a/utilities/wallet-connector/src/common/components/TxBuilder.tsx b/utilities/wallet-connector/src/common/components/TxBuilder.tsx new file mode 100644 index 00000000000..c61a920d431 --- /dev/null +++ b/utilities/wallet-connector/src/common/components/TxBuilder.tsx @@ -0,0 +1,113 @@ +import { Address, AuxiliaryData, BigNum, Ed25519KeyHash, GeneralTransactionMetadata, Transaction, TransactionBuilder, TransactionMetadatum, TransactionOutput, TransactionWitnessSet, Value } from "@emurgo/cardano-serialization-lib-asmjs"; +import { useForm } from "react-hook-form"; + +import { BASE_INPUT_STYLE } from "common/constants"; + +type FormValues = { + regAddress: string; + regAmount: string; + regText: string; + regLabel: string; + stakeCred: string; +}; + +type Props = { + +}; + +function TxBuilder({ }: Props) { + const { handleSubmit, register } = useForm({ + defaultValues: { + + } + }); + + async function buildTx(formValues: FormValues) { + // Initialize builder with protocol parameters + const txBuilder = new TransactionBuilder(); + + // Set address to send ada to + const registrationAddress = Address.from_bech32(formValues.regAddress); + // Set amount to send + const registrationAmount = Value.new(BigNum.from_str(formValues.regAmount)); + + // Set transactional metadatum message + const regMessageMetadatum = TransactionMetadatum.new_text(formValues.regText); + const regMessageMetadatumLabel = BigNum.from_str(formValues.regLabel); + + // Create Tx metadata object and parse into auxiliary data + const txMetadata = (GeneralTransactionMetadata.new()); + txMetadata.insert(regMessageMetadatumLabel, regMessageMetadatum); + const auxMetadata = AuxiliaryData.new(); + auxMetadata.set_metadata(txMetadata); + + // Add metadatum to transaction builder, so it can be included in the transaction balancing + txBuilder.set_auxiliary_data(auxMetadata); + + // Add extra signature witness to transaction builder + txBuilder.add_required_signer(Ed25519KeyHash.from_hex(formValues.stakeCred)); + + // Add outputs to the transaction builder + txBuilder.add_output( + TransactionOutput.new( + registrationAddress, + registrationAmount + ), + ); + + // Find the available UTxOs in the wallet and use them as Inputs for the transaction + const txUnspentOutputs = await this.getTxUnspentOutputs(); + // Use UTxO selection strategy RandomImproveMultiAsset aka 3 + txBuilder.add_inputs_from(txUnspentOutputs, 3); + + // Set change address, incase too much ADA provided for fee + const shelleyChangeAddress = Address.from_bech32(this.state.changeAddress); + txBuilder.add_change_if_needed(shelleyChangeAddress); + + // Make a full transaction, passing in empty witness set + const txBody = txBuilder.build(); + const transactionWitnessSet = TransactionWitnessSet.new(); + const tx = Transaction.new( + txBody, + TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()), + auxMetadata + ); + + // console.log("UnsignedTx: ", Buffer.from(tx.to_bytes(), "utf8").toString("hex")) + } + + async function onSubmit(formValues: FormValues) { + + } + + return ( +
+ + + + +
+ ); +} + +export default TxBuilder; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/TxInput.tsx b/utilities/wallet-connector/src/common/components/TxInput.tsx new file mode 100644 index 00000000000..8f2659bb3bf --- /dev/null +++ b/utilities/wallet-connector/src/common/components/TxInput.tsx @@ -0,0 +1,40 @@ +import { noop } from "lodash-es"; +import { useState } from "react"; +import { twMerge } from "tailwind-merge"; + +import CBOREditor from "./CBOREditor"; +import TxBuilder from "./TxBuilder"; + +type Mode = "raw" | "builder"; + +type Props = { + value: string; + isReadOnly?: boolean; + onChange?: (value: string) => void; +}; + +function TxInput({ value, isReadOnly = false, onChange = noop }: Props) { + const [mode, setMode] = useState("raw"); + + return ( +
+
+ + +
+
+ {mode === "raw" ? ( + + ) : ( + + )} +
+
+ ); +} + +export default TxInput; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/constants/index.ts b/utilities/wallet-connector/src/common/constants/index.ts new file mode 100644 index 00000000000..cb25e757ee4 --- /dev/null +++ b/utilities/wallet-connector/src/common/constants/index.ts @@ -0,0 +1 @@ +export const BASE_INPUT_STYLE = "rounded-md border border-solid border-black/10 p-2"; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index 3b82baa3918..71899e836bd 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -1,10 +1,12 @@ import type { WalletApi } from "@cardano-sdk/cip30"; +import { Address, TransactionUnspentOutput, Value } from "@emurgo/cardano-serialization-lib-asmjs"; import { camelCase, mapValues } from "lodash-es"; export default async function extractApiData(api: WalletApi, cipExt?: number): Promise { - const safeTry = async (fn: () => Promise): Promise => { + const safeTry = async (fn: () => Promise, transformer?: (v: T) => T): Promise => { try { - return await fn(); + const v = await fn(); + return transformer ? transformer(v) : v; } catch (err) { return `Failed: ${String(err)}` as T; } @@ -32,13 +34,13 @@ export default async function extractApiData(api: WalletApi, cipExt?: number): P info: { ...mapValues({ networkId: await safeTry(api.getNetworkId), - utxos: await safeTry(api.getUtxos), - balance: await safeTry(api.getBalance), + utxos: await safeTry(api.getUtxos, (v) => v?.map((v) => TransactionUnspentOutput.from_hex(v).to_json())), + balance: await safeTry(api.getBalance, (v) => Number(Value.from_hex(v).coin().to_str()).toLocaleString("en")), collateral: await safeTry(api.getCollateral), - usedAddresses: await safeTry(api.getUsedAddresses), - unusedAddresses: await safeTry(api.getUnusedAddresses), - changeAddress: await safeTry(api.getChangeAddress), - rewardAddresses: await safeTry(api.getRewardAddresses), + usedAddresses: await safeTry(api.getUsedAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v), + unusedAddresses: await safeTry(api.getUnusedAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v), + changeAddress: await safeTry(api.getChangeAddress, (v) => Address.from_hex(v).to_bech32()), + rewardAddresses: await safeTry(api.getRewardAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v), }, (v) => ({ from: "cip30", value: v })), ...extData } diff --git a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx similarity index 95% rename from utilities/wallet-connector/src/modules/SignTxnPanel.tsx rename to utilities/wallet-connector/src/modules/SignTxPanel.tsx index edf983e5b14..ff503453442 100644 --- a/utilities/wallet-connector/src/modules/SignTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -12,6 +12,7 @@ import InputBlock from "common/components/InputBlock"; import WalletResponseSelection from "common/components/WalletResponseSelection"; import cleanHex from "common/helpers/cleanHex"; import type { ExtractedWalletApi } from "types/cardano"; +import TxInput from "common/components/TxInput"; type Props = { selectedWallets: string[]; @@ -23,7 +24,7 @@ type FormValues = { tx: string; }; -function SignTxnPanel({ selectedWallets, walletApi }: Props) { +function SignTxPanel({ selectedWallets, walletApi }: Props) { const [selectedResponseWallet, setSelectedResponseWallet] = useState(""); const { isLoading, mutateAsync, data } = useMutation({ @@ -91,7 +92,7 @@ function SignTxnPanel({ selectedWallets, walletApi }: Props) { control={payloadForm.control} name="tx" render={({ field: { value, onChange } }) => ( - + )} /> @@ -123,4 +124,4 @@ function SignTxnPanel({ selectedWallets, walletApi }: Props) { ); } -export default SignTxnPanel; +export default SignTxPanel; diff --git a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx b/utilities/wallet-connector/src/modules/SubmitTxPanel.tsx similarity index 83% rename from utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx rename to utilities/wallet-connector/src/modules/SubmitTxPanel.tsx index c394455392a..0c675fb508d 100644 --- a/utilities/wallet-connector/src/modules/SubmitTxnPanel.tsx +++ b/utilities/wallet-connector/src/modules/SubmitTxPanel.tsx @@ -5,7 +5,7 @@ type Props = { walletApi: Record; }; -function SubmitTxnPanel({}: Props) { +function SubmitTxPanel({}: Props) { return (
@@ -15,4 +15,4 @@ function SubmitTxnPanel({}: Props) { ); } -export default SubmitTxnPanel; +export default SubmitTxPanel; diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx index 86a33b6bec0..df0c3816b03 100644 --- a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletActionsSection.tsx @@ -6,8 +6,8 @@ import { twMerge } from "tailwind-merge"; import type { ExtractedWalletApi } from "types/cardano"; import SignDataPanel from "./SignDataPanel"; -import SignTxnPanel from "./SignTxnPanel"; -import SubmitTxnPanel from "./SubmitTxnPanel"; +import SignTxPanel from "./SignTxPanel"; +import SubmitTxPanel from "./SubmitTxPanel"; const ACTIONS = ["Sign Transaction", "Sign Data", "Submit Transaction"]; @@ -41,13 +41,13 @@ function WalletActionsSection({ walletApi, selectedWallets }: Props) { - + - + diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index 448fa94d6ed..9287fd10ee8 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -8,6 +8,7 @@ import { twMerge } from "tailwind-merge"; import Button from "common/components/Button"; import InfoItem from "common/components/InfoItem"; +import { BASE_INPUT_STYLE } from "common/constants"; import getCardano from "common/helpers/getCardano"; import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; @@ -114,7 +115,7 @@ function WalletInfoSection({

Extension

Date: Thu, 21 Mar 2024 17:39:51 +0700 Subject: [PATCH 37/73] feat: unsigned tx function --- utilities/wallet-connector/package-lock.json | 62 -------------- utilities/wallet-connector/package.json | 1 - .../src/common/components/InfoItem.tsx | 81 +++++++++++-------- .../src/common/components/TxBuilder.tsx | 55 ------------- .../src/common/helpers/extractApiData.ts | 18 ++++- .../src/modules/WalletInfoSection.tsx | 3 +- 6 files changed, 63 insertions(+), 157 deletions(-) diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index b79f1e4b00f..f730cb3f064 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -15,7 +15,6 @@ "@mui/icons-material": "^5.15.13", "@mui/material": "^5.15.13", "ace-builds": "^1.32.7", - "buffer": "^6.0.3", "cborg": "^4.1.1", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", @@ -2866,25 +2865,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", @@ -2979,29 +2959,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/bufferutil": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", @@ -4587,25 +4544,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index fcc4d31646e..2229f75f305 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -21,7 +21,6 @@ "@mui/icons-material": "^5.15.13", "@mui/material": "^5.15.13", "ace-builds": "^1.32.7", - "buffer": "^6.0.3", "cborg": "^4.1.1", "dayjs": "^1.11.10", "lodash-es": "^4.17.21", diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index 136383f7e00..7b87be4b1a1 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -1,3 +1,4 @@ +import { Disclosure } from "@headlessui/react"; import { toast } from "react-toastify"; import type { ExtensionArguments } from "types/cardano"; @@ -5,10 +6,11 @@ import type { ExtensionArguments } from "types/cardano"; type Props = { heading: string; value: string | string[] | null | ExtensionArguments[]; + raw?: string; from?: string; }; -function InfoItem({ heading, value, from }: Props) { +function InfoItem({ heading, value, raw, from }: Props) { async function handleCopy(value: string) { await navigator.clipboard.writeText(value); @@ -16,39 +18,50 @@ function InfoItem({ heading, value, from }: Props) { } return ( -
-
-
{from?.toUpperCase()}
-

{heading}:

-
- {typeof value === "string" ? ( - - ) : Array.isArray(value) && value.length ? ( -
    - {value - .map((v) => (typeof v === "object" ? JSON.stringify(v) : v)) - .map((v) => ( -
      - -
    - ))} -
- ) : ( -

{String(value) || "-"}

- )} -
+ + +
+
{from?.toUpperCase()}
+

{heading}:

+
+
+ + {typeof raw !== "undefined" && Boolean(String(raw)) && ( +
+ +
+ )} + {typeof value === "string" ? ( + + ) : Array.isArray(value) && value.length ? ( +
    + {value + .map((v) => (typeof v === "object" ? JSON.stringify(v) : v)) + .map((v) => ( +
      + +
    + ))} +
+ ) : ( +

{String(value) || "-"}

+ )} +
+
); } diff --git a/utilities/wallet-connector/src/common/components/TxBuilder.tsx b/utilities/wallet-connector/src/common/components/TxBuilder.tsx index c61a920d431..cd7d01dd7d2 100644 --- a/utilities/wallet-connector/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-connector/src/common/components/TxBuilder.tsx @@ -1,4 +1,3 @@ -import { Address, AuxiliaryData, BigNum, Ed25519KeyHash, GeneralTransactionMetadata, Transaction, TransactionBuilder, TransactionMetadatum, TransactionOutput, TransactionWitnessSet, Value } from "@emurgo/cardano-serialization-lib-asmjs"; import { useForm } from "react-hook-form"; import { BASE_INPUT_STYLE } from "common/constants"; @@ -22,60 +21,6 @@ function TxBuilder({ }: Props) { } }); - async function buildTx(formValues: FormValues) { - // Initialize builder with protocol parameters - const txBuilder = new TransactionBuilder(); - - // Set address to send ada to - const registrationAddress = Address.from_bech32(formValues.regAddress); - // Set amount to send - const registrationAmount = Value.new(BigNum.from_str(formValues.regAmount)); - - // Set transactional metadatum message - const regMessageMetadatum = TransactionMetadatum.new_text(formValues.regText); - const regMessageMetadatumLabel = BigNum.from_str(formValues.regLabel); - - // Create Tx metadata object and parse into auxiliary data - const txMetadata = (GeneralTransactionMetadata.new()); - txMetadata.insert(regMessageMetadatumLabel, regMessageMetadatum); - const auxMetadata = AuxiliaryData.new(); - auxMetadata.set_metadata(txMetadata); - - // Add metadatum to transaction builder, so it can be included in the transaction balancing - txBuilder.set_auxiliary_data(auxMetadata); - - // Add extra signature witness to transaction builder - txBuilder.add_required_signer(Ed25519KeyHash.from_hex(formValues.stakeCred)); - - // Add outputs to the transaction builder - txBuilder.add_output( - TransactionOutput.new( - registrationAddress, - registrationAmount - ), - ); - - // Find the available UTxOs in the wallet and use them as Inputs for the transaction - const txUnspentOutputs = await this.getTxUnspentOutputs(); - // Use UTxO selection strategy RandomImproveMultiAsset aka 3 - txBuilder.add_inputs_from(txUnspentOutputs, 3); - - // Set change address, incase too much ADA provided for fee - const shelleyChangeAddress = Address.from_bech32(this.state.changeAddress); - txBuilder.add_change_if_needed(shelleyChangeAddress); - - // Make a full transaction, passing in empty witness set - const txBody = txBuilder.build(); - const transactionWitnessSet = TransactionWitnessSet.new(); - const tx = Transaction.new( - txBody, - TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()), - auxMetadata - ); - - // console.log("UnsignedTx: ", Buffer.from(tx.to_bytes(), "utf8").toString("hex")) - } - async function onSubmit(formValues: FormValues) { } diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index 71899e836bd..3b8f21f5aa6 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -3,12 +3,22 @@ import { Address, TransactionUnspentOutput, Value } from "@emurgo/cardano-serial import { camelCase, mapValues } from "lodash-es"; export default async function extractApiData(api: WalletApi, cipExt?: number): Promise { - const safeTry = async (fn: () => Promise, transformer?: (v: T) => T): Promise => { + const safeTry = async (fn: () => Promise, transformer?: (v: T) => T): Promise<{ raw: T; formatted: T; }> => { try { const v = await fn(); - return transformer ? transformer(v) : v; + return transformer ? { + raw: v, + formatted: transformer(v) + } : { + raw: v, + formatted: v + }; } catch (err) { - return `Failed: ${String(err)}` as T; + const fmtErr = `Failed: ${String(err)}` as T; + return { + raw: fmtErr, + formatted: fmtErr + }; } }; @@ -41,7 +51,7 @@ export default async function extractApiData(api: WalletApi, cipExt?: number): P unusedAddresses: await safeTry(api.getUnusedAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v), changeAddress: await safeTry(api.getChangeAddress, (v) => Address.from_hex(v).to_bech32()), rewardAddresses: await safeTry(api.getRewardAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v), - }, (v) => ({ from: "cip30", value: v })), + }, (v) => ({ from: "cip30", raw: v.raw, value: v.formatted })), ...extData } }; diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index 9287fd10ee8..2c3cff7e43c 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -95,11 +95,12 @@ function WalletInfoSection({
{Boolean(walletApi[wallet]) && (
- {Object.entries(walletApi[wallet]?.["info"] ?? {}).map(([key, { from, value }]: [string, any]) => ( + {Object.entries(walletApi[wallet]?.["info"] ?? {}).map(([key, { from, value, raw }]: [string, any]) => ( ))} From bbf18a8082a3b5698a95d41fc555250a62bc1438 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 21 Mar 2024 20:55:45 +0700 Subject: [PATCH 38/73] feat: tx builder interaction --- utilities/wallet-connector/src/App.tsx | 5 +- .../src/common/components/InfoItem.tsx | 4 +- .../src/common/components/TxBuilder.tsx | 48 ++++---- .../src/common/components/TxInput.tsx | 40 ------- .../src/common/constants/index.ts | 2 +- .../src/common/helpers/buildUnsingedReg.ts | 103 ++++++++++++++++++ .../src/common/helpers/extractApiData.ts | 69 ++++++++---- .../src/modules/SignTxPanel.tsx | 30 ++++- .../src/modules/WalletInfoSection.tsx | 26 +++-- .../wallet-connector/src/types/cardano.ts | 14 ++- 10 files changed, 239 insertions(+), 102 deletions(-) delete mode 100644 utilities/wallet-connector/src/common/components/TxInput.tsx create mode 100644 utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 300ea9e99a4..8366bd2aae0 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -59,7 +59,10 @@ function App() { ? await walletProps.enable() : await walletProps.enable({ extensions: [walletExtArg[walletName]] }); - const extractedApi = await extractApiData(api, walletExtArg[walletName]?.cip ?? undefined); + const extractedApi = await extractApiData( + api, + walletExtArg[walletName]?.cip ?? undefined + ); return [walletName, extractedApi]; }) diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-connector/src/common/components/InfoItem.tsx index 7b87be4b1a1..34abf512472 100644 --- a/utilities/wallet-connector/src/common/components/InfoItem.tsx +++ b/utilities/wallet-connector/src/common/components/InfoItem.tsx @@ -29,7 +29,9 @@ function InfoItem({ heading, value, raw, from }: Props) { {typeof raw !== "undefined" && Boolean(String(raw)) && (
)} diff --git a/utilities/wallet-connector/src/common/components/TxBuilder.tsx b/utilities/wallet-connector/src/common/components/TxBuilder.tsx index cd7d01dd7d2..f78716a0959 100644 --- a/utilities/wallet-connector/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-connector/src/common/components/TxBuilder.tsx @@ -1,32 +1,32 @@ +import { noop } from "lodash-es"; import { useForm } from "react-hook-form"; import { BASE_INPUT_STYLE } from "common/constants"; +import type { TxBuilderArguments } from "types/cardano"; -type FormValues = { - regAddress: string; - regAmount: string; - regText: string; - regLabel: string; - stakeCred: string; -}; +import Button from "./Button"; -type Props = { +type FormValues = TxBuilderArguments; +type Props = { + onSubmit?: (value: FormValues) => void; }; -function TxBuilder({ }: Props) { - const { handleSubmit, register } = useForm({ - defaultValues: { - - } +function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { + const { handleSubmit, register, reset } = useForm({ + defaultValues: {}, }); - async function onSubmit(formValues: FormValues) { + function handleReset() { + reset(); + } + async function onSubmit(formValues: FormValues) { + onPropSubmit(formValues); } return ( -
+ +
+ + +
); } -export default TxBuilder; \ No newline at end of file +export default TxBuilder; diff --git a/utilities/wallet-connector/src/common/components/TxInput.tsx b/utilities/wallet-connector/src/common/components/TxInput.tsx deleted file mode 100644 index 8f2659bb3bf..00000000000 --- a/utilities/wallet-connector/src/common/components/TxInput.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { noop } from "lodash-es"; -import { useState } from "react"; -import { twMerge } from "tailwind-merge"; - -import CBOREditor from "./CBOREditor"; -import TxBuilder from "./TxBuilder"; - -type Mode = "raw" | "builder"; - -type Props = { - value: string; - isReadOnly?: boolean; - onChange?: (value: string) => void; -}; - -function TxInput({ value, isReadOnly = false, onChange = noop }: Props) { - const [mode, setMode] = useState("raw"); - - return ( -
-
- - -
-
- {mode === "raw" ? ( - - ) : ( - - )} -
-
- ); -} - -export default TxInput; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/constants/index.ts b/utilities/wallet-connector/src/common/constants/index.ts index cb25e757ee4..20b127c8394 100644 --- a/utilities/wallet-connector/src/common/constants/index.ts +++ b/utilities/wallet-connector/src/common/constants/index.ts @@ -1 +1 @@ -export const BASE_INPUT_STYLE = "rounded-md border border-solid border-black/10 p-2"; \ No newline at end of file +export const BASE_INPUT_STYLE = "rounded-md border border-solid border-black/10 p-2"; diff --git a/utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts b/utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts new file mode 100644 index 00000000000..69fab619377 --- /dev/null +++ b/utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts @@ -0,0 +1,103 @@ +import { + Address, + AuxiliaryData, + BaseAddress, + BigNum, + Ed25519KeyHash, + GeneralTransactionMetadata, + Transaction, + TransactionBuilder, + TransactionMetadatum, + TransactionOutput, + TransactionUnspentOutput, + TransactionUnspentOutputs, + TransactionWitnessSet, + Value, +} from "@emurgo/cardano-serialization-lib-asmjs"; + +type Payload = { + /** Raw registration address in hex string. */ + regAddress: string; + /** String number in lovelace unit. */ + regAmount: string; + /** Transaction metadatum text, e.g., Cardano Wallet Tester. */ + regText: string; + /** Transaction metadatum label, e.g., 98117105100108. */ + regLabel: string; + /** Raw hex string address from `API.getUsedAddresses()`. */ + usedAddresses: string[]; + /** Raw hex string address from `API.getChangeAddress()`. */ + changeAddress: string; + /** Raw hex string UTXOs directed from calling `API.getUtxos()`. */ + rawUtxos: string[]; +}; + +export default async function buildUnsingedReg(payload: Payload): Promise { + console.log(payload); + + // Initialize builder with protocol parameters + const txBuilder = new TransactionBuilder(); + + // Set address to send ada to + const registrationAddress = Address.from_bech32(payload.regAddress); + + // Set amount to send + const registrationAmount = Value.new(BigNum.from_str(payload.regAmount)); + + // Set transactional metadatum message + const regMessageMetadatum = TransactionMetadatum.new_text(payload.regText); + const regMessageMetadatumLabel = BigNum.from_str(payload.regLabel); + + // Create Tx metadata object and parse into auxiliary data + const txMetadata = GeneralTransactionMetadata.new(); + txMetadata.insert(regMessageMetadatumLabel, regMessageMetadatum); + const auxMetadata = AuxiliaryData.new(); + auxMetadata.set_metadata(txMetadata); + + console.log("passsss"); + + // Add metadatum to transaction builder, so it can be included in the transaction balancing + txBuilder.set_auxiliary_data(auxMetadata); + + // Add extra signature witness to transaction builder + if (!payload.usedAddresses[0]) { + throw new Error("cannot find any used address"); + } + + const stakeCred = BaseAddress.from_address(Address.from_hex(payload.usedAddresses[0])) + ?.stake_cred() + .to_keyhash() + ?.to_hex(); + + if (!stakeCred) { + throw new Error("cannot create a stake credential"); + } + + txBuilder.add_required_signer(Ed25519KeyHash.from_hex(stakeCred)); + + // Add outputs to the transaction builder + txBuilder.add_output(TransactionOutput.new(registrationAddress, registrationAmount)); + + // Find the available UTxOs in the wallet and use them as Inputs for the transaction + const txUnspentOutputs = payload.rawUtxos.reduce((acc, utxo) => { + acc.add(TransactionUnspentOutput.from_hex(utxo)); + return acc; + }, TransactionUnspentOutputs.new()); + // Use UTxO selection strategy RandomImproveMultiAsset aka 3 + txBuilder.add_inputs_from(txUnspentOutputs, 3); + + // Set change address, incase too much ADA provided for fee + const shelleyChangeAddress = Address.from_bech32(payload.changeAddress); + txBuilder.add_change_if_needed(shelleyChangeAddress); + + // Make a full transaction, passing in empty witness set + const txBody = txBuilder.build(); + const transactionWitnessSet = TransactionWitnessSet.new(); + const unsingedTx = Transaction.new( + txBody, + TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()), + auxMetadata + ); + + return unsingedTx; +} diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index 3b8f21f5aa6..fc9e51b786e 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -3,21 +3,26 @@ import { Address, TransactionUnspentOutput, Value } from "@emurgo/cardano-serial import { camelCase, mapValues } from "lodash-es"; export default async function extractApiData(api: WalletApi, cipExt?: number): Promise { - const safeTry = async (fn: () => Promise, transformer?: (v: T) => T): Promise<{ raw: T; formatted: T; }> => { + const safeTry = async ( + fn: () => Promise, + transformer?: (v: T) => T + ): Promise<{ raw: T; formatted: T }> => { try { const v = await fn(); - return transformer ? { - raw: v, - formatted: transformer(v) - } : { - raw: v, - formatted: v - }; + return transformer + ? { + raw: v, + formatted: transformer(v), + } + : { + raw: v, + formatted: v, + }; } catch (err) { const fmtErr = `Failed: ${String(err)}` as T; return { raw: fmtErr, - formatted: fmtErr + formatted: fmtErr, }; } }; @@ -31,8 +36,8 @@ export default async function extractApiData(api: WalletApi, cipExt?: number): P camelCase(key.slice(3)), { from: `cip${cipExt}`, - value: await value?.() - } + value: await value?.(), + }, ]); } } @@ -42,17 +47,35 @@ export default async function extractApiData(api: WalletApi, cipExt?: number): P return { ...api, info: { - ...mapValues({ - networkId: await safeTry(api.getNetworkId), - utxos: await safeTry(api.getUtxos, (v) => v?.map((v) => TransactionUnspentOutput.from_hex(v).to_json())), - balance: await safeTry(api.getBalance, (v) => Number(Value.from_hex(v).coin().to_str()).toLocaleString("en")), - collateral: await safeTry(api.getCollateral), - usedAddresses: await safeTry(api.getUsedAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v), - unusedAddresses: await safeTry(api.getUnusedAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v), - changeAddress: await safeTry(api.getChangeAddress, (v) => Address.from_hex(v).to_bech32()), - rewardAddresses: await safeTry(api.getRewardAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v), - }, (v) => ({ from: "cip30", raw: v.raw, value: v.formatted })), - ...extData - } + ...mapValues( + { + networkId: await safeTry(api.getNetworkId), + utxos: await safeTry(api.getUtxos, (v) => + v?.map((v) => TransactionUnspentOutput.from_hex(v).to_json()) + ), + balance: await safeTry(api.getBalance, (v) => + Number(Value.from_hex(v).coin().to_str()).toLocaleString("en") + ), + collateral: await safeTry(api.getCollateral), + usedAddresses: await safeTry( + api.getUsedAddresses, + (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v + ), + unusedAddresses: await safeTry( + api.getUnusedAddresses, + (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v + ), + changeAddress: await safeTry(api.getChangeAddress, (v) => + Address.from_hex(v).to_bech32() + ), + rewardAddresses: await safeTry( + api.getRewardAddresses, + (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v + ), + }, + (v) => ({ from: "cip30", raw: v.raw, value: v.formatted }) + ), + ...extData, + }, }; } diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx index ff503453442..9d463ccc396 100644 --- a/utilities/wallet-connector/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -9,10 +9,11 @@ import Button from "common/components/Button"; import CBOREditor from "common/components/CBOREditor"; import CheckBox from "common/components/CheckBox"; import InputBlock from "common/components/InputBlock"; +import TxBuilder from "common/components/TxBuilder"; import WalletResponseSelection from "common/components/WalletResponseSelection"; +import buildUnsingedReg from "common/helpers/buildUnsingedReg"; import cleanHex from "common/helpers/cleanHex"; -import type { ExtractedWalletApi } from "types/cardano"; -import TxInput from "common/components/TxInput"; +import type { ExtractedWalletApi, TxBuilderArguments } from "types/cardano"; type Props = { selectedWallets: string[]; @@ -56,6 +57,26 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { setSelectedResponseWallet(wallet); } + async function handleTxBuilderSubmit(builderArgs: TxBuilderArguments) { + try { + const lace = walletApi["lace"]; + + const tx = await buildUnsingedReg({ + regAddress: builderArgs.regAddress, + regAmount: builderArgs.regAmount, + regLabel: builderArgs.regLabel, + regText: builderArgs.regText, + usedAddresses: lace.info.usedAddresses.raw, + changeAddress: lace.info.changeAddress.raw, + rawUtxos: lace.info.utxos.raw, + }); + + console.log("UnsignedTx:", tx.to_hex()); + } catch (err) { + return void toast.error(String(err)); + } + } + async function handleExecute(formValues: FormValues) { if (!selectedWallets.length) { return void toast.error("Please select at least one wallet to execute."); @@ -92,7 +113,10 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { control={payloadForm.control} name="tx" render={({ field: { value, onChange } }) => ( - +
+ + +
)} /> diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index 2c3cff7e43c..f886f03b08f 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -86,7 +86,11 @@ function WalletInfoSection({ {selectedWallets.map((wallet) => (
- + {Boolean(walletApi[wallet]) && (
- {Object.entries(walletApi[wallet]?.["info"] ?? {}).map(([key, { from, value, raw }]: [string, any]) => ( - - ))} + {Object.entries(walletApi[wallet]?.["info"] ?? {}).map( + ([key, { from, value, raw }]: [string, any]) => ( + + ) + )}
)}
diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index 4cb0c6b5972..5b4b7a0367a 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -5,8 +5,8 @@ type Extracted any> = Awaited>; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number; }[]; }): Promise; - supportedExtensions: { cip: number; }[]; + enable(args: { extensions: { cip: number }[] }): Promise; + supportedExtensions: { cip: number }[]; }; }; @@ -26,5 +26,13 @@ export type ExtractedWalletApi = { signTx: cip30.SignTx; signData: cip30.SignData; submitTx: cip30.SubmitTx; - [key: string]: any + [key: string]: any; +}; + +export type TxBuilderArguments = { + regAddress: string; + regAmount: string; + regText: string; + regLabel: string; + stakeCred: string; }; From 51c06a9067eca8817ac487df6d0797c0c20940a5 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 16:06:27 +0700 Subject: [PATCH 39/73] feat: advanced config --- utilities/wallet-connector/package.json | 3 +- .../src/common/components/Input.tsx | 31 +++++ .../src/common/components/TxBuilder.tsx | 114 ++++++++++++++---- .../src/common/constants/index.ts | 1 - .../src/common/helpers/buildUnsingedReg.ts | 28 ++++- .../src/modules/SignTxPanel.tsx | 26 ++-- .../src/modules/WalletInfoSection.tsx | 9 +- .../wallet-connector/src/types/cardano.ts | 18 ++- 8 files changed, 185 insertions(+), 45 deletions(-) create mode 100644 utilities/wallet-connector/src/common/components/Input.tsx delete mode 100644 utilities/wallet-connector/src/common/constants/index.ts diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index 2229f75f305..199faf5726f 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -9,8 +9,7 @@ "check": "tsc --noEmit", "lint": "eslint './src/**/*.{ts,tsx}'", "lintfix": "eslint './src/**/*.{ts,tsx}' --fix", - "prettier": "prettier --write './src/**/*.{ts,tsx}'", - "fmt": "npm run prettier && npm run fix:scripts", + "fmt": "prettier --write './src/**/*.{ts,tsx}'", "preview": "vite preview" }, "dependencies": { diff --git a/utilities/wallet-connector/src/common/components/Input.tsx b/utilities/wallet-connector/src/common/components/Input.tsx new file mode 100644 index 00000000000..b748cebdb40 --- /dev/null +++ b/utilities/wallet-connector/src/common/components/Input.tsx @@ -0,0 +1,31 @@ +import { useId, type InputHTMLAttributes } from "react"; +import type { UseFormRegisterReturn } from "react-hook-form"; + +type Props = { + label: string; + formRegister?: UseFormRegisterReturn; +} & InputHTMLAttributes; + +function Input({ label, formRegister, ...props }: Props) { + const id = useId(); + + return ( +
+ + +
+ ); +} + +export default Input; diff --git a/utilities/wallet-connector/src/common/components/TxBuilder.tsx b/utilities/wallet-connector/src/common/components/TxBuilder.tsx index f78716a0959..254fa7f713d 100644 --- a/utilities/wallet-connector/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-connector/src/common/components/TxBuilder.tsx @@ -1,10 +1,28 @@ -import { noop } from "lodash-es"; +import { Disclosure } from "@headlessui/react"; +import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; +import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp"; +import { cloneDeep, noop } from "lodash-es"; import { useForm } from "react-hook-form"; -import { BASE_INPUT_STYLE } from "common/constants"; import type { TxBuilderArguments } from "types/cardano"; import Button from "./Button"; +import Input from "./Input"; + +const PROTOCOL_PARAMS = { + linearFee: { + minFeeA: "44", + minFeeB: "155381", + }, + minUtxo: "34482", + poolDeposit: "500000000", + keyDeposit: "2000000", + maxValSize: 5000, + maxTxSize: 16384, + priceMem: 0.0577, + priceStep: 0.0000721, + coinsPerUtxoWord: "34482", +} as const; type FormValues = TxBuilderArguments; @@ -14,7 +32,14 @@ type Props = { function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { const { handleSubmit, register, reset } = useForm({ - defaultValues: {}, + defaultValues: { + regAddress: "", + regAmount: "", + regText: "", + regLabel: "", + stakeCred: "", + config: cloneDeep(PROTOCOL_PARAMS) + }, }); function handleReset() { @@ -27,30 +52,77 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { return (
- - - - + + + {({ open }) => ( + <> +
+ {open ? : } +
+

Advanced Configs

+ + )} +
+ +
+ + +
+ + + + + +
+
{isLoading && } diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index f886f03b08f..7a939ff8242 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -8,7 +8,7 @@ import { twMerge } from "tailwind-merge"; import Button from "common/components/Button"; import InfoItem from "common/components/InfoItem"; -import { BASE_INPUT_STYLE } from "common/constants"; +import Input from "common/components/Input"; import getCardano from "common/helpers/getCardano"; import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; @@ -121,11 +121,10 @@ function WalletInfoSection({

{walletApi[wallet] ? "Re-Enable" : "Enable"}

Extension

-
diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index 5b4b7a0367a..f62f0d04d65 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -5,8 +5,8 @@ type Extracted any> = Awaited>; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number }[] }): Promise; - supportedExtensions: { cip: number }[]; + enable(args: { extensions: { cip: number; }[]; }): Promise; + supportedExtensions: { cip: number; }[]; }; }; @@ -35,4 +35,18 @@ export type TxBuilderArguments = { regText: string; regLabel: string; stakeCred: string; + config: { + linearFee: { + minFeeA: string; + minFeeB: string; + }; + minUtxo: string; + poolDeposit: string; + keyDeposit: string; + maxValSize: number; + maxTxSize: number; + priceMem: number; + priceStep: number; + coinsPerUtxoWord: string; + }; }; From 0493fda3449f4dae7bdc801eb9f6022cdd8f0c28 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 16:08:55 +0700 Subject: [PATCH 40/73] chore: lintfix --- .../wallet-connector/src/common/helpers/buildUnsingedReg.ts | 1 + utilities/wallet-connector/src/common/helpers/extractApiData.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts b/utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts index 8022d3a657b..cde383b1597 100644 --- a/utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts +++ b/utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts @@ -16,6 +16,7 @@ import { TransactionWitnessSet, Value, } from "@emurgo/cardano-serialization-lib-asmjs"; + import type { TxBuilderArguments } from "types/cardano"; type Payload = { diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index fc9e51b786e..4ef8f67c8d0 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -6,7 +6,7 @@ export default async function extractApiData(api: WalletApi, cipExt?: number): P const safeTry = async ( fn: () => Promise, transformer?: (v: T) => T - ): Promise<{ raw: T; formatted: T }> => { + ): Promise<{ raw: T; formatted: T; }> => { try { const v = await fn(); return transformer From 90dd87f12d984c82f7a7f64768809efb47e6c1cb Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 16:55:36 +0700 Subject: [PATCH 41/73] feat: badge --- .../src/common/components/Badge.tsx | 19 +++++++ ...eSelection.tsx => WalletViewSelection.tsx} | 4 +- .../src/modules/SignTxPanel.tsx | 55 ++++++++++++++----- .../src/modules/WalletInfoSection.tsx | 8 +-- .../wallet-connector/src/styles/global.css | 4 ++ 5 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 utilities/wallet-connector/src/common/components/Badge.tsx rename utilities/wallet-connector/src/common/components/{WalletResponseSelection.tsx => WalletViewSelection.tsx} (81%) diff --git a/utilities/wallet-connector/src/common/components/Badge.tsx b/utilities/wallet-connector/src/common/components/Badge.tsx new file mode 100644 index 00000000000..036daf8ef8f --- /dev/null +++ b/utilities/wallet-connector/src/common/components/Badge.tsx @@ -0,0 +1,19 @@ +import WarningIcon from "@mui/icons-material/Warning"; + +type Props = { + variant: "warn"; + text: string; +}; + +function Badge({ text }: Props) { + return ( +
+
+ +

{text}

+
+
+ ); +} + +export default Badge; \ No newline at end of file diff --git a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx b/utilities/wallet-connector/src/common/components/WalletViewSelection.tsx similarity index 81% rename from utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx rename to utilities/wallet-connector/src/common/components/WalletViewSelection.tsx index d7b69cd4c77..ab1d3e8f6a3 100644 --- a/utilities/wallet-connector/src/common/components/WalletResponseSelection.tsx +++ b/utilities/wallet-connector/src/common/components/WalletViewSelection.tsx @@ -8,7 +8,7 @@ type Props = { onSelect: (wallet: string) => void; }; -function WalletResponseSelection({ wallets, selectedWallet, onSelect = noop }: Props) { +function WalletViewSelection({ wallets, selectedWallet, onSelect = noop }: Props) { if (!wallets.length) { return null; } @@ -29,4 +29,4 @@ function WalletResponseSelection({ wallets, selectedWallet, onSelect = noop }: P ); } -export default WalletResponseSelection; +export default WalletViewSelection; diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx index 693f8e2fb4e..928404c8bee 100644 --- a/utilities/wallet-connector/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -2,17 +2,18 @@ import type { SignTx } from "@cardano-sdk/cip30"; import { Transaction } from "@emurgo/cardano-serialization-lib-asmjs"; import RefreshIcon from "@mui/icons-material/Refresh"; import { decode, encode } from "cborg"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { useMutation } from "react-query"; import { toast } from "react-toastify"; +import Badge from "common/components/Badge"; import Button from "common/components/Button"; import CBOREditor from "common/components/CBOREditor"; import CheckBox from "common/components/CheckBox"; import InputBlock from "common/components/InputBlock"; import TxBuilder from "common/components/TxBuilder"; -import WalletResponseSelection from "common/components/WalletResponseSelection"; +import WalletViewSelection from "common/components/WalletViewSelection"; import bin2hex from "common/helpers/bin2hex"; import buildUnsingedReg from "common/helpers/buildUnsingedReg"; import hex2bin from "common/helpers/hex2bin"; @@ -29,9 +30,17 @@ type FormValues = { }; function SignTxPanel({ selectedWallets, walletApi }: Props) { + const [selectedTxWallet, setSelectedTxWallet] = useState(""); const [selectedResponseWallet, setSelectedResponseWallet] = useState(""); const [editorRefreshSignal, setEditorRefreshSignal] = useState(0); + useEffect(() => { + const walletNames = Object.keys(walletApi); + if (!selectedTxWallet && walletNames[0]) { + setSelectedTxWallet(walletNames[0]); + } + }, [walletApi]); + const { isLoading, mutateAsync, data } = useMutation({ onError: (err) => { console.log(err); @@ -47,6 +56,8 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { }, }); + const hasEnabledWallet = Boolean(Object.keys(walletApi).length); + async function mutateFn(args: Parameters): Promise> { const responses = await Promise.all( selectedWallets.map(async (wallet) => [wallet, await walletApi[wallet]?.signTx(...args)]) @@ -63,6 +74,10 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { async function handleTxBuilderSubmit(builderArgs: TxBuilderArguments) { try { + /* for (const [name, api] of Object.entries(walletApi)) { + + } */ + const lace = walletApi["lace"]; const tx = await buildUnsingedReg({ @@ -92,7 +107,7 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { console.log(tx.to_js_value()); - // await mutateAsync([cleanHex(formValues.tx), formValues.partialSign]); + await mutateAsync([tx.to_hex(), formValues.partialSign]); } return ( @@ -123,28 +138,40 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { control={control} name="tx" render={({ field: { value, onChange } }) => ( -
+
- + {hasEnabledWallet ? ( + <> + + + + ) : ( + + )}
)} /> -
-
- - {isLoading && } + {hasEnabledWallet && ( +
+
+ + {isLoading && } +
-
-
+ )}
{data && ( <>
-
) : ( -
-
- -

Please select at least one wallet to view the information.

-
-
+ )}
); diff --git a/utilities/wallet-connector/src/styles/global.css b/utilities/wallet-connector/src/styles/global.css index 6ce4efa1100..359b115fd7c 100644 --- a/utilities/wallet-connector/src/styles/global.css +++ b/utilities/wallet-connector/src/styles/global.css @@ -29,3 +29,7 @@ button { button:disabled { opacity: 0.6; } + +.Toastify__toast { + font-family: Poppins, sans-serif; +} From e096ef85a89e40828e196a31017582fd42506a96 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 18:10:20 +0700 Subject: [PATCH 42/73] feat: complete sign tx --- .../src/common/components/Badge.tsx | 2 +- .../src/common/components/TxBuilder.tsx | 18 +-- .../src/common/helpers/extractApiData.ts | 2 +- .../src/modules/SignTxPanel.tsx | 136 ++++++++++-------- .../src/modules/WalletInfoSection.tsx | 2 +- .../wallet-connector/src/types/cardano.ts | 4 +- 6 files changed, 86 insertions(+), 78 deletions(-) diff --git a/utilities/wallet-connector/src/common/components/Badge.tsx b/utilities/wallet-connector/src/common/components/Badge.tsx index 036daf8ef8f..3318e671d59 100644 --- a/utilities/wallet-connector/src/common/components/Badge.tsx +++ b/utilities/wallet-connector/src/common/components/Badge.tsx @@ -16,4 +16,4 @@ function Badge({ text }: Props) { ); } -export default Badge; \ No newline at end of file +export default Badge; diff --git a/utilities/wallet-connector/src/common/components/TxBuilder.tsx b/utilities/wallet-connector/src/common/components/TxBuilder.tsx index 254fa7f713d..8d2801bee5e 100644 --- a/utilities/wallet-connector/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-connector/src/common/components/TxBuilder.tsx @@ -38,7 +38,7 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { regText: "", regLabel: "", stakeCred: "", - config: cloneDeep(PROTOCOL_PARAMS) + config: cloneDeep(PROTOCOL_PARAMS), }, }); @@ -76,9 +76,7 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { {({ open }) => ( <> -
- {open ? : } -
+
{open ? : }

Advanced Configs

)} @@ -101,16 +99,8 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { label="Coins per UTXO word" formRegister={register("config.coinsPerUtxoWord")} /> - - + + ( fn: () => Promise, transformer?: (v: T) => T - ): Promise<{ raw: T; formatted: T; }> => { + ): Promise<{ raw: T; formatted: T }> => { try { const v = await fn(); return transformer diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx index 928404c8bee..5e255858255 100644 --- a/utilities/wallet-connector/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -1,10 +1,9 @@ -import type { SignTx } from "@cardano-sdk/cip30"; -import { Transaction } from "@emurgo/cardano-serialization-lib-asmjs"; +import { Transaction, TransactionWitnessSet } from "@emurgo/cardano-serialization-lib-asmjs"; import RefreshIcon from "@mui/icons-material/Refresh"; import { decode, encode } from "cborg"; -import { useEffect, useState } from "react"; +import { isEmpty } from "lodash-es"; +import { Fragment, useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; -import { useMutation } from "react-query"; import { toast } from "react-toastify"; import Badge from "common/components/Badge"; @@ -24,13 +23,24 @@ type Props = { walletApi: Record; }; +type Response = { + [walletName: string]: { + isError: boolean; + data: string; + }; +}; + type FormValues = { partialSign: boolean; - tx: string; + tx: { + [walletName: string]: string; + }; }; function SignTxPanel({ selectedWallets, walletApi }: Props) { const [selectedTxWallet, setSelectedTxWallet] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const [response, setResponse] = useState({}); const [selectedResponseWallet, setSelectedResponseWallet] = useState(""); const [editorRefreshSignal, setEditorRefreshSignal] = useState(0); @@ -41,57 +51,34 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { } }, [walletApi]); - const { isLoading, mutateAsync, data } = useMutation({ - onError: (err) => { - console.log(err); - toast.error(String(err)); - }, - mutationFn: mutateFn, - }); - const { control, handleSubmit, setValue } = useForm({ defaultValues: { partialSign: false, - tx: "", + tx: {}, }, }); - const hasEnabledWallet = Boolean(Object.keys(walletApi).length); - - async function mutateFn(args: Parameters): Promise> { - const responses = await Promise.all( - selectedWallets.map(async (wallet) => [wallet, await walletApi[wallet]?.signTx(...args)]) - ); - - setSelectedResponseWallet(responses[0]?.[0] ?? ""); - - return Object.fromEntries(responses); - } - - function handleResponseWalletSelect(wallet: string) { - setSelectedResponseWallet(wallet); - } + const hasResponse = !isEmpty(response); async function handleTxBuilderSubmit(builderArgs: TxBuilderArguments) { try { - /* for (const [name, api] of Object.entries(walletApi)) { - - } */ - - const lace = walletApi["lace"]; - - const tx = await buildUnsingedReg({ - regAddress: builderArgs.regAddress, - regAmount: builderArgs.regAmount, - regLabel: builderArgs.regLabel, - regText: builderArgs.regText, - usedAddresses: lace.info.usedAddresses.raw, - changeAddress: lace.info.changeAddress.raw, - rawUtxos: lace.info.utxos.raw, - config: builderArgs.config, - }); - - setValue("tx", bin2hex(encode(tx.to_js_value()))); + const resTx: FormValues["tx"] = {}; + for (const [walletName, api] of Object.entries(walletApi)) { + const tx = await buildUnsingedReg({ + regAddress: builderArgs.regAddress, + regAmount: builderArgs.regAmount, + regLabel: builderArgs.regLabel, + regText: builderArgs.regText, + usedAddresses: api.info.usedAddresses.raw, + changeAddress: api.info.changeAddress.raw, + rawUtxos: api.info.utxos.raw, + config: builderArgs.config, + }); + + resTx[walletName] = bin2hex(encode(tx.to_js_value())); + } + + setValue("tx", resTx); setEditorRefreshSignal((prev) => (prev ? 0 : 1)); } catch (err) { return void toast.error(String(err)); @@ -103,11 +90,36 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { return void toast.error("Please select at least one wallet to execute."); } - const tx = Transaction.from_json(JSON.stringify(decode(hex2bin(formValues.tx)))); - - console.log(tx.to_js_value()); + setIsLoading(true); + + const response: Response = {}; + for (const [walletName, cborHex] of Object.entries(formValues.tx)) { + if (!walletName) { + continue; + } + + const jsonTx = JSON.stringify(decode(hex2bin(cborHex))); + const tx = Transaction.from_json(jsonTx); + + try { + const res = await walletApi[walletName]?.signTx(tx.to_hex(), formValues.partialSign); + const resFmt = TransactionWitnessSet.from_hex(res ?? "").to_js_value(); + + response[walletName] = { + isError: !res, + data: bin2hex(encode(resFmt)), + }; + } catch (err) { + response[walletName] = { + isError: true, + data: String(err), + }; + } + } - await mutateAsync([tx.to_hex(), formValues.partialSign]); + setResponse(response); + setSelectedResponseWallet(Object.keys(formValues.tx)[0] ?? ""); + setIsLoading(false); } return ( @@ -140,14 +152,20 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { render={({ field: { value, onChange } }) => (
- {hasEnabledWallet ? ( + {selectedTxWallet ? ( <> - + + onChange({ ...value, [selectedTxWallet]: v })} + /> + ) : ( @@ -156,7 +174,7 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { )} /> - {hasEnabledWallet && ( + {selectedTxWallet && (
)}
- {data && ( + {hasResponse && ( <>

Response:

- +
)} diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index b7abf71849d..36dc8cc6bbc 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -6,12 +6,12 @@ import { Fragment } from "react/jsx-runtime"; import { useForm } from "react-hook-form"; import { twMerge } from "tailwind-merge"; +import Badge from "common/components/Badge"; import Button from "common/components/Button"; import InfoItem from "common/components/InfoItem"; import Input from "common/components/Input"; import getCardano from "common/helpers/getCardano"; import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; -import Badge from "common/components/Badge"; type Props = { selectedWallets: string[]; diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index f62f0d04d65..a0532fcd3ef 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -5,8 +5,8 @@ type Extracted any> = Awaited>; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number; }[]; }): Promise; - supportedExtensions: { cip: number; }[]; + enable(args: { extensions: { cip: number }[] }): Promise; + supportedExtensions: { cip: number }[]; }; }; From 21e7fe93f66e2e9e3858e7fdc8dff6f6c8b5a7b0 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 18:15:56 +0700 Subject: [PATCH 43/73] chore: lint --- .../src/common/helpers/extractApiData.ts | 2 +- .../src/common/helpers/getCardano.ts | 4 +++- .../wallet-connector/src/modules/SignTxPanel.tsx | 6 +++--- .../src/modules/WalletInfoSection.tsx | 1 - utilities/wallet-connector/src/types/cardano.ts | 13 ++++++++++--- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index fc9e51b786e..4ef8f67c8d0 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -6,7 +6,7 @@ export default async function extractApiData(api: WalletApi, cipExt?: number): P const safeTry = async ( fn: () => Promise, transformer?: (v: T) => T - ): Promise<{ raw: T; formatted: T }> => { + ): Promise<{ raw: T; formatted: T; }> => { try { const v = await fn(); return transformer diff --git a/utilities/wallet-connector/src/common/helpers/getCardano.ts b/utilities/wallet-connector/src/common/helpers/getCardano.ts index d767eeeba2e..68f491b6b4e 100644 --- a/utilities/wallet-connector/src/common/helpers/getCardano.ts +++ b/utilities/wallet-connector/src/common/helpers/getCardano.ts @@ -3,5 +3,7 @@ import type { WalletCollections } from "types/cardano"; export default function getCardano( walletName?: T ): T extends string ? WalletCollections[string] : WalletCollections { - return walletName ? globalThis.cardano[walletName] : globalThis.cardano; + return (walletName ? globalThis.cardano[walletName] : globalThis.cardano) as T extends string + ? WalletCollections[string] + : WalletCollections; } diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx index 5e255858255..0e7aad01c9d 100644 --- a/utilities/wallet-connector/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -69,9 +69,9 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { regAmount: builderArgs.regAmount, regLabel: builderArgs.regLabel, regText: builderArgs.regText, - usedAddresses: api.info.usedAddresses.raw, - changeAddress: api.info.changeAddress.raw, - rawUtxos: api.info.utxos.raw, + usedAddresses: api.info["usedAddresses"]?.raw, + changeAddress: api.info["changeAddress"]?.raw, + rawUtxos: api.info["utxos"]?.raw, config: builderArgs.config, }); diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index 36dc8cc6bbc..cc7be0545aa 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -1,6 +1,5 @@ import { Tab } from "@headlessui/react"; import ArrowRightIcon from "@mui/icons-material/ArrowRight"; -import WarningIcon from "@mui/icons-material/Warning"; import { capitalize, noop, pickBy, upperCase } from "lodash-es"; import { Fragment } from "react/jsx-runtime"; import { useForm } from "react-hook-form"; diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index a0532fcd3ef..83ae2f633e6 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -5,8 +5,8 @@ type Extracted any> = Awaited>; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number }[] }): Promise; - supportedExtensions: { cip: number }[]; + enable(args: { extensions: { cip: number; }[]; }): Promise; + supportedExtensions: { cip: number; }[]; }; }; @@ -26,7 +26,14 @@ export type ExtractedWalletApi = { signTx: cip30.SignTx; signData: cip30.SignData; submitTx: cip30.SubmitTx; - [key: string]: any; + info: { + [key: string]: { + from: string; + raw: any; + value: any; + }; + }; + [key: `cip${number}`]: any; }; export type TxBuilderArguments = { From b3b906ad5926accad0d0667af7aea045ed8f6092 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 19:30:47 +0700 Subject: [PATCH 44/73] feat: badge variant --- .../src/common/components/Badge.tsx | 20 +++++++++++++++---- .../src/common/components/TxBuilder.tsx | 16 ++++----------- .../src/common/helpers/extractApiData.ts | 7 ++++++- .../src/modules/SignTxPanel.tsx | 13 ++++++++---- .../wallet-connector/src/types/cardano.ts | 11 ---------- 5 files changed, 35 insertions(+), 32 deletions(-) diff --git a/utilities/wallet-connector/src/common/components/Badge.tsx b/utilities/wallet-connector/src/common/components/Badge.tsx index 3318e671d59..73723974355 100644 --- a/utilities/wallet-connector/src/common/components/Badge.tsx +++ b/utilities/wallet-connector/src/common/components/Badge.tsx @@ -1,15 +1,27 @@ import WarningIcon from "@mui/icons-material/Warning"; +import { twMerge } from "tailwind-merge"; type Props = { - variant: "warn"; + variant: "warn" | "error"; text: string; }; -function Badge({ text }: Props) { +function Badge({ variant, text }: Props) { return ( -
+
- +

{text}

diff --git a/utilities/wallet-connector/src/common/components/TxBuilder.tsx b/utilities/wallet-connector/src/common/components/TxBuilder.tsx index 8d2801bee5e..3dd58edfa30 100644 --- a/utilities/wallet-connector/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-connector/src/common/components/TxBuilder.tsx @@ -54,24 +54,16 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { - - + + {({ open }) => ( diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index 4ef8f67c8d0..7c8cb484228 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -2,7 +2,12 @@ import type { WalletApi } from "@cardano-sdk/cip30"; import { Address, TransactionUnspentOutput, Value } from "@emurgo/cardano-serialization-lib-asmjs"; import { camelCase, mapValues } from "lodash-es"; -export default async function extractApiData(api: WalletApi, cipExt?: number): Promise { +import type { ExtractedWalletApi } from "types/cardano"; + +export default async function extractApiData( + api: WalletApi, + cipExt?: number +): Promise { const safeTry = async ( fn: () => Promise, transformer?: (v: T) => T diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx index 0e7aad01c9d..b22abc3f38c 100644 --- a/utilities/wallet-connector/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -58,8 +58,6 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { }, }); - const hasResponse = !isEmpty(response); - async function handleTxBuilderSubmit(builderArgs: TxBuilderArguments) { try { const resTx: FormValues["tx"] = {}; @@ -185,7 +183,7 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) {
)}
- {hasResponse && ( + {!isEmpty(response) && ( <>
@@ -195,7 +193,14 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { onSelect={setSelectedResponseWallet} />

Response:

- + {response[selectedResponseWallet]?.isError ? ( + + ) : ( + + )}
)} diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index 83ae2f633e6..fc75c5385dc 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -1,8 +1,5 @@ import * as cip30 from "@cardano-sdk/cip30"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type Extracted any> = Awaited>; - export type WalletCollections = { [k: string]: Omit & { enable(args: { extensions: { cip: number; }[]; }): Promise; @@ -15,14 +12,6 @@ export type ExtensionArguments = { }; export type ExtractedWalletApi = { - networkId: Extracted; - utxos: Extracted; - balance: Extracted; - collateral: Extracted; - usedAddresses: Extracted; - unusedAddresses: Extracted; - changeAddress: Extracted; - rewardAddresses: Extracted; signTx: cip30.SignTx; signData: cip30.SignData; submitTx: cip30.SubmitTx; From 8ce840d7bf107d8c72e2af7861cae9776fa4eb01 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 19:57:50 +0700 Subject: [PATCH 45/73] fix: selection state --- .../src/modules/SignTxPanel.tsx | 19 ++++++++----------- .../src/modules/WalletInfoSection.tsx | 17 ++++++++++++----- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx index b22abc3f38c..dbb8c6e8300 100644 --- a/utilities/wallet-connector/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -45,11 +45,10 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { const [editorRefreshSignal, setEditorRefreshSignal] = useState(0); useEffect(() => { - const walletNames = Object.keys(walletApi); - if (!selectedTxWallet && walletNames[0]) { - setSelectedTxWallet(walletNames[0]); - } - }, [walletApi]); + const walletNames = Object.keys(walletApi).filter((w) => selectedWallets.includes(w)); + + setSelectedTxWallet((prev) => selectedWallets.includes(prev) ? prev : (walletNames[0] ?? "")); + }, [walletApi, selectedWallets]); const { control, handleSubmit, setValue } = useForm({ defaultValues: { @@ -60,8 +59,10 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { async function handleTxBuilderSubmit(builderArgs: TxBuilderArguments) { try { + const activeWallets = Object.entries(walletApi).filter(([w]) => selectedWallets.includes(w)); + const resTx: FormValues["tx"] = {}; - for (const [walletName, api] of Object.entries(walletApi)) { + for (const [walletName, api] of activeWallets) { const tx = await buildUnsingedReg({ regAddress: builderArgs.regAddress, regAmount: builderArgs.regAmount, @@ -84,10 +85,6 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { } async function handleExecute(formValues: FormValues) { - if (!selectedWallets.length) { - return void toast.error("Please select at least one wallet to execute."); - } - setIsLoading(true); const response: Response = {}; @@ -154,7 +151,7 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { <> selectedWallets.includes(w))} onSelect={setSelectedTxWallet} /> diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx index cc7be0545aa..0bdd7775656 100644 --- a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx +++ b/utilities/wallet-connector/src/modules/WalletInfoSection.tsx @@ -1,5 +1,6 @@ import { Tab } from "@headlessui/react"; import ArrowRightIcon from "@mui/icons-material/ArrowRight"; +import RefreshIcon from "@mui/icons-material/Refresh"; import { capitalize, noop, pickBy, upperCase } from "lodash-es"; import { Fragment } from "react/jsx-runtime"; import { useForm } from "react-hook-form"; @@ -65,8 +66,8 @@ function WalletInfoSection({
- {selectedWallets.map((wallet) => ( - + {selectedWallets.map((walletName) => ( + {({ selected }) => (
- icon -

{wallet}

+ {enablingWallets.includes(walletName) ? ( +
+ +
+ ) : ( + icon + )} +

{walletName}

{selected && }
)} @@ -100,7 +107,7 @@ function WalletInfoSection({ {Boolean(walletApi[wallet]) && (
{Object.entries(walletApi[wallet]?.["info"] ?? {}).map( - ([key, { from, value, raw }]: [string, any]) => ( + ([key, { from, value, raw }]) => ( Date: Fri, 22 Mar 2024 20:04:35 +0700 Subject: [PATCH 46/73] fix: submit status --- utilities/wallet-connector/src/modules/SignTxPanel.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx index dbb8c6e8300..692c608c4b4 100644 --- a/utilities/wallet-connector/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -87,8 +87,10 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { async function handleExecute(formValues: FormValues) { setIsLoading(true); + const activeTx = Object.entries(formValues.tx).filter(([w]) => selectedWallets.includes(w)); + const response: Response = {}; - for (const [walletName, cborHex] of Object.entries(formValues.tx)) { + for (const [walletName, cborHex] of activeTx) { if (!walletName) { continue; } From b2ac953a55e2ff035e952186539ea419bc57451e Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 20:14:22 +0700 Subject: [PATCH 47/73] chore: remove unused pkgs --- utilities/wallet-connector/.eslintrc.yaml | 3 - utilities/wallet-connector/package-lock.json | 176 ++---------------- utilities/wallet-connector/package.json | 2 - utilities/wallet-connector/src/App.tsx | 17 +- .../src/modules/SignTxPanel.tsx | 4 +- 5 files changed, 21 insertions(+), 181 deletions(-) diff --git a/utilities/wallet-connector/.eslintrc.yaml b/utilities/wallet-connector/.eslintrc.yaml index b975a528131..64fd1f9b632 100644 --- a/utilities/wallet-connector/.eslintrc.yaml +++ b/utilities/wallet-connector/.eslintrc.yaml @@ -10,7 +10,6 @@ extends: - plugin:react/recommended - plugin:react/jsx-runtime - plugin:react-hooks/recommended - - plugin:@tanstack/eslint-plugin-query/recommended - plugin:jsx-a11y/strict parserOptions: ecmaFeatures: @@ -28,8 +27,6 @@ plugins: - jsx-a11y - import - react-refresh - - i18next - - "@tanstack/query" overrides: - files: - "*.yaml" diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-connector/package-lock.json index f730cb3f064..a51fbe1e3c9 100644 --- a/utilities/wallet-connector/package-lock.json +++ b/utilities/wallet-connector/package-lock.json @@ -23,8 +23,6 @@ "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-hook-form": "^7.51.0", - "react-query": "^3.39.3", - "react-textarea-autosize": "^8.5.3", "react-toastify": "^10.0.4", "tailwind-merge": "^2.2.1" }, @@ -2863,15 +2861,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "engines": { - "node": ">=0.6" - } + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "devOptional": true }, "node_modules/bignumber.js": { "version": "9.1.2", @@ -2912,21 +2903,6 @@ "node": ">=8" } }, - "node_modules/broadcast-channel": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz", - "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==", - "dependencies": { - "@babel/runtime": "^7.7.2", - "detect-node": "^2.1.0", - "js-sha3": "0.8.0", - "microseconds": "0.2.0", - "nano-time": "1.0.0", - "oblivious-set": "1.0.0", - "rimraf": "3.0.2", - "unload": "2.2.0" - } - }, "node_modules/browserslist": { "version": "4.23.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", @@ -3133,7 +3109,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "optional": true }, "node_modules/convert-source-map": { "version": "1.9.0", @@ -3272,11 +3249,6 @@ "node": ">=6" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -4239,7 +4211,8 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "optional": true }, "node_modules/fsevents": { "version": "2.3.3", @@ -4330,6 +4303,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "optional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4361,6 +4335,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4370,6 +4345,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4581,6 +4557,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "optional": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -4589,7 +4566,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "optional": true }, "node_modules/internal-slot": { "version": "1.0.7", @@ -5022,11 +5000,6 @@ "jiti": "bin/jiti.js" } }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5201,15 +5174,6 @@ "node": ">=10" } }, - "node_modules/match-sorter": { - "version": "6.3.4", - "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz", - "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==", - "dependencies": { - "@babel/runtime": "^7.23.8", - "remove-accents": "0.5.0" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5232,11 +5196,6 @@ "node": ">=8.6" } }, - "node_modules/microseconds": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", - "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" - }, "node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -5287,14 +5246,6 @@ "thenify-all": "^1.0.0" } }, - "node_modules/nano-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", - "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", - "dependencies": { - "big-integer": "^1.6.16" - } - }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -5503,15 +5454,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/oblivious-set": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz", - "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==" - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "optional": true, "dependencies": { "wrappy": "1" } @@ -5604,6 +5551,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -6004,47 +5952,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, - "node_modules/react-query": { - "version": "3.39.3", - "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", - "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "broadcast-channel": "^3.4.1", - "match-sorter": "^6.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/react-textarea-autosize": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz", - "integrity": "sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==", - "dependencies": { - "@babel/runtime": "^7.20.13", - "use-composed-ref": "^1.3.0", - "use-latest": "^1.2.1" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/react-toastify": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.4.tgz", @@ -6137,11 +6044,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/remove-accents": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", - "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" - }, "node_modules/requireindex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", @@ -6189,6 +6091,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "optional": true, "dependencies": { "glob": "^7.1.3" }, @@ -6999,15 +6902,6 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, - "node_modules/unload": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz", - "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==", - "dependencies": { - "@babel/runtime": "^7.6.2", - "detect-node": "^2.0.4" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -7047,43 +6941,6 @@ "punycode": "^2.1.0" } }, - "node_modules/use-composed-ref": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", - "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-latest": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", - "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", - "dependencies": { - "use-isomorphic-layout-effect": "^1.1.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/utf-8-validate": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", @@ -7392,7 +7249,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "optional": true }, "node_modules/ws": { "version": "7.5.9", diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-connector/package.json index 199faf5726f..40df31019b4 100644 --- a/utilities/wallet-connector/package.json +++ b/utilities/wallet-connector/package.json @@ -28,8 +28,6 @@ "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-hook-form": "^7.51.0", - "react-query": "^3.39.3", - "react-textarea-autosize": "^8.5.3", "react-toastify": "^10.0.4", "tailwind-merge": "^2.2.1" }, diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index 8366bd2aae0..f854b469815 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -4,7 +4,6 @@ import "./styles/global.css"; import { isEmpty, pickBy, xor } from "lodash-es"; import { useState } from "react"; -import { QueryClient, QueryClientProvider } from "react-query"; import { ToastContainer, toast } from "react-toastify"; import WalletCard from "common/components/WalletCard"; @@ -14,18 +13,6 @@ import WalletActionsSection from "modules/WalletActionsSection"; import WalletInfoSection from "modules/WalletInfoSection"; import type { ExtensionArguments, ExtractedWalletApi } from "types/cardano"; -const queryClient = new QueryClient({ - defaultOptions: { - queries: { - retry: false, - refetchOnWindowFocus: false, - }, - mutations: { - retry: false, - }, - }, -}); - function App() { // enabled wallets with the API object const [walletApi, setWalletApi] = useState>({}); @@ -79,7 +66,7 @@ function App() { } return ( - + <>
@@ -125,7 +112,7 @@ function App() {
-
+ ); } diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-connector/src/modules/SignTxPanel.tsx index 692c608c4b4..9b213cf2112 100644 --- a/utilities/wallet-connector/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-connector/src/modules/SignTxPanel.tsx @@ -46,8 +46,8 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { useEffect(() => { const walletNames = Object.keys(walletApi).filter((w) => selectedWallets.includes(w)); - - setSelectedTxWallet((prev) => selectedWallets.includes(prev) ? prev : (walletNames[0] ?? "")); + + setSelectedTxWallet((prev) => (selectedWallets.includes(prev) ? prev : walletNames[0] ?? "")); }, [walletApi, selectedWallets]); const { control, handleSubmit, setValue } = useForm({ From d96514ec052a88fb24720cf9c9daaa9db338a9bb Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 20:17:21 +0700 Subject: [PATCH 48/73] fix: lint --- .../wallet-connector/src/common/helpers/extractApiData.ts | 4 ++-- utilities/wallet-connector/src/types/cardano.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index 7c8cb484228..54b42a62724 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -5,7 +5,7 @@ import { camelCase, mapValues } from "lodash-es"; import type { ExtractedWalletApi } from "types/cardano"; export default async function extractApiData( - api: WalletApi, + api: WalletApi & { [ext: `cip${number}`]: unknown; }, cipExt?: number ): Promise { const safeTry = async ( @@ -35,7 +35,7 @@ export default async function extractApiData( let extData = {}; if (typeof cipExt === "number") { const out = []; - for (const [key, value] of Object.entries((api as any)[`cip${cipExt}`] ?? {})) { + for (const [key, value] of Object.entries(api[`cip${cipExt}`] ?? {})) { if (key.startsWith("get") && value instanceof Function) { out.push([ camelCase(key.slice(3)), diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-connector/src/types/cardano.ts index fc75c5385dc..169419007bc 100644 --- a/utilities/wallet-connector/src/types/cardano.ts +++ b/utilities/wallet-connector/src/types/cardano.ts @@ -1,3 +1,5 @@ +/* eslint @typescript-eslint/no-explicit-any: off */ + import * as cip30 from "@cardano-sdk/cip30"; export type WalletCollections = { From 60c04ce6b2569accaf4d56049304763b723577d3 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 20:27:06 +0700 Subject: [PATCH 49/73] feat: col fmt --- .../wallet-connector/src/common/helpers/extractApiData.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index 54b42a62724..9e17103d2eb 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -37,11 +37,14 @@ export default async function extractApiData( const out = []; for (const [key, value] of Object.entries(api[`cip${cipExt}`] ?? {})) { if (key.startsWith("get") && value instanceof Function) { + const resVal = await value?.(); + out.push([ camelCase(key.slice(3)), { from: `cip${cipExt}`, - value: await value?.(), + raw: resVal, + value: resVal, }, ]); } @@ -61,7 +64,7 @@ export default async function extractApiData( balance: await safeTry(api.getBalance, (v) => Number(Value.from_hex(v).coin().to_str()).toLocaleString("en") ), - collateral: await safeTry(api.getCollateral), + collateral: await safeTry(api.getCollateral, (v) => v?.map((v) => TransactionUnspentOutput.from_hex(v).to_json()) ?? v), usedAddresses: await safeTry( api.getUsedAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v From 163a2a6ca9a72c79fb26cd9b5d48b3ff8c3a3df6 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 20:27:33 +0700 Subject: [PATCH 50/73] chore: lintfix --- .../wallet-connector/src/common/helpers/extractApiData.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-connector/src/common/helpers/extractApiData.ts index 9e17103d2eb..32519797992 100644 --- a/utilities/wallet-connector/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-connector/src/common/helpers/extractApiData.ts @@ -64,7 +64,10 @@ export default async function extractApiData( balance: await safeTry(api.getBalance, (v) => Number(Value.from_hex(v).coin().to_str()).toLocaleString("en") ), - collateral: await safeTry(api.getCollateral, (v) => v?.map((v) => TransactionUnspentOutput.from_hex(v).to_json()) ?? v), + collateral: await safeTry( + api.getCollateral, + (v) => v?.map((v) => TransactionUnspentOutput.from_hex(v).to_json()) ?? v + ), usedAddresses: await safeTry( api.getUsedAddresses, (v) => v?.map((v) => Address.from_hex(v).to_bech32()) ?? v From bfe1d45d1bf75c669a4254dc963ba61af9edcdf4 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 20:43:24 +0700 Subject: [PATCH 51/73] fix: change title --- utilities/wallet-connector/index.html | 2 +- utilities/wallet-connector/src/App.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/utilities/wallet-connector/index.html b/utilities/wallet-connector/index.html index 10f741ec8ff..507b9b266fd 100644 --- a/utilities/wallet-connector/index.html +++ b/utilities/wallet-connector/index.html @@ -6,7 +6,7 @@ - Hermes Wallet Connector + Cardano Wallet Tester
diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-connector/src/App.tsx index f854b469815..ffdb64a5a3b 100644 --- a/utilities/wallet-connector/src/App.tsx +++ b/utilities/wallet-connector/src/App.tsx @@ -75,6 +75,7 @@ function App() { {isCardanoActivated ? ( <>
+

Cardano Wallet Tester

Select available wallets:

{Object.keys(getCardano()).map((walletName) => ( From 1aa3836be317747e19ea185e43fe6a7b95e97f8b Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 20:44:08 +0700 Subject: [PATCH 52/73] refactor: rename to wallet tester --- utilities/{wallet-connector => wallet-tester}/.eslintrc.yaml | 0 utilities/{wallet-connector => wallet-tester}/.gitignore | 0 utilities/{wallet-connector => wallet-tester}/.prettierrc.yaml | 0 utilities/{wallet-connector => wallet-tester}/Earthfile | 0 utilities/{wallet-connector => wallet-tester}/README.md | 0 utilities/{wallet-connector => wallet-tester}/index.html | 0 utilities/{wallet-connector => wallet-tester}/package-lock.json | 0 utilities/{wallet-connector => wallet-tester}/package.json | 0 utilities/{wallet-connector => wallet-tester}/postcss.config.js | 0 utilities/{wallet-connector => wallet-tester}/src/App.tsx | 0 .../src/common/components/Badge.tsx | 0 .../src/common/components/Button.tsx | 0 .../src/common/components/CBOREditor.tsx | 0 .../src/common/components/CheckBox.tsx | 0 .../src/common/components/InfoItem.tsx | 0 .../src/common/components/Input.tsx | 0 .../src/common/components/InputBlock.tsx | 0 .../src/common/components/TxBuilder.tsx | 0 .../src/common/components/WalletCard.tsx | 0 .../src/common/components/WalletViewSelection.tsx | 0 .../src/common/helpers/bin2hex.ts | 0 .../src/common/helpers/buildUnsingedReg.ts | 0 .../src/common/helpers/cleanHex.ts | 0 .../src/common/helpers/diag2hex.ts | 0 .../src/common/helpers/extractApiData.ts | 0 .../src/common/helpers/getCardano.ts | 0 .../src/common/helpers/hex2bin.ts | 0 .../src/common/helpers/hex2diag.ts | 0 .../src/common/helpers/readFile.ts | 0 utilities/{wallet-connector => wallet-tester}/src/main.tsx | 0 .../src/modules/SignDataPanel.tsx | 0 .../src/modules/SignTxPanel.tsx | 0 .../src/modules/SubmitTxPanel.tsx | 0 .../src/modules/WalletActionsSection.tsx | 0 .../src/modules/WalletInfoSection.tsx | 0 .../{wallet-connector => wallet-tester}/src/styles/global.css | 0 .../{wallet-connector => wallet-tester}/src/types/cardano.ts | 0 .../{wallet-connector => wallet-tester}/src/types/global.d.ts | 0 utilities/{wallet-connector => wallet-tester}/tailwind.config.js | 0 utilities/{wallet-connector => wallet-tester}/tsconfig.json | 0 utilities/{wallet-connector => wallet-tester}/tsconfig.node.json | 0 utilities/{wallet-connector => wallet-tester}/vite.config.ts | 0 42 files changed, 0 insertions(+), 0 deletions(-) rename utilities/{wallet-connector => wallet-tester}/.eslintrc.yaml (100%) rename utilities/{wallet-connector => wallet-tester}/.gitignore (100%) rename utilities/{wallet-connector => wallet-tester}/.prettierrc.yaml (100%) rename utilities/{wallet-connector => wallet-tester}/Earthfile (100%) rename utilities/{wallet-connector => wallet-tester}/README.md (100%) rename utilities/{wallet-connector => wallet-tester}/index.html (100%) rename utilities/{wallet-connector => wallet-tester}/package-lock.json (100%) rename utilities/{wallet-connector => wallet-tester}/package.json (100%) rename utilities/{wallet-connector => wallet-tester}/postcss.config.js (100%) rename utilities/{wallet-connector => wallet-tester}/src/App.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/Badge.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/Button.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/CBOREditor.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/CheckBox.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/InfoItem.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/Input.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/InputBlock.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/TxBuilder.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/WalletCard.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/components/WalletViewSelection.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/bin2hex.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/buildUnsingedReg.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/cleanHex.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/diag2hex.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/extractApiData.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/getCardano.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/hex2bin.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/hex2diag.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/common/helpers/readFile.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/main.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/modules/SignDataPanel.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/modules/SignTxPanel.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/modules/SubmitTxPanel.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/modules/WalletActionsSection.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/modules/WalletInfoSection.tsx (100%) rename utilities/{wallet-connector => wallet-tester}/src/styles/global.css (100%) rename utilities/{wallet-connector => wallet-tester}/src/types/cardano.ts (100%) rename utilities/{wallet-connector => wallet-tester}/src/types/global.d.ts (100%) rename utilities/{wallet-connector => wallet-tester}/tailwind.config.js (100%) rename utilities/{wallet-connector => wallet-tester}/tsconfig.json (100%) rename utilities/{wallet-connector => wallet-tester}/tsconfig.node.json (100%) rename utilities/{wallet-connector => wallet-tester}/vite.config.ts (100%) diff --git a/utilities/wallet-connector/.eslintrc.yaml b/utilities/wallet-tester/.eslintrc.yaml similarity index 100% rename from utilities/wallet-connector/.eslintrc.yaml rename to utilities/wallet-tester/.eslintrc.yaml diff --git a/utilities/wallet-connector/.gitignore b/utilities/wallet-tester/.gitignore similarity index 100% rename from utilities/wallet-connector/.gitignore rename to utilities/wallet-tester/.gitignore diff --git a/utilities/wallet-connector/.prettierrc.yaml b/utilities/wallet-tester/.prettierrc.yaml similarity index 100% rename from utilities/wallet-connector/.prettierrc.yaml rename to utilities/wallet-tester/.prettierrc.yaml diff --git a/utilities/wallet-connector/Earthfile b/utilities/wallet-tester/Earthfile similarity index 100% rename from utilities/wallet-connector/Earthfile rename to utilities/wallet-tester/Earthfile diff --git a/utilities/wallet-connector/README.md b/utilities/wallet-tester/README.md similarity index 100% rename from utilities/wallet-connector/README.md rename to utilities/wallet-tester/README.md diff --git a/utilities/wallet-connector/index.html b/utilities/wallet-tester/index.html similarity index 100% rename from utilities/wallet-connector/index.html rename to utilities/wallet-tester/index.html diff --git a/utilities/wallet-connector/package-lock.json b/utilities/wallet-tester/package-lock.json similarity index 100% rename from utilities/wallet-connector/package-lock.json rename to utilities/wallet-tester/package-lock.json diff --git a/utilities/wallet-connector/package.json b/utilities/wallet-tester/package.json similarity index 100% rename from utilities/wallet-connector/package.json rename to utilities/wallet-tester/package.json diff --git a/utilities/wallet-connector/postcss.config.js b/utilities/wallet-tester/postcss.config.js similarity index 100% rename from utilities/wallet-connector/postcss.config.js rename to utilities/wallet-tester/postcss.config.js diff --git a/utilities/wallet-connector/src/App.tsx b/utilities/wallet-tester/src/App.tsx similarity index 100% rename from utilities/wallet-connector/src/App.tsx rename to utilities/wallet-tester/src/App.tsx diff --git a/utilities/wallet-connector/src/common/components/Badge.tsx b/utilities/wallet-tester/src/common/components/Badge.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/Badge.tsx rename to utilities/wallet-tester/src/common/components/Badge.tsx diff --git a/utilities/wallet-connector/src/common/components/Button.tsx b/utilities/wallet-tester/src/common/components/Button.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/Button.tsx rename to utilities/wallet-tester/src/common/components/Button.tsx diff --git a/utilities/wallet-connector/src/common/components/CBOREditor.tsx b/utilities/wallet-tester/src/common/components/CBOREditor.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/CBOREditor.tsx rename to utilities/wallet-tester/src/common/components/CBOREditor.tsx diff --git a/utilities/wallet-connector/src/common/components/CheckBox.tsx b/utilities/wallet-tester/src/common/components/CheckBox.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/CheckBox.tsx rename to utilities/wallet-tester/src/common/components/CheckBox.tsx diff --git a/utilities/wallet-connector/src/common/components/InfoItem.tsx b/utilities/wallet-tester/src/common/components/InfoItem.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/InfoItem.tsx rename to utilities/wallet-tester/src/common/components/InfoItem.tsx diff --git a/utilities/wallet-connector/src/common/components/Input.tsx b/utilities/wallet-tester/src/common/components/Input.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/Input.tsx rename to utilities/wallet-tester/src/common/components/Input.tsx diff --git a/utilities/wallet-connector/src/common/components/InputBlock.tsx b/utilities/wallet-tester/src/common/components/InputBlock.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/InputBlock.tsx rename to utilities/wallet-tester/src/common/components/InputBlock.tsx diff --git a/utilities/wallet-connector/src/common/components/TxBuilder.tsx b/utilities/wallet-tester/src/common/components/TxBuilder.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/TxBuilder.tsx rename to utilities/wallet-tester/src/common/components/TxBuilder.tsx diff --git a/utilities/wallet-connector/src/common/components/WalletCard.tsx b/utilities/wallet-tester/src/common/components/WalletCard.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/WalletCard.tsx rename to utilities/wallet-tester/src/common/components/WalletCard.tsx diff --git a/utilities/wallet-connector/src/common/components/WalletViewSelection.tsx b/utilities/wallet-tester/src/common/components/WalletViewSelection.tsx similarity index 100% rename from utilities/wallet-connector/src/common/components/WalletViewSelection.tsx rename to utilities/wallet-tester/src/common/components/WalletViewSelection.tsx diff --git a/utilities/wallet-connector/src/common/helpers/bin2hex.ts b/utilities/wallet-tester/src/common/helpers/bin2hex.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/bin2hex.ts rename to utilities/wallet-tester/src/common/helpers/bin2hex.ts diff --git a/utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts b/utilities/wallet-tester/src/common/helpers/buildUnsingedReg.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/buildUnsingedReg.ts rename to utilities/wallet-tester/src/common/helpers/buildUnsingedReg.ts diff --git a/utilities/wallet-connector/src/common/helpers/cleanHex.ts b/utilities/wallet-tester/src/common/helpers/cleanHex.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/cleanHex.ts rename to utilities/wallet-tester/src/common/helpers/cleanHex.ts diff --git a/utilities/wallet-connector/src/common/helpers/diag2hex.ts b/utilities/wallet-tester/src/common/helpers/diag2hex.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/diag2hex.ts rename to utilities/wallet-tester/src/common/helpers/diag2hex.ts diff --git a/utilities/wallet-connector/src/common/helpers/extractApiData.ts b/utilities/wallet-tester/src/common/helpers/extractApiData.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/extractApiData.ts rename to utilities/wallet-tester/src/common/helpers/extractApiData.ts diff --git a/utilities/wallet-connector/src/common/helpers/getCardano.ts b/utilities/wallet-tester/src/common/helpers/getCardano.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/getCardano.ts rename to utilities/wallet-tester/src/common/helpers/getCardano.ts diff --git a/utilities/wallet-connector/src/common/helpers/hex2bin.ts b/utilities/wallet-tester/src/common/helpers/hex2bin.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/hex2bin.ts rename to utilities/wallet-tester/src/common/helpers/hex2bin.ts diff --git a/utilities/wallet-connector/src/common/helpers/hex2diag.ts b/utilities/wallet-tester/src/common/helpers/hex2diag.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/hex2diag.ts rename to utilities/wallet-tester/src/common/helpers/hex2diag.ts diff --git a/utilities/wallet-connector/src/common/helpers/readFile.ts b/utilities/wallet-tester/src/common/helpers/readFile.ts similarity index 100% rename from utilities/wallet-connector/src/common/helpers/readFile.ts rename to utilities/wallet-tester/src/common/helpers/readFile.ts diff --git a/utilities/wallet-connector/src/main.tsx b/utilities/wallet-tester/src/main.tsx similarity index 100% rename from utilities/wallet-connector/src/main.tsx rename to utilities/wallet-tester/src/main.tsx diff --git a/utilities/wallet-connector/src/modules/SignDataPanel.tsx b/utilities/wallet-tester/src/modules/SignDataPanel.tsx similarity index 100% rename from utilities/wallet-connector/src/modules/SignDataPanel.tsx rename to utilities/wallet-tester/src/modules/SignDataPanel.tsx diff --git a/utilities/wallet-connector/src/modules/SignTxPanel.tsx b/utilities/wallet-tester/src/modules/SignTxPanel.tsx similarity index 100% rename from utilities/wallet-connector/src/modules/SignTxPanel.tsx rename to utilities/wallet-tester/src/modules/SignTxPanel.tsx diff --git a/utilities/wallet-connector/src/modules/SubmitTxPanel.tsx b/utilities/wallet-tester/src/modules/SubmitTxPanel.tsx similarity index 100% rename from utilities/wallet-connector/src/modules/SubmitTxPanel.tsx rename to utilities/wallet-tester/src/modules/SubmitTxPanel.tsx diff --git a/utilities/wallet-connector/src/modules/WalletActionsSection.tsx b/utilities/wallet-tester/src/modules/WalletActionsSection.tsx similarity index 100% rename from utilities/wallet-connector/src/modules/WalletActionsSection.tsx rename to utilities/wallet-tester/src/modules/WalletActionsSection.tsx diff --git a/utilities/wallet-connector/src/modules/WalletInfoSection.tsx b/utilities/wallet-tester/src/modules/WalletInfoSection.tsx similarity index 100% rename from utilities/wallet-connector/src/modules/WalletInfoSection.tsx rename to utilities/wallet-tester/src/modules/WalletInfoSection.tsx diff --git a/utilities/wallet-connector/src/styles/global.css b/utilities/wallet-tester/src/styles/global.css similarity index 100% rename from utilities/wallet-connector/src/styles/global.css rename to utilities/wallet-tester/src/styles/global.css diff --git a/utilities/wallet-connector/src/types/cardano.ts b/utilities/wallet-tester/src/types/cardano.ts similarity index 100% rename from utilities/wallet-connector/src/types/cardano.ts rename to utilities/wallet-tester/src/types/cardano.ts diff --git a/utilities/wallet-connector/src/types/global.d.ts b/utilities/wallet-tester/src/types/global.d.ts similarity index 100% rename from utilities/wallet-connector/src/types/global.d.ts rename to utilities/wallet-tester/src/types/global.d.ts diff --git a/utilities/wallet-connector/tailwind.config.js b/utilities/wallet-tester/tailwind.config.js similarity index 100% rename from utilities/wallet-connector/tailwind.config.js rename to utilities/wallet-tester/tailwind.config.js diff --git a/utilities/wallet-connector/tsconfig.json b/utilities/wallet-tester/tsconfig.json similarity index 100% rename from utilities/wallet-connector/tsconfig.json rename to utilities/wallet-tester/tsconfig.json diff --git a/utilities/wallet-connector/tsconfig.node.json b/utilities/wallet-tester/tsconfig.node.json similarity index 100% rename from utilities/wallet-connector/tsconfig.node.json rename to utilities/wallet-tester/tsconfig.node.json diff --git a/utilities/wallet-connector/vite.config.ts b/utilities/wallet-tester/vite.config.ts similarity index 100% rename from utilities/wallet-connector/vite.config.ts rename to utilities/wallet-tester/vite.config.ts From f28d382810c7c5c36a02d3cdd795cc55331adda2 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 21:32:06 +0700 Subject: [PATCH 53/73] refactor: fix words --- .config/dictionaries/project.dic | 12 ++++++++++++ .../src/common/components/CBOREditor.tsx | 2 ++ .../src/common/components/TxBuilder.tsx | 2 ++ .../{buildUnsingedReg.ts => buildUnsignedTx.ts} | 8 +++++--- utilities/wallet-tester/src/modules/SignTxPanel.tsx | 4 ++-- utilities/wallet-tester/src/styles/global.css | 2 ++ 6 files changed, 25 insertions(+), 5 deletions(-) rename utilities/wallet-tester/src/common/helpers/{buildUnsingedReg.ts => buildUnsignedTx.ts} (95%) diff --git a/.config/dictionaries/project.dic b/.config/dictionaries/project.dic index 8a8ec9e2024..46c51d4bbf6 100644 --- a/.config/dictionaries/project.dic +++ b/.config/dictionaries/project.dic @@ -6,15 +6,19 @@ afinet androidx appspot Arbritrary +asmjs asyncio asyncpg auditability +bech bkioshn bluefireteam BROTLI canvaskit cardano Catalyst +CBOR +cborg CEST cfbundle chromedriver @@ -37,6 +41,7 @@ dotglob drep dreps earthfile +emurgo encryptor fetchval fmtchk @@ -51,6 +56,7 @@ genhtml gethostname gmtime gradlew +headlessui ideascale idents integ @@ -89,6 +95,7 @@ pg_isready plpgsql podfile podhelper +postcss preprod projectcatalyst Prokhorenko @@ -124,10 +131,15 @@ testunit thiserror thollander timelike +toastify +Toastify Traceback TXNZD unmanaged UTXO +Utxos +utxos +vite vitss voteplan voteplans diff --git a/utilities/wallet-tester/src/common/components/CBOREditor.tsx b/utilities/wallet-tester/src/common/components/CBOREditor.tsx index 6dbc71fc8fd..dcb254ce6e0 100644 --- a/utilities/wallet-tester/src/common/components/CBOREditor.tsx +++ b/utilities/wallet-tester/src/common/components/CBOREditor.tsx @@ -1,3 +1,5 @@ +// cspell: words noconflict + import SwapHorizIcon from "@mui/icons-material/SwapHoriz"; import { decode, encode } from "cborg"; import { noop } from "lodash-es"; diff --git a/utilities/wallet-tester/src/common/components/TxBuilder.tsx b/utilities/wallet-tester/src/common/components/TxBuilder.tsx index 3dd58edfa30..e3e99f39794 100644 --- a/utilities/wallet-tester/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-tester/src/common/components/TxBuilder.tsx @@ -1,3 +1,5 @@ +// cspell: words Lovelaces Coeff + import { Disclosure } from "@headlessui/react"; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp"; diff --git a/utilities/wallet-tester/src/common/helpers/buildUnsingedReg.ts b/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts similarity index 95% rename from utilities/wallet-tester/src/common/helpers/buildUnsingedReg.ts rename to utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts index cde383b1597..5207873a381 100644 --- a/utilities/wallet-tester/src/common/helpers/buildUnsingedReg.ts +++ b/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts @@ -1,3 +1,5 @@ +// cspell: words Metadatum metadatum keyhash + import { Address, AuxiliaryData, @@ -38,7 +40,7 @@ type Payload = { config: TxBuilderArguments["config"]; }; -export default async function buildUnsingedReg(payload: Payload): Promise { +export default async function buildUnsignedTx(payload: Payload): Promise { // Initialize builder with protocol parameters const txBuilder = TransactionBuilder.new( TransactionBuilderConfigBuilder.new() @@ -110,11 +112,11 @@ export default async function buildUnsingedReg(payload: Payload): Promise Date: Fri, 22 Mar 2024 21:37:39 +0700 Subject: [PATCH 54/73] fix: markdown lint docs --- utilities/wallet-tester/README.md | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/utilities/wallet-tester/README.md b/utilities/wallet-tester/README.md index 9cf712a64db..c765a5259e6 100644 --- a/utilities/wallet-tester/README.md +++ b/utilities/wallet-tester/README.md @@ -4,21 +4,23 @@ 1. Make sure you have the version of Node.js 18 or 20 on your current machine as the requirement to run Vite. 2. Install all dependencies via `npm i`. -3. Done. You can develop the project via the `npm run dev` command, and build the project by running the `npm run build` command. See more scripts in `package.json`. +3. Done. + You can develop the project via the `npm run dev` command, and build the project by running the `npm run build` command. + See more scripts in `package.json`. Runs the app in the development mode.\ Open [http://localhost:3000](http://localhost:3000) to view it in your browser. ## Tools -- **Scripting**: TypeScript 5 -- **UI Framework**: React 18 -- **Styling**: Tailwind CSS -- **Async State Management**: Tanstack Query -- **UI Components**: Headless UI -- **Utilities**: Lodash -- **Icons**: Material UI Icons -- **Build Tool**: Vite +* **Scripting**: TypeScript 5 +* **UI Framework**: React 18 +* **Styling**: Tailwind CSS +* **Async State Management**: Tanstack Query +* **UI Components**: Headless UI +* **Utilities**: Lodash +* **Icons**: Material UI Icons +* **Build Tool**: Vite ## Runs with Earthly @@ -30,10 +32,11 @@ And run with docker: docker run -p ...:80 -t cat-wallet-connector ``` -## What it can do: +## What it can do + First step, the tool will scan all accessible wallets installed as browser extensions. It executes fundamental wallet actions as outlined in [CIP30](https://cips.cardano.org/cip/CIP-30/) including: -- Retrieving wallet details -- Simultaneously signing transactions using multiple wallets -- (WIP) Simultaneously signing data with multiple wallets -- (WIP) Simultaneously submitting transactions using multiple wallets +* Retrieving wallet details +* Simultaneously signing transactions using multiple wallets +* (WIP) Simultaneously signing data with multiple wallets +* (WIP) Simultaneously submitting transactions using multiple wallets From 672554304179c0f519a222f58ee6ce00715703a1 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Fri, 22 Mar 2024 21:46:40 +0700 Subject: [PATCH 55/73] chore: remove tanstack --- utilities/wallet-tester/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/utilities/wallet-tester/README.md b/utilities/wallet-tester/README.md index c765a5259e6..bb262d2d5d2 100644 --- a/utilities/wallet-tester/README.md +++ b/utilities/wallet-tester/README.md @@ -16,7 +16,6 @@ Open [http://localhost:3000](http://localhost:3000) to view it in your browser. * **Scripting**: TypeScript 5 * **UI Framework**: React 18 * **Styling**: Tailwind CSS -* **Async State Management**: Tanstack Query * **UI Components**: Headless UI * **Utilities**: Lodash * **Icons**: Material UI Icons From 52513b5f82b96c0128df854c0fe0465c40c6034c Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Tue, 26 Mar 2024 20:24:43 +0700 Subject: [PATCH 56/73] feat: builder fields --- .../src/common/components/CBOREditor.tsx | 21 ++- .../src/common/components/Dropdown.tsx | 42 +++++ .../src/common/components/TxBuilder.tsx | 144 +++++++++++++++++- .../TxBuilderMultiFieldsSection.tsx | 46 ++++++ .../TxBuilderSingleFieldSection.tsx | 41 +++++ .../src/common/helpers/buildUnsignedTx.ts | 3 +- .../src/common/helpers/extractApiData.ts | 4 +- .../src/common/helpers/json2tx.ts | 9 ++ .../src/common/helpers/tx2json.ts | 9 ++ .../wallet-tester/src/modules/SignTxPanel.tsx | 2 +- utilities/wallet-tester/src/types/cardano.ts | 56 ++++++- 11 files changed, 361 insertions(+), 16 deletions(-) create mode 100644 utilities/wallet-tester/src/common/components/Dropdown.tsx create mode 100644 utilities/wallet-tester/src/common/components/TxBuilderMultiFieldsSection.tsx create mode 100644 utilities/wallet-tester/src/common/components/TxBuilderSingleFieldSection.tsx create mode 100644 utilities/wallet-tester/src/common/helpers/json2tx.ts create mode 100644 utilities/wallet-tester/src/common/helpers/tx2json.ts diff --git a/utilities/wallet-tester/src/common/components/CBOREditor.tsx b/utilities/wallet-tester/src/common/components/CBOREditor.tsx index dcb254ce6e0..e0daa9701ca 100644 --- a/utilities/wallet-tester/src/common/components/CBOREditor.tsx +++ b/utilities/wallet-tester/src/common/components/CBOREditor.tsx @@ -1,7 +1,7 @@ // cspell: words noconflict import SwapHorizIcon from "@mui/icons-material/SwapHoriz"; -import { decode, encode } from "cborg"; +import { encode } from "cborg"; import { noop } from "lodash-es"; import { useEffect, useState, type CSSProperties } from "react"; import AceEditor from "react-ace"; @@ -13,7 +13,9 @@ import bin2hex from "common/helpers/bin2hex"; import diag2hex from "common/helpers/diag2hex"; import hex2bin from "common/helpers/hex2bin"; import hex2diag from "common/helpers/hex2diag"; +import json2tx from "common/helpers/json2tx"; import readFile from "common/helpers/readFile"; +import tx2json from "common/helpers/tx2json"; import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/mode-json"; @@ -25,6 +27,8 @@ type Mode = "bin2diag" | "bin2json"; type Props = { value: string; isReadOnly?: boolean; + cbor2json?: (hex: string) => string; + json2cbor?: (json: string) => string; onChange?: (value: string) => void; }; @@ -35,7 +39,13 @@ const EDITOR_STYLE: CSSProperties = { height: "240px", } as const; -function CBOREditor({ value, isReadOnly = false, onChange = noop }: Props) { +function CBOREditor({ + value, + cbor2json = tx2json, + json2cbor = json2tx, + isReadOnly = false, + onChange = noop, +}: Props) { const [shouldRefresh, setShouldRefresh] = useState(true); const [mode, setMode] = useState("bin2diag"); const [focusingSide, setFocusingSide] = useState(null); @@ -82,10 +92,7 @@ function CBOREditor({ value, isReadOnly = false, onChange = noop }: Props) { useEffect(() => { if (shouldRefresh) { try { - const rhsValue = - mode === "bin2diag" - ? hex2diag(value) - : JSON.stringify(value ? decode(hex2bin(value)) : undefined, null, 2); + const rhsValue = mode === "bin2diag" ? hex2diag(value) : cbor2json(value); setRhsValue(rhsValue); } catch (e) { @@ -111,7 +118,7 @@ function CBOREditor({ value, isReadOnly = false, onChange = noop }: Props) { setRhsValue(value); try { - const result = mode === "bin2diag" ? diag2hex(value) : bin2hex(encode(JSON.parse(value))); + const result = mode === "bin2diag" ? diag2hex(value) : json2cbor(value); result.includes("Error:") ? setLhsValue(result) : (onChange(result), setShouldRefresh(true)); } catch (e) { diff --git a/utilities/wallet-tester/src/common/components/Dropdown.tsx b/utilities/wallet-tester/src/common/components/Dropdown.tsx new file mode 100644 index 00000000000..577dd5ee933 --- /dev/null +++ b/utilities/wallet-tester/src/common/components/Dropdown.tsx @@ -0,0 +1,42 @@ +import { Menu } from "@headlessui/react"; +import { noop } from "lodash-es"; + +type Props = { + value: string; + items: { + label: string; + value: string; + }[]; + onSelect?: (value: string) => void; +}; + +function Dropdown({ value, items, onSelect = noop }: Props) { + const valueLabel = items.find((item) => item.value === value)?.label ?? value; + + return ( + + +

{valueLabel}

+
+ + {items.map((item) => ( + + {({ active }) => ( + + )} + + ))} + +
+ ); +} + +export default Dropdown; diff --git a/utilities/wallet-tester/src/common/components/TxBuilder.tsx b/utilities/wallet-tester/src/common/components/TxBuilder.tsx index e3e99f39794..c6bfc80d3db 100644 --- a/utilities/wallet-tester/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-tester/src/common/components/TxBuilder.tsx @@ -4,12 +4,15 @@ import { Disclosure } from "@headlessui/react"; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp"; import { cloneDeep, noop } from "lodash-es"; -import { useForm } from "react-hook-form"; +import { useFieldArray, useForm } from "react-hook-form"; -import type { TxBuilderArguments } from "types/cardano"; +import { CertificateType, type TxBuilderArguments } from "types/cardano"; import Button from "./Button"; import Input from "./Input"; +import TxBuilderMultiFieldsSection from "./TxBuilderMultiFieldsSection"; +import TxBuilderSingleFieldSection from "./TxBuilderSingleFieldSection"; +import Dropdown from "./Dropdown"; const PROTOCOL_PARAMS = { linearFee: { @@ -33,8 +36,9 @@ type Props = { }; function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { - const { handleSubmit, register, reset } = useForm({ + const { handleSubmit, register, resetField, control, reset } = useForm({ defaultValues: { + txInputs: [], regAddress: "", regAmount: "", regText: "", @@ -44,16 +48,150 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { }, }); + const txInputFields = useFieldArray({ control, name: "txInputs" }); + const txOutputFields = useFieldArray({ control, name: "txOutputs" }); + const certificateFields = useFieldArray({ control, name: "certificates" }); + const requiredSignerFields = useFieldArray({ control, name: "requiredSigners" }); + function handleReset() { reset(); } async function onSubmit(formValues: FormValues) { + console.log(formValues); onPropSubmit(formValues); } return ( + txInputFields.append({ hash: "", id: "" })} + onRemoveClick={(i) => txInputFields.remove(i)} + fields={txInputFields.fields} + render={(i) => ( +
+ + +
+ )} + /> + txOutputFields.append({ address: "", amount: "" })} + onRemoveClick={(i) => txOutputFields.remove(i)} + fields={txOutputFields.fields} + render={(i) => ( +
+ + +
+ )} + /> + resetField("transactionFee")} + render={() => ( + + )} + /> + resetField("timeToLive")} + render={() => ( + + )} + /> + + certificateFields.append({ + type: "stake_delegation", + hashType: "addr_keyhash", + hash: "", + poolKeyhash: "", + }) + } + onRemoveClick={(i) => certificateFields.remove(i)} + fields={certificateFields.fields} + render={(i) => ( +
+ ({ + value: item, + label: item, + }))} + /> +
+
+ )} + /> + resetField("auxilliaryDataHash")} + render={() => ( + + )} + /> + resetField("validityIntervalStart")} + render={() => ( + + )} + /> + requiredSignerFields.append({ hash: "" })} + onRemoveClick={(i) => requiredSignerFields.remove(i)} + fields={requiredSignerFields.fields} + render={(i) => ( +
+ +
+ )} + /> + resetField("networkId")} + render={() => } + /> + +
+
+
+
+
+
ReactNode; + fields: { + id: string; + }[]; + onAddClick?: () => void; + onRemoveClick?: (index: number) => void; +}; + +function TxBuilderMultiFieldsSection({ + heading, + render, + fields, + onAddClick = noop, + onRemoveClick = noop, +}: Props) { + return ( +
+
+

{heading}

+ +
+
+ {fields.map((field, i) => ( +
+ {render(i)} + +
+ ))} +
+
+ ); +} + +export default TxBuilderMultiFieldsSection; diff --git a/utilities/wallet-tester/src/common/components/TxBuilderSingleFieldSection.tsx b/utilities/wallet-tester/src/common/components/TxBuilderSingleFieldSection.tsx new file mode 100644 index 00000000000..8293220b6a0 --- /dev/null +++ b/utilities/wallet-tester/src/common/components/TxBuilderSingleFieldSection.tsx @@ -0,0 +1,41 @@ +import AddIcon from "@mui/icons-material/Add"; +import ClearIcon from "@mui/icons-material/Clear"; +import { noop } from "lodash-es"; +import { useState, type ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; + +type Props = { + heading: string; + render: () => ReactNode; + onAddClick?: () => void; + onRemoveClick?: () => void; +}; + +function TxBuilderSingleFieldSection({ + heading, + render, + onAddClick = noop, + onRemoveClick = noop, +}: Props) { + const [isOpen, setIsOpen] = useState(false); + + function handleToggle() { + isOpen ? onRemoveClick() : onAddClick(); + + setIsOpen((prev) => !prev); + } + + return ( +
+
+

{heading}

+ +
+
{render()}
+
+ ); +} + +export default TxBuilderSingleFieldSection; diff --git a/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts b/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts index 5207873a381..8c223d34bca 100644 --- a/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts +++ b/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts @@ -11,6 +11,7 @@ import { Transaction, TransactionBuilder, TransactionBuilderConfigBuilder, + TransactionInput, TransactionMetadatum, TransactionOutput, TransactionUnspentOutput, @@ -66,8 +67,8 @@ export default async function buildUnsignedTx(payload: Payload): Promise { const safeTry = async ( fn: () => Promise, transformer?: (v: T) => T - ): Promise<{ raw: T; formatted: T; }> => { + ): Promise<{ raw: T; formatted: T }> => { try { const v = await fn(); return transformer diff --git a/utilities/wallet-tester/src/common/helpers/json2tx.ts b/utilities/wallet-tester/src/common/helpers/json2tx.ts new file mode 100644 index 00000000000..7c9c125a65f --- /dev/null +++ b/utilities/wallet-tester/src/common/helpers/json2tx.ts @@ -0,0 +1,9 @@ +import { Transaction } from "@emurgo/cardano-serialization-lib-asmjs"; + +import bin2hex from "./bin2hex"; + +export default function json2tx(json: string): string { + const tx = Transaction.from_json(json); + + return bin2hex(tx.to_bytes()); +} diff --git a/utilities/wallet-tester/src/common/helpers/tx2json.ts b/utilities/wallet-tester/src/common/helpers/tx2json.ts new file mode 100644 index 00000000000..6fba2d7728c --- /dev/null +++ b/utilities/wallet-tester/src/common/helpers/tx2json.ts @@ -0,0 +1,9 @@ +import { Transaction } from "@emurgo/cardano-serialization-lib-asmjs"; + +import cleanHex from "./cleanHex"; + +export default function tx2json(hex: string): string { + const tx = Transaction.from_hex(cleanHex(hex)); + + return JSON.stringify(hex ? tx.to_js_value() : undefined, null, 2); +} diff --git a/utilities/wallet-tester/src/modules/SignTxPanel.tsx b/utilities/wallet-tester/src/modules/SignTxPanel.tsx index 61cdecba61b..c1fd5e03fd7 100644 --- a/utilities/wallet-tester/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-tester/src/modules/SignTxPanel.tsx @@ -74,7 +74,7 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { config: builderArgs.config, }); - resTx[walletName] = bin2hex(encode(tx.to_js_value())); + resTx[walletName] = bin2hex(tx.to_bytes()); } setValue("tx", resTx); diff --git a/utilities/wallet-tester/src/types/cardano.ts b/utilities/wallet-tester/src/types/cardano.ts index 169419007bc..57ab1753c03 100644 --- a/utilities/wallet-tester/src/types/cardano.ts +++ b/utilities/wallet-tester/src/types/cardano.ts @@ -4,8 +4,8 @@ import * as cip30 from "@cardano-sdk/cip30"; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number; }[]; }): Promise; - supportedExtensions: { cip: number; }[]; + enable(args: { extensions: { cip: number }[] }): Promise; + supportedExtensions: { cip: number }[]; }; }; @@ -27,7 +27,59 @@ export type ExtractedWalletApi = { [key: `cip${number}`]: any; }; +export enum CertificateType { + StakeRegistration = "stake_registration", + StakeDeregistration = "stake_deregistration", + StakeDelegation = "stake_delegation", + PoolRegistration = "pool_registration", + PoolRetirement = "pool_retirement", + GenesisKeyDelegation = "genesis_key_delegation", + MoveInstantaneousRewardsCert = "move_instantaneous_rewards_cert", +} + export type TxBuilderArguments = { + txInputs: { + hash: string; + id: string; + }[]; + txOutputs: { + address: string; + amount: string; + }[]; + timeToLive: string; + certificates: ( + | { + type: "stake_registration"; + } + | { + type: "stake_deregistration"; + } + | { + type: "stake_delegation"; + hashType: "addr_keyhash" | "scripthash"; + hash: string; + poolKeyhash: string; + } + | { + type: "pool_registration"; + } + | { + type: "pool_retirement"; + } + | { + type: "genesis_key_delegation"; + } + | { + type: "move_instantaneous_rewards_cert"; + } + )[]; + transactionFee: string; + auxilliaryDataHash: string; + validityIntervalStart: string; + requiredSigners: { + hash: string; + }[]; + networkId: string; regAddress: string; regAmount: string; regText: string; From b83ca02c28518e1f449f56c06f2df3eb55e802eb Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Tue, 26 Mar 2024 20:25:44 +0700 Subject: [PATCH 57/73] chore: lintfix --- .../wallet-tester/src/common/components/Dropdown.tsx | 8 +++++--- .../wallet-tester/src/common/components/TxBuilder.tsx | 2 +- .../wallet-tester/src/common/helpers/extractApiData.ts | 4 ++-- utilities/wallet-tester/src/types/cardano.ts | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/utilities/wallet-tester/src/common/components/Dropdown.tsx b/utilities/wallet-tester/src/common/components/Dropdown.tsx index 577dd5ee933..31dfeef4a47 100644 --- a/utilities/wallet-tester/src/common/components/Dropdown.tsx +++ b/utilities/wallet-tester/src/common/components/Dropdown.tsx @@ -1,5 +1,6 @@ import { Menu } from "@headlessui/react"; import { noop } from "lodash-es"; +import { twMerge } from "tailwind-merge"; type Props = { value: string; @@ -25,9 +26,10 @@ function Dropdown({ value, items, onSelect = noop }: Props) { diff --git a/utilities/wallet-tester/src/common/components/TxBuilder.tsx b/utilities/wallet-tester/src/common/components/TxBuilder.tsx index c6bfc80d3db..911ac522aa2 100644 --- a/utilities/wallet-tester/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-tester/src/common/components/TxBuilder.tsx @@ -9,10 +9,10 @@ import { useFieldArray, useForm } from "react-hook-form"; import { CertificateType, type TxBuilderArguments } from "types/cardano"; import Button from "./Button"; +import Dropdown from "./Dropdown"; import Input from "./Input"; import TxBuilderMultiFieldsSection from "./TxBuilderMultiFieldsSection"; import TxBuilderSingleFieldSection from "./TxBuilderSingleFieldSection"; -import Dropdown from "./Dropdown"; const PROTOCOL_PARAMS = { linearFee: { diff --git a/utilities/wallet-tester/src/common/helpers/extractApiData.ts b/utilities/wallet-tester/src/common/helpers/extractApiData.ts index 5e6a2d07b0a..32519797992 100644 --- a/utilities/wallet-tester/src/common/helpers/extractApiData.ts +++ b/utilities/wallet-tester/src/common/helpers/extractApiData.ts @@ -5,13 +5,13 @@ import { camelCase, mapValues } from "lodash-es"; import type { ExtractedWalletApi } from "types/cardano"; export default async function extractApiData( - api: WalletApi & { [ext: `cip${number}`]: unknown }, + api: WalletApi & { [ext: `cip${number}`]: unknown; }, cipExt?: number ): Promise { const safeTry = async ( fn: () => Promise, transformer?: (v: T) => T - ): Promise<{ raw: T; formatted: T }> => { + ): Promise<{ raw: T; formatted: T; }> => { try { const v = await fn(); return transformer diff --git a/utilities/wallet-tester/src/types/cardano.ts b/utilities/wallet-tester/src/types/cardano.ts index 57ab1753c03..d510ede21b4 100644 --- a/utilities/wallet-tester/src/types/cardano.ts +++ b/utilities/wallet-tester/src/types/cardano.ts @@ -4,8 +4,8 @@ import * as cip30 from "@cardano-sdk/cip30"; export type WalletCollections = { [k: string]: Omit & { - enable(args: { extensions: { cip: number }[] }): Promise; - supportedExtensions: { cip: number }[]; + enable(args: { extensions: { cip: number; }[]; }): Promise; + supportedExtensions: { cip: number; }[]; }; }; From 6e4d00512e9ae2179b96ee917a3aec899e8b1e5d Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Wed, 27 Mar 2024 00:59:59 +0700 Subject: [PATCH 58/73] feat: certificate stake delegation --- .../src/common/components/Dropdown.tsx | 13 ++- .../src/common/components/TxBuilder.tsx | 87 ++++++++++++++++--- utilities/wallet-tester/src/types/cardano.ts | 16 ++-- 3 files changed, 95 insertions(+), 21 deletions(-) diff --git a/utilities/wallet-tester/src/common/components/Dropdown.tsx b/utilities/wallet-tester/src/common/components/Dropdown.tsx index 31dfeef4a47..c17d99ad2e1 100644 --- a/utilities/wallet-tester/src/common/components/Dropdown.tsx +++ b/utilities/wallet-tester/src/common/components/Dropdown.tsx @@ -1,4 +1,6 @@ import { Menu } from "@headlessui/react"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; import { noop } from "lodash-es"; import { twMerge } from "tailwind-merge"; @@ -7,6 +9,7 @@ type Props = { items: { label: string; value: string; + disabled?: boolean; }[]; onSelect?: (value: string) => void; }; @@ -16,8 +19,13 @@ function Dropdown({ value, items, onSelect = noop }: Props) { return ( - -

{valueLabel}

+ + {({ open }) => ( + <> +

{valueLabel}

+ {open ? : } + + )}
{items.map((item) => ( @@ -25,6 +33,7 @@ function Dropdown({ value, items, onSelect = noop }: Props) { {({ active }) => (
)} @@ -122,7 +125,7 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { heading="Certificates" onAddClick={() => certificateFields.append({ - type: "stake_delegation", + type: CertificateType.StakeDelegation, hashType: "addr_keyhash", hash: "", poolKeyhash: "", @@ -131,15 +134,77 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { onRemoveClick={(i) => certificateFields.remove(i)} fields={certificateFields.fields} render={(i) => ( -
+
({ - value: item, - label: item, + value={certificateFields.fields[i]?.type ?? ""} + items={Object.entries(CertificateType).map(([key, value]) => ({ + value: value, + label: capitalize(upperCase(key)), + // TODO: add more type support + disabled: value !== CertificateType.StakeDelegation, }))} + onSelect={(value) => + certificateFields.fields[i]?.type === value + ? null + : certificateFields.replace({ + type: value /* TODO: support default values for each type */, + }) + } /> -
+ {certificateFields.fields[i]?.type === CertificateType.StakeDelegation ? ( +
+
+ + +
+
+ + +
+
+ ) : null}
)} /> diff --git a/utilities/wallet-tester/src/types/cardano.ts b/utilities/wallet-tester/src/types/cardano.ts index d510ede21b4..ada93926297 100644 --- a/utilities/wallet-tester/src/types/cardano.ts +++ b/utilities/wallet-tester/src/types/cardano.ts @@ -40,7 +40,7 @@ export enum CertificateType { export type TxBuilderArguments = { txInputs: { hash: string; - id: string; + index: string; }[]; txOutputs: { address: string; @@ -49,28 +49,28 @@ export type TxBuilderArguments = { timeToLive: string; certificates: ( | { - type: "stake_registration"; + type: CertificateType.StakeRegistration; } | { - type: "stake_deregistration"; + type: CertificateType.StakeDeregistration; } | { - type: "stake_delegation"; + type: CertificateType.StakeDelegation; hashType: "addr_keyhash" | "scripthash"; hash: string; poolKeyhash: string; } | { - type: "pool_registration"; + type: CertificateType.PoolRegistration; } | { - type: "pool_retirement"; + type: CertificateType.PoolRetirement; } | { - type: "genesis_key_delegation"; + type: CertificateType.GenesisKeyDelegation; } | { - type: "move_instantaneous_rewards_cert"; + type: CertificateType.MoveInstantaneousRewardsCert; } )[]; transactionFee: string; From 75cf9a938b51b81c36d8c04cc827d8dcc5dd37fc Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Thu, 28 Mar 2024 20:23:03 +0700 Subject: [PATCH 59/73] feat: apply builder fields to builder function --- .../src/common/components/SwitchButton.tsx | 0 .../src/common/components/TxBuilder.tsx | 49 ++-- .../src/common/helpers/buildUnsignedTx.ts | 235 ++++++++++++------ .../wallet-tester/src/modules/SignTxPanel.tsx | 73 ++---- utilities/wallet-tester/src/types/cardano.ts | 15 +- 5 files changed, 219 insertions(+), 153 deletions(-) create mode 100644 utilities/wallet-tester/src/common/components/SwitchButton.tsx diff --git a/utilities/wallet-tester/src/common/components/SwitchButton.tsx b/utilities/wallet-tester/src/common/components/SwitchButton.tsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utilities/wallet-tester/src/common/components/TxBuilder.tsx b/utilities/wallet-tester/src/common/components/TxBuilder.tsx index 16f7a77e491..d14838bfecb 100644 --- a/utilities/wallet-tester/src/common/components/TxBuilder.tsx +++ b/utilities/wallet-tester/src/common/components/TxBuilder.tsx @@ -3,8 +3,6 @@ import { Disclosure } from "@headlessui/react"; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp"; -import SwitchLeftIcon from "@mui/icons-material/SwitchLeft"; -import SwitchRightIcon from "@mui/icons-material/SwitchRight"; import { capitalize, cloneDeep, noop, upperCase } from "lodash-es"; import { useFieldArray, useForm } from "react-hook-form"; import { twMerge } from "tailwind-merge"; @@ -35,10 +33,12 @@ const PROTOCOL_PARAMS = { type FormValues = TxBuilderArguments; type Props = { + txIds: string[]; + addrs: string[]; onSubmit?: (value: FormValues) => void; }; -function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { +function TxBuilder({ txIds, addrs, onSubmit: onPropSubmit = noop }: Props) { const { handleSubmit, register, resetField, control, reset } = useForm({ defaultValues: { txInputs: [], @@ -69,20 +69,17 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { txInputFields.append({ hash: "", index: "" })} + onAddClick={() => txInputFields.append({ hex: "" })} onRemoveClick={(i) => txInputFields.remove(i)} fields={txInputFields.fields} render={(i) => ( -
+
-
)} @@ -93,12 +90,14 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { onRemoveClick={(i) => txOutputFields.remove(i)} fields={txOutputFields.fields} render={(i) => ( -
- +
+
+ +
{certificateFields.fields[i]?.type === CertificateType.StakeDelegation ? ( @@ -159,7 +158,7 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { className={twMerge( "w-full rounded px-1 border border-solid border-black", certificateFields.fields[i]?.hashType === "addr_keyhash" && - "bg-black text-white" + "bg-black text-white" )} onClick={() => certificateFields.update(i, { @@ -175,7 +174,7 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { className={twMerge( "w-full rounded px-1 border border-solid border-black", certificateFields.fields[i]?.hashType === "scripthash" && - "bg-black text-white" + "bg-black text-white" )} onClick={() => certificateFields.update(i, { @@ -232,15 +231,15 @@ function TxBuilder({ onSubmit: onPropSubmit = noop }: Props) { /> requiredSignerFields.append({ hash: "" })} + onAddClick={() => requiredSignerFields.append({ address: "" })} onRemoveClick={(i) => requiredSignerFields.remove(i)} fields={requiredSignerFields.fields} render={(i) => ( -
+
)} diff --git a/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts b/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts index 8c223d34bca..22b18c28fbe 100644 --- a/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts +++ b/utilities/wallet-tester/src/common/helpers/buildUnsignedTx.ts @@ -11,113 +11,200 @@ import { Transaction, TransactionBuilder, TransactionBuilderConfigBuilder, - TransactionInput, TransactionMetadatum, TransactionOutput, TransactionUnspentOutput, TransactionUnspentOutputs, TransactionWitnessSet, - Value, + Value } from "@emurgo/cardano-serialization-lib-asmjs"; import type { TxBuilderArguments } from "types/cardano"; -type Payload = { - /** Raw registration address in hex string. */ - regAddress: string; - /** String number in lovelace unit. */ - regAmount: string; - /** Transaction metadatum text, e.g., Cardano Wallet Tester. */ - regText: string; - /** Transaction metadatum label, e.g., 98117105100108. */ - regLabel: string; - /** Raw hex string address from `API.getUsedAddresses()`. */ - usedAddresses: string[]; - /** Raw hex string address from `API.getChangeAddress()`. */ - changeAddress: string; - /** Raw hex string UTXOs directed from calling `API.getUtxos()`. */ - rawUtxos: string[]; - /** Transaction config */ - config: TxBuilderArguments["config"]; -}; - -export default async function buildUnsignedTx(payload: Payload): Promise { +export default async function buildUnsignedTx(payload: TxBuilderArguments): Promise { + const { config, ...builder } = payload; + // Initialize builder with protocol parameters const txBuilder = TransactionBuilder.new( TransactionBuilderConfigBuilder.new() .fee_algo( LinearFee.new( - BigNum.from_str(payload.config.linearFee.minFeeA), - BigNum.from_str(payload.config.linearFee.minFeeB) + BigNum.from_str(config.linearFee.minFeeA), + BigNum.from_str(config.linearFee.minFeeB) ) ) - .pool_deposit(BigNum.from_str(payload.config.poolDeposit)) - .key_deposit(BigNum.from_str(payload.config.keyDeposit)) - .coins_per_utxo_word(BigNum.from_str(payload.config.coinsPerUtxoWord)) - .max_value_size(payload.config.maxValSize) - .max_tx_size(payload.config.maxTxSize) + .pool_deposit(BigNum.from_str(config.poolDeposit)) + .key_deposit(BigNum.from_str(config.keyDeposit)) + .coins_per_utxo_word(BigNum.from_str(config.coinsPerUtxoWord)) + .max_value_size(config.maxValSize) + .max_tx_size(config.maxTxSize) .prefer_pure_change(true) .build() ); - // Set address to send ada to - const registrationAddress = Address.from_bech32(payload.regAddress); + // add inputs + const utxos = TransactionUnspentOutputs.new(); + for (const input of builder.txInputs) { + const utxo = TransactionUnspentOutput.from_hex(input.hex); + utxos.add(utxo); + } - // Set amount to send - const registrationAmount = Value.new(BigNum.from_str(payload.regAmount)); + if (utxos.len()) { + txBuilder.add_inputs_from(utxos, 3); + } - // Set transactional metadatum message - const regMessageMetadatumLabel = BigNum.from_str(payload.regLabel); - const regMessageMetadatum = TransactionMetadatum.new_text(payload.regText); + // add outputs + for (const output of builder.txOutputs) { + const address = Address.from_bech32(output.address); + const amount = Value.new(BigNum.from_str(output.amount)); + txBuilder.add_output(TransactionOutput.new(address, amount)); + } - // Create Tx metadata object and parse into auxiliary data - const txMetadata = GeneralTransactionMetadata.new(); - txMetadata.insert(regMessageMetadatumLabel, regMessageMetadatum); - const auxMetadata = AuxiliaryData.new(); - auxMetadata.set_metadata(txMetadata); + // add required signers + for (const requiredSigner of builder.requiredSigners) { + const stakeCred = BaseAddress.from_address(Address.from_bech32(requiredSigner.address)) + ?.stake_cred() + .to_keyhash() + ?.to_hex(); - // Add metadatum to transaction builder, so it can be included in the transaction balancing - txBuilder.set_auxiliary_data(auxMetadata); + if (!stakeCred) { + throw new Error("cannot create a stake credential"); + } - // Add extra signature witness to transaction builder - if (!payload.usedAddresses[0]) { - throw new Error("cannot find any used address"); + txBuilder.add_required_signer(Ed25519KeyHash.from_hex(stakeCred)); } - const stakeCred = BaseAddress.from_address(Address.from_hex(payload.usedAddresses[0])) - ?.stake_cred() - .to_keyhash() - ?.to_hex(); - - if (!stakeCred) { - throw new Error("cannot create a stake credential"); + // aux data + const auxMetadata = AuxiliaryData.new(); + const txMetadata = GeneralTransactionMetadata.new(); + for (const item of builder.auxMetadata.metadata) { + const regMessageMetadatumLabel = BigNum.from_str(item.key); + // TODO: support other types + const regMessageMetadatum = TransactionMetadatum.new_text(item.value); + txMetadata.insert(regMessageMetadatumLabel, regMessageMetadatum); } - txBuilder.add_required_signer(Ed25519KeyHash.from_hex(stakeCred)); - - // Add outputs to the transaction builder - txBuilder.add_output(TransactionOutput.new(registrationAddress, registrationAmount)); - - // Find the available UTxOs in the wallet and use them as Inputs for the transaction - const txUnspentOutputs = payload.rawUtxos.reduce((acc, utxo) => { - acc.add(TransactionUnspentOutput.from_hex(utxo)); - return acc; - }, TransactionUnspentOutputs.new()); - // Use UTxO selection strategy RandomImproveMultiAsset aka 3 - txBuilder.add_inputs_from(txUnspentOutputs, 3); - - // Set change address, incase too much ADA provided for fee - const shelleyChangeAddress = Address.from_hex(payload.changeAddress); - txBuilder.add_change_if_needed(shelleyChangeAddress); + if (txMetadata.len()) { + auxMetadata.set_metadata(txMetadata); + } - // Make a full transaction, passing in empty witness set - const txBody = txBuilder.build(); - const transactionWitnessSet = TransactionWitnessSet.new(); + // build a full transaction, passing in empty witness set const unsignedTx = Transaction.new( - txBody, - TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()), + txBuilder.build(), + TransactionWitnessSet.new(), auxMetadata ); return unsignedTx; } + +// type Payload = { +// /** Raw registration address in hex string. */ +// regAddress: string; +// /** String number in lovelace unit. */ +// regAmount: string; +// /** Transaction metadatum text, e.g., Cardano Wallet Tester. */ +// regText: string; +// /** Transaction metadatum label, e.g., 98117105100108. */ +// regLabel: string; +// /** Raw hex string address from `API.getUsedAddresses()`. */ +// usedAddresses: string[]; +// /** Raw hex string address from `API.getChangeAddress()`. */ +// changeAddress: string; +// /** Raw hex string UTXOs directed from calling `API.getUtxos()`. */ +// rawUtxos: string[]; +// /** Transaction config */ +// config: TxBuilderArguments["config"]; +// }; + +// const tx = await buildUnsignedTx({ +// regAddress: builderArgs.regAddress, +// regAmount: builderArgs.regAmount, +// regLabel: builderArgs.regLabel, +// regText: builderArgs.regText, +// usedAddresses: api.info["usedAddresses"]?.raw, +// changeAddress: api.info["changeAddress"]?.raw, +// rawUtxos: api.info["utxos"]?.raw, +// config: builderArgs.config, +// }); + +// export default async function buildUnsignedTx(payload: Payload): Promise { +// // Initialize builder with protocol parameters +// const txBuilder = TransactionBuilder.new( +// TransactionBuilderConfigBuilder.new() +// .fee_algo( +// LinearFee.new( +// BigNum.from_str(payload.config.linearFee.minFeeA), +// BigNum.from_str(payload.config.linearFee.minFeeB) +// ) +// ) +// .pool_deposit(BigNum.from_str(payload.config.poolDeposit)) +// .key_deposit(BigNum.from_str(payload.config.keyDeposit)) +// .coins_per_utxo_word(BigNum.from_str(payload.config.coinsPerUtxoWord)) +// .max_value_size(payload.config.maxValSize) +// .max_tx_size(payload.config.maxTxSize) +// .prefer_pure_change(true) +// .build() +// ); + +// // Set address to send ada to +// const registrationAddress = Address.from_bech32(payload.regAddress); + +// // Set amount to send +// const registrationAmount = Value.new(BigNum.from_str(payload.regAmount)); + +// // Set transactional metadatum message +// const regMessageMetadatumLabel = BigNum.from_str(payload.regLabel); +// const regMessageMetadatum = TransactionMetadatum.new_text(payload.regText); + +// // Create Tx metadata object and parse into auxiliary data +// const txMetadata = GeneralTransactionMetadata.new(); +// txMetadata.insert(regMessageMetadatumLabel, regMessageMetadatum); +// const auxMetadata = AuxiliaryData.new(); +// auxMetadata.set_metadata(txMetadata); + +// // Add metadatum to transaction builder, so it can be included in the transaction balancing +// txBuilder.set_auxiliary_data(auxMetadata); + +// // Add extra signature witness to transaction builder +// if (!payload.usedAddresses[0]) { +// throw new Error("cannot find any used address"); +// } + +// const stakeCred = BaseAddress.from_address(Address.from_hex(payload.usedAddresses[0])) +// ?.stake_cred() +// .to_keyhash() +// ?.to_hex(); + +// if (!stakeCred) { +// throw new Error("cannot create a stake credential"); +// } + +// txBuilder.add_required_signer(Ed25519KeyHash.from_hex(stakeCred)); + +// // Add outputs to the transaction builder +// txBuilder.add_output(TransactionOutput.new(registrationAddress, registrationAmount)); + +// // Find the available UTxOs in the wallet and use them as Inputs for the transaction +// const txUnspentOutputs = payload.rawUtxos.reduce((acc, utxo) => { +// acc.add(TransactionUnspentOutput.from_hex(utxo)); +// return acc; +// }, TransactionUnspentOutputs.new()); +// // Use UTxO selection strategy RandomImproveMultiAsset aka 3 +// txBuilder.add_inputs_from(txUnspentOutputs, 3); + +// // Set change address, incase too much ADA provided for fee +// const shelleyChangeAddress = Address.from_hex(payload.changeAddress); +// txBuilder.add_change_if_needed(shelleyChangeAddress); + +// // Make a full transaction, passing in empty witness set +// const txBody = txBuilder.build(); +// const transactionWitnessSet = TransactionWitnessSet.new(); +// const unsignedTx = Transaction.new( +// txBody, +// TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes()), +// auxMetadata +// ); + +// return unsignedTx; +// } \ No newline at end of file diff --git a/utilities/wallet-tester/src/modules/SignTxPanel.tsx b/utilities/wallet-tester/src/modules/SignTxPanel.tsx index c1fd5e03fd7..d4c9fc5f5e5 100644 --- a/utilities/wallet-tester/src/modules/SignTxPanel.tsx +++ b/utilities/wallet-tester/src/modules/SignTxPanel.tsx @@ -1,8 +1,8 @@ import { Transaction, TransactionWitnessSet } from "@emurgo/cardano-serialization-lib-asmjs"; import RefreshIcon from "@mui/icons-material/Refresh"; import { decode, encode } from "cborg"; -import { isEmpty } from "lodash-es"; -import { Fragment, useEffect, useState } from "react"; +import { isEmpty, pickBy } from "lodash-es"; +import { useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { toast } from "react-toastify"; @@ -32,52 +32,33 @@ type Response = { type FormValues = { partialSign: boolean; - tx: { - [walletName: string]: string; - }; + tx: string; }; function SignTxPanel({ selectedWallets, walletApi }: Props) { - const [selectedTxWallet, setSelectedTxWallet] = useState(""); const [isLoading, setIsLoading] = useState(false); const [response, setResponse] = useState({}); const [selectedResponseWallet, setSelectedResponseWallet] = useState(""); const [editorRefreshSignal, setEditorRefreshSignal] = useState(0); - useEffect(() => { - const walletNames = Object.keys(walletApi).filter((w) => selectedWallets.includes(w)); - - setSelectedTxWallet((prev) => (selectedWallets.includes(prev) ? prev : walletNames[0] ?? "")); - }, [walletApi, selectedWallets]); - const { control, handleSubmit, setValue } = useForm({ defaultValues: { partialSign: false, - tx: {}, + tx: "", }, }); + const sellectedWalletApi = pickBy(walletApi, (v, k) => selectedWallets.includes(k)); + const txIds = []; + const addrs = [ + ...Object.values(walletApi).flatMap((api) => api.info["usedAddresses"]?.value ?? []) + ]; + async function handleTxBuilderSubmit(builderArgs: TxBuilderArguments) { try { - const activeWallets = Object.entries(walletApi).filter(([w]) => selectedWallets.includes(w)); - - const resTx: FormValues["tx"] = {}; - for (const [walletName, api] of activeWallets) { - const tx = await buildUnsignedTx({ - regAddress: builderArgs.regAddress, - regAmount: builderArgs.regAmount, - regLabel: builderArgs.regLabel, - regText: builderArgs.regText, - usedAddresses: api.info["usedAddresses"]?.raw, - changeAddress: api.info["changeAddress"]?.raw, - rawUtxos: api.info["utxos"]?.raw, - config: builderArgs.config, - }); - - resTx[walletName] = bin2hex(tx.to_bytes()); - } + const tx = await buildUnsignedTx(builderArgs); - setValue("tx", resTx); + setValue("tx", bin2hex(tx.to_bytes())); setEditorRefreshSignal((prev) => (prev ? 0 : 1)); } catch (err) { return void toast.error(String(err)); @@ -148,30 +129,20 @@ function SignTxPanel({ selectedWallets, walletApi }: Props) { name="tx" render={({ field: { value, onChange } }) => (
- - {selectedTxWallet ? ( - <> - selectedWallets.includes(w))} - onSelect={setSelectedTxWallet} - /> - - onChange({ ...value, [selectedTxWallet]: v })} - /> - - - ) : ( - - )} + {/* TODO: add empty */} + +
)} /> - {selectedTxWallet && ( + {isEmpty(sellectedWalletApi) ? ( + + ) : (
From 90db9592be99bee961d7ba9bed1a470db909c673 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Wed, 3 Apr 2024 16:32:05 +0700 Subject: [PATCH 72/73] fix: docs: earthfile --- utilities/wallet-tester/Earthfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/wallet-tester/Earthfile b/utilities/wallet-tester/Earthfile index c5d2cb2689c..0926786d823 100644 --- a/utilities/wallet-tester/Earthfile +++ b/utilities/wallet-tester/Earthfile @@ -24,7 +24,7 @@ build: SAVE ARTIFACT dist -# local - Makes a docker image that can serve the docs for development purposes. +# local - Makes a docker image that can serve the app for development purposes. local: FROM nginx:1.25-alpine From dff0e0936a71621f11b190d60735c2677d0a9336 Mon Sep 17 00:00:00 2001 From: Apisit Ritreungroj Date: Mon, 8 Apr 2024 19:41:26 +0700 Subject: [PATCH 73/73] chore: remove empty switch button component --- utilities/wallet-tester/src/common/components/SwitchButton.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 utilities/wallet-tester/src/common/components/SwitchButton.tsx diff --git a/utilities/wallet-tester/src/common/components/SwitchButton.tsx b/utilities/wallet-tester/src/common/components/SwitchButton.tsx deleted file mode 100644 index e69de29bb2d..00000000000