diff --git a/examples/typescript/passkey/.eslintrc.cjs b/examples/typescript/passkey/.eslintrc.cjs
new file mode 100644
index 000000000..d6c953795
--- /dev/null
+++ b/examples/typescript/passkey/.eslintrc.cjs
@@ -0,0 +1,18 @@
+module.exports = {
+ root: true,
+ env: { browser: true, es2020: true },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:react-hooks/recommended',
+ ],
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
+ parser: '@typescript-eslint/parser',
+ plugins: ['react-refresh'],
+ rules: {
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true },
+ ],
+ },
+}
diff --git a/examples/typescript/passkey/.gitignore b/examples/typescript/passkey/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/examples/typescript/passkey/.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?
diff --git a/examples/typescript/passkey/README.md b/examples/typescript/passkey/README.md
new file mode 100644
index 000000000..1ebe379f5
--- /dev/null
+++ b/examples/typescript/passkey/README.md
@@ -0,0 +1,27 @@
+# React + TypeScript + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+
+Currently, two official plugins are available:
+
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+
+## Expanding the ESLint configuration
+
+If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
+
+- Configure the top-level `parserOptions` property like this:
+
+```js
+ parserOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ project: ['./tsconfig.json', './tsconfig.node.json'],
+ tsconfigRootDir: __dirname,
+ },
+```
+
+- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
+- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
+- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
diff --git a/examples/typescript/passkey/index.html b/examples/typescript/passkey/index.html
new file mode 100644
index 000000000..e4b78eae1
--- /dev/null
+++ b/examples/typescript/passkey/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite + React + TS
+
+
+
+
+
+
diff --git a/examples/typescript/passkey/package.json b/examples/typescript/passkey/package.json
new file mode 100644
index 000000000..2f8a785ee
--- /dev/null
+++ b/examples/typescript/passkey/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "passkey-ts",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@noble/hashes": "^1.3.2",
+ "@simplewebauthn/server": "^8.3.5",
+ "aptos": "^1.20.0",
+ "base64url": "^3.0.1",
+ "crypto-js": "^4.2.0",
+ "elliptic": "^6.5.4",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "peerDependencies": {
+ "@aptos-labs/ts-sdk": "link:../../.."
+ },
+ "devDependencies": {
+ "@types/crypto-js": "^4.2.2",
+ "@types/elliptic": "^6.4.18",
+ "@types/react": "^18.2.15",
+ "@types/react-dom": "^18.2.7",
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
+ "@typescript-eslint/parser": "^6.0.0",
+ "@vitejs/plugin-react": "^4.0.3",
+ "eslint": "^8.45.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.4.3",
+ "sha256": "link:@types/crypto-js/sha256",
+ "typescript": "^5.0.2",
+ "vite": "^4.4.5"
+ }
+}
diff --git a/examples/typescript/passkey/pnpm-lock.yaml b/examples/typescript/passkey/pnpm-lock.yaml
new file mode 100644
index 000000000..f3ddfd4ba
--- /dev/null
+++ b/examples/typescript/passkey/pnpm-lock.yaml
@@ -0,0 +1,2351 @@
+lockfileVersion: '6.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+dependencies:
+ '@aptos-labs/ts-sdk':
+ specifier: link:../../..
+ version: link:../../..
+ '@noble/hashes':
+ specifier: ^1.3.2
+ version: 1.3.2
+ '@simplewebauthn/server':
+ specifier: ^8.3.5
+ version: 8.3.5
+ aptos:
+ specifier: ^1.20.0
+ version: 1.20.0
+ base64url:
+ specifier: ^3.0.1
+ version: 3.0.1
+ crypto-js:
+ specifier: ^4.2.0
+ version: 4.2.0
+ elliptic:
+ specifier: ^6.5.4
+ version: 6.5.4
+ react:
+ specifier: ^18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: ^18.2.0
+ version: 18.2.0(react@18.2.0)
+
+devDependencies:
+ '@types/crypto-js':
+ specifier: ^4.2.2
+ version: 4.2.2
+ '@types/elliptic':
+ specifier: ^6.4.18
+ version: 6.4.18
+ '@types/react':
+ specifier: ^18.2.15
+ version: 18.2.28
+ '@types/react-dom':
+ specifier: ^18.2.7
+ version: 18.2.13
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^6.0.0
+ version: 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/parser':
+ specifier: ^6.0.0
+ version: 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ '@vitejs/plugin-react':
+ specifier: ^4.0.3
+ version: 4.1.0(vite@4.4.11)
+ eslint:
+ specifier: ^8.45.0
+ version: 8.51.0
+ eslint-plugin-react-hooks:
+ specifier: ^4.6.0
+ version: 4.6.0(eslint@8.51.0)
+ eslint-plugin-react-refresh:
+ specifier: ^0.4.3
+ version: 0.4.3(eslint@8.51.0)
+ sha256:
+ specifier: link:@types/crypto-js/sha256
+ version: link:@types/crypto-js/sha256
+ typescript:
+ specifier: ^5.0.2
+ version: 5.2.2
+ vite:
+ specifier: ^4.4.5
+ version: 4.4.11
+
+packages:
+
+ /@aashutoshrathi/word-wrap@1.2.6:
+ resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /@ampproject/remapping@2.2.1:
+ resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.3
+ '@jridgewell/trace-mapping': 0.3.19
+ dev: true
+
+ /@aptos-labs/aptos-client@0.0.2:
+ resolution: {integrity: sha512-FgKZb5zDPz8MmAcVxXzYhxP6OkzuIPoDRJp48YJ8+vrZ9EOZ35HaWGN2M3u+GPdnFE9mODFqkxw3azh3kHGZjQ==}
+ engines: {node: '>=15.10.0'}
+ dependencies:
+ axios: 0.27.2
+ got: 11.8.6
+ transitivePeerDependencies:
+ - debug
+ dev: false
+
+ /@babel/code-frame@7.22.13:
+ resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/highlight': 7.22.20
+ chalk: 2.4.2
+ dev: true
+
+ /@babel/compat-data@7.23.2:
+ resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/core@7.23.2:
+ resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@ampproject/remapping': 2.2.1
+ '@babel/code-frame': 7.22.13
+ '@babel/generator': 7.23.0
+ '@babel/helper-compilation-targets': 7.22.15
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2)
+ '@babel/helpers': 7.23.2
+ '@babel/parser': 7.23.0
+ '@babel/template': 7.22.15
+ '@babel/traverse': 7.23.2
+ '@babel/types': 7.23.0
+ convert-source-map: 2.0.0
+ debug: 4.3.4
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/generator@7.23.0:
+ resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.23.0
+ '@jridgewell/gen-mapping': 0.3.3
+ '@jridgewell/trace-mapping': 0.3.19
+ jsesc: 2.5.2
+ dev: true
+
+ /@babel/helper-compilation-targets@7.22.15:
+ resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/compat-data': 7.23.2
+ '@babel/helper-validator-option': 7.22.15
+ browserslist: 4.22.1
+ lru-cache: 5.1.1
+ semver: 6.3.1
+ dev: true
+
+ /@babel/helper-environment-visitor@7.22.20:
+ resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helper-function-name@7.23.0:
+ resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/template': 7.22.15
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/helper-hoist-variables@7.22.5:
+ resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/helper-module-imports@7.22.15:
+ resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.23.2
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-module-imports': 7.22.15
+ '@babel/helper-simple-access': 7.22.5
+ '@babel/helper-split-export-declaration': 7.22.6
+ '@babel/helper-validator-identifier': 7.22.20
+ dev: true
+
+ /@babel/helper-plugin-utils@7.22.5:
+ resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helper-simple-access@7.22.5:
+ resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/helper-split-export-declaration@7.22.6:
+ resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/helper-string-parser@7.22.5:
+ resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helper-validator-identifier@7.22.20:
+ resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helper-validator-option@7.22.15:
+ resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helpers@7.23.2:
+ resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/template': 7.22.15
+ '@babel/traverse': 7.23.2
+ '@babel/types': 7.23.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/highlight@7.22.20:
+ resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-validator-identifier': 7.22.20
+ chalk: 2.4.2
+ js-tokens: 4.0.0
+ dev: true
+
+ /@babel/parser@7.23.0:
+ resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+ dependencies:
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.23.2):
+ resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.23.2
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
+ /@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.23.2):
+ resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.23.2
+ '@babel/helper-plugin-utils': 7.22.5
+ dev: true
+
+ /@babel/template@7.22.15:
+ resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.22.13
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@babel/traverse@7.23.2:
+ resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.22.13
+ '@babel/generator': 7.23.0
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-function-name': 7.23.0
+ '@babel/helper-hoist-variables': 7.22.5
+ '@babel/helper-split-export-declaration': 7.22.6
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
+ debug: 4.3.4
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/types@7.23.0:
+ resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.22.5
+ '@babel/helper-validator-identifier': 7.22.20
+ to-fast-properties: 2.0.0
+ dev: true
+
+ /@cbor-extract/cbor-extract-darwin-arm64@2.1.1:
+ resolution: {integrity: sha512-blVBy5MXz6m36Vx0DfLd7PChOQKEs8lK2bD1WJn/vVgG4FXZiZmZb2GECHFvVPA5T7OnODd9xZiL3nMCv6QUhA==}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-darwin-x64@2.1.1:
+ resolution: {integrity: sha512-h6KFOzqk8jXTvkOftyRIWGrd7sKQzQv2jVdTL9nKSf3D2drCvQB/LHUxAOpPXo3pv2clDtKs3xnHalpEh3rDsw==}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-linux-arm64@2.1.1:
+ resolution: {integrity: sha512-SxAaRcYf8S0QHaMc7gvRSiTSr7nUYMqbUdErBEu+HYA4Q6UNydx1VwFE68hGcp1qvxcy9yT5U7gA+a5XikfwSQ==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-linux-arm@2.1.1:
+ resolution: {integrity: sha512-ds0uikdcIGUjPyraV4oJqyVE5gl/qYBpa/Wnh6l6xLE2lj/hwnjT2XcZCChdXwW/YFZ1LUHs6waoYN8PmK0nKQ==}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-linux-x64@2.1.1:
+ resolution: {integrity: sha512-GVK+8fNIE9lJQHAlhOROYiI0Yd4bAZ4u++C2ZjlkS3YmO6hi+FUxe6Dqm+OKWTcMpL/l71N6CQAmaRcb4zyJuA==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-win32-x64@2.1.1:
+ resolution: {integrity: sha512-2Niq1C41dCRIDeD8LddiH+mxGlO7HJ612Ll3D/E73ZWBmycued+8ghTr/Ho3CMOWPUEr08XtyBMVXAjqF+TcKw==}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@esbuild/android-arm64@0.18.20:
+ resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/android-arm@0.18.20:
+ resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/android-x64@0.18.20:
+ resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/darwin-arm64@0.18.20:
+ resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/darwin-x64@0.18.20:
+ resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/freebsd-arm64@0.18.20:
+ resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/freebsd-x64@0.18.20:
+ resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-arm64@0.18.20:
+ resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-arm@0.18.20:
+ resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-ia32@0.18.20:
+ resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-loong64@0.18.20:
+ resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-mips64el@0.18.20:
+ resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-ppc64@0.18.20:
+ resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-riscv64@0.18.20:
+ resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-s390x@0.18.20:
+ resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-x64@0.18.20:
+ resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/netbsd-x64@0.18.20:
+ resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/openbsd-x64@0.18.20:
+ resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/sunos-x64@0.18.20:
+ resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-arm64@0.18.20:
+ resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-ia32@0.18.20:
+ resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-x64@0.18.20:
+ resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@eslint-community/eslint-utils@4.4.0(eslint@8.51.0):
+ resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ dependencies:
+ eslint: 8.51.0
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /@eslint-community/regexpp@4.9.1:
+ resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+ dev: true
+
+ /@eslint/eslintrc@2.1.2:
+ resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.3.4
+ espree: 9.6.1
+ globals: 13.23.0
+ ignore: 5.2.4
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@eslint/js@8.51.0:
+ resolution: {integrity: sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /@hexagon/base64@1.1.28:
+ resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==}
+ dev: false
+
+ /@humanwhocodes/config-array@0.11.11:
+ resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
+ engines: {node: '>=10.10.0'}
+ dependencies:
+ '@humanwhocodes/object-schema': 1.2.1
+ debug: 4.3.4
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@humanwhocodes/module-importer@1.0.1:
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+ dev: true
+
+ /@humanwhocodes/object-schema@1.2.1:
+ resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
+ dev: true
+
+ /@jridgewell/gen-mapping@0.3.3:
+ resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/set-array': 1.1.2
+ '@jridgewell/sourcemap-codec': 1.4.15
+ '@jridgewell/trace-mapping': 0.3.19
+ dev: true
+
+ /@jridgewell/resolve-uri@3.1.1:
+ resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
+ engines: {node: '>=6.0.0'}
+ dev: true
+
+ /@jridgewell/set-array@1.1.2:
+ resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
+ engines: {node: '>=6.0.0'}
+ dev: true
+
+ /@jridgewell/sourcemap-codec@1.4.15:
+ resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+ dev: true
+
+ /@jridgewell/trace-mapping@0.3.19:
+ resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+ dev: true
+
+ /@noble/hashes@1.1.3:
+ resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==}
+ dev: false
+
+ /@noble/hashes@1.3.2:
+ resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
+ engines: {node: '>= 16'}
+ dev: false
+
+ /@nodelib/fs.scandir@2.1.5:
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+ dev: true
+
+ /@nodelib/fs.stat@2.0.5:
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /@nodelib/fs.walk@1.2.8:
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.15.0
+ dev: true
+
+ /@peculiar/asn1-android@2.3.10:
+ resolution: {integrity: sha512-z9Rx9cFJv7UUablZISe7uksNbFJCq13hO0yEAOoIpAymALTLlvUOSLnGiQS7okPaM5dP42oTLhezH6XDXRXjGw==}
+ dependencies:
+ '@peculiar/asn1-schema': 2.3.8
+ asn1js: 3.0.5
+ tslib: 2.6.2
+ dev: false
+
+ /@peculiar/asn1-ecc@2.3.8:
+ resolution: {integrity: sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ==}
+ dependencies:
+ '@peculiar/asn1-schema': 2.3.8
+ '@peculiar/asn1-x509': 2.3.8
+ asn1js: 3.0.5
+ tslib: 2.6.2
+ dev: false
+
+ /@peculiar/asn1-rsa@2.3.8:
+ resolution: {integrity: sha512-ES/RVEHu8VMYXgrg3gjb1m/XG0KJWnV4qyZZ7mAg7rrF3VTmRbLxO8mk+uy0Hme7geSMebp+Wvi2U6RLLEs12Q==}
+ dependencies:
+ '@peculiar/asn1-schema': 2.3.8
+ '@peculiar/asn1-x509': 2.3.8
+ asn1js: 3.0.5
+ tslib: 2.6.2
+ dev: false
+
+ /@peculiar/asn1-schema@2.3.8:
+ resolution: {integrity: sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==}
+ dependencies:
+ asn1js: 3.0.5
+ pvtsutils: 1.3.5
+ tslib: 2.6.2
+ dev: false
+
+ /@peculiar/asn1-x509@2.3.8:
+ resolution: {integrity: sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw==}
+ dependencies:
+ '@peculiar/asn1-schema': 2.3.8
+ asn1js: 3.0.5
+ ipaddr.js: 2.1.0
+ pvtsutils: 1.3.5
+ tslib: 2.6.2
+ dev: false
+
+ /@scure/base@1.1.3:
+ resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==}
+ dev: false
+
+ /@scure/bip39@1.1.0:
+ resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==}
+ dependencies:
+ '@noble/hashes': 1.1.3
+ '@scure/base': 1.1.3
+ dev: false
+
+ /@simplewebauthn/server@8.3.5:
+ resolution: {integrity: sha512-Y6FkggTkzUdPk3cG3LLCiv7rqPQ3QI7g//RU9937G1pxogChvx12Y7/AZdWeMoeP+LFl0fPpdc1bIE0etJOxGA==}
+ engines: {node: '>=16.0.0'}
+ dependencies:
+ '@hexagon/base64': 1.1.28
+ '@peculiar/asn1-android': 2.3.10
+ '@peculiar/asn1-ecc': 2.3.8
+ '@peculiar/asn1-rsa': 2.3.8
+ '@peculiar/asn1-schema': 2.3.8
+ '@peculiar/asn1-x509': 2.3.8
+ '@simplewebauthn/typescript-types': 8.3.4
+ cbor-x: 1.5.4
+ cross-fetch: 4.0.0
+ transitivePeerDependencies:
+ - encoding
+ dev: false
+
+ /@simplewebauthn/typescript-types@8.3.4:
+ resolution: {integrity: sha512-38xtca0OqfRVNloKBrFB5LEM6PN5vzFbJG6rAutPVrtGHFYxPdiV3btYWq0eAZAZmP+dqFPYJxJWeJrGfmYHng==}
+ dev: false
+
+ /@sindresorhus/is@4.6.0:
+ resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
+ engines: {node: '>=10'}
+ dev: false
+
+ /@szmarczak/http-timer@4.0.6:
+ resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
+ engines: {node: '>=10'}
+ dependencies:
+ defer-to-connect: 2.0.1
+ dev: false
+
+ /@types/babel__core@7.20.2:
+ resolution: {integrity: sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==}
+ dependencies:
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
+ '@types/babel__generator': 7.6.5
+ '@types/babel__template': 7.4.2
+ '@types/babel__traverse': 7.20.2
+ dev: true
+
+ /@types/babel__generator@7.6.5:
+ resolution: {integrity: sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==}
+ dependencies:
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@types/babel__template@7.4.2:
+ resolution: {integrity: sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==}
+ dependencies:
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@types/babel__traverse@7.20.2:
+ resolution: {integrity: sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==}
+ dependencies:
+ '@babel/types': 7.23.0
+ dev: true
+
+ /@types/bn.js@5.1.5:
+ resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==}
+ dependencies:
+ '@types/node': 20.8.7
+ dev: true
+
+ /@types/cacheable-request@6.0.3:
+ resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==}
+ dependencies:
+ '@types/http-cache-semantics': 4.0.3
+ '@types/keyv': 3.1.4
+ '@types/node': 20.8.7
+ '@types/responselike': 1.0.2
+ dev: false
+
+ /@types/crypto-js@4.2.2:
+ resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==}
+ dev: true
+
+ /@types/elliptic@6.4.18:
+ resolution: {integrity: sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==}
+ dependencies:
+ '@types/bn.js': 5.1.5
+ dev: true
+
+ /@types/http-cache-semantics@4.0.3:
+ resolution: {integrity: sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA==}
+ dev: false
+
+ /@types/json-schema@7.0.13:
+ resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==}
+ dev: true
+
+ /@types/keyv@3.1.4:
+ resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
+ dependencies:
+ '@types/node': 20.8.7
+ dev: false
+
+ /@types/node@20.8.7:
+ resolution: {integrity: sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==}
+ dependencies:
+ undici-types: 5.25.3
+
+ /@types/prop-types@15.7.8:
+ resolution: {integrity: sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==}
+ dev: true
+
+ /@types/react-dom@18.2.13:
+ resolution: {integrity: sha512-eJIUv7rPP+EC45uNYp/ThhSpE16k22VJUknt5OLoH9tbXoi8bMhwLf5xRuWMywamNbWzhrSmU7IBJfPup1+3fw==}
+ dependencies:
+ '@types/react': 18.2.28
+ dev: true
+
+ /@types/react@18.2.28:
+ resolution: {integrity: sha512-ad4aa/RaaJS3hyGz0BGegdnSRXQBkd1CCYDCdNjBPg90UUpLgo+WlJqb9fMYUxtehmzF3PJaTWqRZjko6BRzBg==}
+ dependencies:
+ '@types/prop-types': 15.7.8
+ '@types/scheduler': 0.16.4
+ csstype: 3.1.2
+ dev: true
+
+ /@types/responselike@1.0.2:
+ resolution: {integrity: sha512-/4YQT5Kp6HxUDb4yhRkm0bJ7TbjvTddqX7PZ5hz6qV3pxSo72f/6YPRo+Mu2DU307tm9IioO69l7uAwn5XNcFA==}
+ dependencies:
+ '@types/node': 20.8.7
+ dev: false
+
+ /@types/scheduler@0.16.4:
+ resolution: {integrity: sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==}
+ dev: true
+
+ /@types/semver@7.5.3:
+ resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==}
+ dev: true
+
+ /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@eslint-community/regexpp': 4.9.1
+ '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/scope-manager': 6.8.0
+ '@typescript-eslint/type-utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ '@typescript-eslint/visitor-keys': 6.8.0
+ debug: 4.3.4
+ eslint: 8.51.0
+ graphemer: 1.4.0
+ ignore: 5.2.4
+ natural-compare: 1.4.0
+ semver: 7.5.4
+ ts-api-utils: 1.0.3(typescript@5.2.2)
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/parser@6.8.0(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 6.8.0
+ '@typescript-eslint/types': 6.8.0
+ '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2)
+ '@typescript-eslint/visitor-keys': 6.8.0
+ debug: 4.3.4
+ eslint: 8.51.0
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/scope-manager@6.8.0:
+ resolution: {integrity: sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.8.0
+ '@typescript-eslint/visitor-keys': 6.8.0
+ dev: true
+
+ /@typescript-eslint/type-utils@6.8.0(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2)
+ '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2)
+ debug: 4.3.4
+ eslint: 8.51.0
+ ts-api-utils: 1.0.3(typescript@5.2.2)
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/types@6.8.0:
+ resolution: {integrity: sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dev: true
+
+ /@typescript-eslint/typescript-estree@6.8.0(typescript@5.2.2):
+ resolution: {integrity: sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 6.8.0
+ '@typescript-eslint/visitor-keys': 6.8.0
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ semver: 7.5.4
+ ts-api-utils: 1.0.3(typescript@5.2.2)
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/utils@6.8.0(eslint@8.51.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
+ '@types/json-schema': 7.0.13
+ '@types/semver': 7.5.3
+ '@typescript-eslint/scope-manager': 6.8.0
+ '@typescript-eslint/types': 6.8.0
+ '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2)
+ eslint: 8.51.0
+ semver: 7.5.4
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
+ /@typescript-eslint/visitor-keys@6.8.0:
+ resolution: {integrity: sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.8.0
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /@vitejs/plugin-react@4.1.0(vite@4.4.11):
+ resolution: {integrity: sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^4.2.0
+ dependencies:
+ '@babel/core': 7.23.2
+ '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.23.2)
+ '@types/babel__core': 7.20.2
+ react-refresh: 0.14.0
+ vite: 4.4.11
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /acorn-jsx@5.3.2(acorn@8.10.0):
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ acorn: 8.10.0
+ dev: true
+
+ /acorn@8.10.0:
+ resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+ dev: true
+
+ /ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+ dev: true
+
+ /ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /ansi-styles@3.2.1:
+ resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+ engines: {node: '>=4'}
+ dependencies:
+ color-convert: 1.9.3
+ dev: true
+
+ /ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+ dependencies:
+ color-convert: 2.0.1
+ dev: true
+
+ /aptos@1.20.0:
+ resolution: {integrity: sha512-driZt7qEr4ndKqqVHMyuFsQAHy4gJ4HPQttgVIpeDfnOIEnIV7A2jyJ9EYO2A+MayuyxXB+7yCNXT4HyBFJdpA==}
+ engines: {node: '>=11.0.0'}
+ dependencies:
+ '@aptos-labs/aptos-client': 0.0.2
+ '@noble/hashes': 1.1.3
+ '@scure/bip39': 1.1.0
+ eventemitter3: 5.0.1
+ form-data: 4.0.0
+ tweetnacl: 1.0.3
+ transitivePeerDependencies:
+ - debug
+ dev: false
+
+ /argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ dev: true
+
+ /array-union@2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /asn1js@3.0.5:
+ resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==}
+ engines: {node: '>=12.0.0'}
+ dependencies:
+ pvtsutils: 1.3.5
+ pvutils: 1.1.3
+ tslib: 2.6.2
+ dev: false
+
+ /asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+ dev: false
+
+ /axios@0.27.2:
+ resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
+ dependencies:
+ follow-redirects: 1.15.3
+ form-data: 4.0.0
+ transitivePeerDependencies:
+ - debug
+ dev: false
+
+ /balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ dev: true
+
+ /base64url@3.0.1:
+ resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==}
+ engines: {node: '>=6.0.0'}
+ dev: false
+
+ /bn.js@4.12.0:
+ resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
+ dev: false
+
+ /brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+ dev: true
+
+ /braces@3.0.2:
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ engines: {node: '>=8'}
+ dependencies:
+ fill-range: 7.0.1
+ dev: true
+
+ /brorand@1.1.0:
+ resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==}
+ dev: false
+
+ /browserslist@4.22.1:
+ resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+ dependencies:
+ caniuse-lite: 1.0.30001549
+ electron-to-chromium: 1.4.556
+ node-releases: 2.0.13
+ update-browserslist-db: 1.0.13(browserslist@4.22.1)
+ dev: true
+
+ /cacheable-lookup@5.0.4:
+ resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==}
+ engines: {node: '>=10.6.0'}
+ dev: false
+
+ /cacheable-request@7.0.4:
+ resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==}
+ engines: {node: '>=8'}
+ dependencies:
+ clone-response: 1.0.3
+ get-stream: 5.2.0
+ http-cache-semantics: 4.1.1
+ keyv: 4.5.4
+ lowercase-keys: 2.0.0
+ normalize-url: 6.1.0
+ responselike: 2.0.1
+ dev: false
+
+ /callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /caniuse-lite@1.0.30001549:
+ resolution: {integrity: sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA==}
+ dev: true
+
+ /cbor-extract@2.1.1:
+ resolution: {integrity: sha512-1UX977+L+zOJHsp0mWFG13GLwO6ucKgSmSW6JTl8B9GUvACvHeIVpFqhU92299Z6PfD09aTXDell5p+lp1rUFA==}
+ hasBin: true
+ requiresBuild: true
+ dependencies:
+ node-gyp-build-optional-packages: 5.0.3
+ optionalDependencies:
+ '@cbor-extract/cbor-extract-darwin-arm64': 2.1.1
+ '@cbor-extract/cbor-extract-darwin-x64': 2.1.1
+ '@cbor-extract/cbor-extract-linux-arm': 2.1.1
+ '@cbor-extract/cbor-extract-linux-arm64': 2.1.1
+ '@cbor-extract/cbor-extract-linux-x64': 2.1.1
+ '@cbor-extract/cbor-extract-win32-x64': 2.1.1
+ dev: false
+ optional: true
+
+ /cbor-x@1.5.4:
+ resolution: {integrity: sha512-PVKILDn+Rf6MRhhcyzGXi5eizn1i0i3F8Fe6UMMxXBnWkalq9+C5+VTmlIjAYM4iF2IYF2N+zToqAfYOp+3rfw==}
+ optionalDependencies:
+ cbor-extract: 2.1.1
+ dev: false
+
+ /chalk@2.4.2:
+ resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+ engines: {node: '>=4'}
+ dependencies:
+ ansi-styles: 3.2.1
+ escape-string-regexp: 1.0.5
+ supports-color: 5.5.0
+ dev: true
+
+ /chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+ dev: true
+
+ /clone-response@1.0.3:
+ resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==}
+ dependencies:
+ mimic-response: 1.0.1
+ dev: false
+
+ /color-convert@1.9.3:
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+ dependencies:
+ color-name: 1.1.3
+ dev: true
+
+ /color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+ dependencies:
+ color-name: 1.1.4
+ dev: true
+
+ /color-name@1.1.3:
+ resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+ dev: true
+
+ /color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ dev: true
+
+ /combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ delayed-stream: 1.0.0
+ dev: false
+
+ /concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+ dev: true
+
+ /convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+ dev: true
+
+ /cross-fetch@4.0.0:
+ resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==}
+ dependencies:
+ node-fetch: 2.7.0
+ transitivePeerDependencies:
+ - encoding
+ dev: false
+
+ /cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+ dev: true
+
+ /crypto-js@4.2.0:
+ resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
+ dev: false
+
+ /csstype@3.1.2:
+ resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
+ dev: true
+
+ /debug@4.3.4:
+ resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.2
+ dev: true
+
+ /decompress-response@6.0.0:
+ resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ mimic-response: 3.1.0
+ dev: false
+
+ /deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+ dev: true
+
+ /defer-to-connect@2.0.1:
+ resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
+ engines: {node: '>=10'}
+ dev: false
+
+ /delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+ dev: false
+
+ /dir-glob@3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-type: 4.0.0
+ dev: true
+
+ /doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: true
+
+ /electron-to-chromium@1.4.556:
+ resolution: {integrity: sha512-6RPN0hHfzDU8D56E72YkDvnLw5Cj2NMXZGg3UkgyoHxjVhG99KZpsKgBWMmTy0Ei89xwan+rbRsVB9yzATmYzQ==}
+ dev: true
+
+ /elliptic@6.5.4:
+ resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==}
+ dependencies:
+ bn.js: 4.12.0
+ brorand: 1.1.0
+ hash.js: 1.1.7
+ hmac-drbg: 1.0.1
+ inherits: 2.0.4
+ minimalistic-assert: 1.0.1
+ minimalistic-crypto-utils: 1.0.1
+ dev: false
+
+ /end-of-stream@1.4.4:
+ resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
+ dependencies:
+ once: 1.4.0
+ dev: false
+
+ /esbuild@0.18.20:
+ resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/android-arm': 0.18.20
+ '@esbuild/android-arm64': 0.18.20
+ '@esbuild/android-x64': 0.18.20
+ '@esbuild/darwin-arm64': 0.18.20
+ '@esbuild/darwin-x64': 0.18.20
+ '@esbuild/freebsd-arm64': 0.18.20
+ '@esbuild/freebsd-x64': 0.18.20
+ '@esbuild/linux-arm': 0.18.20
+ '@esbuild/linux-arm64': 0.18.20
+ '@esbuild/linux-ia32': 0.18.20
+ '@esbuild/linux-loong64': 0.18.20
+ '@esbuild/linux-mips64el': 0.18.20
+ '@esbuild/linux-ppc64': 0.18.20
+ '@esbuild/linux-riscv64': 0.18.20
+ '@esbuild/linux-s390x': 0.18.20
+ '@esbuild/linux-x64': 0.18.20
+ '@esbuild/netbsd-x64': 0.18.20
+ '@esbuild/openbsd-x64': 0.18.20
+ '@esbuild/sunos-x64': 0.18.20
+ '@esbuild/win32-arm64': 0.18.20
+ '@esbuild/win32-ia32': 0.18.20
+ '@esbuild/win32-x64': 0.18.20
+ dev: true
+
+ /escalade@3.1.1:
+ resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /escape-string-regexp@1.0.5:
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+ engines: {node: '>=0.8.0'}
+ dev: true
+
+ /escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /eslint-plugin-react-hooks@4.6.0(eslint@8.51.0):
+ resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
+ dependencies:
+ eslint: 8.51.0
+ dev: true
+
+ /eslint-plugin-react-refresh@0.4.3(eslint@8.51.0):
+ resolution: {integrity: sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==}
+ peerDependencies:
+ eslint: '>=7'
+ dependencies:
+ eslint: 8.51.0
+ dev: true
+
+ /eslint-scope@7.2.2:
+ resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+ dev: true
+
+ /eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /eslint@8.51.0:
+ resolution: {integrity: sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ hasBin: true
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
+ '@eslint-community/regexpp': 4.9.1
+ '@eslint/eslintrc': 2.1.2
+ '@eslint/js': 8.51.0
+ '@humanwhocodes/config-array': 0.11.11
+ '@humanwhocodes/module-importer': 1.0.1
+ '@nodelib/fs.walk': 1.2.8
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.3
+ debug: 4.3.4
+ 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.5.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ globals: 13.23.0
+ graphemer: 1.4.0
+ ignore: 5.2.4
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ 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
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /espree@9.6.1:
+ resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ acorn: 8.10.0
+ acorn-jsx: 5.3.2(acorn@8.10.0)
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /esquery@1.5.0:
+ resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
+ engines: {node: '>=0.10'}
+ dependencies:
+ estraverse: 5.3.0
+ dev: true
+
+ /esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+ dependencies:
+ estraverse: 5.3.0
+ dev: true
+
+ /estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+ dev: true
+
+ /esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /eventemitter3@5.0.1:
+ resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+ dev: false
+
+ /fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+ dev: true
+
+ /fast-glob@3.3.1:
+ resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+ dev: true
+
+ /fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+ dev: true
+
+ /fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+ dev: true
+
+ /fastq@1.15.0:
+ resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+ dependencies:
+ reusify: 1.0.4
+ dev: true
+
+ /file-entry-cache@6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flat-cache: 3.1.1
+ dev: true
+
+ /fill-range@7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+ dev: true
+
+ /find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+ dev: true
+
+ /flat-cache@3.1.1:
+ resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==}
+ engines: {node: '>=12.0.0'}
+ dependencies:
+ flatted: 3.2.9
+ keyv: 4.5.4
+ rimraf: 3.0.2
+ dev: true
+
+ /flatted@3.2.9:
+ resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
+ dev: true
+
+ /follow-redirects@1.15.3:
+ resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+ dev: false
+
+ /form-data@4.0.0:
+ resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
+ engines: {node: '>= 6'}
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+ dev: false
+
+ /fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+ dev: true
+
+ /fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /get-stream@5.2.0:
+ resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
+ engines: {node: '>=8'}
+ dependencies:
+ pump: 3.0.0
+ dev: false
+
+ /glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+ dependencies:
+ is-glob: 4.0.3
+ dev: true
+
+ /glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+ dependencies:
+ is-glob: 4.0.3
+ dev: true
+
+ /glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+ dev: true
+
+ /globals@11.12.0:
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /globals@13.23.0:
+ resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==}
+ engines: {node: '>=8'}
+ dependencies:
+ type-fest: 0.20.2
+ dev: true
+
+ /globby@11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+ engines: {node: '>=10'}
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.3.1
+ ignore: 5.2.4
+ merge2: 1.4.1
+ slash: 3.0.0
+ dev: true
+
+ /got@11.8.6:
+ resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==}
+ engines: {node: '>=10.19.0'}
+ dependencies:
+ '@sindresorhus/is': 4.6.0
+ '@szmarczak/http-timer': 4.0.6
+ '@types/cacheable-request': 6.0.3
+ '@types/responselike': 1.0.2
+ cacheable-lookup: 5.0.4
+ cacheable-request: 7.0.4
+ decompress-response: 6.0.0
+ http2-wrapper: 1.0.3
+ lowercase-keys: 2.0.0
+ p-cancelable: 2.1.1
+ responselike: 2.0.1
+ dev: false
+
+ /graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+ dev: true
+
+ /has-flag@3.0.0:
+ resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /hash.js@1.1.7:
+ resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
+ dependencies:
+ inherits: 2.0.4
+ minimalistic-assert: 1.0.1
+ dev: false
+
+ /hmac-drbg@1.0.1:
+ resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==}
+ dependencies:
+ hash.js: 1.1.7
+ minimalistic-assert: 1.0.1
+ minimalistic-crypto-utils: 1.0.1
+ dev: false
+
+ /http-cache-semantics@4.1.1:
+ resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
+ dev: false
+
+ /http2-wrapper@1.0.3:
+ resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==}
+ engines: {node: '>=10.19.0'}
+ dependencies:
+ quick-lru: 5.1.1
+ resolve-alpn: 1.2.1
+ dev: false
+
+ /ignore@5.2.4:
+ resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
+ engines: {node: '>= 4'}
+ dev: true
+
+ /import-fresh@3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+ dev: true
+
+ /imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+ dev: true
+
+ /inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+ dev: true
+
+ /inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ /ipaddr.js@2.1.0:
+ resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==}
+ engines: {node: '>= 10'}
+ dev: false
+
+ /is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extglob: 2.1.1
+ dev: true
+
+ /is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+ dev: true
+
+ /is-path-inside@3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ dev: true
+
+ /js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ /js-yaml@4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+ dependencies:
+ argparse: 2.0.1
+ dev: true
+
+ /jsesc@2.5.2:
+ resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
+ engines: {node: '>=4'}
+ hasBin: true
+ dev: true
+
+ /json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ /json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ dev: true
+
+ /json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+ dev: true
+
+ /json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+ dev: true
+
+ /keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+ dependencies:
+ json-buffer: 3.0.1
+
+ /levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ dev: true
+
+ /locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-locate: 5.0.0
+ dev: true
+
+ /lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+ dev: true
+
+ /loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+ dependencies:
+ js-tokens: 4.0.0
+ dev: false
+
+ /lowercase-keys@2.0.0:
+ resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+ dependencies:
+ yallist: 3.1.1
+ dev: true
+
+ /lru-cache@6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+ dependencies:
+ yallist: 4.0.0
+ dev: true
+
+ /merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /micromatch@4.0.5:
+ resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.3.1
+ dev: true
+
+ /mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ mime-db: 1.52.0
+ dev: false
+
+ /mimic-response@1.0.1:
+ resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==}
+ engines: {node: '>=4'}
+ dev: false
+
+ /mimic-response@3.1.0:
+ resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
+ engines: {node: '>=10'}
+ dev: false
+
+ /minimalistic-assert@1.0.1:
+ resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
+ dev: false
+
+ /minimalistic-crypto-utils@1.0.1:
+ resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==}
+ dev: false
+
+ /minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ dependencies:
+ brace-expansion: 1.1.11
+ dev: true
+
+ /ms@2.1.2:
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+ dev: true
+
+ /nanoid@3.3.6:
+ resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+ dev: true
+
+ /natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ dev: true
+
+ /node-fetch@2.7.0:
+ resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
+ engines: {node: 4.x || >=6.0.0}
+ peerDependencies:
+ encoding: ^0.1.0
+ peerDependenciesMeta:
+ encoding:
+ optional: true
+ dependencies:
+ whatwg-url: 5.0.0
+ dev: false
+
+ /node-gyp-build-optional-packages@5.0.3:
+ resolution: {integrity: sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==}
+ hasBin: true
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /node-releases@2.0.13:
+ resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
+ dev: true
+
+ /normalize-url@6.1.0:
+ resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
+ engines: {node: '>=10'}
+ dev: false
+
+ /once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ dependencies:
+ wrappy: 1.0.2
+
+ /optionator@0.9.3:
+ resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ '@aashutoshrathi/word-wrap': 1.2.6
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ dev: true
+
+ /p-cancelable@2.1.1:
+ resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ yocto-queue: 0.1.0
+ dev: true
+
+ /p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-limit: 3.1.0
+ dev: true
+
+ /parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+ dependencies:
+ callsites: 3.1.0
+ dev: true
+
+ /path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /path-type@4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /picocolors@1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+ dev: true
+
+ /picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+ dev: true
+
+ /postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.6
+ picocolors: 1.0.0
+ source-map-js: 1.0.2
+ dev: true
+
+ /prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+ dev: true
+
+ /pump@3.0.0:
+ resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
+ dependencies:
+ end-of-stream: 1.4.4
+ once: 1.4.0
+ dev: false
+
+ /punycode@2.3.0:
+ resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /pvtsutils@1.3.5:
+ resolution: {integrity: sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==}
+ dependencies:
+ tslib: 2.6.2
+ dev: false
+
+ /pvutils@1.1.3:
+ resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==}
+ engines: {node: '>=6.0.0'}
+ dev: false
+
+ /queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ dev: true
+
+ /quick-lru@5.1.1:
+ resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
+ engines: {node: '>=10'}
+ dev: false
+
+ /react-dom@18.2.0(react@18.2.0):
+ resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
+ peerDependencies:
+ react: ^18.2.0
+ dependencies:
+ loose-envify: 1.4.0
+ react: 18.2.0
+ scheduler: 0.23.0
+ dev: false
+
+ /react-refresh@0.14.0:
+ resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /react@18.2.0:
+ resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ loose-envify: 1.4.0
+ dev: false
+
+ /resolve-alpn@1.2.1:
+ resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
+ dev: false
+
+ /resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /responselike@2.0.1:
+ resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==}
+ dependencies:
+ lowercase-keys: 2.0.0
+ dev: false
+
+ /reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ dev: true
+
+ /rimraf@3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ hasBin: true
+ dependencies:
+ glob: 7.2.3
+ dev: true
+
+ /rollup@3.29.4:
+ resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
+ engines: {node: '>=14.18.0', npm: '>=8.0.0'}
+ hasBin: true
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
+ /run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ dependencies:
+ queue-microtask: 1.2.3
+ dev: true
+
+ /scheduler@0.23.0:
+ resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
+ dependencies:
+ loose-envify: 1.4.0
+ dev: false
+
+ /semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+ dev: true
+
+ /semver@7.5.4:
+ resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+ dev: true
+
+ /shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+ dependencies:
+ shebang-regex: 3.0.0
+ dev: true
+
+ /shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /slash@3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /source-map-js@1.0.2:
+ resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-regex: 5.0.1
+ dev: true
+
+ /strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /supports-color@5.5.0:
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+ engines: {node: '>=4'}
+ dependencies:
+ has-flag: 3.0.0
+ dev: true
+
+ /supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+ dependencies:
+ has-flag: 4.0.0
+ dev: true
+
+ /text-table@0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+ dev: true
+
+ /to-fast-properties@2.0.0:
+ resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+ dependencies:
+ is-number: 7.0.0
+ dev: true
+
+ /tr46@0.0.3:
+ resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+ dev: false
+
+ /ts-api-utils@1.0.3(typescript@5.2.2):
+ resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
+ engines: {node: '>=16.13.0'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+ dependencies:
+ typescript: 5.2.2
+ dev: true
+
+ /tslib@2.6.2:
+ resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
+ dev: false
+
+ /tweetnacl@1.0.3:
+ resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==}
+ dev: false
+
+ /type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ dev: true
+
+ /type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /typescript@5.2.2:
+ resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+ dev: true
+
+ /undici-types@5.25.3:
+ resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==}
+
+ /update-browserslist-db@1.0.13(browserslist@4.22.1):
+ resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+ dependencies:
+ browserslist: 4.22.1
+ escalade: 3.1.1
+ picocolors: 1.0.0
+ dev: true
+
+ /uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ dependencies:
+ punycode: 2.3.0
+ dev: true
+
+ /vite@4.4.11:
+ resolution: {integrity: sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': '>= 14'
+ 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
+ dependencies:
+ esbuild: 0.18.20
+ postcss: 8.4.31
+ rollup: 3.29.4
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
+ /webidl-conversions@3.0.1:
+ resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
+ dev: false
+
+ /whatwg-url@5.0.0:
+ resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
+ dependencies:
+ tr46: 0.0.3
+ webidl-conversions: 3.0.1
+ dev: false
+
+ /which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+ dependencies:
+ isexe: 2.0.0
+ dev: true
+
+ /wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ /yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+ dev: true
+
+ /yallist@4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ dev: true
+
+ /yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+ dev: true
diff --git a/examples/typescript/passkey/public/vite.svg b/examples/typescript/passkey/public/vite.svg
new file mode 100644
index 000000000..e7b8dfb1b
--- /dev/null
+++ b/examples/typescript/passkey/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/typescript/passkey/src/App.css b/examples/typescript/passkey/src/App.css
new file mode 100644
index 000000000..389dfbe2c
--- /dev/null
+++ b/examples/typescript/passkey/src/App.css
@@ -0,0 +1,56 @@
+#root {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+ width: 100%;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+ transition: filter 300ms;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.react:hover {
+ filter: drop-shadow(0 0 2em #61dafbaa);
+}
+
+@keyframes logo-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ a:nth-of-type(2) .logo {
+ animation: logo-spin infinite 20s linear;
+ }
+}
+
+.card {
+ padding: 2em;
+}
+
+.comfy-row {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ flex-wrap: wrap;
+ gap: 8px;
+ width: 100%;
+}
+
+.read-the-docs {
+ color: #888;
+}
+
+.text-wrap {
+ word-break: break-all;
+}
\ No newline at end of file
diff --git a/examples/typescript/passkey/src/App.tsx b/examples/typescript/passkey/src/App.tsx
new file mode 100644
index 000000000..1c0043bc0
--- /dev/null
+++ b/examples/typescript/passkey/src/App.tsx
@@ -0,0 +1,208 @@
+import { useState } from "react";
+import "./App.css";
+import { AccountAddress, Aptos, AptosConfig, Network, Secp256r1PublicKey, postAptosFaucet } from "@aptos-labs/ts-sdk";
+
+const COIN_STORE = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>";
+
+function App() {
+ const [credentialId, setCredentialId] = useState(window.localStorage.getItem("credentialId"));
+ const [publicKey, setPublicKey] = useState(window.localStorage.getItem("publicKey"));
+ const [recipientAddress, setRecipientAddress] = useState(null);
+ const [sendAmount, setSendAmount] = useState(0);
+ const [faucetIsLoading, setFaucetIsLoading] = useState(false);
+ const [passkeyAddr, setPasskeyAddr] = useState(null);
+ const [currentNetwork, setCurrentNetwork] = useState(Network.DEVNET);
+
+ const config = new AptosConfig({ network: currentNetwork });
+ const aptos = new Aptos(config);
+
+ /**
+ * Prints the balance of an account
+ * @param aptos
+ * @param name
+ * @param address
+ * @returns {Promise<*>}
+ *
+ */
+ const balance = async (aptos: Aptos, name: string, address: AccountAddress) => {
+ type Coin = { coin: { value: string } };
+ const resource = await aptos.getAccountResource({
+ accountAddress: address,
+ resourceType: COIN_STORE,
+ });
+ const amount = Number(resource.coin.value);
+
+ console.log(`${name}'s balance is: ${amount}`);
+ return amount;
+ };
+
+ // Create the passkey via credential registration ceremony
+ const createPasskey = async () => {
+ const options = await aptos.generateRegistrationOptions({
+ rpName: window.location.origin,
+ rpID: window.location.hostname,
+ userName: "Andrew",
+ userID: "andrew.apt",
+ authenticatorAttachment: "platform",
+ });
+
+ const cred = await aptos.registerCredential(options);
+ const pubKey = aptos.parsePublicKey(cred);
+ const addr = await aptos.getPasskeyAccountAddress({ publicKey: pubKey.toString() });
+
+ console.log(addr.toString());
+
+ setCredentialId(cred.rawId);
+ setPublicKey(aptos.parsePublicKey(cred).toString());
+ setPasskeyAddr(addr.toString());
+ console.log(cred);
+ window.localStorage.setItem("credentialId", cred.rawId);
+ window.localStorage.setItem("publicKey", aptos.parsePublicKey(cred).toString());
+ };
+
+ const fundAccount = async () => {
+ if (!publicKey) {
+ alert("No registered publicKey");
+ return;
+ }
+
+ setFaucetIsLoading(true);
+
+ const addr = await aptos.getPasskeyAccountAddress({ publicKey });
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const { data } = await postAptosFaucet }>({
+ aptosConfig: config,
+ path: "fund",
+ body: {
+ address: AccountAddress.from(addr).toString(),
+ amount: 1e9,
+ },
+ originMethod: "fundAccount",
+ });
+
+ const txnHash = data.txn_hashes[0];
+
+ const confirmedTxn = await aptos.waitForTransaction({ transactionHash: txnHash });
+ alert("Faucet 1 APT deposited, txn hash: " + confirmedTxn.hash);
+
+ console.log("\n=== Balances ===\n");
+ await balance(aptos, "Passkey Account", new AccountAddress(addr.toUint8Array()));
+ setFaucetIsLoading(false);
+ };
+
+ const checkBalance = async () => {
+ if (!publicKey) {
+ alert("No registered publicKey");
+ return;
+ }
+
+ const addr = await aptos.getPasskeyAccountAddress({ publicKey });
+
+ console.log("\n=== Balances ===\n");
+ const bal = await balance(aptos, "Passkey Account", new AccountAddress(addr.toUint8Array()));
+
+ window.alert(bal / 1e8 + " APT");
+ };
+
+ /**
+ * Use the passkey credential registered to the user to sign a coin transfer
+ */
+ const signWithPasskey = async () => {
+ if (!credentialId) {
+ alert("No registered credential");
+ return;
+ }
+
+ if (!publicKey) {
+ alert("No registered publicKey");
+ return;
+ }
+
+ const addr = await aptos.getPasskeyAccountAddress({ publicKey });
+ const recipient = AccountAddress.fromString(recipientAddress || "0x1");
+
+ const txn = await aptos.transferCoinTransaction({
+ sender: addr,
+ recipient: recipient,
+ amount: sendAmount * 1e8,
+ });
+
+ console.log("\n=== Transfer transaction ===\n");
+ const pendingTxn = await aptos.signAndSubmitWithPasskey({
+ credentialId: credentialId,
+ transaction: txn,
+ publicKey: new Secp256r1PublicKey(publicKey),
+ options: {}
+ });
+ console.log("PENDING TXN", pendingTxn);
+
+ const committedTxn = await aptos.waitForTransaction({ transactionHash: pendingTxn.hash });
+ console.log("COMMITTED TXN", committedTxn);
+
+ // This doesn't work until the indexer works for passkeys
+ // await aptos.waitForTransaction({ transactionHash: committedTxn.hash });
+ // console.log(`Committed transaction: ${committedTxn.hash}`);
+ };
+
+ const getAddress = async () => {
+ if (!credentialId) {
+ alert("No registered credential");
+ return;
+ }
+
+ if (!publicKey) {
+ alert("No registered publicKey");
+ return;
+ }
+
+ const addr = await aptos.getPasskeyAccountAddress({ publicKey: publicKey });
+ setPasskeyAddr(addr.toString());
+
+ alert(addr);
+ };
+
+ const switchNetwork: React.ChangeEventHandler = (event) => {
+ if (Object.values(Network).includes(event.target.value as Network)) {
+ setCurrentNetwork(event.target.value as Network);
+ } else {
+ alert("Error: Incorrect network selected");
+ }
+ }
+
+ return (
+ <>
+ Passkeys Demo
+ {passkeyAddr ? {"Your address: " + passkeyAddr}
: null}
+ {passkeyAddr ? (
+
+ Explorer link
+
+ ) : null}
+
+
+
+
+
+
+
+
+
Recipient address
+
setRecipientAddress(e.currentTarget.value)} />
+
Send amount (APT)
+
setSendAmount(Number(e.currentTarget.value))} />
+
rpId: {window.location.hostname}
+
+
+ >
+ );
+}
+
+export default App;
diff --git a/examples/typescript/passkey/src/assets/react.svg b/examples/typescript/passkey/src/assets/react.svg
new file mode 100644
index 000000000..6c87de9bb
--- /dev/null
+++ b/examples/typescript/passkey/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/typescript/passkey/src/index.css b/examples/typescript/passkey/src/index.css
new file mode 100644
index 000000000..23f70f293
--- /dev/null
+++ b/examples/typescript/passkey/src/index.css
@@ -0,0 +1,91 @@
+:root {
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+select {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+select:hover {
+ border-color: #646cff;
+}
+select:focus,
+select:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+ select {
+ background-color: #f9f9f9;
+ }
+}
diff --git a/examples/typescript/passkey/src/main.tsx b/examples/typescript/passkey/src/main.tsx
new file mode 100644
index 000000000..3d7150da8
--- /dev/null
+++ b/examples/typescript/passkey/src/main.tsx
@@ -0,0 +1,10 @@
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import App from './App.tsx'
+import './index.css'
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+ ,
+)
diff --git a/examples/typescript/passkey/src/recoverPubKey.ts b/examples/typescript/passkey/src/recoverPubKey.ts
new file mode 100644
index 000000000..ed7fdeabd
--- /dev/null
+++ b/examples/typescript/passkey/src/recoverPubKey.ts
@@ -0,0 +1,65 @@
+import EC from 'elliptic';
+const ec = new EC.ec('secp256r1');
+
+export async function sha256(message: Uint8Array) {
+ const hashBuffer = await crypto.subtle.digest('SHA-256', message);
+ return new Uint8Array(hashBuffer);
+}
+
+export function concatenateUint8Arrays(array1: Uint8Array, array2: Uint8Array) {
+ const result = new Uint8Array(array1.length + array2.length);
+ result.set(array1, 0);
+ result.set(array2, array1.length);
+
+ return result;
+}
+
+export async function recoverPublicKey(
+ authenticatorData: Uint8Array,
+ clientDataJSON: Uint8Array,
+ signature: Uint8Array
+) {
+ const shaClientDataJSON = await sha256(clientDataJSON);
+ const message = concatenateUint8Arrays(authenticatorData, shaClientDataJSON);
+
+ const result = await recoverPublicKeyFromMessageAndSignature(message, signature);
+ return result;
+}
+
+export async function recoverPublicKeyFromMessageAndSignature(message: Uint8Array, signature: Uint8Array) {
+ // Hash the message
+ const msgHash = await sha256(message);
+
+ // Assume signature is an object with r and s components
+ // In real scenarios, ensure to parse the signature from its encoded form
+ let publicKey;
+ for (let recoveryId = 0; recoveryId < 2; recoveryId++) {
+ try {
+ publicKey = ec.recoverPubKey(msgHash, signature, recoveryId);
+ // If recovery was successful and publicKey is valid, break out of the loop
+ if (publicKey) break;
+ } catch (error) {
+ // If this recoveryId does not work, catch the error and try the next one
+ console.error("Recovery with ID", recoveryId, "failed:", error);
+ }
+ }
+
+ if (!publicKey) {
+ throw new Error('Failed to recover public key');
+ }
+
+ // Convert the public key to its byte representation
+ const publicKeyBytes = publicKey.encode('array', false);
+ console.log(publicKeyBytes);
+ return publicKeyBytes;
+}
+
+// Example usage (pseudo-code, depends on actual signature format and input)
+// const message = 'Your message here';
+// const signature = { r: 'signatureRValue', s: 'signatureSValue' };
+// try {
+// const publicKeyBytes = recoverPublicKeyFromSignatureWithoutRecoveryId(message, signature);
+// console.log(publicKeyBytes);
+// } catch (error) {
+// console.error(error);
+// }
diff --git a/examples/typescript/passkey/src/vite-env.d.ts b/examples/typescript/passkey/src/vite-env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/examples/typescript/passkey/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/examples/typescript/passkey/tsconfig.json b/examples/typescript/passkey/tsconfig.json
new file mode 100644
index 000000000..a7fc6fbf2
--- /dev/null
+++ b/examples/typescript/passkey/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/examples/typescript/passkey/tsconfig.node.json b/examples/typescript/passkey/tsconfig.node.json
new file mode 100644
index 000000000..42872c59f
--- /dev/null
+++ b/examples/typescript/passkey/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/examples/typescript/passkey/vite.config.ts b/examples/typescript/passkey/vite.config.ts
new file mode 100644
index 000000000..9cc50ead1
--- /dev/null
+++ b/examples/typescript/passkey/vite.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+});
diff --git a/package.json b/package.json
index 1bf32656f..463ea45c4 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,9 @@
"@noble/hashes": "^1.3.3",
"@scure/bip32": "^1.3.3",
"@scure/bip39": "^1.2.1",
+ "@simplewebauthn/browser": "^8.3.4",
+ "@simplewebauthn/server": "^8.3.5",
+ "base64url": "^3.0.1",
"form-data": "^4.0.0",
"tweetnacl": "^1.0.3",
"eventemitter3": "^5.0.1"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e6d383949..49f479cb2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -20,6 +20,15 @@ dependencies:
'@scure/bip39':
specifier: ^1.2.1
version: 1.2.1
+ '@simplewebauthn/browser':
+ specifier: ^8.3.4
+ version: 8.3.4
+ '@simplewebauthn/server':
+ specifier: ^8.3.5
+ version: 8.3.5
+ base64url:
+ specifier: ^3.0.1
+ version: 3.0.1
eventemitter3:
specifier: ^5.0.1
version: 5.0.1
@@ -985,6 +994,54 @@ packages:
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
dev: true
+ /@cbor-extract/cbor-extract-darwin-arm64@2.2.0:
+ resolution: {integrity: sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-darwin-x64@2.2.0:
+ resolution: {integrity: sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-linux-arm64@2.2.0:
+ resolution: {integrity: sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-linux-arm@2.2.0:
+ resolution: {integrity: sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-linux-x64@2.2.0:
+ resolution: {integrity: sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@cbor-extract/cbor-extract-win32-x64@2.2.0:
+ resolution: {integrity: sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
/@cspotcode/source-map-support@0.8.1:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
@@ -1887,6 +1944,10 @@ packages:
graphql: 16.8.1
dev: true
+ /@hexagon/base64@1.1.28:
+ resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==}
+ dev: false
+
/@humanwhocodes/config-array@0.11.13:
resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==}
engines: {node: '>=10.10.0'}
@@ -2233,13 +2294,48 @@ packages:
fastq: 1.15.0
dev: true
- /@peculiar/asn1-schema@2.3.6:
- resolution: {integrity: sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==}
+ /@peculiar/asn1-android@2.3.10:
+ resolution: {integrity: sha512-z9Rx9cFJv7UUablZISe7uksNbFJCq13hO0yEAOoIpAymALTLlvUOSLnGiQS7okPaM5dP42oTLhezH6XDXRXjGw==}
+ dependencies:
+ '@peculiar/asn1-schema': 2.3.8
+ asn1js: 3.0.5
+ tslib: 2.6.2
+ dev: false
+
+ /@peculiar/asn1-ecc@2.3.8:
+ resolution: {integrity: sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ==}
+ dependencies:
+ '@peculiar/asn1-schema': 2.3.8
+ '@peculiar/asn1-x509': 2.3.8
+ asn1js: 3.0.5
+ tslib: 2.6.2
+ dev: false
+
+ /@peculiar/asn1-rsa@2.3.8:
+ resolution: {integrity: sha512-ES/RVEHu8VMYXgrg3gjb1m/XG0KJWnV4qyZZ7mAg7rrF3VTmRbLxO8mk+uy0Hme7geSMebp+Wvi2U6RLLEs12Q==}
+ dependencies:
+ '@peculiar/asn1-schema': 2.3.8
+ '@peculiar/asn1-x509': 2.3.8
+ asn1js: 3.0.5
+ tslib: 2.6.2
+ dev: false
+
+ /@peculiar/asn1-schema@2.3.8:
+ resolution: {integrity: sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==}
dependencies:
asn1js: 3.0.5
pvtsutils: 1.3.5
tslib: 2.6.2
- dev: true
+
+ /@peculiar/asn1-x509@2.3.8:
+ resolution: {integrity: sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw==}
+ dependencies:
+ '@peculiar/asn1-schema': 2.3.8
+ asn1js: 3.0.5
+ ipaddr.js: 2.1.0
+ pvtsutils: 1.3.5
+ tslib: 2.6.2
+ dev: false
/@peculiar/json-schema@1.1.12:
resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==}
@@ -2252,7 +2348,7 @@ packages:
resolution: {integrity: sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==}
engines: {node: '>=10.12.0'}
dependencies:
- '@peculiar/asn1-schema': 2.3.6
+ '@peculiar/asn1-schema': 2.3.8
'@peculiar/json-schema': 1.1.12
pvtsutils: 1.3.5
tslib: 2.6.2
@@ -2390,6 +2486,34 @@ packages:
'@scure/base': 1.1.3
dev: false
+ /@simplewebauthn/browser@8.3.4:
+ resolution: {integrity: sha512-rO0hZ0ESD28bZl6Qe8k7RUuYvDLbsS6oPezkMMTtZ5vC80U07j4qBELKBzojDD6BsdL3dIJ9SExVp8E7pqQ5fA==}
+ dependencies:
+ '@simplewebauthn/typescript-types': 8.3.4
+ dev: false
+
+ /@simplewebauthn/server@8.3.5:
+ resolution: {integrity: sha512-Y6FkggTkzUdPk3cG3LLCiv7rqPQ3QI7g//RU9937G1pxogChvx12Y7/AZdWeMoeP+LFl0fPpdc1bIE0etJOxGA==}
+ engines: {node: '>=16.0.0'}
+ dependencies:
+ '@hexagon/base64': 1.1.28
+ '@peculiar/asn1-android': 2.3.10
+ '@peculiar/asn1-ecc': 2.3.8
+ '@peculiar/asn1-rsa': 2.3.8
+ '@peculiar/asn1-schema': 2.3.8
+ '@peculiar/asn1-x509': 2.3.8
+ '@simplewebauthn/typescript-types': 8.3.4
+ cbor-x: 1.5.8
+ cross-fetch: 4.0.0
+ transitivePeerDependencies:
+ - encoding
+ dev: false
+
+ /@simplewebauthn/typescript-types@8.3.4:
+ resolution: {integrity: sha512-38xtca0OqfRVNloKBrFB5LEM6PN5vzFbJG6rAutPVrtGHFYxPdiV3btYWq0eAZAZmP+dqFPYJxJWeJrGfmYHng==}
+ deprecated: This package has been renamed to @simplewebauthn/types. Please install @simplewebauthn/types instead to ensure you receive future updates.
+ dev: false
+
/@sinclair/typebox@0.27.8:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
dev: true
@@ -3076,7 +3200,6 @@ packages:
pvtsutils: 1.3.5
pvutils: 1.1.3
tslib: 2.6.2
- dev: true
/astral-regex@2.0.0:
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
@@ -3226,6 +3349,11 @@ packages:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
dev: true
+ /base64url@3.0.1:
+ resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==}
+ engines: {node: '>=6.0.0'}
+ dev: false
+
/binary-extensions@2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
@@ -3375,6 +3503,28 @@ packages:
upper-case-first: 2.0.2
dev: true
+ /cbor-extract@2.2.0:
+ resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==}
+ hasBin: true
+ requiresBuild: true
+ dependencies:
+ node-gyp-build-optional-packages: 5.1.1
+ optionalDependencies:
+ '@cbor-extract/cbor-extract-darwin-arm64': 2.2.0
+ '@cbor-extract/cbor-extract-darwin-x64': 2.2.0
+ '@cbor-extract/cbor-extract-linux-arm': 2.2.0
+ '@cbor-extract/cbor-extract-linux-arm64': 2.2.0
+ '@cbor-extract/cbor-extract-linux-x64': 2.2.0
+ '@cbor-extract/cbor-extract-win32-x64': 2.2.0
+ dev: false
+ optional: true
+
+ /cbor-x@1.5.8:
+ resolution: {integrity: sha512-gc3bHBsvG6GClCY6c0/iip+ghlqizkVp+TtaL927lwvP4VP9xBdi1HmqPR5uj/Mj/0TOlngMkIYa25wKg+VNrQ==}
+ optionalDependencies:
+ cbor-extract: 2.2.0
+ dev: false
+
/chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
@@ -3661,6 +3811,14 @@ packages:
- encoding
dev: true
+ /cross-fetch@4.0.0:
+ resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==}
+ dependencies:
+ node-fetch: 2.7.0
+ transitivePeerDependencies:
+ - encoding
+ dev: false
+
/cross-inspect@1.0.0:
resolution: {integrity: sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==}
engines: {node: '>=16.0.0'}
@@ -3772,6 +3930,13 @@ packages:
engines: {node: '>=8'}
dev: true
+ /detect-libc@2.0.2:
+ resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
+ engines: {node: '>=8'}
+ requiresBuild: true
+ dev: false
+ optional: true
+
/detect-newline@3.1.0:
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
engines: {node: '>=8'}
@@ -4848,6 +5013,11 @@ packages:
loose-envify: 1.4.0
dev: true
+ /ipaddr.js@2.1.0:
+ resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==}
+ engines: {node: '>= 10'}
+ dev: false
+
/is-absolute@1.0.0:
resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==}
engines: {node: '>=0.10.0'}
@@ -5926,7 +6096,15 @@ packages:
optional: true
dependencies:
whatwg-url: 5.0.0
- dev: true
+
+ /node-gyp-build-optional-packages@5.1.1:
+ resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==}
+ hasBin: true
+ requiresBuild: true
+ dependencies:
+ detect-libc: 2.0.2
+ dev: false
+ optional: true
/node-int64@0.4.0:
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
@@ -6296,12 +6474,10 @@ packages:
resolution: {integrity: sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==}
dependencies:
tslib: 2.6.2
- dev: true
/pvutils@1.1.3:
resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==}
engines: {node: '>=6.0.0'}
- dev: true
/queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@@ -6923,7 +7099,6 @@ packages:
/tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
- dev: true
/tr46@1.0.1:
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
@@ -7054,7 +7229,6 @@ packages:
/tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
- dev: true
/tsup@8.0.1(ts-node@10.9.2)(typescript@5.3.3):
resolution: {integrity: sha512-hvW7gUSG96j53ZTSlT4j/KL0q1Q2l6TqGBFc6/mu/L46IoNWqLLUzLRLP1R8Q7xrJTmkDxxDoojV5uCVs1sVOg==}
@@ -7302,7 +7476,7 @@ packages:
/webcrypto-core@1.7.7:
resolution: {integrity: sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==}
dependencies:
- '@peculiar/asn1-schema': 2.3.6
+ '@peculiar/asn1-schema': 2.3.8
'@peculiar/json-schema': 1.1.12
asn1js: 3.0.5
pvtsutils: 1.3.5
@@ -7311,7 +7485,6 @@ packages:
/webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
- dev: true
/webidl-conversions@4.0.2:
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
@@ -7367,7 +7540,6 @@ packages:
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
- dev: true
/whatwg-url@7.1.0:
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
diff --git a/src/api/aptos.ts b/src/api/aptos.ts
index 92dc0e106..a71847c1d 100644
--- a/src/api/aptos.ts
+++ b/src/api/aptos.ts
@@ -10,6 +10,7 @@ import { Faucet } from "./faucet";
import { FungibleAsset } from "./fungibleAsset";
import { General } from "./general";
import { ANS } from "./ans";
+import { PasskeysBrowser } from "./passkey";
import { Staking } from "./staking";
import { Transaction } from "./transaction";
@@ -39,6 +40,8 @@ export class Aptos {
readonly general: General;
+ readonly passkeysBrowser: PasskeysBrowser;
+
readonly staking: Staking;
readonly transaction: Transaction;
@@ -53,6 +56,7 @@ export class Aptos {
this.faucet = new Faucet(this.config);
this.fungibleAsset = new FungibleAsset(this.config);
this.general = new General(this.config);
+ this.passkeysBrowser = new PasskeysBrowser(this.config);
this.staking = new Staking(this.config);
this.transaction = new Transaction(this.config);
}
@@ -69,6 +73,7 @@ export interface Aptos
Faucet,
FungibleAsset,
General,
+ PasskeysBrowser,
Staking,
Omit {}
@@ -101,5 +106,6 @@ applyMixin(Aptos, Event, "event");
applyMixin(Aptos, Faucet, "faucet");
applyMixin(Aptos, FungibleAsset, "fungibleAsset");
applyMixin(Aptos, General, "general");
+applyMixin(Aptos, PasskeysBrowser, "passkeysBrowser");
applyMixin(Aptos, Staking, "staking");
applyMixin(Aptos, Transaction, "transaction");
diff --git a/src/api/passkey.ts b/src/api/passkey.ts
new file mode 100644
index 000000000..d973ea6ba
--- /dev/null
+++ b/src/api/passkey.ts
@@ -0,0 +1,76 @@
+/* eslint-disable class-methods-use-this */
+// Copyright © Aptos Foundation
+// SPDX-License-Identifier: Apache-2.0
+
+import { PublicKeyCredentialCreationOptionsJSON, RegistrationResponseJSON } from "@simplewebauthn/server/esm/deps";
+import { AptosConfig } from "./aptosConfig";
+import { HexInput, PendingTransactionResponse } from "../types";
+import { AnyRawTransaction } from "../transactions";
+import {
+ generateRegistrationOptions,
+ getPasskeyAccountAddress,
+ parsePublicKey,
+ registerCredential,
+ signAndSubmitWithPasskey,
+} from "../internal/passkey";
+import { AccountAddress, PublicKey } from "../core";
+
+/**
+ * A class for all `Passkeys` related operations on Aptos on the browser.
+ */
+export class PasskeysBrowser {
+ readonly config: AptosConfig;
+
+ constructor(config: AptosConfig) {
+ this.config = config;
+ }
+
+ /**
+ * Given a credentialId and a transaction, it prompts the client to sign the transaction
+ *
+ * @param args.credentialId The credential ID of the passkey
+ * @param args.publicKey The public key associated with the passkey
+ * @param args.transaction The transaction to sign
+ * @returns The pending transaction response
+ */
+ async signAndSubmitWithPasskey(args: {
+ credentialId: string | Uint8Array;
+ publicKey: PublicKey;
+ transaction: AnyRawTransaction;
+ timeout?: number;
+ rpID?: string;
+ options?: {
+ allowCredentials?: PublicKeyCredentialDescriptor[]
+ }
+ }): Promise {
+ return signAndSubmitWithPasskey({ aptosConfig: this.config, ...args });
+ }
+
+ async getPasskeyAccountAddress(args: { publicKey: HexInput }): Promise {
+ return getPasskeyAccountAddress(args);
+ }
+
+ async generateRegistrationOptions(args: {
+ rpName: string;
+ rpID: string;
+ userID: string;
+ userName: string;
+ challenge?: string | Uint8Array;
+ userDisplayName?: string;
+ timeout?: number;
+ attestationType?: AttestationConveyancePreference;
+ authenticatorAttachment?: AuthenticatorAttachment;
+ }): Promise {
+ return generateRegistrationOptions(args);
+ }
+
+ async registerCredential(
+ creationOptionsJSON: PublicKeyCredentialCreationOptionsJSON,
+ ): Promise {
+ return registerCredential(creationOptionsJSON);
+ }
+
+ parsePublicKey(response: RegistrationResponseJSON): PublicKey {
+ return parsePublicKey(response);
+ }
+}
diff --git a/src/core/authenticationKey.ts b/src/core/authenticationKey.ts
index b9cea2a3e..c3d61bb38 100644
--- a/src/core/authenticationKey.ts
+++ b/src/core/authenticationKey.ts
@@ -12,6 +12,7 @@ import { AnyPublicKey } from "./crypto/anyPublicKey";
import { MultiKey } from "./crypto/multiKey";
import { Serializable, Serializer } from "../bcs/serializer";
import { Deserializer } from "../bcs/deserializer";
+import { Secp256k1PublicKey, Secp256r1PublicKey } from "./crypto";
/**
* Each account stores an authentication key. Authentication key enables account owners to rotate
@@ -110,7 +111,7 @@ export class AuthenticationKey extends Serializable {
* @returns AuthenticationKey
*/
static fromPublicKey(args: { publicKey: PublicKey }): AuthenticationKey {
- const { publicKey } = args;
+ let { publicKey } = args;
let scheme: number;
if (publicKey instanceof Ed25519PublicKey) {
@@ -119,6 +120,14 @@ export class AuthenticationKey extends Serializable {
} else if (publicKey instanceof MultiEd25519PublicKey) {
// for legacy support
scheme = SigningScheme.MultiEd25519.valueOf();
+ } else if (publicKey instanceof Secp256k1PublicKey) {
+ // Only single sender supported for Secp256k1
+ scheme = SigningScheme.SingleKey.valueOf();
+ publicKey = new AnyPublicKey(publicKey);
+ } else if (publicKey instanceof Secp256r1PublicKey) {
+ // Only single sender supported for Secp256r1
+ scheme = SigningScheme.SingleKey.valueOf();
+ publicKey = new AnyPublicKey(publicKey);
} else if (publicKey instanceof AnyPublicKey) {
scheme = SigningScheme.SingleKey.valueOf();
} else if (publicKey instanceof MultiKey) {
diff --git a/src/core/crypto/anyPublicKey.ts b/src/core/crypto/anyPublicKey.ts
index 1797b2083..f8c90bb3a 100644
--- a/src/core/crypto/anyPublicKey.ts
+++ b/src/core/crypto/anyPublicKey.ts
@@ -4,6 +4,7 @@ import { AnySignature } from "./anySignature";
import { PublicKey } from "./asymmetricCrypto";
import { Ed25519PublicKey } from "./ed25519";
import { Secp256k1PublicKey } from "./secp256k1";
+import { Secp256r1PublicKey } from "./secp256r1";
/**
* Represents any public key supported by Aptos.
@@ -61,6 +62,9 @@ export class AnyPublicKey extends PublicKey {
} else if (this.publicKey instanceof Secp256k1PublicKey) {
serializer.serializeU32AsUleb128(AnyPublicKeyVariant.Secp256k1);
this.publicKey.serialize(serializer);
+ } else if (this.publicKey instanceof Secp256r1PublicKey) {
+ serializer.serializeU32AsUleb128(AnyPublicKeyVariant.Secp256r1);
+ this.publicKey.serialize(serializer);
} else {
throw new Error("Unknown public key type");
}
@@ -73,6 +77,8 @@ export class AnyPublicKey extends PublicKey {
return new AnyPublicKey(Ed25519PublicKey.load(deserializer));
case AnyPublicKeyVariant.Secp256k1:
return new AnyPublicKey(Secp256k1PublicKey.load(deserializer));
+ case AnyPublicKeyVariant.Secp256r1:
+ return new AnyPublicKey(Secp256r1PublicKey.load(deserializer));
default:
throw new Error(`Unknown variant index for AnyPublicKey: ${index}`);
}
diff --git a/src/core/crypto/anySignature.ts b/src/core/crypto/anySignature.ts
index f8f99acf3..b18dd6376 100644
--- a/src/core/crypto/anySignature.ts
+++ b/src/core/crypto/anySignature.ts
@@ -3,6 +3,7 @@ import { AnySignatureVariant } from "../../types";
import { Signature } from "./asymmetricCrypto";
import { Ed25519Signature } from "./ed25519";
import { Secp256k1Signature } from "./secp256k1";
+import { WebAuthnSignature } from "./webauthn";
export class AnySignature extends Signature {
public readonly signature: Signature;
@@ -37,6 +38,9 @@ export class AnySignature extends Signature {
} else if (this.signature instanceof Secp256k1Signature) {
serializer.serializeU32AsUleb128(AnySignatureVariant.Secp256k1);
this.signature.serialize(serializer);
+ } else if (this.signature instanceof WebAuthnSignature) {
+ serializer.serializeU32AsUleb128(AnySignatureVariant.WebAuthn);
+ this.signature.serialize(serializer);
} else {
throw new Error("Unknown signature type");
}
@@ -49,6 +53,8 @@ export class AnySignature extends Signature {
return new AnySignature(Ed25519Signature.load(deserializer));
case AnySignatureVariant.Secp256k1:
return new AnySignature(Secp256k1Signature.load(deserializer));
+ case AnySignatureVariant.WebAuthn:
+ return new AnySignature(WebAuthnSignature.load(deserializer));
default:
throw new Error(`Unknown variant index for AnySignature: ${index}`);
}
diff --git a/src/core/crypto/index.ts b/src/core/crypto/index.ts
index 7b63a1dd0..7afcd73c7 100644
--- a/src/core/crypto/index.ts
+++ b/src/core/crypto/index.ts
@@ -5,6 +5,7 @@ export * from "./asymmetricCrypto";
export * from "./ed25519";
export * from "./multiEd25519";
export * from "./secp256k1";
+export * from "./secp256r1";
export * from "./multiKey";
export * from "./hdKey";
export * from "./anyPublicKey";
diff --git a/src/core/crypto/secp256r1.ts b/src/core/crypto/secp256r1.ts
new file mode 100644
index 000000000..a84a42319
--- /dev/null
+++ b/src/core/crypto/secp256r1.ts
@@ -0,0 +1,273 @@
+// Copyright © Aptos Foundation
+// SPDX-License-Identifier: Apache-2.0
+
+import { sha3_256 } from "@noble/hashes/sha3";
+import { p256 } from "@noble/curves/p256";
+import { bufferToBase64URLString } from "@simplewebauthn/browser";
+import { sha256 } from "@noble/hashes/sha256";
+import { PrivateKey, PublicKey, Signature } from "./asymmetricCrypto";
+import { Deserializer, Serializer } from "../../bcs";
+import { Hex } from "../hex";
+import { HexInput } from "../../types";
+import type { WebAuthnSignature } from "./webauthn";
+
+/**
+ * Represents the Secp256r1 public key
+ *
+ * Secp256r1 authentication key is represented in the SDK as `AnyPublicKey`. It is used to verify WebAuthnSignatures.
+ */
+export class Secp256r1PublicKey extends PublicKey {
+ // Secp256r1 ecdsa public keys contain a prefix indicating compression and two 32-byte coordinates.
+ static readonly LENGTH: number = 65;
+
+ // Hex value of the public key
+ private readonly key: Hex;
+
+ /**
+ * Create a new PublicKey instance from a Uint8Array or String.
+ *
+ * @param hexInput A HexInput (string or Uint8Array)
+ */
+ constructor(hexInput: HexInput) {
+ super();
+
+ const hex = Hex.fromHexInput(hexInput);
+ if (hex.toUint8Array().length !== Secp256r1PublicKey.LENGTH) {
+ throw new Error(`PublicKey length should be ${Secp256r1PublicKey.LENGTH}`);
+ }
+ this.key = hex;
+ }
+
+ /**
+ * Get the public key in bytes (Uint8Array).
+ *
+ * @returns Uint8Array representation of the public key
+ */
+ toUint8Array(): Uint8Array {
+ return this.key.toUint8Array();
+ }
+
+ /**
+ * Get the public key as a hex string with the 0x prefix.
+ *
+ * @returns string representation of the public key
+ */
+ toString(): string {
+ return this.key.toString();
+ }
+
+ /**
+ * Verifies a signed data with a public key
+ *
+ * @param args.message message
+ * @param args.signature The signature
+ * @returns true if the signature is valid
+ */
+ verifySignature(args: { message: HexInput; signature: Secp256r1Signature }): boolean {
+ const { message, signature } = args;
+
+ const msgHex = Hex.fromHexInput(message).toUint8Array();
+ const sha3Message = sha256(msgHex);
+ const rawSignature = signature.toUint8Array();
+ return p256.verify(rawSignature, sha3Message, this.toUint8Array());
+ }
+
+ /**
+ * Verifies a signed data with a public key
+ *
+ * @param args.message message
+ * @param args.signature The signature
+ * @returns true if the signature is valid
+ */
+ verifyWebAuthnSignature(args: { message: HexInput; signature: WebAuthnSignature }): boolean {
+ const { message, signature } = args;
+
+ if (!(signature.paar.signature.signature instanceof Secp256r1Signature)) {
+ throw new Error("Attestation signature is not a Secp256r1Signature");
+ }
+
+ // Check challenge
+ const { challenge } = signature.getCollectedClientData();
+
+ const messageBase64URLString = bufferToBase64URLString(Hex.fromHexInput(message).toUint8Array());
+ if (challenge !== messageBase64URLString) {
+ return false;
+ }
+
+ // Get verification data.
+ const verificationData = signature.getVerificationData();
+
+ // Verify the the signature is the signed verification data.
+ return this.verifySignature({ message: verificationData, signature: signature.paar.signature.signature });
+ }
+
+ serialize(serializer: Serializer): void {
+ serializer.serializeBytes(this.key.toUint8Array());
+ }
+
+ static deserialize(deserializer: Deserializer): Secp256r1PublicKey {
+ const bytes = deserializer.deserializeBytes();
+ return new Secp256r1PublicKey(bytes);
+ }
+
+ static load(deserializer: Deserializer): Secp256r1PublicKey {
+ const bytes = deserializer.deserializeBytes();
+ return new Secp256r1PublicKey(bytes);
+ }
+}
+
+/**
+ * A Secp256r1 ecdsa private key - this is only used for test purposes as signing is done via passkeys
+ */
+export class Secp256r1PrivateKey extends PrivateKey {
+ /**
+ * Length of Secp256r1 ecdsa private key
+ */
+ static readonly LENGTH: number = 32;
+
+ /**
+ * The private key bytes
+ * @private
+ */
+ private readonly key: Hex;
+
+ /**
+ * Create a new PrivateKey instance from a Uint8Array or String.
+ *
+ * @param hexInput A HexInput (string or Uint8Array)
+ */
+ constructor(hexInput: HexInput) {
+ super();
+
+ const privateKeyHex = Hex.fromHexInput(hexInput);
+ if (privateKeyHex.toUint8Array().length !== Secp256r1PrivateKey.LENGTH) {
+ throw new Error(`PrivateKey length should be ${Secp256r1PrivateKey.LENGTH}`);
+ }
+
+ this.key = privateKeyHex;
+ }
+
+ /**
+ * Get the private key in bytes (Uint8Array).
+ *
+ * @returns
+ */
+ toUint8Array(): Uint8Array {
+ return this.key.toUint8Array();
+ }
+
+ /**
+ * Get the private key as a hex string with the 0x prefix.
+ *
+ * @returns string representation of the private key
+ */
+ toString(): string {
+ return this.key.toString();
+ }
+
+ /**
+ * Sign the given message with the private key.
+ *
+ * @param message in HexInput format
+ * @returns Signature
+ */
+ sign(message: HexInput): Secp256r1Signature {
+ const msgHex = Hex.fromHexInput(message);
+ const sha3Message = sha3_256(msgHex.toUint8Array());
+ const signature = p256.sign(sha3Message, this.key.toUint8Array());
+ return new Secp256r1Signature(signature.toCompactRawBytes());
+ }
+
+ serialize(serializer: Serializer): void {
+ serializer.serializeBytes(this.toUint8Array());
+ }
+
+ static deserialize(deserializer: Deserializer): Secp256r1PrivateKey {
+ const bytes = deserializer.deserializeBytes();
+ return new Secp256r1PrivateKey(bytes);
+ }
+
+ /**
+ * Generate a new random private key.
+ *
+ * @returns Secp256r1PrivateKey
+ */
+ static generate(): Secp256r1PrivateKey {
+ const hexInput = p256.utils.randomPrivateKey();
+ return new Secp256r1PrivateKey(hexInput);
+ }
+
+ /**
+ * Derive the Secp256r1PublicKey from this private key.
+ *
+ * @returns Secp256r1PublicKey
+ */
+ publicKey(): Secp256r1PublicKey {
+ const bytes = p256.getPublicKey(this.key.toUint8Array(), false);
+ return new Secp256r1PublicKey(bytes);
+ }
+}
+
+/**
+ * A signature of a message signed using an Secp256r1 ecdsa private key
+ */
+export class Secp256r1Signature extends Signature {
+ /**
+ * Secp256r1 ecdsa signatures are 256-bit.
+ */
+ static readonly LENGTH = 64;
+
+ /**
+ * The signature bytes
+ * @private
+ */
+ private readonly data: Hex;
+
+ /**
+ * Create a new Signature instance from a Uint8Array or String. It will convert the signature to its canonical if needed.
+ *
+ * @param hexInput A HexInput (string or Uint8Array)
+ */
+ constructor(hexInput: HexInput) {
+ super();
+
+ const hex = Hex.fromHexInput(hexInput);
+ if (hex.toUint8Array().length !== Secp256r1Signature.LENGTH) {
+ throw new Error(`Signature length should be ${Secp256r1Signature.LENGTH}, recieved ${hex.toUint8Array().length}`);
+ }
+ const signature = p256.Signature.fromCompact(hexInput).normalizeS().toCompactRawBytes();
+ this.data = Hex.fromHexInput(signature);
+ }
+
+ /**
+ * Get the signature in bytes (Uint8Array).
+ *
+ * @returns Uint8Array representation of the signature
+ */
+ toUint8Array(): Uint8Array {
+ return this.data.toUint8Array();
+ }
+
+ /**
+ * Get the signature as a hex string with the 0x prefix.
+ *
+ * @returns string representation of the signature
+ */
+ toString(): string {
+ return this.data.toString();
+ }
+
+ serialize(serializer: Serializer): void {
+ serializer.serializeBytes(this.data.toUint8Array());
+ }
+
+ static deserialize(deserializer: Deserializer): Secp256r1Signature {
+ const hex = deserializer.deserializeBytes();
+ return new Secp256r1Signature(hex);
+ }
+
+ static load(deserializer: Deserializer): Secp256r1Signature {
+ const bytes = deserializer.deserializeBytes();
+ return new Secp256r1Signature(bytes);
+ }
+}
diff --git a/src/core/crypto/webauthn.ts b/src/core/crypto/webauthn.ts
new file mode 100644
index 000000000..cadd0d9e9
--- /dev/null
+++ b/src/core/crypto/webauthn.ts
@@ -0,0 +1,155 @@
+// Copyright © Aptos Foundation
+// SPDX-License-Identifier: Apache-2.0
+
+import { sha256 } from "@noble/hashes/sha256";
+import { Signature } from "./asymmetricCrypto";
+import { Deserializer, Serializer } from "../../bcs";
+import { Hex } from "../hex";
+import { AssertionSignatureVariant, HexInput } from "../../types";
+import { Secp256r1Signature } from "./secp256r1";
+
+export class AssertionSignature extends Signature {
+ public readonly signature: Signature;
+
+ constructor(signature: Signature) {
+ super();
+ this.signature = signature;
+ }
+
+ /**
+ * Get the signature in bytes (Uint8Array).
+ *
+ * @returns Uint8Array representation of the signature
+ */
+ toUint8Array(): Uint8Array {
+ return this.signature.toUint8Array();
+ }
+
+ /**
+ * Get the signature as a hex string with the 0x prefix.
+ *
+ * @returns string representation of the signature
+ */
+ toString(): string {
+ return this.signature.toString();
+ }
+
+ serialize(serializer: Serializer): void {
+ if (this.signature instanceof Secp256r1Signature) {
+ serializer.serializeU32AsUleb128(AssertionSignatureVariant.Secp256r1);
+ this.signature.serialize(serializer);
+ } else {
+ throw new Error("Unknown signature type for AssertionSignature");
+ }
+ }
+
+ static deserialize(deserializer: Deserializer): AssertionSignature {
+ const index = deserializer.deserializeUleb128AsU32();
+ switch (index) {
+ case AssertionSignatureVariant.Secp256r1:
+ return new AssertionSignature(Secp256r1Signature.load(deserializer));
+ default:
+ throw new Error(`Unknown variant index for AssertionSignature: ${index}`);
+ }
+ }
+}
+
+export class PartialAuthenticatorAssertionResponse {
+ readonly signature: AssertionSignature;
+
+ readonly authenticatorData: Uint8Array;
+
+ readonly clientDataJSON: Uint8Array;
+
+ constructor(signature: Signature, authenticatorData: HexInput, clientDataJSON: HexInput) {
+ this.signature = new AssertionSignature(signature);
+
+ this.authenticatorData = Hex.fromHexInput(authenticatorData).toUint8Array();
+
+ this.clientDataJSON = Hex.fromHexInput(clientDataJSON).toUint8Array();
+ }
+}
+
+export type ClientDataJSON = {
+ type: string;
+ challenge: string;
+ origin: string;
+ crossOrigin?: boolean;
+ tokenBinding?: {
+ id?: string;
+ status: "present" | "supported" | "not-supported";
+ };
+};
+
+/**
+ * A signature of WebAuthn transaction
+ */
+export class WebAuthnSignature extends Signature {
+ /**
+ * The signature bytes
+ */
+ readonly paar: PartialAuthenticatorAssertionResponse;
+
+ /**
+ * Create a new Signature instance from a Uint8Array or String.
+ *
+ * @param hexInput A HexInput (string or Uint8Array)
+ */
+ constructor(signature: Signature, authenticatorData: HexInput, clientDataJSON: HexInput) {
+ super();
+
+ this.paar = new PartialAuthenticatorAssertionResponse(signature, authenticatorData, clientDataJSON);
+ }
+
+ /**
+ * Get the signature in bytes (Uint8Array).
+ *
+ * @returns Uint8Array representation of the signature
+ */
+ toUint8Array(): Uint8Array {
+ return this.paar.signature.toUint8Array();
+ }
+
+ /**
+ * Get the signature as a hex string with the 0x prefix.
+ *
+ * @returns string representation of the signature
+ */
+ toString(): string {
+ return this.paar.toString();
+ }
+
+ getCollectedClientData(): ClientDataJSON {
+ const utf8Decoder = new TextDecoder("utf-8");
+ const decodedClientData = utf8Decoder.decode(this.paar.clientDataJSON);
+ return JSON.parse(decodedClientData);
+ }
+
+ getVerificationData(): Uint8Array {
+ const clientDataJSONHash = sha256(this.paar.clientDataJSON);
+ const mergedArray = new Uint8Array(clientDataJSONHash.length + this.paar.authenticatorData.length);
+ mergedArray.set(this.paar.authenticatorData);
+ mergedArray.set(clientDataJSONHash, this.paar.authenticatorData.length);
+ return mergedArray;
+ }
+
+ serialize(serializer: Serializer): void {
+ this.paar.signature.serialize(serializer);
+ serializer.serializeBytes(this.paar.authenticatorData);
+ serializer.serializeBytes(this.paar.clientDataJSON);
+ }
+
+ static deserialize(deserializer: Deserializer): WebAuthnSignature {
+ const sig = AssertionSignature.deserialize(deserializer);
+ const authData = deserializer.deserializeBytes();
+ const clientDataJSON = deserializer.deserializeBytes();
+ return new WebAuthnSignature(sig.signature, authData, clientDataJSON);
+ }
+
+ static load(deserializer: Deserializer): WebAuthnSignature {
+ const sig = AssertionSignature.deserialize(deserializer);
+ const authData = deserializer.deserializeBytes();
+ const clientDataJSON = deserializer.deserializeBytes();
+ return new WebAuthnSignature(sig.signature, authData, clientDataJSON);
+ }
+}
diff --git a/src/internal/passkey.ts b/src/internal/passkey.ts
new file mode 100644
index 000000000..fb40d8aea
--- /dev/null
+++ b/src/internal/passkey.ts
@@ -0,0 +1,157 @@
+// Copyright © Aptos Foundation
+// SPDX-License-Identifier: Apache-2.0
+
+/**
+ * This file contains the underlying implementations for exposed API surface in
+ * the {@link api/passkeysBrowser}. By moving the methods out into a separate file,
+ * other namespaces and processes can access these methods without depending on the entire
+ * faucet namespace and without having a dependency cycle error.
+ */
+import {
+ generateRegistrationOptions as _generateRegistrationOptions,
+ verifyRegistrationResponse as _verifyRegistrationResponse,
+ generateAuthenticationOptions as _generateAuthenticationOptions,
+ verifyAuthenticationResponse as _verifyAuthenticationResponse,
+ VerifiedRegistrationResponse,
+ VerifiedAuthenticationResponse,
+} from "@simplewebauthn/server";
+import { startRegistration, startAuthentication } from "@simplewebauthn/browser";
+import { isoBase64URL, cose, parseAuthenticatorData, convertCOSEtoPKCS } from "@simplewebauthn/server/helpers";
+import { AuthenticationResponseJSON, AuthenticatorDevice, PublicKeyCredentialCreationOptionsJSON,
+ PublicKeyCredentialRequestOptionsJSON, RegistrationResponseJSON } from "@simplewebauthn/server/esm/deps";
+import { AptosConfig } from "../api/aptosConfig";
+import { AccountAddress, AuthenticationKey, PublicKey } from "../core";
+import { AnyRawTransaction, signWithPasskey } from "../transactions";
+import { HexInput, PendingTransactionResponse } from "../types";
+import { submitTransaction } from "./transactionSubmission";
+import { Secp256r1PublicKey } from "../core/crypto/secp256r1";
+
+const supportedAlgorithmIDs = [cose.COSEALG.ES256];
+
+export async function generateRegistrationOptions(args: {
+ rpName: string;
+ rpID: string;
+ userID: string;
+ userName: string;
+ challenge?: string | Uint8Array;
+ userDisplayName?: string;
+ timeout?: number;
+ attestationType?: AttestationConveyancePreference;
+ authenticatorAttachment?: AuthenticatorAttachment;
+}): Promise {
+ const { authenticatorAttachment } = args;
+ const authenticatorSelection: AuthenticatorSelectionCriteria = {
+ authenticatorAttachment,
+ residentKey: "required",
+ userVerification: "required",
+ };
+
+ return _generateRegistrationOptions({
+ ...args,
+ authenticatorSelection,
+ supportedAlgorithmIDs,
+ });
+}
+
+export async function registerCredential(
+ creationOptionsJSON: PublicKeyCredentialCreationOptionsJSON,
+): Promise {
+ return startRegistration(creationOptionsJSON);
+}
+
+export async function verifyRegistrationResponse(args: {
+ response: RegistrationResponseJSON;
+ expectedChallenge: string | ((challenge: string) => boolean | Promise);
+ expectedOrigin: string | string[];
+ expectedRPID?: string | string[];
+}): Promise {
+ return _verifyRegistrationResponse({
+ ...args,
+ requireUserVerification: true,
+ supportedAlgorithmIDs,
+ });
+}
+
+export async function generateAuthenticationOptions(args: {
+ credentialId: string | Uint8Array;
+ timeout?: number;
+ rpID?: string;
+}): Promise {
+ const {credentialId} = args;
+ const allowCredentials: PublicKeyCredentialDescriptor[] = [
+ {
+ type: "public-key",
+ id: typeof credentialId === "string" ? isoBase64URL.toBuffer(credentialId) : credentialId,
+ },
+ ];
+ return _generateAuthenticationOptions({...args, allowCredentials, userVerification: "required"})
+}
+
+export async function authenticateCredential(
+ requestOptionsJSON: PublicKeyCredentialRequestOptionsJSON
+): Promise {
+ return startAuthentication(requestOptionsJSON)
+}
+
+export async function verifyAuthenticationResponse(args: {
+ response: AuthenticationResponseJSON;
+ expectedChallenge: string | ((challenge: string) => boolean | Promise);
+ expectedOrigin: string | string[];
+ expectedRPID: string | string[];
+ expectedType?: string | string[];
+ authenticator: AuthenticatorDevice;
+ requireUserVerification?: boolean;
+ advancedFIDOConfig?: {
+ userVerification?: UserVerificationRequirement;
+ };
+}): Promise {
+
+ return _verifyAuthenticationResponse({...args})
+}
+
+export function parsePublicKey(response: RegistrationResponseJSON): PublicKey {
+ const authData = isoBase64URL.toBuffer(response.response.authenticatorData!);
+ const parsedAuthenticatorData = parseAuthenticatorData(authData);
+ // Convert from COSE
+ const publicKey = convertCOSEtoPKCS(parsedAuthenticatorData.credentialPublicKey!);
+ return new Secp256r1PublicKey(publicKey);
+}
+
+export async function signAndSubmitWithPasskey(args: {
+ aptosConfig: AptosConfig;
+ credentialId: string | Uint8Array;
+ publicKey: PublicKey;
+ transaction: AnyRawTransaction;
+ timeout?: number;
+ rpID?: string;
+ options?: {
+ allowCredentials?: PublicKeyCredentialDescriptor[]
+ }
+}): Promise {
+ const { aptosConfig, transaction } = args;
+
+ const authenticator = await signWithPasskey({ ...args });
+ console.log(authenticator);
+ return submitTransaction({
+ aptosConfig,
+ transaction,
+ senderAuthenticator: authenticator,
+ });
+}
+
+export async function getPasskeyAccountAddress(args: { publicKey: HexInput; alg?: number }): Promise {
+ const { publicKey, alg } = args;
+ const algorithm = alg ?? cose.COSEALG.ES256;
+
+ let publicKeyObj: PublicKey;
+ switch (algorithm) {
+ // ES256, P256, Secp256r1 are all the same thing.
+ case cose.COSEALG.ES256:
+ publicKeyObj = new Secp256r1PublicKey(publicKey);
+ break;
+ default:
+ throw new Error("Algorithm is not supported");
+ }
+ const authKey = AuthenticationKey.fromPublicKey({ publicKey: publicKeyObj });
+ return AccountAddress.from(authKey.toString());
+}
diff --git a/src/internal/transactionSubmission.ts b/src/internal/transactionSubmission.ts
index c73ab7830..4d7f5ae47 100644
--- a/src/internal/transactionSubmission.ts
+++ b/src/internal/transactionSubmission.ts
@@ -21,7 +21,7 @@ import {
sign,
generateSigningMessage,
} from "../transactions/transactionBuilder/transactionBuilder";
-import {
+import type {
InputGenerateTransactionData,
AnyRawTransaction,
InputSimulateTransactionData,
diff --git a/src/transactions/transactionBuilder/transactionBuilder.ts b/src/transactions/transactionBuilder/transactionBuilder.ts
index fd797237e..4f276c3de 100644
--- a/src/transactions/transactionBuilder/transactionBuilder.ts
+++ b/src/transactions/transactionBuilder/transactionBuilder.ts
@@ -7,6 +7,10 @@
* and a signed transaction that can be simulated, signed and submitted to chain.
*/
import { sha3_256 as sha3Hash } from "@noble/hashes/sha3";
+import { isoBase64URL } from "@simplewebauthn/server/helpers";
+import { p256 } from "@noble/curves/p256";
+import { base64URLStringToBuffer, startAuthentication } from "@simplewebauthn/browser";
+import { generateAuthenticationOptions } from "@simplewebauthn/server";
import { AptosConfig } from "../../api/aptosConfig";
import { AccountAddress, AccountAddressInput, Hex, PublicKey } from "../../core";
import { Account } from "../../core/account";
@@ -14,6 +18,7 @@ import { AnyPublicKey } from "../../core/crypto/anyPublicKey";
import { AnySignature } from "../../core/crypto/anySignature";
import { Ed25519PublicKey, Ed25519Signature } from "../../core/crypto/ed25519";
import { Secp256k1PublicKey, Secp256k1Signature } from "../../core/crypto/secp256k1";
+import { Secp256r1PublicKey, Secp256r1Signature } from "../../core/crypto/secp256r1";
import { getInfo } from "../../internal/account";
import { getLedgerInfo } from "../../internal/general";
import { getGasPriceEstimation } from "../../internal/transaction";
@@ -74,8 +79,10 @@ import {
} from "../types";
import { convertArgument, fetchEntryFunctionAbi, standardizeTypeTags } from "./remoteAbi";
import { memoizeAsync } from "../../utils/memoize";
-import { AnyNumber, SigningScheme } from "../../types";
+import { AnyNumber, HexInput, SigningScheme } from "../../types";
import { getFunctionParts, isScriptDataInput } from "./helpers";
+import { WebAuthnSignature } from "../../core/crypto/webauthn";
+import { getSigningMessage } from "../../internal/transactionSubmission";
/**
* We are defining function signatures, each with its specific input and output.
@@ -452,6 +459,93 @@ export function sign(args: { signer: Account; transaction: AnyRawTransaction }):
}
}
+export async function signWithPasskey(args: {
+ publicKey: PublicKey;
+ credentialId: string | Uint8Array;
+ transaction: AnyRawTransaction;
+ timeout?: number;
+ rpID?: string;
+ options?: {
+ allowCredentials?: PublicKeyCredentialDescriptor[]
+ }
+}): Promise {
+ const { credentialId, publicKey, transaction, timeout, rpID, options } = args;
+ console.log("PublicKey", publicKey.toString());
+
+ if (!(publicKey instanceof Secp256r1PublicKey)) {
+ throw new Error("Unsupported public key for passkey signing.");
+ }
+
+ const allowCredentials: PublicKeyCredentialDescriptor[] = options?.allowCredentials ?? [
+ {
+ type: "public-key",
+ id: typeof credentialId === "string" ? isoBase64URL.toBuffer(credentialId) : credentialId,
+ },
+ ];
+
+ // Get the signing message and hash it to create the challenge
+ const transactionToSign: SimpleTransaction = { rawTransaction: deriveTransactionType(transaction) as RawTransaction };
+ const signingMessage = getSigningMessage({ transaction: transactionToSign as AnyRawTransaction });
+ const challenge = sha3Hash(signingMessage);
+
+ const authOptions = await generateAuthenticationOptions({
+ allowCredentials,
+ challenge,
+ timeout,
+ rpID,
+ userVerification: "required",
+ });
+ const authenticationResponse = await startAuthentication(authOptions);
+
+ const authenticatorAssertionResponse = authenticationResponse.response;
+ console.log(authenticatorAssertionResponse);
+
+ const { clientDataJSON, authenticatorData, signature } = authenticatorAssertionResponse;
+
+ console.log("DER Signature: ", signature)
+ const signatureCompact = p256.Signature.fromDER(
+ new Uint8Array(base64URLStringToBuffer(signature)),
+ ).toCompactRawBytes();
+
+ console.log("COMPACT Signature: ", new Hex(signatureCompact).toString());
+
+ const webAuthnSignature = new WebAuthnSignature(
+ new Secp256r1Signature(signatureCompact),
+ isoBase64URL.toBuffer(authenticatorData),
+ isoBase64URL.toBuffer(clientDataJSON),
+ );
+
+ console.log("WEBAUTHN Signature: ", webAuthnSignature);
+ return new AccountAuthenticatorSingleKey(new AnyPublicKey(publicKey), new AnySignature(webAuthnSignature));
+}
+
+/**
+ * Creates and returns the Authenticator for passkey signed transactions.
+ *
+ * @param args.publicKey The public key of the passkey credential.
+ * @param args.signature The P256signature which is the signed challenge.
+ * @param args.authenticatorData The AuthenticatorData of the assertion.
+ * @param args.clientDataJSON The clientDataJSON of the assertion.
+ *
+ * @return The signer AccountAuthenticator
+ */
+export function getAuthenticatorForWebAuthn(args: {
+ publicKey: PublicKey;
+ signature: HexInput;
+ authenticatorData: HexInput;
+ clientDataJSON: HexInput;
+}): AccountAuthenticator {
+ const { publicKey, signature, authenticatorData, clientDataJSON } = args;
+ let signatureObj: AnySignature;
+ if (publicKey instanceof Secp256r1PublicKey) {
+ signatureObj = new AnySignature(new Secp256r1Signature(signature));
+ } else {
+ throw new Error("Unsupported public key");
+ }
+ const webAuthnSignature = new WebAuthnSignature(signatureObj, authenticatorData, clientDataJSON);
+ return new AccountAuthenticatorSingleKey(new AnyPublicKey(publicKey), new AnySignature(webAuthnSignature));
+}
+
/**
* Prepare a transaction to be submitted to chain
*
diff --git a/src/types/index.ts b/src/types/index.ts
index d63e131bd..bd3739297 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -107,11 +107,17 @@ export enum AccountAuthenticatorVariant {
export enum AnyPublicKeyVariant {
Ed25519 = 0,
Secp256k1 = 1,
+ Secp256r1 = 2,
}
export enum AnySignatureVariant {
Ed25519 = 0,
Secp256k1 = 1,
+ WebAuthn = 2,
+}
+
+export enum AssertionSignatureVariant {
+ Secp256r1 = 0,
}
/**
@@ -1025,6 +1031,10 @@ export enum SigningSchemeInput {
* For Secp256k1Ecdsa
*/
Secp256k1Ecdsa = 2,
+ /**
+ * For Secp256r1Ecdsa
+ */
+ Secp256r1Ecdsa = 3,
}
/**
@@ -1080,4 +1090,16 @@ export type GenerateAccountWithSingleSignerSecp256k1Key = {
legacy?: false;
};
-export type GenerateAccount = GenerateAccountWithEd25519 | GenerateAccountWithSingleSignerSecp256k1Key;
+/**
+ * Input type to generate an account using Single Signer
+ * Secp256r1
+ */
+export type GenerateAccountWithSingleSignerSecp256r1Key = {
+ scheme: SigningSchemeInput.Secp256r1Ecdsa;
+ legacy?: false;
+};
+
+export type GenerateAccount =
+ | GenerateAccountWithEd25519
+ | GenerateAccountWithSingleSignerSecp256k1Key
+ | GenerateAccountWithSingleSignerSecp256r1Key;