From d8b253bc54f03eafeae0ab6fc6448d1f0ffc0fbf Mon Sep 17 00:00:00 2001 From: Alfreedom Date: Tue, 13 Aug 2024 12:23:24 +0200 Subject: [PATCH 1/4] Added Flutter universal links (#2695) --- .../.well-known/apple-app-site-association | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/apps/laboratory/public/.well-known/apple-app-site-association b/apps/laboratory/public/.well-known/apple-app-site-association index 1fccee72ae..145dd6d308 100644 --- a/apps/laboratory/public/.well-known/apple-app-site-association +++ b/apps/laboratory/public/.well-known/apple-app-site-association @@ -43,6 +43,42 @@ "paths": [ "/rn_walletkit*" ] + }, + { + "appID": "W5R8AG9K22.com.walletconnect.flutterwallet", + "paths": [ + "/walletkit_flutter" + ] + }, + { + "appID": "W5R8AG9K22.com.walletconnect.flutterwallet.internal", + "paths": [ + "/walletkit_flutter_internal" + ] + }, + { + "appID": "W5R8AG9K22.com.walletconnect.flutterdapp", + "paths": [ + "/appkit_flutter" + ] + }, + { + "appID": "W5R8AG9K22.com.walletconnect.flutterdapp.internal", + "paths": [ + "/appkit_flutter_internal" + ] + }, + { + "appID": "W5R8AG9K22.com.web3modal.flutterExample", + "paths": [ + "/appkit_flutter_modal" + ] + }, + { + "appID": "W5R8AG9K22.com.web3modal.flutterExample.internal", + "paths": [ + "/appkit_flutter_modal_internal" + ] } ] } From 0c55f979f684112b960f48565a34a70222aa11e2 Mon Sep 17 00:00:00 2001 From: Luka Isailovic Date: Tue, 13 Aug 2024 19:05:46 +0200 Subject: [PATCH 2/4] feat: add bundle size check (#2694) --- .github/workflows/pr_checks.yml | 30 ++ examples/react-wagmi/package.json | 8 +- package.json | 3 +- pnpm-lock.yaml | 557 +++++------------------------- 4 files changed, 127 insertions(+), 471 deletions(-) diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml index 11cc599aa6..793359bbd9 100644 --- a/.github/workflows/pr_checks.yml +++ b/.github/workflows/pr_checks.yml @@ -9,6 +9,9 @@ on: - V5 - main +permissions: + pull-requests: write + concurrency: # Support push/pr as event types with different behaviors each: # 1. push: queue up builds @@ -56,6 +59,33 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + bundle_size: + runs-on: ubuntu-latest + name: Bundle size check + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + + - name: setup-node + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'pnpm' + + - name: install + run: pnpm install + + - name: build + run: pnpm build + + - name: Running vite-size script + uses: glitch-txs/vite-size-action@v1.0.3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + test: runs-on: ubuntu-latest continue-on-error: true diff --git a/examples/react-wagmi/package.json b/examples/react-wagmi/package.json index b4c52284e5..9154f2a2f1 100644 --- a/examples/react-wagmi/package.json +++ b/examples/react-wagmi/package.json @@ -4,21 +4,23 @@ "version": "5.0.10", "scripts": { "dev": "vite --port 3002", - "build": "vite build" + "build": "vite build", + "size": "pnpm run build && vite-size --react --externals wagmi viem @tanstack/react-query react react-dom" }, "dependencies": { "@tanstack/react-query": "5.24.8", "@web3modal/wagmi": "workspace:*", "react": "18.2.0", "react-dom": "18.2.0", - "vite": "5.2.11", "viem": "2.17.8", + "vite": "5.2.11", "wagmi": "2.12.2" }, "devDependencies": { "@types/react": "18.2.62", "@types/react-dom": "18.2.7", "@vitejs/plugin-react": "4.2.1", - "vite": "5.2.11" + "vite": "5.2.11", + "vite-size": "0.0.4" } } diff --git a/package.json b/package.json index 450f42bc50..c871f9ddce 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "publish:alpha": "pnpm install; pnpm build; changeset publish --tag alpha", "publish:beta": "pnpm install; pnpm build; changeset publish --tag beta", "publish:canary": "pnpm install; pnpm build; changeset publish --tag canary", - "prepare": "husky" + "prepare": "husky", + "size": "pnpm --filter=./examples/react-wagmi size" }, "devDependencies": { "@changesets/changelog-github": "0.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 539c508311..c3df54a87d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,7 +27,7 @@ importers: version: 6.18.1(eslint@8.56.0)(typescript@5.3.3) '@vitest/coverage-v8': specifier: 1.1.2 - version: 1.1.2(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.3)) + version: 1.1.2(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3)) danger: specifier: 11.3.1 version: 11.3.1 @@ -452,7 +452,7 @@ importers: version: 0.1.14(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-wallets': specifier: 0.19.32 - version: 0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10) + version: 0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10) '@tanstack/react-query': specifier: 5.24.8 version: 5.24.8(react@18.2.0) @@ -512,6 +512,9 @@ importers: '@vitejs/plugin-react': specifier: 4.2.1 version: 4.2.1(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + vite-size: + specifier: 0.0.4 + version: 0.0.4(@types/node@20.11.5)(terser@5.31.3)(vue@3.4.3(typescript@5.3.3)) examples/vue-ethers5: dependencies: @@ -539,7 +542,7 @@ importers: version: 0.1.14(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-wallets': specifier: 0.19.32 - version: 0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) + version: 0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10) '@web3modal/solana': specifier: workspace:* version: link:../../packages/solana @@ -6148,6 +6151,13 @@ packages: vite: ^5.0.0 vue: ^3.2.25 + '@vitejs/plugin-vue@5.1.2': + resolution: {integrity: sha512-nY9IwH12qeiJqumTCLJLE7IiNx7HZ39cbHaysEUd+Myvbz9KAqd2yq+U01Kab1R/H1BmiyM2ShTYlNH32Fzo3A==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + '@vitest/coverage-v8@1.1.2': resolution: {integrity: sha512-W12+EiqKxNgcot5ZdUA/8G/P+3bHVr1Ggi4G7qWbLGXFfyEANCDidpV7KzxnOgFGrL4DAB1nsh4mzTIZ3Nz79A==} peerDependencies: @@ -11870,6 +11880,10 @@ packages: peerDependencies: vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + vite-size@0.0.4: + resolution: {integrity: sha512-DJFt5orZzqe+2vWXYxkckgjtUPqvHiqOEvwi+R1C9hB2NMPYRI9C65ZNLMcyUIme8DGol9HhnspNpHBfLIJfeg==} + hasBin: true + vite@5.2.11: resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -11898,6 +11912,34 @@ packages: terser: optional: true + vite@5.2.9: + resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vitest@2.0.3: resolution: {integrity: sha512-o3HRvU93q6qZK4rI2JrhKyZMMuxg/JRt30E6qeQs6ueaiz5hr1cPj+Sk2kATgQzMMqsa2DiNI0TIK++1ULx8Jw==} engines: {node: ^18.0.0 || >=20.0.0} @@ -17026,23 +17068,6 @@ snapshots: optionalDependencies: '@types/react': 18.2.62 - '@react-native/virtualized-lists@0.74.87(@types/react@18.2.62)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)': - dependencies: - invariant: 2.2.4 - nullthrows: 1.1.1 - react: 18.2.0 - react-native: 0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10) - optionalDependencies: - '@types/react': 18.2.62 - optional: true - - '@react-native/virtualized-lists@0.74.87(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))': - dependencies: - invariant: 2.2.4 - nullthrows: 1.1.1 - react-native: 0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10) - optional: true - '@rnx-kit/chromium-edge-launcher@1.0.0': dependencies: '@types/node': 18.19.43 @@ -17716,40 +17741,6 @@ snapshots: - tslib - utf-8-validate - '@solana/wallet-adapter-trezor@0.1.2(@babel/core@7.25.2)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@trezor/connect-web': 9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - buffer: 6.0.3 - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - supports-color - - tslib - - utf-8-validate - - '@solana/wallet-adapter-trezor@0.1.2(@babel/core@7.25.2)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@trezor/connect-web': 9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - buffer: 6.0.3 - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - supports-color - - tslib - - utf-8-validate - '@solana/wallet-adapter-trust@0.1.13(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) @@ -17856,76 +17847,7 @@ snapshots: - uWebSockets.js - utf-8-validate - '@solana/wallet-adapter-wallets@0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@solana/wallet-adapter-alpha': 0.1.10(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-avana': 0.1.13(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-bitkeep': 0.3.20(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-bitpie': 0.5.18(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-clover': 0.4.19(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-coin98': 0.5.20(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-coinbase': 0.1.19(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-coinhub': 0.3.18(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-fractal': 0.1.8(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@solana/wallet-adapter-huobi': 0.1.15(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-hyperpay': 0.1.14(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-keystone': 0.1.15(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-krystal': 0.1.12(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-ledger': 0.9.25(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-mathwallet': 0.9.18(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-neko': 0.2.12(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-nightly': 0.1.16(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-nufi': 0.1.17(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-onto': 0.1.7(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-particle': 0.1.12(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0) - '@solana/wallet-adapter-phantom': 0.9.24(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-safepal': 0.5.18(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-saifu': 0.1.15(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-salmon': 0.1.14(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-sky': 0.1.15(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-solflare': 0.6.28(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-solong': 0.9.18(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-spot': 0.1.15(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-tokenary': 0.1.12(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-tokenpocket': 0.4.19(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-torus': 0.11.28(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-trezor': 0.1.2(@babel/core@7.25.2)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-trust': 0.1.13(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-unsafe-burner': 0.1.7(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-walletconnect': 0.1.16(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-xdefi': 0.1.7(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@babel/core' - - '@babel/runtime' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@sentry/types' - - '@upstash/redis' - - '@vercel/kv' - - bs58 - - bufferutil - - encoding - - expo-constants - - expo-localization - - ioredis - - react - - react-dom - - react-native - - supports-color - - tslib - - uWebSockets.js - - utf-8-validate - - '@solana/wallet-adapter-wallets@0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': + '@solana/wallet-adapter-wallets@0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10)': dependencies: '@solana/wallet-adapter-alpha': 0.1.10(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-avana': 0.1.13(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) @@ -17958,7 +17880,7 @@ snapshots: '@solana/wallet-adapter-tokenary': 0.1.12(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-tokenpocket': 0.4.19(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-torus': 0.11.28(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-trezor': 0.1.2(@babel/core@7.25.2)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) + '@solana/wallet-adapter-trezor': 0.1.2(@babel/core@7.25.2)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) '@solana/wallet-adapter-trust': 0.1.13(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-unsafe-burner': 0.1.7(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-walletconnect': 0.1.16(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -18901,26 +18823,6 @@ snapshots: - expo-localization - react-native - '@trezor/analytics@1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)': - dependencies: - '@trezor/env-utils': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - expo-constants - - expo-localization - - react-native - - '@trezor/analytics@1.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)': - dependencies: - '@trezor/env-utils': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - expo-constants - - expo-localization - - react-native - '@trezor/blockchain-link-types@1.1.0(bufferutil@4.0.8)(tslib@2.6.3)(utf-8-validate@5.0.10)': dependencies: '@solana/web3.js': 1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -18949,36 +18851,6 @@ snapshots: - react-native - utf-8-validate - '@trezor/blockchain-link-utils@1.1.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@mobily/ts-belt': 3.13.1 - '@solana/web3.js': 1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@trezor/env-utils': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - utf-8-validate - - '@trezor/blockchain-link-utils@1.1.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@mobily/ts-belt': 3.13.1 - '@solana/web3.js': 1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@trezor/env-utils': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - utf-8-validate - '@trezor/blockchain-link@2.2.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 @@ -19002,52 +18874,6 @@ snapshots: - supports-color - utf-8-validate - '@trezor/blockchain-link@2.2.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@trezor/blockchain-link-types': 1.1.0(bufferutil@4.0.8)(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/blockchain-link-utils': 1.1.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/utils': 9.1.0(tslib@2.6.3) - '@trezor/utxo-lib': 2.1.0(tslib@2.6.3) - '@types/web': 0.0.138 - events: 3.3.0 - ripple-lib: 1.10.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) - socks-proxy-agent: 6.1.1 - tslib: 2.6.3 - ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - supports-color - - utf-8-validate - - '@trezor/blockchain-link@2.2.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@trezor/blockchain-link-types': 1.1.0(bufferutil@4.0.8)(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/blockchain-link-utils': 1.1.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/utils': 9.1.0(tslib@2.6.3) - '@trezor/utxo-lib': 2.1.0(tslib@2.6.3) - '@types/web': 0.0.138 - events: 3.3.0 - ripple-lib: 1.10.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) - socks-proxy-agent: 6.1.1 - tslib: 2.6.3 - ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - supports-color - - utf-8-validate - '@trezor/connect-analytics@1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)': dependencies: '@trezor/analytics': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) @@ -19057,24 +18883,6 @@ snapshots: - expo-localization - react-native - '@trezor/connect-analytics@1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)': - dependencies: - '@trezor/analytics': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - expo-constants - - expo-localization - - react-native - - '@trezor/connect-analytics@1.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)': - dependencies: - '@trezor/analytics': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - expo-constants - - expo-localization - - react-native - '@trezor/connect-common@0.1.0(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)': dependencies: '@trezor/env-utils': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) @@ -19085,26 +18893,6 @@ snapshots: - expo-localization - react-native - '@trezor/connect-common@0.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)': - dependencies: - '@trezor/env-utils': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - expo-constants - - expo-localization - - react-native - - '@trezor/connect-common@0.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)': - dependencies: - '@trezor/env-utils': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - expo-constants - - expo-localization - - react-native - '@trezor/connect-web@9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': dependencies: '@trezor/connect': 9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) @@ -19121,38 +18909,6 @@ snapshots: - supports-color - utf-8-validate - '@trezor/connect-web@9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@trezor/connect': 9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/connect-common': 0.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - supports-color - - utf-8-validate - - '@trezor/connect-web@9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@trezor/connect': 9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/connect-common': 0.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - tslib: 2.6.3 - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - supports-color - - utf-8-validate - '@trezor/connect@9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': dependencies: '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) @@ -19184,68 +18940,6 @@ snapshots: - supports-color - utf-8-validate - '@trezor/connect@9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) - '@ethereumjs/common': 4.3.0 - '@ethereumjs/tx': 5.3.0 - '@fivebinaries/coin-selection': 2.2.1 - '@trezor/blockchain-link': 2.2.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/blockchain-link-types': 1.1.0(bufferutil@4.0.8)(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/connect-analytics': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/connect-common': 0.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/protobuf': 1.1.0(tslib@2.6.3) - '@trezor/protocol': 1.1.0(tslib@2.6.3) - '@trezor/schema-utils': 1.1.0(tslib@2.6.3) - '@trezor/transport': 1.2.0(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - '@trezor/utxo-lib': 2.1.0(tslib@2.6.3) - blakejs: 1.2.1 - bs58: 5.0.0 - bs58check: 3.0.1 - cross-fetch: 4.0.0 - tslib: 2.6.3 - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - supports-color - - utf-8-validate - - '@trezor/connect@9.3.0(@babel/core@7.25.2)(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10)': - dependencies: - '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) - '@ethereumjs/common': 4.3.0 - '@ethereumjs/tx': 5.3.0 - '@fivebinaries/coin-selection': 2.2.1 - '@trezor/blockchain-link': 2.2.0(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/blockchain-link-types': 1.1.0(bufferutil@4.0.8)(tslib@2.6.3)(utf-8-validate@5.0.10) - '@trezor/connect-analytics': 1.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/connect-common': 0.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3) - '@trezor/protobuf': 1.1.0(tslib@2.6.3) - '@trezor/protocol': 1.1.0(tslib@2.6.3) - '@trezor/schema-utils': 1.1.0(tslib@2.6.3) - '@trezor/transport': 1.2.0(tslib@2.6.3) - '@trezor/utils': 9.1.0(tslib@2.6.3) - '@trezor/utxo-lib': 2.1.0(tslib@2.6.3) - blakejs: 1.2.1 - bs58: 5.0.0 - bs58check: 3.0.1 - cross-fetch: 4.0.0 - tslib: 2.6.3 - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - encoding - - expo-constants - - expo-localization - - react-native - - supports-color - - utf-8-validate - '@trezor/env-utils@1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)': dependencies: tslib: 2.6.3 @@ -19253,20 +18947,6 @@ snapshots: optionalDependencies: react-native: 0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10) - '@trezor/env-utils@1.1.0(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(tslib@2.6.3)': - dependencies: - tslib: 2.6.3 - ua-parser-js: 1.0.38 - optionalDependencies: - react-native: 0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10) - - '@trezor/env-utils@1.1.0(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10))(tslib@2.6.3)': - dependencies: - tslib: 2.6.3 - ua-parser-js: 1.0.38 - optionalDependencies: - react-native: 0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@trezor/protobuf@1.1.0(tslib@2.6.3)': dependencies: '@trezor/schema-utils': 1.1.0(tslib@2.6.3) @@ -19680,12 +19360,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitejs/plugin-react@4.2.1(vite@5.2.9(@types/node@20.11.5)(terser@5.31.3))': + dependencies: + '@babel/core': 7.25.2 + '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.2.9(@types/node@20.11.5)(terser@5.31.3) + transitivePeerDependencies: + - supports-color + '@vitejs/plugin-vue@5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3))': dependencies: vite: 5.2.11(@types/node@20.11.5)(terser@5.31.3) vue: 3.4.3(typescript@5.3.3) - '@vitest/coverage-v8@1.1.2(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)(terser@5.31.3))': + '@vitejs/plugin-vue@5.1.2(vite@5.2.9(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3))': + dependencies: + vite: 5.2.9(@types/node@20.11.5)(terser@5.31.3) + vue: 3.4.3(typescript@5.3.3) + + '@vitest/coverage-v8@1.1.2(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -25402,105 +25098,6 @@ snapshots: - supports-color - utf-8-validate - react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10): - dependencies: - '@jest/create-cache-key-function': 29.7.0 - '@react-native-community/cli': 13.6.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@react-native-community/cli-platform-android': 13.6.9 - '@react-native-community/cli-platform-ios': 13.6.9 - '@react-native/assets-registry': 0.74.87 - '@react-native/codegen': 0.74.87(@babel/preset-env@7.25.3(@babel/core@7.25.2)) - '@react-native/community-cli-plugin': 0.74.87(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@react-native/gradle-plugin': 0.74.87 - '@react-native/js-polyfills': 0.74.87 - '@react-native/normalize-colors': 0.74.87 - '@react-native/virtualized-lists': 0.74.87(@types/react@18.2.62)(react-native@0.74.5(@babel/core@7.25.2)(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0) - abort-controller: 3.0.0 - anser: 1.4.10 - ansi-regex: 5.0.1 - base64-js: 1.5.1 - chalk: 4.1.2 - event-target-shim: 5.0.1 - flow-enums-runtime: 0.0.6 - invariant: 2.2.4 - jest-environment-node: 29.7.0 - jsc-android: 250231.0.0 - memoize-one: 5.2.1 - metro-runtime: 0.80.9 - metro-source-map: 0.80.9 - mkdirp: 0.5.6 - nullthrows: 1.1.1 - pretty-format: 26.6.2 - promise: 8.3.0 - react: 18.2.0 - react-devtools-core: 5.3.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) - react-refresh: 0.14.2 - react-shallow-renderer: 16.15.0(react@18.2.0) - regenerator-runtime: 0.13.11 - scheduler: 0.24.0-canary-efb381bbf-20230505 - stacktrace-parser: 0.1.10 - whatwg-fetch: 3.6.20 - ws: 6.2.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) - yargs: 17.7.2 - optionalDependencies: - '@types/react': 18.2.62 - transitivePeerDependencies: - - '@babel/core' - - '@babel/preset-env' - - bufferutil - - encoding - - supports-color - - utf-8-validate - optional: true - - react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10): - dependencies: - '@jest/create-cache-key-function': 29.7.0 - '@react-native-community/cli': 13.6.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@react-native-community/cli-platform-android': 13.6.9 - '@react-native-community/cli-platform-ios': 13.6.9 - '@react-native/assets-registry': 0.74.87 - '@react-native/codegen': 0.74.87(@babel/preset-env@7.25.3(@babel/core@7.25.2)) - '@react-native/community-cli-plugin': 0.74.87(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@react-native/gradle-plugin': 0.74.87 - '@react-native/js-polyfills': 0.74.87 - '@react-native/normalize-colors': 0.74.87 - '@react-native/virtualized-lists': 0.74.87(react-native@0.74.5(@babel/core@7.25.2)(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - abort-controller: 3.0.0 - anser: 1.4.10 - ansi-regex: 5.0.1 - base64-js: 1.5.1 - chalk: 4.1.2 - event-target-shim: 5.0.1 - flow-enums-runtime: 0.0.6 - invariant: 2.2.4 - jest-environment-node: 29.7.0 - jsc-android: 250231.0.0 - memoize-one: 5.2.1 - metro-runtime: 0.80.9 - metro-source-map: 0.80.9 - mkdirp: 0.5.6 - nullthrows: 1.1.1 - pretty-format: 26.6.2 - promise: 8.3.0 - react-devtools-core: 5.3.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) - react-refresh: 0.14.2 - react-shallow-renderer: 16.15.0(react@18.2.0) - regenerator-runtime: 0.13.11 - scheduler: 0.24.0-canary-efb381bbf-20230505 - stacktrace-parser: 0.1.10 - whatwg-fetch: 3.6.20 - ws: 6.2.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) - yargs: 17.7.2 - transitivePeerDependencies: - - '@babel/core' - - '@babel/preset-env' - - bufferutil - - encoding - - supports-color - - utf-8-validate - optional: true - react-qr-reader@2.2.1(react-dom@16.13.1(react@16.13.1))(react@16.13.1): dependencies: jsqr: 1.4.0 @@ -27038,6 +26635,22 @@ snapshots: transitivePeerDependencies: - rollup + vite-size@0.0.4(@types/node@20.11.5)(terser@5.31.3)(vue@3.4.3(typescript@5.3.3)): + dependencies: + '@vitejs/plugin-react': 4.2.1(vite@5.2.9(@types/node@20.11.5)(terser@5.31.3)) + '@vitejs/plugin-vue': 5.1.2(vite@5.2.9(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3)) + vite: 5.2.9(@types/node@20.11.5)(terser@5.31.3) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - vue + vite@5.2.11(@types/node@20.11.5)(terser@5.31.3): dependencies: esbuild: 0.20.2 @@ -27048,6 +26661,16 @@ snapshots: fsevents: 2.3.3 terser: 5.31.3 + vite@5.2.9(@types/node@20.11.5)(terser@5.31.3): + dependencies: + esbuild: 0.20.2 + postcss: 8.4.41 + rollup: 4.20.0 + optionalDependencies: + '@types/node': 20.11.5 + fsevents: 2.3.3 + terser: 5.31.3 + vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3): dependencies: '@ampproject/remapping': 2.3.0 From acc534ad8eca8d38d351307bf2a658a8133a9554 Mon Sep 17 00:00:00 2001 From: Felipe Mendes Date: Wed, 14 Aug 2024 12:08:51 -0300 Subject: [PATCH 3/4] chore: remove unnecessary window.postMessage for W3mFrame (#2658) Co-authored-by: tomiir --- packages/wallet/src/W3mFrame.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/wallet/src/W3mFrame.ts b/packages/wallet/src/W3mFrame.ts index 0d724e6eaf..bd29a13eb1 100644 --- a/packages/wallet/src/W3mFrame.ts +++ b/packages/wallet/src/W3mFrame.ts @@ -124,7 +124,6 @@ export class W3mFrame { throw new Error('W3mFrame: iframe is not set') } W3mFrameSchema.appEvent.parse(event) - window.postMessage(event) this.iframe.contentWindow.postMessage(event, '*') } }, From 3e2b0aad8970533a470922417feae227e5cf2173 Mon Sep 17 00:00:00 2001 From: Felipe Mendes Date: Wed, 14 Aug 2024 17:40:33 -0300 Subject: [PATCH 4/4] refactor: standardize solana provider adapters (#2690) --- .../Solana/SolanaSendTransactionTest.tsx | 4 +- .../SolanaSignAndSendTransactionTest.tsx | 2 +- .../Solana/SolanaSignMessageTest.tsx | 5 +- .../Solana/SolanaSignTransactionTest.tsx | 10 +- .../Solana/SolanaWriteContractTest.tsx | 4 +- packages/solana/exports/react.tsx | 10 +- packages/solana/exports/vue.ts | 14 +- packages/solana/package.json | 13 +- packages/solana/src/client.ts | 424 ++++--------- .../solana/src/connectors/baseConnector.ts | 350 ----------- .../src/connectors/universalProvider.ts | 50 -- .../src/connectors/walletConnectConnector.ts | 208 ------- .../src/providers/WalletConnectProvider.ts | 255 ++++++++ .../src/providers/WalletStandardProvider.ts | 236 +++++++ .../solana/src/providers/shared/Errors.ts | 5 + .../providers/shared/ProviderEventEmitter.ts | 37 ++ .../solana/src/utils/chainPath/constants.ts | 7 - packages/solana/src/utils/chainPath/index.ts | 57 -- packages/solana/src/utils/chains.ts | 7 + packages/solana/src/utils/clusterFactory.ts | 104 ---- packages/solana/src/utils/hash.ts | 43 -- packages/solana/src/utils/nameService.ts | 30 - .../src/utils/scaffold/SolanaConstantsUtil.ts | 16 +- .../src/utils/scaffold/SolanaHelpersUtils.ts | 20 +- .../src/utils/scaffold/SolanaStoreUtil.ts | 13 +- .../src/utils/scaffold/SolanaTypesUtil.ts | 305 ++------- .../src/utils/wallet-standard/adapter.ts | 581 ------------------ .../{wallet-standard => }/watchStandard.ts | 21 +- packages/solana/src/utils/websocket.ts | 18 - packages/solana/tests/GenericProvider.test.ts | 85 +++ .../tests/WalletConnectProvider.test.ts | 106 ++++ .../tests/WalletStandardProvider.test.ts | 128 ++++ packages/solana/tests/mocks/Transaction.ts | 37 ++ .../solana/tests/mocks/UniversalProvider.ts | 101 +++ packages/solana/tests/mocks/WalletStandard.ts | 96 +++ packages/solana/tests/util/TestConstants.ts | 25 + packages/solana/tsconfig.build.json | 4 + packages/solana/tsconfig.json | 2 +- pnpm-lock.yaml | 547 +++++++++-------- 39 files changed, 1640 insertions(+), 2340 deletions(-) delete mode 100644 packages/solana/src/connectors/baseConnector.ts delete mode 100644 packages/solana/src/connectors/universalProvider.ts delete mode 100644 packages/solana/src/connectors/walletConnectConnector.ts create mode 100644 packages/solana/src/providers/WalletConnectProvider.ts create mode 100644 packages/solana/src/providers/WalletStandardProvider.ts create mode 100644 packages/solana/src/providers/shared/Errors.ts create mode 100644 packages/solana/src/providers/shared/ProviderEventEmitter.ts delete mode 100644 packages/solana/src/utils/chainPath/constants.ts delete mode 100644 packages/solana/src/utils/chainPath/index.ts delete mode 100644 packages/solana/src/utils/clusterFactory.ts delete mode 100644 packages/solana/src/utils/hash.ts delete mode 100644 packages/solana/src/utils/nameService.ts delete mode 100644 packages/solana/src/utils/wallet-standard/adapter.ts rename packages/solana/src/utils/{wallet-standard => }/watchStandard.ts (57%) delete mode 100644 packages/solana/src/utils/websocket.ts create mode 100644 packages/solana/tests/GenericProvider.test.ts create mode 100644 packages/solana/tests/WalletConnectProvider.test.ts create mode 100644 packages/solana/tests/WalletStandardProvider.test.ts create mode 100644 packages/solana/tests/mocks/Transaction.ts create mode 100644 packages/solana/tests/mocks/UniversalProvider.ts create mode 100644 packages/solana/tests/mocks/WalletStandard.ts create mode 100644 packages/solana/tests/util/TestConstants.ts create mode 100644 packages/solana/tsconfig.build.json diff --git a/apps/laboratory/src/components/Solana/SolanaSendTransactionTest.tsx b/apps/laboratory/src/components/Solana/SolanaSendTransactionTest.tsx index 68ee572b38..8fff3b998d 100644 --- a/apps/laboratory/src/components/Solana/SolanaSendTransactionTest.tsx +++ b/apps/laboratory/src/components/Solana/SolanaSendTransactionTest.tsx @@ -25,7 +25,7 @@ export function SolanaSendTransactionTest() { async function onSendTransaction() { try { setLoading(true) - if (!walletProvider || !address) { + if (!walletProvider?.publicKey || !address) { throw Error('user is disconnected') } @@ -73,7 +73,7 @@ export function SolanaSendTransactionTest() { async function onSendVersionedTransaction() { try { setLoading(true) - if (!walletProvider || !address) { + if (!walletProvider?.publicKey || !address) { throw Error('user is disconnected') } diff --git a/apps/laboratory/src/components/Solana/SolanaSignAndSendTransactionTest.tsx b/apps/laboratory/src/components/Solana/SolanaSignAndSendTransactionTest.tsx index da9c1a5728..5cd1fc7000 100644 --- a/apps/laboratory/src/components/Solana/SolanaSignAndSendTransactionTest.tsx +++ b/apps/laboratory/src/components/Solana/SolanaSignAndSendTransactionTest.tsx @@ -25,7 +25,7 @@ export function SolanaSignAndSendTransaction() { async function onSendTransaction(mode: 'legacy' | 'versioned') { try { setLoading(true) - if (!walletProvider || !address) { + if (!walletProvider?.publicKey || !address) { throw Error('user is disconnected') } diff --git a/apps/laboratory/src/components/Solana/SolanaSignMessageTest.tsx b/apps/laboratory/src/components/Solana/SolanaSignMessageTest.tsx index eba14f5a77..fdfd169976 100644 --- a/apps/laboratory/src/components/Solana/SolanaSignMessageTest.tsx +++ b/apps/laboratory/src/components/Solana/SolanaSignMessageTest.tsx @@ -1,18 +1,17 @@ import { Button } from '@chakra-ui/react' -import { useWeb3ModalAccount, useWeb3ModalProvider } from '@web3modal/solana/react' +import { useWeb3ModalProvider } from '@web3modal/solana/react' import { ConstantsUtil } from '../../utils/ConstantsUtil' import { useChakraToast } from '../Toast' export function SolanaSignMessageTest() { const toast = useChakraToast() - const { address } = useWeb3ModalAccount() const { walletProvider } = useWeb3ModalProvider() async function onSignMessage() { try { - if (!walletProvider || !address) { + if (!walletProvider) { throw Error('user is disconnected') } diff --git a/apps/laboratory/src/components/Solana/SolanaSignTransactionTest.tsx b/apps/laboratory/src/components/Solana/SolanaSignTransactionTest.tsx index eb1eacd852..380ff64507 100644 --- a/apps/laboratory/src/components/Solana/SolanaSignTransactionTest.tsx +++ b/apps/laboratory/src/components/Solana/SolanaSignTransactionTest.tsx @@ -19,14 +19,14 @@ const amountInLamports = 10_000_000 export function SolanaSignTransactionTest() { const toast = useChakraToast() - const { address, chainId } = useWeb3ModalAccount() + const { chainId } = useWeb3ModalAccount() const { walletProvider, connection } = useWeb3ModalProvider() const [loading, setLoading] = useState(false) async function onSignTransaction() { try { setLoading(true) - if (!walletProvider || !address) { + if (!walletProvider?.publicKey) { throw Error('user is disconnected') } @@ -73,7 +73,7 @@ export function SolanaSignTransactionTest() { async function onSignVersionedTransaction() { try { setLoading(true) - if (!walletProvider || !address) { + if (!walletProvider?.publicKey) { throw Error('user is disconnected') } @@ -122,10 +122,6 @@ export function SolanaSignTransactionTest() { } } - if (!address) { - return null - } - if (chainId === solana.chainId) { return ( diff --git a/apps/laboratory/src/components/Solana/SolanaWriteContractTest.tsx b/apps/laboratory/src/components/Solana/SolanaWriteContractTest.tsx index 046fe154cc..1433b71d69 100644 --- a/apps/laboratory/src/components/Solana/SolanaWriteContractTest.tsx +++ b/apps/laboratory/src/components/Solana/SolanaWriteContractTest.tsx @@ -16,7 +16,7 @@ import { useChakraToast } from '../Toast' export function SolanaWriteContractTest() { const toast = useChakraToast() - const { address, currentChain } = useWeb3ModalAccount() + const { currentChain } = useWeb3ModalAccount() const { walletProvider, connection } = useWeb3ModalProvider() const [loading, setLoading] = useState(false) @@ -26,7 +26,7 @@ export function SolanaWriteContractTest() { const PROGRAM_ID = new PublicKey(detectProgramId(currentChain?.chainId ?? '')) try { - if (!walletProvider || !address) { + if (!walletProvider?.publicKey) { throw new Error('User is disconnected') } diff --git a/packages/solana/exports/react.tsx b/packages/solana/exports/react.tsx index ce080913cd..9e01d90092 100644 --- a/packages/solana/exports/react.tsx +++ b/packages/solana/exports/react.tsx @@ -6,10 +6,9 @@ import { getWeb3Modal } from '@web3modal/scaffold-react' import { Web3Modal } from '../src/client.js' -import { SolStoreUtil } from '../src/utils/scaffold/index.js' +import { SolStoreUtil, type Connection, type Provider } from '../src/utils/scaffold/index.js' import type { Web3ModalOptions } from '../src/client.js' -import type { Connection, Provider } from '../src/utils/scaffold/index.js' // -- Setup ------------------------------------------------------------------- let modal: Web3Modal | undefined = undefined @@ -31,12 +30,11 @@ export function createWeb3Modal(options: Web3ModalOptions) { // -- Hooks ------------------------------------------------------------------- export function useWeb3ModalProvider() { - const { provider, providerType, connection } = useSnapshot(SolStoreUtil.state) + const { provider, connection } = useSnapshot(SolStoreUtil.state) return { - walletProvider: provider as Provider, - walletProviderType: providerType, - connection: connection as Connection + walletProvider: provider as Provider | undefined, + connection: connection as Connection | undefined } } diff --git a/packages/solana/exports/vue.ts b/packages/solana/exports/vue.ts index d49e6d69b0..9f3e453cc7 100644 --- a/packages/solana/exports/vue.ts +++ b/packages/solana/exports/vue.ts @@ -4,8 +4,7 @@ import { ConstantsUtil } from '@web3modal/scaffold-utils' import { getWeb3Modal } from '@web3modal/scaffold-vue' import type { Web3ModalOptions } from '../src/client.js' -import type { CaipNetwork } from 'packages/core/dist/types/index.js' -import type { Provider } from '../src/utils/scaffold/index.js' +import type { CaipNetwork } from '@web3modal/scaffold' import { SolStoreUtil } from '../src/utils/scaffold/SolanaStoreUtil.js' import { Web3Modal } from '../src/client.js' @@ -33,13 +32,11 @@ export function useWeb3ModalProvider() { throw new Error('Please call "createWeb3Modal" before using "useWeb3ModalProvider" composition') } - const walletProvider = ref(SolStoreUtil.state.provider as Provider) - const walletProviderType = ref(SolStoreUtil.state.providerType) + const walletProvider = ref(SolStoreUtil.state.provider) const connection = ref(SolStoreUtil.state.connection) const unsubscribe = modal.subscribeProvider(state => { - walletProvider.value = state.provider as Provider - walletProviderType.value = state.providerType + walletProvider.value = state.provider }) onUnmounted(() => { @@ -47,9 +44,8 @@ export function useWeb3ModalProvider() { }) return { - walletProvider, - walletProviderType, - connection + walletProvider: walletProvider.value ?? undefined, + connection: connection.value ?? undefined } } diff --git a/packages/solana/package.json b/packages/solana/package.json index f9cb7e7a96..59baba1738 100644 --- a/packages/solana/package.json +++ b/packages/solana/package.json @@ -45,10 +45,11 @@ }, "scripts": { "build:clean": "rm -rf dist", - "build": "tsc --build", + "build": "tsc --build tsconfig.build.json", "watch": "tsc --watch", "typecheck": "tsc --noEmit", - "lint": "eslint . --ext .js,.jsx,.ts,.tsx" + "lint": "eslint . --ext .js,.jsx,.ts,.tsx", + "test": "vitest run --dir tests --coverage.enabled=true --coverage.reporter=json --coverage.reporter=json-summary --coverage.reportOnFailure=true" }, "dependencies": { "@ethersproject/sha2": "5.7.0", @@ -61,8 +62,8 @@ "@wallet-standard/features": "1.0.3", "@wallet-standard/wallet": "1.0.1", "@walletconnect/universal-provider": "2.14.0", - "@web3modal/core": "workspace:*", "@web3modal/common": "workspace:*", + "@web3modal/core": "workspace:*", "@web3modal/polyfills": "workspace:*", "@web3modal/scaffold": "workspace:*", "@web3modal/scaffold-react": "workspace:*", @@ -70,14 +71,16 @@ "@web3modal/scaffold-vue": "workspace:*", "@web3modal/wallet": "workspace:*", "bn.js": "5.2.1", - "bs58": "5.0.0", "borsh": "0.7.0", + "bs58": "5.0.0", "buffer": "6.0.3", "valtio": "1.11.2" }, "devDependencies": { "@types/bn.js": "5.1.5", - "@walletconnect/types": "2.14.0" + "@vitest/coverage-v8": "2.0.5", + "@walletconnect/types": "2.14.0", + "vitest": "2.0.3" }, "peerDependencies": { "react": ">=17", diff --git a/packages/solana/src/client.ts b/packages/solana/src/client.ts index 499c970bba..2fe4c17fbf 100644 --- a/packages/solana/src/client.ts +++ b/packages/solana/src/client.ts @@ -12,11 +12,10 @@ import { ConstantsUtil, HelpersUtil, PresetsUtil } from '@web3modal/scaffold-uti import { ConstantsUtil as CommonConstantsUtil } from '@web3modal/common' import { SolConstantsUtil, SolHelpersUtil, SolStoreUtil } from './utils/scaffold/index.js' -import { WalletConnectConnector } from './connectors/walletConnectConnector.js' import type { BaseWalletAdapter } from '@solana/wallet-adapter-base' -import type { PublicKey, Commitment, ConnectionConfig } from '@solana/web3.js' -import type UniversalProvider from '@walletconnect/universal-provider' +import { PublicKey, type Commitment, type ConnectionConfig } from '@solana/web3.js' +import UniversalProvider, { type UniversalProviderOpts } from '@walletconnect/universal-provider' import type { CaipNetworkId, ConnectionControllerClient, @@ -31,9 +30,8 @@ import type { import type { Chain as AvailableChain } from '@web3modal/common' import type { ProviderType, Chain, Provider, SolStoreUtilState } from './utils/scaffold/index.js' -import { watchStandard } from './utils/wallet-standard/watchStandard.js' -import { StandardWalletAdapter } from './utils/wallet-standard/adapter.js' -import { SolanaChainIDs } from './utils/chainPath/constants.js' +import { watchStandard } from './utils/watchStandard.js' +import { WalletConnectProvider } from './providers/WalletConnectProvider.js' export interface Web3ModalClientOptions extends Omit { solanaConfig: ProviderType @@ -55,16 +53,15 @@ export type Web3ModalOptions = Omit { if (caipNetwork) { try { - // Update chain for Solflare - this.walletAdapters = wallets as ExtendedBaseWalletAdapter[] - const walletId = localStorage.getItem(SolConstantsUtil.WALLET_ID) - const wallet = walletId?.split('_')[1] - if (wallet === 'solflare' && window[wallet as keyof Window]) { - const adapter = this.walletAdapters.find(a => a.name.toLocaleLowerCase() === wallet) - if (!adapter) { - return - } - await adapter.connect() - this.setInjectedProvider(adapter as unknown as Provider) - } - await this.switchNetwork(caipNetwork) } catch (error) { SolStoreUtil.setError(error) @@ -111,91 +95,54 @@ export class Web3Modal extends Web3ModalScaffold { } }, - getApprovedCaipNetworksData: async () => - new Promise(async resolve => { - const walletChoice = localStorage.getItem(SolConstantsUtil.WALLET_ID) - if (walletChoice?.includes(ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID)) { - const provider = await this.WalletConnectConnector.getProvider() - if (!provider) { - throw new Error( - 'networkControllerClient:getApprovedCaipNetworks - connector is undefined' - ) - } - const ns = provider?.session?.namespaces - const nsChains = ns?.['solana']?.chains - const result = { - supportsAllNetworks: false, - approvedCaipNetworkIds: nsChains as CaipNetworkId[] | undefined - } - - resolve(result) - } else { - const provider = SolStoreUtil.state.provider - if (provider && provider instanceof StandardWalletAdapter) { - const solanaNetworkNameToIdMap: Record = { - mainnet: SolanaChainIDs.Mainnet, - testnet: SolanaChainIDs.Testnet, - devnet: SolanaChainIDs.Devnet - } - const approvedCaipNetworkIds: CaipNetworkId[] = provider.wallet?.chains - .map(network => { - const networkName = network.split(':')[1] || '' - const networkId = solanaNetworkNameToIdMap[networkName] - - return networkId && `solana:${networkId}` - }) - .filter(Boolean) as CaipNetworkId[] - - resolve({ - approvedCaipNetworkIds, - supportsAllNetworks: false - }) - } else { - resolve({ - approvedCaipNetworkIds: undefined, - supportsAllNetworks: true - }) - } - } + getApprovedCaipNetworksData: async () => { + if (SolStoreUtil.state.provider) { + const approvedCaipNetworkIds = SolStoreUtil.state.provider.chains.map( + chain => `solana:${chain.chainId}` + ) + + return Promise.resolve({ + approvedCaipNetworkIds, + supportsAllNetworks: false + }) + } + + return Promise.resolve({ + approvedCaipNetworkIds: undefined, + supportsAllNetworks: false }) + } } const connectionControllerClient: ConnectionControllerClient = { connectWalletConnect: async onUri => { - const WalletConnectProvider = await this.WalletConnectConnector.getProvider() - if (!WalletConnectProvider) { + const wcProvider = this.availableProviders.find( + provider => provider.type === 'WALLET_CONNECT' + ) + + if (!wcProvider || !(wcProvider instanceof WalletConnectProvider)) { throw new Error('connectionControllerClient:getWalletConnectUri - provider is undefined') } - WalletConnectProvider.on('display_uri', onUri) - const address = await this.WalletConnectConnector.connect() - this.setWalletConnectProvider(address) - WalletConnectProvider.removeListener('display_uri', onUri) + wcProvider.onUri = onUri + + return this.setProvider(wcProvider) }, connectExternal: async ({ id }) => { - const adapter = this.filteredWalletAdapters?.find( - a => a.name.toLocaleLowerCase() === id.toLocaleLowerCase() + const externalProvider = this.availableProviders.find( + provider => provider.name.toLocaleLowerCase() === id.toLocaleLowerCase() ) - if (!adapter) { + if (!externalProvider) { throw Error('connectionControllerClient:connectExternal - adapter was undefined') } - await adapter.connect() - this.setInjectedProvider(adapter as unknown as Provider) + + return this.setProvider(externalProvider) }, disconnect: async () => { - const provider = SolStoreUtil.state.provider as Provider - const providerType = SolStoreUtil.state.providerType - localStorage.removeItem(SolConstantsUtil.WALLET_ID) - if (providerType === ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID) { - const WalletConnectProvider = provider - await (WalletConnectProvider as unknown as UniversalProvider).disconnect() - } else if (provider) { - provider.emit('disconnect') - } - SolStoreUtil.reset() + await SolStoreUtil.state.provider?.disconnect() }, signMessage: async (message: string) => { @@ -204,12 +151,9 @@ export class Web3Modal extends Web3ModalScaffold { throw new Error('connectionControllerClient:signMessage - provider is undefined') } - const signature = await provider.request({ - method: 'personal_sign', - params: [message, this.getAddress()] - }) + const signature = await provider.signMessage(new TextEncoder().encode(message)) - return signature as string + return new TextDecoder().decode(signature) }, estimateGas: async () => await Promise.resolve(BigInt(0)), @@ -247,6 +191,12 @@ export class Web3Modal extends Web3ModalScaffold { ...w3mOptions } as ScaffoldOptions) + this.initializeProviders({ + relayUrl: 'wss://relay.walletconnect.com', + metadata, + projectId: w3mOptions.projectId + }) + this.chains = chains this.connectionSettings = connectionSettings this.syncRequestedNetworks(chains, chainImages) @@ -261,20 +211,6 @@ export class Web3Modal extends Web3ModalScaffold { } this.syncNetwork(chainImages) - this.walletAdapters = wallets as ExtendedBaseWalletAdapter[] - this.WalletConnectConnector = new WalletConnectConnector({ - relayerRegion: 'wss://relay.walletconnect.com', - metadata, - chains, - qrcode: true - }) - SolStoreUtil.setConnection( - new Connection( - SolHelpersUtil.detectRpcUrl(chain, OptionsController.state.projectId), - this.connectionSettings - ) - ) - SolStoreUtil.subscribeKey('address', () => { this.syncAccount() }) @@ -315,42 +251,18 @@ export class Web3Modal extends Web3ModalScaffold { } } }) - - if (CoreHelperUtil.isClient()) { - this.checkActiveProviders() - this.syncStandardAdapters() - watchStandard(standardAdapters => { - const uniqueIds = standardAdapters - ? new Set(standardAdapters.map(s => s.name)) - : new Set([]) - this.filteredWalletAdapters = [ - ...standardAdapters, - ...this.walletAdapters.filter( - adapter => !uniqueIds.has(adapter.name) && uniqueIds.add(adapter.name) - ) - ] - this.checkActiveProviders.bind(this)(standardAdapters) - this.syncStandardAdapters.bind(this)(standardAdapters) - }) - } } - public setAddress(address?: string) { - SolStoreUtil.setAddress(address ?? '') + public setAddress(address = '') { + SolStoreUtil.setAddress(address) } public disconnect() { - const provider = SolStoreUtil.state.provider as Provider - - if (provider) { - provider.emit('disconnect') - } + return this.getProvider().disconnect() } public getAddress() { - const { address } = SolStoreUtil.state - - return address ? SolStoreUtil.state.address : address + return SolStoreUtil.state.address } public getWalletProvider() { @@ -358,103 +270,14 @@ export class Web3Modal extends Web3ModalScaffold { } public getWalletProviderType() { - return SolStoreUtil.state.providerType + return SolStoreUtil.state.provider?.type } public getWalletConnection() { return SolStoreUtil.state.connection } - public async checkActiveProviders(standardAdapters?: StandardWalletAdapter[]) { - const walletId = localStorage.getItem(SolConstantsUtil.WALLET_ID) - - if (!walletId) { - return - } - - try { - if (walletId === ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID) { - const provider = await this.WalletConnectConnector.getProvider() - if (provider.session) { - const account = provider.session.namespaces['solana']?.accounts[0] - this.setWalletConnectProvider(account?.split(':')[2]) - } - } else { - const walletArray = walletId?.split('_') ?? [] - if (walletArray[0] === 'announced' && standardAdapters) { - const adapter = standardAdapters.find(a => a.name === walletArray[1]) - - if (adapter) { - await adapter.connect() - this.setInjectedProvider(adapter as unknown as Provider) - - return - } - } else if (walletArray[0] === 'injected') { - const adapter = [...(standardAdapters ?? []), ...this.walletAdapters].find( - a => a.name === walletArray[1] - ) as ExtendedBaseWalletAdapter - await adapter.connect() - this.setInjectedProvider(adapter as unknown as Provider) - - return - } - - throw new Error('AppKit:checkActiveProviders - Invalid type in walletId') - } - } catch (error) { - SolStoreUtil.setError(error) - } - } - // -- Private ----------------------------------------------------------------- - - private syncStandardAdapters(standardAdapters?: StandardWalletAdapter[]) { - const w3mConnectors: Connector[] = [] - - const connectorType = PresetsUtil.ConnectorTypesMap[ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID] - if (connectorType) { - w3mConnectors.push({ - id: ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID, - explorerId: PresetsUtil.ConnectorExplorerIds[ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID], - type: connectorType, - imageUrl: 'https://avatars.githubusercontent.com/u/37784886', - name: this.WalletConnectConnector.name, - provider: this.WalletConnectConnector.getProvider(), - chain: this.chain - }) - } - - const uniqueIds = standardAdapters ? new Set(standardAdapters.map(s => s.name)) : new Set([]) - const FILTER_OUT_ADAPTERS = ['Trust'] - const filteredAdapters = this.walletAdapters - .filter(adapter => FILTER_OUT_ADAPTERS.some(filter => filter === adapter.name)) - .filter(adapter => !uniqueIds.has(adapter.name) && uniqueIds.add(adapter.name)) - - standardAdapters?.forEach(adapter => { - w3mConnectors.push({ - id: adapter.name, - type: 'ANNOUNCED', - imageUrl: adapter.icon, - name: adapter.name, - provider: adapter, - chain: CommonConstantsUtil.CHAIN.SOLANA - }) - }) - filteredAdapters.forEach(adapter => { - w3mConnectors.push({ - id: adapter.name, - type: 'EXTERNAL', - imageUrl: adapter.icon, - name: adapter.name, - provider: adapter, - chain: CommonConstantsUtil.CHAIN.SOLANA - }) - }) - - this.setConnectors(w3mConnectors) - } - private async syncAccount() { const address = SolStoreUtil.state.address const chainId = SolStoreUtil.state.currentChain?.chainId @@ -475,14 +298,19 @@ export class Web3Modal extends Web3ModalScaffold { } private async syncBalance(address: string) { - const caipChainId = SolStoreUtil.state.caipChainId - if (caipChainId && this.chains) { - const chain = SolHelpersUtil.getChainFromCaip(this.chains, caipChainId) - if (chain) { - const balance = await this.WalletConnectConnector.getBalance(address) - this.setBalance(balance.decimals.toString(), chain.currency) - } + if (!SolStoreUtil.state.connection) { + throw new Error('Connection is not set') + } + + if (!SolStoreUtil.state.currentChain) { + throw new Error('Chain is not set') } + + const balance = + (await SolStoreUtil.state.connection.getBalance(new PublicKey(address))) / + SolConstantsUtil.LAMPORTS_PER_SOL + + this.setBalance(balance.toString(), SolStoreUtil.state.currentChain.currency) } private syncRequestedNetworks( @@ -497,49 +325,24 @@ export class Web3Modal extends Web3ModalScaffold { imageId: PresetsUtil.EIP155NetworkImageIds[chain.chainId], imageUrl: chainImages?.[chain.chainId], chain: this.chain - }) as CaipNetwork + }) as const ) this.setRequestedCaipNetworks(requestedCaipNetworks ?? []) } public async switchNetwork(caipNetwork: CaipNetwork) { const caipChainId = caipNetwork.id - const providerType = SolStoreUtil.state.providerType - const provider = SolStoreUtil.state.provider const chain = SolHelpersUtil.getChainFromCaip(this.chains, caipChainId) if (chain) { SolStoreUtil.setCaipChainId(`solana:${chain.chainId}`) SolStoreUtil.setCurrentChain(chain) localStorage.setItem(SolConstantsUtil.CAIP_CHAIN_ID, `solana:${chain.chainId}`) - if (!providerType) { - throw new Error('connectionControllerClient:switchNetwork - providerType is undefined') - } - if (providerType === ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID) { - const universalProvider = await this.WalletConnectConnector.getProvider() - const namespaces = this.WalletConnectConnector.generateNamespaces(chain.chainId) - SolStoreUtil.setConnection( - new Connection( - SolHelpersUtil.detectRpcUrl(chain, OptionsController.state.projectId), - this.connectionSettings - ) - ) - universalProvider.connect({ namespaces, pairingTopic: undefined }) - await this.syncAccount() - } else { - SolStoreUtil.setConnection( - new Connection( - SolHelpersUtil.detectRpcUrl(chain, OptionsController.state.projectId), - this.connectionSettings - ) - ) - const name = provider ? (provider as Provider).name : '' - this.setAddress( - this.filteredWalletAdapters?.find(adapter => adapter.name === name)?.publicKey?.toString() - ) - await this.syncAccount() - } + this.setLoading(true) + await this.syncNetwork() + await this.syncAccount() + this.setLoading(false) } } @@ -553,6 +356,13 @@ export class Web3Modal extends Web3ModalScaffold { if (chain) { const caipChainId: CaipNetworkId = `solana:${chain.chainId}` + SolStoreUtil.setConnection( + new Connection( + SolHelpersUtil.detectRpcUrl(chain, OptionsController.state.projectId), + this.connectionSettings + ) + ) + this.setCaipNetwork({ id: caipChainId, name: chain.name, @@ -579,7 +389,9 @@ export class Web3Modal extends Web3ModalScaffold { return SolStoreUtil.subscribe(callback) } - private async setWalletConnectProvider(address = '') { + private async setProvider(provider: Provider) { + const address = await provider.connect() + const caipChainId = `${SolStoreUtil.state.currentChain?.name}:${SolStoreUtil.state.currentChain?.chainId}` const chain = SolHelpersUtil.getChainFromCaip( this.chains, @@ -590,40 +402,17 @@ export class Web3Modal extends Web3ModalScaffold { } SolStoreUtil.setIsConnected(true) SolStoreUtil.setCaipChainId(caipChainId) - - SolStoreUtil.setProviderType('walletConnect') - SolStoreUtil.setProvider(this.WalletConnectConnector as unknown as Provider) + SolStoreUtil.setProvider(provider) this.setAddress(address) - window?.localStorage.setItem( - SolConstantsUtil.WALLET_ID, - ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID - ) - await Promise.all([this.syncBalance(address), this.setApprovedCaipNetworksData()]) - } - - private setInjectedProvider(provider: Provider) { - const id = SolHelpersUtil.getStorageInjectedId(provider as unknown as ExtendedBaseWalletAdapter) - const address = provider.publicKey?.toString() + window?.localStorage.setItem(SolConstantsUtil.WALLET_ID, provider.name) - window?.localStorage.setItem(SolConstantsUtil.WALLET_ID, id) + await Promise.all([this.syncBalance(address), this.setApprovedCaipNetworksData()]) - const chainId = SolStoreUtil.state.currentChain?.chainId - const caipChainId = `solana:${chainId}` - - if (address && chainId) { - SolStoreUtil.setIsConnected(true) - SolStoreUtil.setCaipChainId(caipChainId) - SolStoreUtil.setProviderType(id) - SolStoreUtil.setProvider(provider) - this.setAddress(address) - this.watchInjected(provider) - this.hasSyncedConnectedAccount = true - this.setApprovedCaipNetworksData() - } + this.watchProvider(provider) } - private watchInjected(provider: Provider) { + private watchProvider(provider: Provider) { function disconnectHandler() { localStorage.removeItem(SolConstantsUtil.WALLET_ID) SolStoreUtil.reset() @@ -649,4 +438,53 @@ export class Web3Modal extends Web3ModalScaffold { provider.on('connect', accountsChangedHandler) } } + + private getProvider() { + if (!this.provider) { + throw new Error('Provider is not set') + } + + return this.provider + } + + private async initializeProviders(opts: UniversalProviderOpts) { + if (CoreHelperUtil.isClient()) { + this.addProvider( + new WalletConnectProvider({ + provider: await UniversalProvider.init(opts), + chains: this.chains + }) + ) + + watchStandard(standardAdapters => this.addProvider.bind(this)(...standardAdapters)) + } + } + + private addProvider(...providers: Provider[]) { + const activeProviderName = localStorage.getItem(SolConstantsUtil.WALLET_ID) + + for (const provider of providers) { + this.availableProviders = this.availableProviders.filter(p => p.name !== provider.name) + this.availableProviders.push(provider) + + if (provider.name === activeProviderName) { + this.setProvider(provider) + } + } + + this.syncConnectors() + } + + private syncConnectors() { + const connectors = this.availableProviders.map(provider => ({ + id: provider.name, + type: provider.type, + imageUrl: provider.icon, + name: provider.name, + provider, + chain: CommonConstantsUtil.CHAIN.SOLANA + })) + + this.setConnectors(connectors) + } } diff --git a/packages/solana/src/connectors/baseConnector.ts b/packages/solana/src/connectors/baseConnector.ts deleted file mode 100644 index 69d6bea7b6..0000000000 --- a/packages/solana/src/connectors/baseConnector.ts +++ /dev/null @@ -1,350 +0,0 @@ -import { - PublicKey, - SystemProgram, - Transaction, - TransactionInstruction, - TransactionMessage, - VersionedTransaction -} from '@solana/web3.js' -import BN from 'bn.js' -import base58 from 'bs58' -import borsh from 'borsh' -import { Buffer } from 'buffer' - -import { registerListener, unregisterListener } from '../utils/clusterFactory.js' -import { SolConstantsUtil, SolStoreUtil } from '../utils/scaffold/index.js' -import { getHashedName, getNameAccountKey } from '../utils/hash.js' -import { NameRegistry } from '../utils/nameService.js' - -import type { - BlockResult, - AccountInfo, - ClusterRequestMethods, - ClusterSubscribeRequestMethods, - FilterObject, - RequestMethods, - TransactionArgs, - TransactionType, - Provider -} from '../utils/scaffold/index.js' - -export interface Connector { - id: string - name: string - ready: boolean - getConnectorName: () => string - disconnect: () => Promise - connect: () => Promise - signMessage: Provider['signMessage'] - signTransaction: Provider['signTransaction'] - signAndSendTransaction: Provider['signAndSendTransaction'] - sendTransaction: Provider['sendTransaction'] - getAccount: ( - requestedAddress?: string, - encoding?: 'base58' | 'base64' | 'jsonParsed' - ) => Promise - getBalance: (requestedAddress: string) => Promise<{ - formatted: string - value: BN - decimals: number - symbol: string - }> - getTransaction: ( - transactionSignature: string - ) => Promise - watchTransaction: ( - transactionSignature: string, - callback: (params: unknown) => void - ) => Promise<() => void> - getAddressFromDomain: (address: string) => Promise - getBlock: (slot: number) => Promise - getFeeForMessage: ( - type: Type, - params: TransactionArgs[Type]['params'] - ) => Promise -} - -type Currency = 'lamports' | 'sol' - -export class BaseConnector { - public getConnectorName() { - return 'base' - } - - public get publicKey() { - return new PublicKey(SolStoreUtil.state.address ?? '') - } - - protected async getProvider(): Promise<{ - /* eslint-disable @typescript-eslint/no-explicit-any */ - request: (args: any) => any - }> { - return Promise.reject(new Error('No provider in base connector')) - } - - protected async constructTransaction( - type: TransType, - params: TransactionArgs[TransType]['params'] - ) { - const transaction = new Transaction() - const fromAddress = SolStoreUtil.state.address - - if (!fromAddress) { - throw new Error('No address connected') - } - const fromPubkey = new PublicKey(fromAddress) - - if (type === 'transfer') { - const transferParams = params as TransactionArgs['transfer']['params'] - const toPubkey = new PublicKey(transferParams.to) - transaction.add( - SystemProgram.transfer({ - fromPubkey, - toPubkey: new PublicKey(transferParams.to), - lamports: transferParams.amountInLamports - }) - ) - transaction.feePayer = transferParams.feePayer === 'from' ? fromPubkey : toPubkey - } else if (type === 'program') { - const programParams = params as TransactionArgs['program']['params'] - transaction.add( - new TransactionInstruction({ - keys: [ - { pubkey: fromPubkey, isSigner: true, isWritable: programParams.isWritableSender } - ], - programId: new PublicKey(programParams.programId), - data: Buffer.from(base58.decode(JSON.stringify(programParams.data))) - }) - ) - transaction.feePayer = fromPubkey - } else { - throw new Error(`No transaction configuration for type ${String(type)}`) - } - - const response = await this.requestCluster('getLatestBlockhash', [{}]) - - const { blockhash: recentBlockhash } = response.value - transaction.recentBlockhash = recentBlockhash - - return transaction - } - - protected async constructVersionedTransaction(params: TransactionArgs['transfer']['params']) { - const fromAddress = SolStoreUtil.state.address - if (!fromAddress) { - throw new Error('No address connected') - } - const fromPubkey = new PublicKey(fromAddress) - const toPubkey = new PublicKey(params.to) - - const instructions = [ - SystemProgram.transfer({ - fromPubkey, - toPubkey, - lamports: params.amountInLamports - }) - ] - - const response = await this.requestCluster('getLatestBlockhash', [{}]) - const { blockhash: recentBlockhash } = response.value - - const messageV0 = new TransactionMessage({ - payerKey: fromPubkey, - recentBlockhash, - instructions - }).compileToV0Message() - - // Make a versioned transaction - const transactionV0 = new VersionedTransaction(messageV0) - - return transactionV0 - } - - public async getTransaction(transactionSignature: string) { - const transaction = await this.requestCluster('getTransaction', [ - transactionSignature, - { encoding: 'jsonParsed', commitment: 'confirmed' } - ]) - - return transaction - } - - public async watchTransaction( - transactionSignature: string, - callback: (params: Transaction | number) => void - ) { - return this.subscribeToCluster('signatureSubscribe', [transactionSignature], callback) - } - - public async getBalance(requestedAddress: string, currency: Currency = 'sol') { - try { - const address = requestedAddress ?? SolStoreUtil.state.address - const balance = await this.requestCluster('getBalance', [ - address, - { commitment: 'processed' } - ]) - const BALANCE_VALUE_DECIMAL_DIVIDER = 1000000000 - const formatted = - currency === 'lamports' - ? `${balance?.value || 0} lamports` - : `${(balance?.value || 0) / BALANCE_VALUE_DECIMAL_DIVIDER} sol` - - return { - value: new BN(balance.value), - formatted, - decimals: balance.value / BALANCE_VALUE_DECIMAL_DIVIDER, - symbol: currency - } - } catch (err) { - SolStoreUtil.setError("Can't get balance") - - return { - value: new BN(0), - formatted: '0 sol', - decimals: 0, - symbol: currency - } - } - } - - public async getFeeForMessage( - type: TransType, - params: TransactionArgs[TransType]['params'] - ) { - const transaction = await this.constructTransaction(type, params) - const message = transaction.compileMessage().serialize() - const encodedMessage = message.toString('base64') - - const result = await this.requestCluster('getFeeForMessage', [encodedMessage]) - - return result - } - - public async getProgramAccounts(requestedAddress: string, filters?: FilterObject[]) { - const programAccounts = await this.requestCluster('getProgramAccounts', [ - requestedAddress, - { filters: filters ?? [], encoding: 'jsonParsed', withContext: true } - ]) - - return programAccounts.value - } - - public async getAllDomains(address: string) { - const accounts = await this.getProgramAccounts(SolConstantsUtil.NAME_PROGRAM_ID.toBase58(), [ - { - memcmp: { - offset: 32, - bytes: address - } - }, - { - memcmp: { - offset: 0, - bytes: SolConstantsUtil.ROOT_DOMAIN_ACCOUNT.toBase58() - } - } - ]) - - return accounts.map(({ pubkey }: any) => pubkey) - } - - public async getAccount( - nameAccountKey?: string, - encoding: 'base58' | 'base64' | 'jsonParsed' = 'base58' - ) { - const address = nameAccountKey ?? SolStoreUtil.state.address - - if (!address) { - throw new Error('No address supplied and none connected') - } - - const response = await this.requestCluster('getAccountInfo', [ - address, - { - encoding - } - ]) - - if (!response) { - throw new Error('Invalid name account provided') - } - - const { value: nameAccount } = response - - return nameAccount - } - - public async getBlock(slot: number) { - const block = await this.requestCluster('getBlock', [slot]) - - return block - } - - public async getAddressFromDomain(domain: string) { - const hashed = getHashedName(domain.replace('.sol', '')) - - const nameAccountKey = await getNameAccountKey( - hashed, - undefined, - SolConstantsUtil.ROOT_DOMAIN_ACCOUNT - ) - const ownerDataRaw = await this.getAccount(nameAccountKey.toBase58(), 'base64') - - if (!ownerDataRaw) { - return null - } - - const ownerData = borsh.deserializeUnchecked( - NameRegistry.schema, - NameRegistry, - Buffer.from(String(ownerDataRaw.data[0]), 'base64') - ) as { owner: any } - - return ownerData.owner.toBase58() - } - - public async request( - method: Method, - params: RequestMethods[Method]['params'] - ): Promise { - return (await this.getProvider()).request({ method, params }) - } - - public async subscribeToCluster( - method: Method, - params: ClusterSubscribeRequestMethods[Method]['params'], - callback: (cb_params: Transaction | number) => void - ) { - const id = await registerListener(method, params, callback) - - return () => { - unregisterListener(id) - } - } - - public async requestCluster( - method: Method, - params: ClusterRequestMethods[Method]['params'] - ): Promise { - const cluster = SolStoreUtil.getCluster() - const { endpoint } = cluster - const res: { result: ClusterRequestMethods[Method]['returns'] } = await fetch(endpoint, { - method: 'post', - body: JSON.stringify({ - method, - params, - jsonrpc: '2.0', - id: SolStoreUtil.getNewRequestId() - }), - headers: { - 'Content-Type': 'application/json' - } - }).then(async httpRes => { - const json = await httpRes.json() - - return json - }) - - return res.result - } -} diff --git a/packages/solana/src/connectors/universalProvider.ts b/packages/solana/src/connectors/universalProvider.ts deleted file mode 100644 index 95d8e70c24..0000000000 --- a/packages/solana/src/connectors/universalProvider.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { UniversalProvider as Provider } from '@walletconnect/universal-provider' - -import { SolStoreUtil } from '../utils/scaffold/SolanaStoreUtil.js' -import type { WalletConnectAppMetadata } from './walletConnectConnector.js' -import type UniversalProvider from '@walletconnect/universal-provider' -const DEFAULT_LOGGER = 'error' - -export class UniversalProviderFactory { - protected static provider: UniversalProvider | undefined - protected static relayerRegion: string | undefined - protected static projectId: string | undefined - protected static metadata: WalletConnectAppMetadata | undefined - - public static setSettings(params: { - projectId: string - relayerRegion: string - metadata: WalletConnectAppMetadata - qrcode: boolean - }) { - UniversalProviderFactory.relayerRegion = params.relayerRegion - UniversalProviderFactory.projectId = params.projectId - UniversalProviderFactory.metadata = params.metadata - } - - public static async init() { - UniversalProviderFactory.provider = await Provider.init({ - logger: DEFAULT_LOGGER, - relayUrl: UniversalProviderFactory.relayerRegion, - projectId: UniversalProviderFactory.projectId, - metadata: UniversalProviderFactory.metadata - }) - - // Subscribe to session delete - UniversalProviderFactory.provider.on('session_delete', () => { - SolStoreUtil.setAddress('') - }) - } - - public static async getProvider() { - if (!UniversalProviderFactory.provider) { - await UniversalProviderFactory.init() - - if (!UniversalProviderFactory.provider) { - throw new Error('Failed to initialize universal provider') - } - } - - return UniversalProviderFactory.provider - } -} diff --git a/packages/solana/src/connectors/walletConnectConnector.ts b/packages/solana/src/connectors/walletConnectConnector.ts deleted file mode 100644 index 5a1778ae55..0000000000 --- a/packages/solana/src/connectors/walletConnectConnector.ts +++ /dev/null @@ -1,208 +0,0 @@ -import base58 from 'bs58' -import { Connection, Transaction, VersionedTransaction, type SendOptions } from '@solana/web3.js' -import { OptionsController } from '@web3modal/core' - -import { SolStoreUtil } from '../utils/scaffold/index.js' -import { UniversalProviderFactory } from './universalProvider.js' -import { BaseConnector } from './baseConnector.js' -import type { Connector } from './baseConnector.js' - -import type UniversalProvider from '@walletconnect/universal-provider' - -import type { Chain, AnyTransaction } from '../utils/scaffold/SolanaTypesUtil.js' -import { - getChainsFromChainId, - getDefaultChainFromSession, - type ChainIDType -} from '../utils/chainPath/index.js' -import { isVersionedTransaction } from '@solana/wallet-adapter-base' - -export interface WalletConnectAppMetadata { - name: string - description: string - url: string - icons: string[] -} - -export class WalletConnectConnector extends BaseConnector implements Connector { - id = 'WalletConnect' - name = 'WalletConnect' - ready = true - chains: Chain[] - - protected provider: UniversalProvider | undefined - protected qrcode: boolean - - public constructor({ - relayerRegion, - metadata, - qrcode, - chains - }: { - relayerRegion: string - metadata: WalletConnectAppMetadata - qrcode?: boolean - chains: Chain[] - }) { - super() - this.chains = chains - this.qrcode = Boolean(qrcode) - UniversalProviderFactory.setSettings({ - projectId: OptionsController.state.projectId, - relayerRegion, - metadata, - qrcode: this.qrcode - }) - - UniversalProviderFactory.init() - } - - public static readonly connectorName = 'walletconnect' - - public async disconnect() { - const provider = await UniversalProviderFactory.getProvider() - await provider.disconnect() - SolStoreUtil.setAddress('') - } - - public override getConnectorName(): string { - return WalletConnectConnector.connectorName - } - - public override async getProvider() { - const provider = await UniversalProviderFactory.getProvider() - - return provider - } - - public async signMessage(message: Uint8Array) { - const signedMessage = await this.request('solana_signMessage', { - message: base58.encode(message), - pubkey: this.getPubkey() - }) - - return base58.decode(signedMessage.signature) - } - - public async signTransaction(transaction: T) { - const serializedTransaction = this.serializeTransaction(transaction) - - const result = await this.request('solana_signTransaction', { - transaction: serializedTransaction, - pubkey: this.getPubkey() - }) - - const decodedTransaction = base58.decode(result.transaction) - - if (isVersionedTransaction(transaction)) { - return VersionedTransaction.deserialize(decodedTransaction) as T - } - - return Transaction.from(decodedTransaction) as T - } - - public async signAndSendTransaction( - transaction: T, - sendOptions?: SendOptions - ) { - const serializedTransaction = this.serializeTransaction(transaction) - - const result = await this.request('solana_signAndSendTransaction', { - transaction: serializedTransaction, - pubkey: this.getPubkey(), - sendOptions - }) - - return result.signature - } - - public async sendTransaction( - transaction: AnyTransaction, - connection: Connection, - options?: SendOptions - ) { - const signedTransaction = await this.signTransaction(transaction) - const signature = await connection.sendRawTransaction(signedTransaction.serialize(), options) - - return signature - } - - /** - * Connect to user's wallet. - * - * If `WalletConnectConnector` was configured with `qrcode = true`, this will - * open a QRCodeModal, where the user will scan the qrcode and then this - * function will resolve/return the address of the wallet. - * - * If `qrcode = false`, this will return the pairing URI used to generate the - * QRCode. - */ - - public generateNamespaces(chainId: string) { - const rpcs = this.chains.reduce>((acc, chain) => { - acc[chain.chainId] = chain.rpcUrl - - return acc - }, {}) - const rpcMap = { - [chainId]: rpcs[chainId] ?? '' - } - - return { - solana: { - chains: getChainsFromChainId(`solana:${chainId}` as ChainIDType), - methods: ['solana_signMessage', 'solana_signTransaction', 'solana_signAndSendTransaction'], - events: [], - rpcMap - } - } - } - - public async connect() { - const currentChainId = SolStoreUtil.state.currentChain?.chainId - const solanaNamespace = this.generateNamespaces(currentChainId ?? '') - - const provider = await UniversalProviderFactory.getProvider() - - return new Promise((resolve, reject) => { - provider - .connect({ - optionalNamespaces: solanaNamespace - }) - .then(session => { - if (!session) { - throw new Error('Failed connection.') - } - const address = session.namespaces['solana']?.accounts[0]?.split(':')[2] ?? null - if (address && this.qrcode) { - const defaultChain = getDefaultChainFromSession( - session, - `solana:${currentChainId}` as ChainIDType - ) - provider.setDefaultChain(defaultChain) - - resolve(address) - } else { - reject(new Error('Could not resolve address')) - } - }) - }) - } - - public async onConnector() { - await this.connect() - } - - private serializeTransaction(transaction: AnyTransaction) { - return base58.encode(transaction.serialize({ verifySignatures: false })) - } - - private getPubkey() { - const address = SolStoreUtil.state.address - if (!address) { - throw new Error('No signer connected') - } - - return address - } -} diff --git a/packages/solana/src/providers/WalletConnectProvider.ts b/packages/solana/src/providers/WalletConnectProvider.ts new file mode 100644 index 0000000000..85e0bd4442 --- /dev/null +++ b/packages/solana/src/providers/WalletConnectProvider.ts @@ -0,0 +1,255 @@ +import UniversalProvider from '@walletconnect/universal-provider' +import { SolConstantsUtil, type AnyTransaction, type Chain, type Provider } from '../utils/scaffold' +import { ProviderEventEmitter } from './shared/ProviderEventEmitter' +import type { SessionTypes } from '@walletconnect/types' +import base58 from 'bs58' +import { + Connection, + PublicKey, + Transaction, + VersionedTransaction, + type SendOptions +} from '@solana/web3.js' +import { isVersionedTransaction } from '@solana/wallet-adapter-base' + +export type WalletConnectProviderConfig = { + provider: UniversalProvider + chains: Chain[] +} + +export class WalletConnectProvider extends ProviderEventEmitter implements Provider { + public readonly name = 'WalletConnect' + public readonly type = 'WALLET_CONNECT' + public readonly icon = + 'https://imagedelivery.net/_aTEfDRm7z3tKgu9JhfeKA/05338e12-4f75-4982-4e8a-83c67b826b00/md' + + private provider: UniversalProvider + private session?: SessionTypes.Struct + private readonly requestedChains: Chain[] + + constructor({ provider, chains }: WalletConnectProviderConfig) { + super() + this.requestedChains = chains + this.provider = provider + } + + // -- Universal Provider Events ------------------------ // + public onUri?: (uri: string) => void + + // -- Public ------------------------------------------- // + + public get chains() { + return ( + (this.session?.namespaces['solana']?.chains + ?.map(sessionChainId => { + // This is a workaround for wallets that only accept Solana deprecated networks + let chainId = sessionChainId + if (chainId === SolConstantsUtil.CHAIN_IDS.Deprecated_Mainnet) { + chainId = SolConstantsUtil.CHAIN_IDS.Mainnet + } else if (chainId === SolConstantsUtil.CHAIN_IDS.Deprecated_Devnet) { + chainId = SolConstantsUtil.CHAIN_IDS.Devnet + } + + return this.requestedChains.find(chain => `solana:${chain.chainId}` === chainId) + }) + .filter(Boolean) as Chain[]) || [] + ) + } + + public get publicKey() { + const account = this.getAccount(false) + + if (account) { + return new PublicKey(account.publicKey) + } + + return undefined + } + + public async connect() { + const rpcMap = this.requestedChains.reduce>((acc, chain) => { + acc[`solana:${chain.chainId}`] = chain.rpcUrl + + return acc + }, {}) + + if (this.provider.session) { + this.session = this.provider.session + } else { + this.provider.on('display_uri', this.onUri) + this.session = await this.provider.connect({ + optionalNamespaces: { + solana: { + chains: this.getRequestedChainsWithDeprecated(), + methods: [ + 'solana_signMessage', + 'solana_signTransaction', + 'solana_signAndSendTransaction' + ], + events: [], + rpcMap + } + } + }) + this.provider.removeListener('display_uri', this.onUri) + } + + const account = this.getAccount(true) + + this.emit('connect', new PublicKey(account.publicKey)) + + return account.address + } + + public async disconnect() { + await this.provider?.disconnect() + this.emit('disconnect', undefined) + } + + public async signMessage(message: Uint8Array) { + const signedMessage = await this.request('solana_signMessage', { + message: base58.encode(message), + pubkey: this.getAccount(true).address + }) + + return base58.decode(signedMessage.signature) + } + + public async signTransaction(transaction: T) { + const serializedTransaction = this.serializeTransaction(transaction) + + const result = await this.request('solana_signTransaction', { + transaction: serializedTransaction, + pubkey: this.getAccount(true).address + }) + + const decodedTransaction = base58.decode(result.transaction) + + if (isVersionedTransaction(transaction)) { + return VersionedTransaction.deserialize(decodedTransaction) as T + } + + return Transaction.from(decodedTransaction) as T + } + + public async signAndSendTransaction( + transaction: T, + sendOptions?: SendOptions + ) { + const serializedTransaction = this.serializeTransaction(transaction) + + const result = await this.request('solana_signAndSendTransaction', { + transaction: serializedTransaction, + pubkey: this.getAccount(true).address, + sendOptions + }) + + return result.signature + } + + public async sendTransaction( + transaction: AnyTransaction, + connection: Connection, + options?: SendOptions + ) { + const signedTransaction = await this.signTransaction(transaction) + const signature = await connection.sendRawTransaction(signedTransaction.serialize(), options) + + return signature + } + + public async signAllTransactions() { + return await Promise.reject(new Error('Sign all transactions is not supported')) + } + + // -- Private ------------------------------------------ // + private request( + method: Method, + params: WalletConnectProvider.RequestMethods[Method]['params'] + ) { + return this.provider?.request({ + method, + params + }) + } + + private serializeTransaction(transaction: AnyTransaction) { + return base58.encode(transaction.serialize({ verifySignatures: false })) + } + + private getAccount( + required?: Required + ): Required extends true + ? WalletConnectProvider.Account + : WalletConnectProvider.Account | undefined { + const account = this.session?.namespaces['solana']?.accounts[0] + if (!account) { + if (required) { + throw new Error('Account not found') + } + + return undefined as Required extends true + ? WalletConnectProvider.Account + : WalletConnectProvider.Account | undefined + } + + const address = account.split(':')[2] + if (!address) { + if (required) { + throw new Error('Address not found') + } + + return undefined as Required extends true + ? WalletConnectProvider.Account + : WalletConnectProvider.Account | undefined + } + + return { + address, + publicKey: base58.decode(address) + } + } + + /** + * This method is a workaround for wallets that only accept Solana deprecated networks + */ + private getRequestedChainsWithDeprecated() { + const chains = this.requestedChains.map(chain => `solana:${chain.chainId}`) + + if (chains.includes(SolConstantsUtil.CHAIN_IDS.Mainnet)) { + chains.push(SolConstantsUtil.CHAIN_IDS.Deprecated_Mainnet) + } + + if (chains.includes(SolConstantsUtil.CHAIN_IDS.Devnet)) { + chains.push(SolConstantsUtil.CHAIN_IDS.Deprecated_Devnet) + } + + return chains + } +} + +export namespace WalletConnectProvider { + export type Request = { + params: Params + returns: Result + } + + export type RequestMethods = { + solana_signMessage: Request<{ message: string; pubkey: string }, { signature: string }> + solana_signTransaction: Request< + { transaction: string; pubkey: string }, + { transaction: string } + > + solana_signAndSendTransaction: Request< + { transaction: string; pubkey: string; sendOptions?: SendOptions }, + { signature: string } + > + } + + export type RequestMethod = keyof RequestMethods + + export type Account = { + address: string + publicKey: Uint8Array + } +} diff --git a/packages/solana/src/providers/WalletStandardProvider.ts b/packages/solana/src/providers/WalletStandardProvider.ts new file mode 100644 index 0000000000..5f0fd833b4 --- /dev/null +++ b/packages/solana/src/providers/WalletStandardProvider.ts @@ -0,0 +1,236 @@ +import { + isVersionedTransaction, + WalletAccountError, + WalletSendTransactionError, + WalletSignMessageError, + WalletSignTransactionError +} from '@solana/wallet-adapter-base' +import { + SolanaSignAndSendTransaction, + type SolanaSignAndSendTransactionFeature, + type SolanaSignInFeature, + SolanaSignMessage, + type SolanaSignMessageFeature, + SolanaSignTransaction, + type SolanaSignTransactionFeature +} from '@solana/wallet-standard-features' +import { getCommitment } from '@solana/wallet-standard-util' +import type { Connection, SendOptions } from '@solana/web3.js' +import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js' +import type { Wallet, WalletAccount, WalletWithFeatures } from '@wallet-standard/base' +import { + StandardConnect, + type StandardConnectFeature, + StandardDisconnect, + type StandardDisconnectFeature, + StandardEvents, + type StandardEventsFeature +} from '@wallet-standard/features' +import { type AnyTransaction, type Chain, type Provider } from '../utils/scaffold/index.js' +import base58 from 'bs58' +import { WalletStandardFeatureNotSupportedError } from './shared/Errors.js' +import { ProviderEventEmitter } from './shared/ProviderEventEmitter.js' +import { solanaChains } from '../utils/chains.js' + +export interface WalletStandardProviderConfig { + wallet: Wallet + getActiveChain: () => Chain | undefined +} + +type AvailableFeatures = StandardConnectFeature & + SolanaSignAndSendTransactionFeature & + SolanaSignTransactionFeature & + StandardDisconnectFeature & + SolanaSignMessageFeature & + SolanaSignInFeature & + StandardEventsFeature + +export class WalletStandardProvider extends ProviderEventEmitter implements Provider { + readonly wallet: Wallet + readonly getActiveChain: WalletStandardProviderConfig['getActiveChain'] + + constructor({ wallet, getActiveChain }: WalletStandardProviderConfig) { + super() + + this.wallet = wallet + this.getActiveChain = getActiveChain + + this.bindEvents() + } + + // -- Public ------------------------------------------- // + public get name() { + return this.wallet.name + } + + public get type() { + const FILTER_OUT_ADAPTERS = ['Trust'] + + if (FILTER_OUT_ADAPTERS.includes(this.wallet.name)) { + return 'EXTERNAL' + } + + return 'ANNOUNCED' + } + + public get publicKey() { + const account = this.getAccount(false) + + if (account) { + return new PublicKey(account.publicKey) + } + + return undefined + } + + public get icon() { + return this.wallet.icon + } + + public get chains() { + return this.wallet.chains.map(chainId => solanaChains[chainId]).filter(Boolean) as Chain[] + } + + public async connect(): Promise { + const feature = this.getWalletFeature(StandardConnect) + await feature.connect() + + const account = this.getAccount(true) + const publicKey = new PublicKey(account.publicKey) + this.emit('connect', publicKey) + + return account.address + } + + public async disconnect() { + const feature = this.getWalletFeature(StandardDisconnect) + await feature.disconnect() + this.emit('disconnect', undefined) + } + + public async signMessage(message: Uint8Array) { + const feature = this.getWalletFeature(SolanaSignMessage) + const account = this.getAccount(true) + + const [result] = await feature.signMessage({ message, account }) + if (!result) { + throw new WalletSignMessageError('Empty result') + } + + return result.signature + } + + public async signTransaction(transaction: T) { + const feature = this.getWalletFeature(SolanaSignTransaction) + const account = this.getAccount(true) + + const serializedTransaction = this.serializeTransaction(transaction) + + const [result] = await feature.signTransaction({ + account, + transaction: serializedTransaction, + chain: this.getActiveChainName() + }) + + if (!result) { + throw new WalletSignTransactionError('Empty result') + } + + if (isVersionedTransaction(transaction)) { + return VersionedTransaction.deserialize(result.signedTransaction) as T + } + + return Transaction.from(result.signedTransaction) as T + } + + public async signAndSendTransaction( + transaction: T, + sendOptions?: SendOptions + ) { + const feature = this.getWalletFeature(SolanaSignAndSendTransaction) + const account = this.getAccount(true) + + const [result] = await feature.signAndSendTransaction({ + account, + transaction: this.serializeTransaction(transaction), + options: { + ...sendOptions, + preflightCommitment: getCommitment(sendOptions?.preflightCommitment) + }, + chain: this.getActiveChainName() + }) + + if (!result) { + throw new WalletSendTransactionError('Empty result') + } + + return base58.encode(result.signature) + } + + public async sendTransaction( + transaction: AnyTransaction, + connection: Connection, + options?: SendOptions + ) { + const signedTransaction = await this.signTransaction(transaction) + const signature = await connection.sendRawTransaction(signedTransaction.serialize(), options) + + return signature + } + + public async signAllTransactions() { + return await Promise.reject(new Error('Sign all transactions is not supported')) + } + + // -- Private ------------------------------------------- // + private serializeTransaction(transaction: AnyTransaction) { + return transaction.serialize({ verifySignatures: false }) + } + + private getAccount( + required?: Required + ): Required extends true ? WalletAccount : WalletAccount | undefined { + const account = this.wallet.accounts[0] + if (required && !account) { + throw new WalletAccountError() + } + + return account as Required extends true ? WalletAccount : WalletAccount | undefined + } + + private getWalletFeature(feature: Name) { + if (!(feature in this.wallet.features)) { + throw new WalletStandardFeatureNotSupportedError(feature) + } + + return this.wallet.features[feature] as WalletWithFeatures< + Record + >['features'][Name] + } + + private getActiveChainName() { + const entry = Object.entries(solanaChains).find( + ([, chain]) => chain.chainId === this.getActiveChain()?.chainId + ) + + if (!entry) { + throw new Error('Invalid chain id') + } + + return entry[0] as `${string}:${string}` + } + + private bindEvents() { + const features = this.getWalletFeature(StandardEvents) + + features.on('change', params => { + if (params.accounts) { + const account = params.accounts[0] + + if (account) { + this.emit('accountsChanged', new PublicKey(account.publicKey)) + } + } + }) + } +} diff --git a/packages/solana/src/providers/shared/Errors.ts b/packages/solana/src/providers/shared/Errors.ts new file mode 100644 index 0000000000..2ab66b6012 --- /dev/null +++ b/packages/solana/src/providers/shared/Errors.ts @@ -0,0 +1,5 @@ +export class WalletStandardFeatureNotSupportedError extends Error { + constructor(feature: string) { + super(`The wallet does not support the "${feature}" feature`) + } +} diff --git a/packages/solana/src/providers/shared/ProviderEventEmitter.ts b/packages/solana/src/providers/shared/ProviderEventEmitter.ts new file mode 100644 index 0000000000..fe4ca86528 --- /dev/null +++ b/packages/solana/src/providers/shared/ProviderEventEmitter.ts @@ -0,0 +1,37 @@ +import type { ProviderEventEmitterMethods } from '../../utils/scaffold' + +type Listeners = { + [Event in ProviderEventEmitterMethods.Event]: Array< + (arg: ProviderEventEmitterMethods.EventParams[Event]) => void + > +} + +export abstract class ProviderEventEmitter implements ProviderEventEmitterMethods { + private listeners: Listeners = { + accountsChanged: [], + chainChanged: [], + connect: [], + disconnect: [] + } + + public on( + event: E, + listener: (data: ProviderEventEmitterMethods.EventParams[E]) => void + ) { + this.listeners[event].push(listener) + } + + public removeListener( + event: E, + listener: (data: ProviderEventEmitterMethods.EventParams[E]) => void + ) { + this.listeners[event] = this.listeners[event].filter(l => l !== listener) as Listeners[E] + } + + public emit( + event: E, + data: ProviderEventEmitterMethods.EventParams[E] + ) { + this.listeners[event].forEach(listener => listener(data)) + } +} diff --git a/packages/solana/src/utils/chainPath/constants.ts b/packages/solana/src/utils/chainPath/constants.ts deleted file mode 100644 index 12edf3d2f4..0000000000 --- a/packages/solana/src/utils/chainPath/constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const SolanaChainIDs = { - Mainnet: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', - Devnet: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', - Testnet: 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z', - Deprecated_Mainnet: 'solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ', - Deprecated_Devnet: 'solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K' -} as const diff --git a/packages/solana/src/utils/chainPath/index.ts b/packages/solana/src/utils/chainPath/index.ts deleted file mode 100644 index e702017429..0000000000 --- a/packages/solana/src/utils/chainPath/index.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { SessionTypes } from '@walletconnect/types' -import { SolanaChainIDs as Chains } from './constants.js' - -export type ChainIDType = (typeof Chains)[keyof typeof Chains] - -export function getChainsFromChainId(chainId: ChainIDType) { - let chains: ChainIDType[] = [chainId] - if (chainId === Chains.Mainnet || chainId === Chains.Deprecated_Mainnet) { - chains = [Chains.Mainnet, Chains.Deprecated_Mainnet] - - if (chainId === Chains.Deprecated_Mainnet) { - console.warn(chainWarns.mainnet) - } - } else if (chainId === Chains.Deprecated_Devnet || chainId === Chains.Devnet) { - chains = [Chains.Devnet, Chains.Deprecated_Devnet] - if (Chains.Deprecated_Devnet) { - console.warn(chainWarns.devnet) - } - } - - return chains -} - -const chainWarns = { - mainnet: `You are using a deprecated chain ID for Solana Mainnet, please use ${Chains.Mainnet} instead.`, - devnet: `You are using a deprecated chain ID for Solana Devnet, please use ${Chains.Devnet} instead.`, - wallet: - 'The connected wallet is using a deprecated chain ID for Solana. Please, contact them to upgrade. You can learn more at https://github.com/ChainAgnostic/namespaces/blob/main/solana/caip10.md#chain-ids' -} - -export function getDefaultChainFromSession( - session: SessionTypes.Struct, - selectedChain: ChainIDType -) { - const chains = session.namespaces['solana']?.accounts.map( - (account: string) => `solana:${account.split(':')[1]}` - ) - - if (selectedChain === Chains.Mainnet) { - if (chains?.find((chain: string) => chain === Chains.Mainnet)) { - return Chains.Mainnet - } - console.warn(chainWarns.wallet) - - return Chains.Deprecated_Mainnet - } else if (selectedChain === Chains.Devnet) { - if (chains?.find((chain: string) => chain === Chains.Devnet)) { - return Chains.Devnet - } - console.warn(chainWarns.wallet) - - return Chains.Deprecated_Devnet - } else if (selectedChain === Chains.Testnet) { - return Chains.Testnet - } - throw Error('WalletConnect Solana Adapter: Unable to get a default chain from the session.') -} diff --git a/packages/solana/src/utils/chains.ts b/packages/solana/src/utils/chains.ts index 9315ae5004..49c4630dc8 100644 --- a/packages/solana/src/utils/chains.ts +++ b/packages/solana/src/utils/chains.ts @@ -1,4 +1,5 @@ import { ConstantsUtil } from '@web3modal/common' +import type { Chain } from './scaffold/index.js' export const solana = { chainId: '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', @@ -26,3 +27,9 @@ export const solanaDevnet = { rpcUrl: 'https://rpc.walletconnect.org/v1', chain: ConstantsUtil.CHAIN.SOLANA } + +export const solanaChains = { + 'solana:mainnet': solana, + 'solana:testnet': solanaTestnet, + 'solana:devnet': solanaDevnet +} as Record<`${string}:${string}`, Chain> diff --git a/packages/solana/src/utils/clusterFactory.ts b/packages/solana/src/utils/clusterFactory.ts deleted file mode 100644 index f076d96978..0000000000 --- a/packages/solana/src/utils/clusterFactory.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { proxy } from 'valtio/vanilla' -import { Transaction } from '@solana/web3.js' - -import { waitForOpenConnection } from './websocket.js' -import { SolStoreUtil } from './scaffold/index.js' - -import type { ClusterSubscribeRequestMethods } from './scaffold/index.js' - -type Listeners = Record< - number, - { - callback: (params: Transaction | number) => void - method: string - id: number - } -> -let socket: WebSocket | undefined = undefined -const listeners: Listeners = proxy({}) -const subIdToReqId: Record = proxy>({}) - -export async function setSocket() { - const cluster = SolStoreUtil.getCluster() - const { endpoint } = cluster - socket = new WebSocket(endpoint.replace('http', 'ws')) - await waitForOpenConnection(socket) - - socket.onmessage = ev => { - const data = JSON.parse(ev.data) as { - id: number - result: number - params: { - subscription: number - result: number - } - } - - /* - * If the request is a subscription init notification - * Copy data to new ID (request ID -> Subscribtion ID) - */ - if (data.id) { - subIdToReqId[data.result] = data.id - } - if (data.params?.subscription) { - const listenerIndex = subIdToReqId[data.params.subscription] - if (typeof listenerIndex !== 'undefined') { - listeners[listenerIndex]?.callback(data.params.result) - } - } - } - - return socket -} - -export function unregisterListener(id: number) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const { method } = listeners[id]! - const subscriptionId = Number( - Object.entries(subIdToReqId).filter(([_, value]) => value === id)[0]?.[0] - ) - - const unsubscribeMethod = method.replace('Subscribe', 'Unsubscribe') - - if (!socket) { - throw new Error('Socket not initialized') - } - - socket.send( - JSON.stringify({ - method: unsubscribeMethod, - params: [subscriptionId], - jsonrpc: '2.0', - id: SolStoreUtil.getNewRequestId() - }) - ) -} - -export async function registerListener( - method: Method, - cParams: ClusterSubscribeRequestMethods[Method]['params'], - callback: (params: Transaction | number) => void -) { - if (!socket) { - await setSocket() - } - const id = SolStoreUtil.getNewRequestId() - - if (!socket) { - throw new Error('Socket not initialized') - } - - socket.send( - JSON.stringify({ - method, - cParams, - jsonrpc: '2.0', - id - }) - ) - - listeners[id] = { method, callback, id } - - return id -} diff --git a/packages/solana/src/utils/hash.ts b/packages/solana/src/utils/hash.ts deleted file mode 100644 index c381161dab..0000000000 --- a/packages/solana/src/utils/hash.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { sha256 } from '@ethersproject/sha2' -import { Buffer } from 'buffer' -import { PublicKey } from '@solana/web3.js' - -import { SolConstantsUtil } from './scaffold/index.js' - -export function getHashedName(name: string): Buffer { - const input = SolConstantsUtil.HASH_PREFIX + name - const str = sha256(Buffer.from(input, 'utf8')).slice(2) - - return Buffer.from(str, 'hex') -} - -if (typeof window !== 'undefined') { - window.getHashedName = getHashedName -} - -export async function getNameAccountKey( - hashed_name: Buffer, - nameClass?: PublicKey, - nameParent?: PublicKey -): Promise { - const seeds = [hashed_name] - - if (nameClass) { - seeds.push(nameClass.toBuffer()) - } else { - seeds.push(Buffer.alloc(32)) - } - - if (nameParent) { - seeds.push(nameParent.toBuffer()) - } else { - seeds.push(Buffer.alloc(32)) - } - - const [nameAccountKey] = await PublicKey.findProgramAddress( - seeds, - SolConstantsUtil.NAME_PROGRAM_ID - ) - - return nameAccountKey -} diff --git a/packages/solana/src/utils/nameService.ts b/packages/solana/src/utils/nameService.ts deleted file mode 100644 index 5f466b6924..0000000000 --- a/packages/solana/src/utils/nameService.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { PublicKey } from '@solana/web3.js' - -import type { Schema } from 'borsh' - -export class NameRegistry { - public parentName: PublicKey - public owner: PublicKey - public class: PublicKey - public data: Buffer | undefined - - public constructor(obj: { parentName: Uint8Array; owner: Uint8Array; class: Uint8Array }) { - this.parentName = new PublicKey(obj.parentName) - this.owner = new PublicKey(obj.owner) - this.class = new PublicKey(obj.class) - } - - public static schema: Schema = new Map([ - [ - NameRegistry, - { - kind: 'struct', - fields: [ - ['parentName', [32]], - ['owner', [32]], - ['class', [32]] - ] - } - ] - ]) -} diff --git a/packages/solana/src/utils/scaffold/SolanaConstantsUtil.ts b/packages/solana/src/utils/scaffold/SolanaConstantsUtil.ts index 24f446c437..9c9184fdac 100644 --- a/packages/solana/src/utils/scaffold/SolanaConstantsUtil.ts +++ b/packages/solana/src/utils/scaffold/SolanaConstantsUtil.ts @@ -1,10 +1,6 @@ import { PublicKey } from '@solana/web3.js' import { ConstantsUtil } from '@web3modal/common' -/** - * Request methods to the solana RPC. - * @see {@link https://solana.com/docs} - */ export const SolConstantsUtil = { HASH_PREFIX: 'SPL Name Service', /** @@ -33,5 +29,13 @@ export const SolConstantsUtil = { explorerUrl: 'https://solscan.io', rpcUrl: `${ConstantsUtil.BLOCKCHAIN_API_RPC_URL}/v1`, chain: ConstantsUtil.CHAIN.SOLANA - } -} + }, + CHAIN_IDS: { + Mainnet: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', + Devnet: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', + Testnet: 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z', + Deprecated_Mainnet: 'solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ', + Deprecated_Devnet: 'solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K' + }, + LAMPORTS_PER_SOL: 1_000_000_000 +} as const diff --git a/packages/solana/src/utils/scaffold/SolanaHelpersUtils.ts b/packages/solana/src/utils/scaffold/SolanaHelpersUtils.ts index 993aa1b0ee..73a33a27cc 100644 --- a/packages/solana/src/utils/scaffold/SolanaHelpersUtils.ts +++ b/packages/solana/src/utils/scaffold/SolanaHelpersUtils.ts @@ -1,12 +1,10 @@ -import { PresetsUtil, ConstantsUtil } from '@web3modal/scaffold-utils' +import { PresetsUtil } from '@web3modal/scaffold-utils' import { ConstantsUtil as CommonConstantsUtil } from '@web3modal/common' import { SolConstantsUtil } from './SolanaConstantsUtil.js' -import type { CaipNetwork } from '@web3modal/core' +import type { CaipNetwork } from '@web3modal/scaffold' import type { Chain, Provider } from './SolanaTypesUtil.js' -import type { ExtendedBaseWalletAdapter } from '../../client.js' -import type { SolStoreUtilState } from './SolanaStoreUtil.js' export const SolHelpersUtil = { detectRpcUrl(chain: Chain, projectId: string) { @@ -68,17 +66,9 @@ export const SolHelpersUtil = { return decimalValue }, - async getAddress(provider: Provider) { - const [address] = await provider.request({ method: 'getAccountInfo' }) + getAddress(provider: Provider) { + const address = provider.publicKey?.toBase58() return address - }, - - getStorageInjectedId: (adapter: ExtendedBaseWalletAdapter) => - (adapter.isAnnounced - ? `${ConstantsUtil.WALLET_STANDARD_CONNECTOR_ID}_${adapter.name}` - : `${ConstantsUtil.INJECTED_CONNECTOR_ID}_${adapter.name}`) as unknown as Exclude< - SolStoreUtilState['providerType'], - undefined - > + } } diff --git a/packages/solana/src/utils/scaffold/SolanaStoreUtil.ts b/packages/solana/src/utils/scaffold/SolanaStoreUtil.ts index 7d59aa1c6d..8f33371ebf 100644 --- a/packages/solana/src/utils/scaffold/SolanaStoreUtil.ts +++ b/packages/solana/src/utils/scaffold/SolanaStoreUtil.ts @@ -2,17 +2,14 @@ import { proxy, ref, subscribe as sub } from 'valtio/vanilla' import { subscribeKey as subKey } from 'valtio/vanilla/utils' import { OptionsController } from '@web3modal/core' -import UniversalProvider from '@walletconnect/universal-provider' - -import type { Chain, CombinedProvider, Provider, Connection } from './SolanaTypesUtil.js' +import type { Chain, Provider, Connection } from './SolanaTypesUtil.js' import { SolConstantsUtil } from './SolanaConstantsUtil.js' import { SolHelpersUtil } from './SolanaHelpersUtils.js' type StateKey = keyof SolStoreUtilState export interface SolStoreUtilState { - provider?: Provider | CombinedProvider | UniversalProvider - providerType?: 'walletConnect' | `injected_${string}` | `announced_${string}` + provider?: Provider address?: string chainId?: string caipChainId?: string @@ -25,7 +22,6 @@ export interface SolStoreUtilState { const state = proxy({ provider: undefined, - providerType: undefined, address: undefined, currentChain: undefined, chainId: undefined, @@ -51,10 +47,6 @@ export const SolStoreUtil = { } }, - setProviderType(providerType: SolStoreUtilState['providerType']) { - state.providerType = providerType - }, - setAddress(address: string) { state.address = address }, @@ -100,7 +92,6 @@ export const SolStoreUtil = { state.provider = undefined state.address = undefined state.chainId = undefined - state.providerType = undefined state.isConnected = false state.error = undefined } diff --git a/packages/solana/src/utils/scaffold/SolanaTypesUtil.ts b/packages/solana/src/utils/scaffold/SolanaTypesUtil.ts index c647848cba..9bf1a053fc 100644 --- a/packages/solana/src/utils/scaffold/SolanaTypesUtil.ts +++ b/packages/solana/src/utils/scaffold/SolanaTypesUtil.ts @@ -1,5 +1,3 @@ -import { W3mFrameProvider } from '@web3modal/wallet' - import type { Connection as SolanaConnection, PublicKey, @@ -10,6 +8,7 @@ import type { } from '@solana/web3.js' import type { SendTransactionOptions } from '@solana/wallet-adapter-base' +import type { ConnectorType } from '@web3modal/scaffold' export type Connection = SolanaConnection @@ -32,37 +31,54 @@ export interface RequestArguments { readonly params?: readonly unknown[] | object } -export interface Provider { - isConnected: () => boolean - publicKey: PublicKey +export interface Provider extends ProviderEventEmitterMethods { + // Metadata name: string - on: (event: string, listener: (data: T) => void) => void - wallet: Provider - removeListener: (event: string, listener: (data: T) => void) => void - emit: (event: string) => void + publicKey?: PublicKey + icon?: string + chains: Chain[] + type: ConnectorType + + // Methods connect: () => Promise disconnect: () => Promise - request: (config: { method: string; params?: object }) => Promise signMessage: (message: Uint8Array) => Promise signTransaction: (transaction: T) => Promise signAndSendTransaction: ( transaction: AnyTransaction, options?: SendOptions ) => Promise - signAllTransactions: (transactions: SolanaWeb3Transaction[]) => Promise - signAndSendAllTransactions: ( - transactions: SolanaWeb3Transaction[] - ) => Promise + signAllTransactions: (transactions: AnyTransaction[]) => Promise sendTransaction: ( transaction: AnyTransaction, connection: Connection, options?: SendTransactionOptions ) => Promise - sendAndConfirm: ( - transaction: AnyTransaction, - connection: Connection, - options?: SendTransactionOptions - ) => Promise +} + +export interface ProviderEventEmitterMethods { + on: ( + event: E, + listener: (data: ProviderEventEmitterMethods.EventParams[E]) => void + ) => void + removeListener: ( + event: E, + listener: (data: ProviderEventEmitterMethods.EventParams[E]) => void + ) => void + emit: ( + event: E, + data: ProviderEventEmitterMethods.EventParams[E] + ) => void +} + +export namespace ProviderEventEmitterMethods { + export type Event = keyof EventParams + export type EventParams = { + connect: PublicKey + disconnect: undefined + accountsChanged: PublicKey + chainChanged: string + } } export type Metadata = { @@ -72,8 +88,6 @@ export type Metadata = { icons: string[] } -export type CombinedProvider = W3mFrameProvider & Provider - export type Chain = { rpcUrl: string explorerUrl: string @@ -82,253 +96,4 @@ export type Chain = { chainId: string } -// eslint-disable-next-line no-shadow -export enum Tag { - Uninitialized = 0, - ActiveOffer = 1, - CancelledOffer = 2, - AcceptedOffer = 3, - FavouriteDomain = 4, - FixedPriceOffer = 5, - AcceptedFixedPriceOffer = 6, - CancelledFixedPriceOffer = 7 -} - -export interface Status { - Ok: null -} - -export interface Meta { - err: null - fee: number - innerInstructions: TransactionInstruction[] - logMessages: string[] - postBalances: number[] - postTokenBalances: number[] - preBalances: number[] - preTokenBalances: number[] - rewards: null - status: Status -} - -interface TransactionInstruction { - accounts: number[] - data: string - programIdIndex: number -} - -export interface TransactionElement { - meta: Meta - transaction: TransactionData -} - -export interface TransactionData { - message: Message - signatures: string[] -} - -export interface Transaction { - message: Message - signatures: string[] -} - -export interface TransactionResult { - meta: Meta - slot: number - transaction: Transaction -} - -export interface Message { - accountKeys: string[] - header: Header - instructions: Instruction[] - recentBlockhash: string -} - -export interface Header { - numReadonlySignedAccounts: number - numReadonlyUnsignedAccounts: number - numRequiredSignatures: number -} - -export interface Instruction { - accounts: number[] - data: string - programIdIndex: number -} - -export interface BlockResult { - blockHeight: number - blockTime: null - blockhash: string - parentSlot: number - previousBlockhash: string - transactions: TransactionElement[] -} - -export interface AccountInfo { - data: string[] - executable: boolean - lamports: number - owner: string - rentEpoch: number -} - -export type FilterObject = - | { - memcmp: { - offset: number - bytes: string - encoding?: string - } - } - | { dataSize: number } - -/** - * Request methods to the solana RPC. - * @see {@link https://solana.com/docs/rpc/http} - */ -export interface RequestMethods { - solana_signMessage: { - params: { - message: string - pubkey: string - } - returns: { signature: string } - } - solana_signTransaction: { - params: { - transaction: string - pubkey: string - } - returns: { - transaction: string - } - } - solana_signAndSendTransaction: { - params: { - transaction: string - pubkey: string - sendOptions?: SendOptions - } - returns: { signature: string } - } - - signMessage: { - params: { - message: Uint8Array - format: string - } - returns: { - signature: string - } | null - } - - signTransaction: { - params: { - // Serialized transaction - message: string - } - returns: { - serialize: () => string - } | null - } -} - -export interface TransactionArgs { - transfer: { - params: { - to: string - amountInLamports: number - feePayer: 'from' | 'to' - } - } - program: { - params: { - programId: string - isWritableSender: boolean - data: Record - } - } -} - -export type TransactionType = keyof TransactionArgs - -export interface ClusterRequestMethods { - sendTransaction: { - // Signed, serialized transaction - params: string[] - returns: string - } - - getFeeForMessage: { - params: [string] - returns: number - } - - getBlock: { - params: [number] - returns: BlockResult | null - } - - getBalance: { - params: [string, { commitment: 'processed' | 'finalized' }] - returns: { - value: number - } - } - - getProgramAccounts: { - params: [ - string, - { - filters?: FilterObject[] - encoding: 'base58' | 'base64' | 'jsonParsed' - withContext?: boolean - } - ] - returns: { - value: { account: AccountInfo }[] - } - } - - getAccountInfo: { - params: [string, { encoding: 'base58' | 'base64' | 'jsonParsed' }] | [string] - returns?: { - value: AccountInfo | null - } - } - - getTransaction: { - params: [ - string, - { - encoding: 'base58' | 'base64' | 'jsonParsed' - commitment: 'confirmed' | 'finalized' - } - ] - returns: TransactionResult | null - } - - getLatestBlockhash: { - params: [{ commitment?: string }] - returns: { - value: { - blockhash: string - } - } - } -} - -export interface ClusterSubscribeRequestMethods { - signatureSubscribe: { - params: string[] - returns: Transaction - } - signatureUnsubscribe: { - params: number[] - returns: unknown - } -} - export type AnyTransaction = SolanaWeb3Transaction | VersionedTransaction diff --git a/packages/solana/src/utils/wallet-standard/adapter.ts b/packages/solana/src/utils/wallet-standard/adapter.ts deleted file mode 100644 index 374cc4a383..0000000000 --- a/packages/solana/src/utils/wallet-standard/adapter.ts +++ /dev/null @@ -1,581 +0,0 @@ -import { - BaseWalletAdapter, - isVersionedTransaction, - type SendTransactionOptions, - type StandardWalletAdapter as StandardWalletAdapterType, - type SupportedTransactionVersions, - WalletAccountError, - type WalletAdapterCompatibleStandardWallet, - WalletConfigError, - WalletConnectionError, - WalletDisconnectedError, - WalletDisconnectionError, - WalletError, - type WalletName, - WalletNotConnectedError, - WalletNotReadyError, - WalletPublicKeyError, - WalletReadyState, - WalletSendTransactionError, - WalletSignInError, - WalletSignMessageError, - WalletSignTransactionError -} from '@solana/wallet-adapter-base' -import { - SolanaSignAndSendTransaction, - SolanaSignIn, - type SolanaSignInInput, - type SolanaSignInOutput, - SolanaSignMessage, - SolanaSignTransaction, - type SolanaSignTransactionFeature -} from '@solana/wallet-standard-features' -import { getChainForEndpoint, getCommitment } from '@solana/wallet-standard-util' -import type { Connection, TransactionSignature } from '@solana/web3.js' -import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js' -import type { WalletAccount } from '@wallet-standard/base' -import { - StandardConnect, - type StandardConnectInput, - StandardDisconnect, - StandardEvents, - type StandardEventsListeners -} from '@wallet-standard/features' -import { arraysEqual } from '@wallet-standard/wallet' -import bs58 from 'bs58' -import { SolStoreUtil } from '../scaffold/index.js' - -/** TODO: docs */ -export interface StandardWalletAdapterConfig { - wallet: WalletAdapterCompatibleStandardWallet -} - -/** TODO: docs */ -export class StandardWalletAdapter extends BaseWalletAdapter implements StandardWalletAdapterType { - #account: WalletAccount | null - #publicKey: PublicKey | null - #connecting: boolean - #disconnecting: boolean - #off: (() => void) | null - #supportedTransactionVersions: SupportedTransactionVersions - readonly #wallet: WalletAdapterCompatibleStandardWallet - readonly #readyState: WalletReadyState = - typeof window === 'undefined' || typeof document === 'undefined' - ? WalletReadyState.Unsupported - : WalletReadyState.Installed - - get name() { - return this.#wallet.name as WalletName - } - - readonly url = 'https://github.com/solana-labs/wallet-standard' - - readonly isAnnounced = true - - get icon() { - return this.#wallet.icon - } - - get readyState() { - return this.#readyState - } - - get publicKey() { - return this.#publicKey - } - - get connecting() { - return this.#connecting - } - - get supportedTransactionVersions() { - return this.#supportedTransactionVersions - } - - get wallet(): WalletAdapterCompatibleStandardWallet { - return this.#wallet - } - - get standard() { - return true as const - } - - constructor({ wallet }: StandardWalletAdapterConfig) { - super() - - this.#wallet = wallet - this.#account = null - this.#publicKey = null - this.#connecting = false - this.#disconnecting = false - this.#off = this.#wallet.features[StandardEvents].on('change', this.#changed) - - this.#reset() - } - - destroy(): void { - this.#account = null - this.#publicKey = null - this.#connecting = false - this.#disconnecting = false - - const off = this.#off - if (off) { - this.#off = null - off() - } - } - - override async autoConnect(): Promise { - return this.#connect({ silent: true }) - } - - async connect(params?: StandardConnectInput): Promise { - return this.#connect(params) - } - - async #connect(input?: StandardConnectInput): Promise { - try { - if (this.connected || this.connecting) { - return - } - if (this.#readyState !== WalletReadyState.Installed) { - throw new WalletNotReadyError() - } - - this.#connecting = true - - if (!this.#wallet.accounts.length) { - try { - await this.#wallet.features[StandardConnect].connect(input) - } catch (error: unknown) { - throw new WalletConnectionError((error as Error)?.message, error) - } - } - - const account = this.#wallet.accounts[0] - if (!account) { - throw new WalletAccountError() - } - - this.#connected(account) - } catch (error: unknown) { - this.emit('error', error as WalletError) - throw error - } finally { - this.#connecting = false - } - } - - async disconnect(): Promise { - if (StandardDisconnect in this.#wallet.features) { - try { - this.#disconnecting = true - await this.#wallet.features[StandardDisconnect].disconnect() - } catch (error: unknown) { - this.emit('error', new WalletDisconnectionError((error as Error)?.message, error)) - } finally { - this.#disconnecting = false - } - } - - this.#disconnected() - } - - #connected(account: WalletAccount) { - let publicKey: PublicKey | undefined = undefined - try { - // Use account.address instead of account.publicKey since address could be a PDA - publicKey = new PublicKey(account.address) - } catch (error: unknown) { - throw new WalletPublicKeyError((error as Error)?.message, error) - } - - this.#account = account - this.#publicKey = publicKey - this.#reset() - this.emit('connect', publicKey) - } - - #disconnected(): void { - this.#account = null - this.#publicKey = null - this.#reset() - this.emit('disconnect') - } - - #reset() { - const supportedTransactionVersions = - SolanaSignAndSendTransaction in this.#wallet.features - ? this.#wallet.features[SolanaSignAndSendTransaction].supportedTransactionVersions - : this.#wallet.features[SolanaSignTransaction].supportedTransactionVersions - this.#supportedTransactionVersions = arraysEqual(supportedTransactionVersions, ['legacy']) - ? null - : new Set(supportedTransactionVersions) - - if ( - SolanaSignTransaction in this.#wallet.features && - this.#account?.features.includes(SolanaSignTransaction) - ) { - this.signTransaction = this.#signTransaction - this.signAllTransactions = this.#signAllTransactions - } else { - delete this.signTransaction - delete this.signAllTransactions - } - - if ( - SolanaSignMessage in this.#wallet.features && - this.#account?.features.includes(SolanaSignMessage) - ) { - this.signMessage = this.#signMessage - } else { - delete this.signMessage - } - - if (SolanaSignIn in this.#wallet.features) { - this.signIn = this.#signIn - } else { - delete this.signIn - } - } - - #changed: StandardEventsListeners['change'] = properties => { - // If accounts have changed on the wallet, reflect this on the adapter. - if ('accounts' in properties) { - const account = this.#wallet.accounts[0] - // If the adapter isn't connected, or is disconnecting, or the first account hasn't changed, do nothing. - if (this.#account && !this.#disconnecting && account !== this.#account) { - // If there's a connected account, connect the adapter. Otherwise, disconnect it. - if (account) { - // Connect the adapter. - this.#connected(account) - } else { - // Emit an error because the wallet spontaneously disconnected. - this.emit('error', new WalletDisconnectedError()) - // Disconnect the adapter. - this.#disconnected() - } - } - } - - // After reflecting account changes, if features have changed on the wallet, reflect this on the adapter. - if ('features' in properties) { - this.#reset() - } - } - - async sendTransaction( - transaction: T, - connection: Connection, - options: SendTransactionOptions = {} - ): Promise { - try { - const { account, chain } = this.getTransactionMetaInputs(connection) - - let feature: typeof SolanaSignAndSendTransaction | typeof SolanaSignTransaction | undefined = - undefined - if (SolanaSignAndSendTransaction in this.#wallet.features) { - if (account.features.includes(SolanaSignAndSendTransaction)) { - feature = SolanaSignAndSendTransaction - } else if ( - SolanaSignTransaction in this.#wallet.features && - account.features.includes(SolanaSignTransaction) - ) { - feature = SolanaSignTransaction - } else { - throw new WalletAccountError() - } - } else if (SolanaSignTransaction in this.#wallet.features) { - if (!account.features.includes(SolanaSignTransaction)) { - throw new WalletAccountError() - } - feature = SolanaSignTransaction - } else { - throw new WalletConfigError() - } - - try { - if (feature === SolanaSignAndSendTransaction) { - return this.signAndSendTransaction(transaction, options) - } - - const serializedTransaction = await this.serializeTransaction( - transaction, - connection, - options - ) - - const [output] = await (this.#wallet.features as SolanaSignTransactionFeature)[ - SolanaSignTransaction - ].signTransaction({ - account, - chain, - transaction: serializedTransaction, - options: { - preflightCommitment: getCommitment( - options.preflightCommitment || connection.commitment - ), - minContextSlot: options.minContextSlot - } - }) - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return await connection.sendRawTransaction(output!.signedTransaction, { - ...options, - preflightCommitment: getCommitment(options.preflightCommitment || connection.commitment) - }) - } catch (error: unknown) { - if (error instanceof WalletError) { - throw error - } - throw new WalletSendTransactionError((error as Error)?.message, error) - } - } catch (error: unknown) { - this.emit('error', error as WalletError) - throw error - } - } - - async signAndSendTransaction( - transaction: T, - options: SendTransactionOptions = {} - ): Promise { - if (!(SolanaSignAndSendTransaction in this.#wallet.features)) { - throw new Error(`The wallet does not support ${SolanaSignAndSendTransaction} feature`) - } - - const { chain, account, connection } = this.getTransactionMetaInputs( - SolStoreUtil.state.connection - ) - - const serializedTransaction = await this.serializeTransaction(transaction, connection, options) - - const [output] = await this.#wallet.features[ - SolanaSignAndSendTransaction - ].signAndSendTransaction({ - account, - chain, - transaction: serializedTransaction, - options: { - preflightCommitment: getCommitment(options.preflightCommitment || connection.commitment), - skipPreflight: options.skipPreflight, - maxRetries: options.maxRetries, - minContextSlot: options.minContextSlot - } - }) - - if (!output) { - throw new WalletSendTransactionError('Invalid transaction result') - } - - return bs58.encode(output.signature) - } - - private async serializeTransaction( - transaction: Transaction | VersionedTransaction, - connection: Connection, - options: SendTransactionOptions - ): Promise { - const { signers, ...sendOptions } = options - - if (isVersionedTransaction(transaction)) { - if (signers?.length) { - transaction.sign(signers) - } - - return transaction.serialize() - } - - const preparedTransaction = await this.prepareTransaction(transaction, connection, sendOptions) - - if (signers?.length) { - preparedTransaction.partialSign(...signers) - } - - return new Uint8Array( - preparedTransaction.serialize({ - requireAllSignatures: false, - verifySignatures: false - }) - ) - } - - private getTransactionMetaInputs(connection?: Connection | null) { - const account = this.#account - if (!account || !connection) { - throw new WalletNotConnectedError() - } - - const chain = getChainForEndpoint(connection.rpcEndpoint) - if (!account.chains.includes(chain)) { - throw new WalletSendTransactionError('Invalid chain') - } - - return { account, chain, connection } - } - - signTransaction: - | ((transaction: T) => Promise) - | undefined - async #signTransaction(transaction: T): Promise { - try { - const account = this.#account - if (!account) { - throw new WalletNotConnectedError() - } - - if (!(SolanaSignTransaction in this.#wallet.features)) { - throw new WalletConfigError() - } - if (!account.features.includes(SolanaSignTransaction)) { - throw new WalletAccountError() - } - try { - const signedTransactions = await this.#wallet.features[ - SolanaSignTransaction - ].signTransaction({ - account, - transaction: isVersionedTransaction(transaction) - ? transaction.serialize() - : new Uint8Array( - transaction.serialize({ - requireAllSignatures: false, - verifySignatures: false - }) - ) - }) - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const serializedTransaction = signedTransactions[0]!.signedTransaction - - return ( - isVersionedTransaction(transaction) - ? VersionedTransaction.deserialize(serializedTransaction) - : Transaction.from(serializedTransaction) - ) as T - } catch (error: unknown) { - if (error instanceof WalletError) { - throw error - } - throw new WalletSignTransactionError((error as Error)?.message, error) - } - } catch (error: unknown) { - this.emit('error', error as WalletError) - throw error - } - } - - signAllTransactions: - | ((transaction: T[]) => Promise) - | undefined - async #signAllTransactions( - transactions: T[] - ): Promise { - try { - const account = this.#account - if (!account) { - throw new WalletNotConnectedError() - } - - if (!(SolanaSignTransaction in this.#wallet.features)) { - throw new WalletConfigError() - } - if (!account.features.includes(SolanaSignTransaction)) { - throw new WalletAccountError() - } - - try { - const signedTransactions = await this.#wallet.features[ - SolanaSignTransaction - ].signTransaction( - ...transactions.map(transaction => ({ - account, - transaction: isVersionedTransaction(transaction) - ? transaction.serialize() - : new Uint8Array( - transaction.serialize({ - requireAllSignatures: false, - verifySignatures: false - }) - ) - })) - ) - - return transactions.map((transaction, index) => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const signedTransaction = signedTransactions[index]!.signedTransaction - - return ( - isVersionedTransaction(transaction) - ? VersionedTransaction.deserialize(signedTransaction) - : Transaction.from(signedTransaction) - ) as T - }) - } catch (error: unknown) { - throw new WalletSignTransactionError((error as Error)?.message, error) - } - } catch (error: unknown) { - this.emit('error', error as WalletError) - throw error - } - } - - signMessage: ((message: Uint8Array) => Promise) | undefined - async #signMessage(message: Uint8Array): Promise { - try { - const account = this.#account - if (!account) { - throw new WalletNotConnectedError() - } - - if (!(SolanaSignMessage in this.#wallet.features)) { - throw new WalletConfigError() - } - if (!account.features.includes(SolanaSignMessage)) { - throw new WalletAccountError() - } - - try { - const signedMessages = await this.#wallet.features[SolanaSignMessage].signMessage({ - account, - message - }) - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return signedMessages[0]!.signature - } catch (error: unknown) { - throw new WalletSignMessageError((error as Error)?.message, error) - } - } catch (error: unknown) { - this.emit('error', error as WalletError) - throw error - } - } - - signIn: ((input?: SolanaSignInInput) => Promise) | undefined - async #signIn(input: SolanaSignInInput = {}): Promise { - try { - if (!(SolanaSignIn in this.#wallet.features)) { - throw new WalletConfigError() - } - - let output: SolanaSignInOutput | undefined = undefined - try { - ;[output] = await this.#wallet.features[SolanaSignIn].signIn(input) - } catch (error: unknown) { - throw new WalletSignInError((error as Error)?.message, error) - } - - if (!output) { - throw new WalletSignInError() - } - this.#connected(output.account) - - return output - } catch (error: unknown) { - this.emit('error', error as WalletError) - throw error - } - } -} diff --git a/packages/solana/src/utils/wallet-standard/watchStandard.ts b/packages/solana/src/utils/watchStandard.ts similarity index 57% rename from packages/solana/src/utils/wallet-standard/watchStandard.ts rename to packages/solana/src/utils/watchStandard.ts index 383b5fdf30..ca5c8c44c0 100644 --- a/packages/solana/src/utils/wallet-standard/watchStandard.ts +++ b/packages/solana/src/utils/watchStandard.ts @@ -1,13 +1,13 @@ import { getWallets } from '@wallet-standard/app' -import { StandardWalletAdapter } from './adapter' +import { WalletStandardProvider } from '../providers/WalletStandardProvider.js' import { isWalletAdapterCompatibleStandardWallet } from '@solana/wallet-adapter-base' import type { Wallet } from '@wallet-standard/base' +import { SolStoreUtil } from './scaffold/SolanaStoreUtil.js' const { get, on } = getWallets() +let standardAdapters: WalletStandardProvider[] = wrapWalletsWithAdapters(get()) -let standardAdapters: StandardWalletAdapter[] = [...wrapWalletsWithAdapters(get())] - -export function watchStandard(callback: (arg: StandardWalletAdapter[]) => void) { +export function watchStandard(callback: (arg: WalletStandardProvider[]) => void) { const listeners = [ on('register', (...wallets) => { if (!standardAdapters || standardAdapters.length === 0) { @@ -25,13 +25,18 @@ export function watchStandard(callback: (arg: StandardWalletAdapter[]) => void) }) ] + standardAdapters = wrapWalletsWithAdapters(get()) callback(standardAdapters) return () => listeners.forEach(off => off()) } -function wrapWalletsWithAdapters(wallets: readonly Wallet[]): readonly StandardWalletAdapter[] { - return wallets - .filter(isWalletAdapterCompatibleStandardWallet) - .map(wallet => new StandardWalletAdapter({ wallet })) +function wrapWalletsWithAdapters(wallets: readonly Wallet[]): WalletStandardProvider[] { + return wallets.filter(isWalletAdapterCompatibleStandardWallet).map( + wallet => + new WalletStandardProvider({ + wallet, + getActiveChain: () => SolStoreUtil.state.currentChain + }) + ) } diff --git a/packages/solana/src/utils/websocket.ts b/packages/solana/src/utils/websocket.ts deleted file mode 100644 index 1bef294188..0000000000 --- a/packages/solana/src/utils/websocket.ts +++ /dev/null @@ -1,18 +0,0 @@ -export async function waitForOpenConnection(socket: WebSocket) { - return new Promise((resolve, reject) => { - const maxNumberOfAttempts = 10 - const intervalTime = 200 - - let currentAttempt = 0 - const interval = setInterval(() => { - if (currentAttempt > maxNumberOfAttempts - 1) { - clearInterval(interval) - reject(new Error('Maximum number of attempts exceeded')) - } else if (socket.readyState === socket.OPEN) { - clearInterval(interval) - resolve() - } - currentAttempt += 1 - }, intervalTime) - }) -} diff --git a/packages/solana/tests/GenericProvider.test.ts b/packages/solana/tests/GenericProvider.test.ts new file mode 100644 index 0000000000..57f327fa39 --- /dev/null +++ b/packages/solana/tests/GenericProvider.test.ts @@ -0,0 +1,85 @@ +import { beforeAll, describe, expect, it, vi } from 'vitest' +import type { Provider } from '../src/utils/scaffold/SolanaTypesUtil' +import { WalletConnectProvider } from '../src/providers/WalletConnectProvider' +import { mockUniversalProvider } from './mocks/UniversalProvider' +import { WalletStandardProvider } from '../src/providers/WalletStandardProvider' +import { mockWalletStandard } from './mocks/WalletStandard' +import { TestConstants } from './util/TestConstants' +import { Transaction, VersionedTransaction } from '@solana/web3.js' +import { mockLegacyTransaction, mockVersionedTransaction } from './mocks/Transaction' + +const providers: { name: string; provider: Provider }[] = [ + { + name: 'WalletConnectProvider', + provider: new WalletConnectProvider({ + provider: mockUniversalProvider(), + chains: TestConstants.chains + }) + }, + { + name: 'WalletStandardProvider', + provider: new WalletStandardProvider({ + wallet: mockWalletStandard(), + getActiveChain: () => TestConstants.chains[0] + }) + } +] + +describe.each(providers)('Generic provider tests for $name', ({ provider }) => { + const events = { + connect: vi.fn(), + disconnect: vi.fn(), + accountsChanged: vi.fn(), + chainChanged: vi.fn() + } + + beforeAll(() => { + provider.on('connect', events.connect) + provider.on('disconnect', events.disconnect) + provider.on('accountsChanged', events.accountsChanged) + provider.on('chainChanged', events.chainChanged) + }) + + it('should connect, return address and emit event', async () => { + const address = await provider.connect() + + expect(address).toEqual(TestConstants.accounts[0].address) + expect(events.connect).toHaveBeenCalledWith(TestConstants.accounts[0].publicKey) + }) + + it('should disconnect and emit event', async () => { + await provider.disconnect() + + expect(events.disconnect).toHaveBeenCalledWith(undefined) + }) + + it('should signMessage', async () => { + const result = await provider.signMessage(new TextEncoder().encode('test')) + + expect(result).toBeInstanceOf(Uint8Array) + }) + + it('should signTransaction with Legacy Transaction', async () => { + const result = await provider.signTransaction(mockLegacyTransaction()) + + expect(result).toBeInstanceOf(Transaction) + }) + + it('should signTransaction with Versioned Transaction', async () => { + const result = await provider.signTransaction(mockVersionedTransaction()) + + expect(result).toBeInstanceOf(VersionedTransaction) + }) + + it('should signAndSendTransaction with Legacy Transaction', async () => { + const result = await provider.signAndSendTransaction(mockLegacyTransaction()) + + expect(result).toBeTypeOf('string') + }) + + it('should signAndSendTransaction with Versioned Transaction', async () => { + const result = await provider.signAndSendTransaction(mockVersionedTransaction()) + + expect(result).toBeTypeOf('string') + }) +}) diff --git a/packages/solana/tests/WalletConnectProvider.test.ts b/packages/solana/tests/WalletConnectProvider.test.ts new file mode 100644 index 0000000000..b5f5afb67d --- /dev/null +++ b/packages/solana/tests/WalletConnectProvider.test.ts @@ -0,0 +1,106 @@ +import { beforeEach, describe, expect, it } from 'vitest' +import { mockUniversalProvider } from './mocks/UniversalProvider' +import { WalletConnectProvider } from '../src/providers/WalletConnectProvider' +import { TestConstants } from './util/TestConstants' +import { mockLegacyTransaction, mockVersionedTransaction } from './mocks/Transaction' + +describe('WalletConnectProvider specific tests', () => { + let provider = mockUniversalProvider() + let walletConnectProvider = new WalletConnectProvider({ + provider, + chains: TestConstants.chains + }) + + beforeEach(() => { + provider = mockUniversalProvider() + walletConnectProvider = new WalletConnectProvider({ + provider, + chains: TestConstants.chains + }) + }) + + it('should call connect', async () => { + await walletConnectProvider.connect() + + expect(provider.connect).toHaveBeenCalled() + }) + + it('should call disconnect', async () => { + await walletConnectProvider.disconnect() + + expect(provider.disconnect).toHaveBeenCalled() + }) + + it('should call signMessage with correct params', async () => { + await walletConnectProvider.connect() + const message = new Uint8Array([1, 2, 3, 4, 5]) + await walletConnectProvider.signMessage(message) + + expect(provider.request).toHaveBeenCalledWith({ + method: 'solana_signMessage', + params: { + message: '7bWpTW', + pubkey: TestConstants.accounts[0].address + } + }) + }) + + it('should call signTransaction with correct params', async () => { + await walletConnectProvider.connect() + const transaction = mockLegacyTransaction() + await walletConnectProvider.signTransaction(transaction) + + expect(provider.request).toHaveBeenCalledWith({ + method: 'solana_signTransaction', + params: { + transaction: + 'AKhoybLLJS1deDJDyjELDNhfkBBX3k4dt4bBfmppjfPVVimhQdFEfDo8AiFcCBCC9VkYWV2r3jkh9n1DAXEhnJPwMmnsrx6huAVrhHAbmRUqfUuWZ9aWMGmdEWaeroCnPR6jkEnjJcn14a59TZhkiTXMygMqu4KaqD1TqzE8vNHSw3YgbW24cfqWfQczGysuy4ugxj4TGSpqRtNmf5D7zRRa76eJTeZEaBcBQGkqxb31vBRXDMdQzGEbq', + pubkey: TestConstants.accounts[0].address + } + }) + }) + + it('should call signTransaction with correct params for VersionedTransaction', async () => { + await walletConnectProvider.connect() + const transaction = mockVersionedTransaction() + await walletConnectProvider.signTransaction(transaction) + + expect(provider.request).toHaveBeenCalledWith({ + method: 'solana_signTransaction', + params: { + transaction: + '48ckoQL1HhH5aqU1ifKqpQkwq3WPDgMnsHHQkVfddisxYcapwAVXr8hejTi2jeJpMPkZMsF72SwmJFDByyfRtaknz4ytCYNAcdHrxtrHa9hTjMKckVQrFFqS8zG63Wj5mJ6wPfj8dv1wKu2XkU6GSXSGdQmuvfRv3K6LUSMbK5XSP3yBGb1SDZKCuoFX4qDKcKhCG7Awn3ssAWB1yRaXMd6mS6HQHKSF11FTp3jTH2HKUNbKyyuGh4tYtq8b', + pubkey: TestConstants.accounts[0].address + } + }) + }) + + it('should call signAndSendTransaction with correct params', async () => { + await walletConnectProvider.connect() + const transaction = mockLegacyTransaction() + + await walletConnectProvider.signAndSendTransaction(transaction) + expect(provider.request).toHaveBeenCalledWith({ + method: 'solana_signAndSendTransaction', + params: { + transaction: + 'AKhoybLLJS1deDJDyjELDNhfkBBX3k4dt4bBfmppjfPVVimhQdFEfDo8AiFcCBCC9VkYWV2r3jkh9n1DAXEhnJPwMmnsrx6huAVrhHAbmRUqfUuWZ9aWMGmdEWaeroCnPR6jkEnjJcn14a59TZhkiTXMygMqu4KaqD1TqzE8vNHSw3YgbW24cfqWfQczGysuy4ugxj4TGSpqRtNmf5D7zRRa76eJTeZEaBcBQGkqxb31vBRXDMdQzGEbq', + pubkey: TestConstants.accounts[0].address, + sendOptions: undefined + } + }) + + await walletConnectProvider.signAndSendTransaction(transaction, { + preflightCommitment: 'singleGossip' + }) + expect(provider.request).toHaveBeenCalledWith({ + method: 'solana_signAndSendTransaction', + params: { + transaction: + 'AKhoybLLJS1deDJDyjELDNhfkBBX3k4dt4bBfmppjfPVVimhQdFEfDo8AiFcCBCC9VkYWV2r3jkh9n1DAXEhnJPwMmnsrx6huAVrhHAbmRUqfUuWZ9aWMGmdEWaeroCnPR6jkEnjJcn14a59TZhkiTXMygMqu4KaqD1TqzE8vNHSw3YgbW24cfqWfQczGysuy4ugxj4TGSpqRtNmf5D7zRRa76eJTeZEaBcBQGkqxb31vBRXDMdQzGEbq', + pubkey: TestConstants.accounts[0].address, + sendOptions: { preflightCommitment: 'singleGossip' } + } + }) + }) +}) diff --git a/packages/solana/tests/WalletStandardProvider.test.ts b/packages/solana/tests/WalletStandardProvider.test.ts new file mode 100644 index 0000000000..bd17ae024a --- /dev/null +++ b/packages/solana/tests/WalletStandardProvider.test.ts @@ -0,0 +1,128 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { mockWalletStandard } from './mocks/WalletStandard' +import { WalletStandardProvider } from '../src/providers/WalletStandardProvider' +import { StandardConnect, StandardDisconnect } from '@wallet-standard/features' +import { + SolanaSignAndSendTransaction, + SolanaSignMessage, + SolanaSignTransaction +} from '@solana/wallet-standard-features' +import { TestConstants } from './util/TestConstants' +import { mockLegacyTransaction, mockVersionedTransaction } from './mocks/Transaction' +import { WalletStandardFeatureNotSupportedError } from '../src/providers/shared/Errors' + +describe('WalletStandardProvider specific tests', () => { + let wallet = mockWalletStandard() + let getActiveChain = vi.fn(() => TestConstants.chains[0]) + let walletStandardProvider = new WalletStandardProvider({ + wallet, + getActiveChain + }) + + beforeEach(() => { + wallet = mockWalletStandard() + walletStandardProvider = new WalletStandardProvider({ + wallet, + getActiveChain + }) + }) + + it('should call connect', async () => { + await walletStandardProvider.connect() + + expect(wallet.features[StandardConnect].connect).toHaveBeenCalled() + }) + + it('should call disconnect', async () => { + await walletStandardProvider.disconnect() + + expect(wallet.features[StandardDisconnect].disconnect).toHaveBeenCalled() + }) + + it('should call signMessage with correct params', async () => { + const message = new Uint8Array([1, 2, 3, 4, 5]) + await walletStandardProvider.signMessage(message) + + expect(wallet.features[SolanaSignMessage].signMessage).toHaveBeenCalledWith({ + message, + account: wallet.accounts[0] + }) + }) + + it('should call signTransaction with correct params', async () => { + const transaction = mockLegacyTransaction() + await walletStandardProvider.signTransaction(transaction) + + expect(wallet.features[SolanaSignTransaction].signTransaction).toHaveBeenCalledWith({ + transaction: transaction.serialize({ verifySignatures: false }), + account: wallet.accounts[0], + chain: 'solana:mainnet' + }) + }) + + it('should call signTransaction with correct params for VersionedTransaction', async () => { + const transaction = mockVersionedTransaction() + await walletStandardProvider.signTransaction(transaction) + + expect(wallet.features[SolanaSignTransaction].signTransaction).toHaveBeenCalledWith({ + transaction: transaction.serialize(), + account: wallet.accounts[0], + chain: 'solana:mainnet' + }) + }) + + it('should call signAndSendTransaction with correct params', async () => { + const transaction = mockLegacyTransaction() + + await walletStandardProvider.signAndSendTransaction(transaction) + expect( + wallet.features[SolanaSignAndSendTransaction].signAndSendTransaction + ).toHaveBeenCalledWith({ + transaction: transaction.serialize({ verifySignatures: false }), + account: wallet.accounts[0], + chain: 'solana:mainnet', + options: { preflighCommitment: undefined } + }) + + await walletStandardProvider.signAndSendTransaction(transaction, { + preflightCommitment: 'singleGossip', + maxRetries: 1, + minContextSlot: 1, + skipPreflight: true + }) + expect( + wallet.features[SolanaSignAndSendTransaction].signAndSendTransaction + ).toHaveBeenCalledWith({ + transaction: transaction.serialize({ verifySignatures: false }), + account: wallet.accounts[0], + chain: 'solana:mainnet', + options: { + preflightCommitment: 'confirmed', + maxRetries: 1, + minContextSlot: 1, + skipPreflight: true + } + }) + }) + + it('should throw if features are not available', async () => { + // @ts-expect-error + wallet.features = {} + + await expect(walletStandardProvider.connect()).rejects.toThrowError( + WalletStandardFeatureNotSupportedError + ) + await expect(walletStandardProvider.disconnect()).rejects.toThrowError( + WalletStandardFeatureNotSupportedError + ) + await expect( + walletStandardProvider.signTransaction(mockLegacyTransaction()) + ).rejects.toThrowError(WalletStandardFeatureNotSupportedError) + await expect(walletStandardProvider.signMessage(new Uint8Array())).rejects.toThrowError( + WalletStandardFeatureNotSupportedError + ) + await expect( + walletStandardProvider.signAndSendTransaction(mockLegacyTransaction()) + ).rejects.toThrowError(WalletStandardFeatureNotSupportedError) + }) +}) diff --git a/packages/solana/tests/mocks/Transaction.ts b/packages/solana/tests/mocks/Transaction.ts new file mode 100644 index 0000000000..fdd9bc3c24 --- /dev/null +++ b/packages/solana/tests/mocks/Transaction.ts @@ -0,0 +1,37 @@ +import { + SystemProgram, + Transaction, + TransactionMessage, + VersionedTransaction +} from '@solana/web3.js' +import { TestConstants } from '../util/TestConstants' + +export function mockLegacyTransaction(): Transaction { + const transaction = new Transaction().add( + SystemProgram.transfer({ + fromPubkey: TestConstants.accounts[0].publicKey, + toPubkey: TestConstants.accounts[0].publicKey, + lamports: 10_000_000 + }) + ) + transaction.feePayer = TestConstants.accounts[0].publicKey + transaction.recentBlockhash = 'EZySCpmzXRuUtM95P2JGv9SitqYph6Nv6HaYBK7a8PKJ' + + return transaction +} + +export function mockVersionedTransaction(): VersionedTransaction { + const messageV0 = new TransactionMessage({ + payerKey: TestConstants.accounts[0].publicKey, + recentBlockhash: 'EZySCpmzXRuUtM95P2JGv9SitqYph6Nv6HaYBK7a8PKJ', + instructions: [ + SystemProgram.transfer({ + fromPubkey: TestConstants.accounts[0].publicKey, + toPubkey: TestConstants.accounts[0].publicKey, + lamports: 10_000_000 + }) + ] + }).compileToV0Message() + + return new VersionedTransaction(messageV0) +} diff --git a/packages/solana/tests/mocks/UniversalProvider.ts b/packages/solana/tests/mocks/UniversalProvider.ts new file mode 100644 index 0000000000..f1fea7d6b8 --- /dev/null +++ b/packages/solana/tests/mocks/UniversalProvider.ts @@ -0,0 +1,101 @@ +import UniversalProvider from '@walletconnect/universal-provider' +import type { SessionTypes } from '@walletconnect/types' +import { vi } from 'vitest' +import { TestConstants } from '../util/TestConstants' +import { WalletConnectProvider } from '../../src/providers/WalletConnectProvider' + +export function mockUniversalProvider() { + const provider = new UniversalProvider({}) + + provider.on = vi.fn() + provider.removeListener = vi.fn() + provider.connect = vi.fn(() => Promise.resolve(mockSession())) + provider.disconnect = vi.fn(() => Promise.resolve()) + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + provider.request = vi.fn((...[{ method }]: Parameters): any => { + switch (method) { + case 'solana_signMessage': + return Promise.resolve({ + signature: + '5bW5EoLn696QKxgJbsDb1aXrBf9hSUvvCa9FbyRt6CyppX4cQMJWyKx736ka5WDKqCZaoVivpWaxHhcAbSwhNx6Qp5Df3cHvSkg7jSX8PVw7FMKv45B5ZaeLjYHubDVsQEFFAs3Ea1CZU7X8xCv2JbhQvoxMoFWAKxUyFbM3DFH4KzuLL5nMZ9ybkiYfGdAAzwfMTDFLY7ymdzG12mWpvPwLJnwECDgHG7BogzZBdehndK8KP5sPLY5VcgVp5D87crr7XhUwmw5QLtDjPMnp4YKwApSS58jVNw3Zy' + } satisfies WalletConnectProvider.RequestMethods['solana_signMessage']['returns']) + case 'solana_signTransaction': + return Promise.resolve({ + transaction: + '4zZMC2ddAFY1YHcA2uFCqbuTHmD1xvB5QLzgNnT3dMb4aQT98md8jVm1YRGUsKJkYkLPYarnkobvESUpjqEUnDmoG76e9cgNJzLuFXBW1i6njs2Sy1Lnr9TZmLnhif5CYjh1agVJEvjfYpTq1QbTnLS3rBt4yKVjQ6FcV3x22Vm3XBPqodTXz17o1YcHMcvYQbHZfVUyikQ3Nmv6ktZzWe36D6ceKCVBV88VvYkkFhwWUWkA5ErPvsHWQU64VvbtENaJXFUUnuqTFSX4q3ccHuHdmtnhWQ7Mv8Xkb' + } satisfies WalletConnectProvider.RequestMethods['solana_signTransaction']['returns']) + case 'solana_signAndSendTransaction': + return Promise.resolve({ + signature: + '2Lb1KQHWfbV3pWMqXZveFWqneSyhH95YsgCENRWnArSkLydjN1M42oB82zSd6BBdGkM9pE6sQLQf1gyBh8KWM2c4' + } satisfies WalletConnectProvider.RequestMethods['solana_signAndSendTransaction']['returns']) + default: + return Promise.reject(new Error('not implemented')) + } + }) + + return provider +} + +function mockSession(replaces: Partial = {}): SessionTypes.Struct { + const chains = TestConstants.chains.map(chain => `solana:${chain.chainId}`) + + const accounts = chains.reduce((acc, cur) => { + for (const account of TestConstants.accounts) { + acc.push(`${cur}:${account.address}`) + } + + return acc + }, []) + + return { + topic: 'ebc6a484a235f10c47b90d7e3d83cdb08ed8802b11cd4960c3907142890bff3a', + relay: { + protocol: 'irn' + }, + expiry: 1724088716, + namespaces: { + solana: { + chains, + methods: ['solana_signTransaction', 'solana_signMessage', 'solana_signAndSendTransaction'], + events: [], + accounts + } + }, + acknowledged: true, + pairingTopic: '06e5b8a04b03f8dec6daafbe6d16cefaff665cc634b52baf906ca05f289eeb46', + requiredNamespaces: { + solana: { + chains, + methods: ['solana_signMessage', 'solana_signTransaction', 'solana_signAndSendTransaction'], + events: [] + } + }, + optionalNamespaces: {}, + controller: '6c4a0bf9796287e690bacd0f7bd4ff9da698cbbb7432535cbe2bf1cd4f560e47', + self: { + publicKey: 'f558d7ee6670ce7a44846ecd311532f499b9a13a21a754672ae5bdc484cee935', + metadata: { + name: 'AppKit Lab', + description: 'Laboratory environment for AppKit testing', + url: 'https://lab.web3modal.com', + icons: ['https://lab.web3modal.com/metadata-icon.svg'], + verifyUrl: '' + } + }, + peer: { + publicKey: '6c4a0bf9796287e690bacd0f7bd4ff9da698cbbb7432535cbe2bf1cd4f560e47', + metadata: { + name: 'React Wallet Example', + description: 'React Wallet for WalletConnect', + url: 'https://walletconnect.com/', + icons: ['https://avatars.githubusercontent.com/u/37784886'] + } + }, + sessionProperties: { + capabilities: '{}' + }, + ...replaces + } +} diff --git a/packages/solana/tests/mocks/WalletStandard.ts b/packages/solana/tests/mocks/WalletStandard.ts new file mode 100644 index 0000000000..949f237817 --- /dev/null +++ b/packages/solana/tests/mocks/WalletStandard.ts @@ -0,0 +1,96 @@ +import type { Wallet, WalletAccount } from '@wallet-standard/base' +import type { + StandardConnectFeature, + StandardDisconnectFeature, + StandardEventsFeature +} from '@wallet-standard/features' +import { vi } from 'vitest' +import { TestConstants } from '../util/TestConstants' +import type { + SolanaSignAndSendTransactionFeature, + SolanaSignMessageFeature, + SolanaSignTransactionFeature +} from '@solana/wallet-standard-features' + +export function mockWalletStandard() { + const accounts = TestConstants.accounts.map(mockAccount) + + return { + accounts, + chains: TestConstants.chains.map(chain => `solana:${chain.chainId}` as const), + features: { + 'standard:connect': { + version: '1.0.0', + connect: vi.fn(() => + Promise.resolve({ + accounts + }) + ) + } satisfies StandardConnectFeature['standard:connect'], + + 'standard:disconnect': { + version: '1.0.0', + disconnect: vi.fn(() => Promise.resolve()) + } satisfies StandardDisconnectFeature['standard:disconnect'], + + 'solana:signMessage': { + version: '1.0.0', + signMessage: vi.fn(() => + Promise.resolve([{ signedMessage: new Uint8Array(0), signature: new Uint8Array(0) }]) + ) + } satisfies SolanaSignMessageFeature['solana:signMessage'], + + 'solana:signTransaction': { + version: '1.0.0', + supportedTransactionVersions: [0, 'legacy'], + signTransaction: vi.fn(() => + Promise.resolve([ + { + signedTransaction: new Uint8Array([ + 1, 195, 86, 227, 117, 63, 116, 76, 21, 3, 236, 37, 188, 235, 178, 151, 68, 192, 248, + 193, 10, 232, 44, 63, 138, 193, 225, 213, 179, 76, 95, 250, 42, 74, 225, 195, 254, + 54, 181, 58, 180, 254, 159, 97, 87, 220, 75, 22, 232, 35, 13, 145, 80, 92, 5, 246, + 108, 246, 45, 237, 87, 8, 153, 134, 3, 1, 0, 2, 4, 22, 62, 150, 132, 19, 255, 121, + 234, 66, 225, 62, 27, 14, 6, 46, 36, 200, 146, 85, 115, 97, 244, 139, 207, 90, 253, + 89, 13, 69, 121, 218, 69, 117, 163, 33, 133, 104, 6, 127, 247, 14, 44, 174, 12, 125, + 42, 138, 162, 30, 211, 204, 233, 91, 171, 238, 30, 3, 233, 117, 104, 74, 10, 196, + 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 6, 70, 111, 229, 33, 23, 50, 255, 236, 173, 186, 114, 195, 155, + 231, 188, 140, 229, 187, 197, 247, 18, 107, 44, 67, 155, 58, 64, 0, 0, 0, 94, 139, + 248, 195, 57, 9, 171, 29, 198, 148, 191, 72, 247, 33, 118, 83, 181, 149, 184, 85, + 112, 19, 234, 30, 63, 54, 237, 157, 192, 138, 99, 27, 3, 3, 0, 9, 3, 160, 134, 1, 0, + 0, 0, 0, 0, 3, 0, 5, 2, 64, 13, 3, 0, 2, 2, 0, 1, 12, 2, 0, 0, 0, 128, 150, 152, 0, + 0, 0, 0, 0 + ]) + } + ]) + ) + } satisfies SolanaSignTransactionFeature['solana:signTransaction'], + + 'solana:signAndSendTransaction': { + version: '1.0.0', + supportedTransactionVersions: [0, 'legacy'], + signAndSendTransaction: vi.fn(() => Promise.resolve([{ signature: new Uint8Array(0) }])) + } satisfies SolanaSignAndSendTransactionFeature['solana:signAndSendTransaction'], + + 'standard:events': { + version: '1.0.0', + on: vi.fn() + } satisfies StandardEventsFeature['standard:events'] + }, + icon: 'data:image/png;base64,mocked...', + name: 'mocked-wallet', + version: '1.0.0' + } as const satisfies Wallet +} + +function mockAccount(account: TestConstants.Account = TestConstants.accounts[0]): WalletAccount { + return { + address: account.address, + chains: TestConstants.chains.map(chain => `solana:${chain.chainId}` as const), + features: [], + publicKey: account.publicKey.toBytes(), + icon: 'data:image/png;base64,mocked...', + label: 'mocked-account' + } +} diff --git a/packages/solana/tests/util/TestConstants.ts b/packages/solana/tests/util/TestConstants.ts new file mode 100644 index 0000000000..0cf9f045a6 --- /dev/null +++ b/packages/solana/tests/util/TestConstants.ts @@ -0,0 +1,25 @@ +import { PublicKey } from '@solana/web3.js' +import { solanaChains } from '../../src/utils/chains' +import base58 from 'bs58' + +export const TestConstants = { + accounts: [ + { + address: '2VqKhjZ766ZN3uBtBpb7Ls3cN4HrocP1rzxzekhVEgoP', + publicKey: new PublicKey(base58.decode('2VqKhjZ766ZN3uBtBpb7Ls3cN4HrocP1rzxzekhVEgoP')) + }, + { + address: '2vRxHxMEmhTCJ4jctfso2MVZvaQkHQxXf9riMNS3CjSu', + publicKey: new PublicKey(base58.decode('2vRxHxMEmhTCJ4jctfso2MVZvaQkHQxXf9riMNS3CjSu')) + } + ] as const satisfies TestConstants.Account[], + + chains: Object.values(solanaChains) +} as const + +export namespace TestConstants { + export type Account = { + address: string + publicKey: PublicKey + } +} diff --git a/packages/solana/tsconfig.build.json b/packages/solana/tsconfig.build.json new file mode 100644 index 0000000000..077d0e1bcb --- /dev/null +++ b/packages/solana/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["tests"] +} diff --git a/packages/solana/tsconfig.json b/packages/solana/tsconfig.json index 26d75e03fb..d7f8f23990 100644 --- a/packages/solana/tsconfig.json +++ b/packages/solana/tsconfig.json @@ -6,5 +6,5 @@ "baseUrl": "../../" }, "extends": "../../tsconfig.json", - "include": ["exports", "src"] + "include": ["exports", "src", "tests"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c3df54a87d..af0c37eead 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,7 +27,7 @@ importers: version: 6.18.1(eslint@8.56.0)(typescript@5.3.3) '@vitest/coverage-v8': specifier: 1.1.2 - version: 1.1.2(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3)) + version: 1.1.2(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0)) danger: specifier: 11.3.1 version: 11.3.1 @@ -60,13 +60,13 @@ importers: version: 5.3.3 vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) vite-plugin-node-polyfills: specifier: 0.22.0 - version: 0.22.0(rollup@4.20.0)(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + version: 0.22.0(rollup@4.20.0)(vite@5.2.11(@types/node@20.11.5)) vitest: specifier: 2.0.3 - version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3) + version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) apps/demo: dependencies: @@ -176,7 +176,7 @@ importers: version: 7.6.7(lit@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@storybook/web-components-vite': specifier: 7.6.7 - version: 7.6.7(bufferutil@4.0.8)(lit@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10)(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + version: 7.6.7(bufferutil@4.0.8)(lit@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10)(vite@5.2.11(@types/node@20.11.5)) file-system-cache: specifier: 2.4.4 version: 2.4.4 @@ -319,7 +319,7 @@ importers: devDependencies: vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) examples/html-wagmi: dependencies: @@ -341,7 +341,7 @@ importers: devDependencies: vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) examples/next-wagmi: dependencies: @@ -412,10 +412,10 @@ importers: version: 18.2.7 '@vitejs/plugin-react': specifier: 4.2.1 - version: 4.2.1(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + version: 4.2.1(vite@5.2.11(@types/node@20.11.5)) vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) examples/react-ethers5: dependencies: @@ -440,10 +440,10 @@ importers: version: 18.2.7 '@vitejs/plugin-react': specifier: 4.2.1 - version: 4.2.1(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + version: 4.2.1(vite@5.2.11(@types/node@20.11.5)) vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) examples/react-solana: dependencies: @@ -452,7 +452,7 @@ importers: version: 0.1.14(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-wallets': specifier: 0.19.32 - version: 0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10) + version: 0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10) '@tanstack/react-query': specifier: 5.24.8 version: 5.24.8(react@18.2.0) @@ -467,7 +467,7 @@ importers: version: 18.2.0(react@18.2.0) vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) devDependencies: '@types/react': specifier: 18.2.62 @@ -477,7 +477,7 @@ importers: version: 18.2.7 '@vitejs/plugin-react': specifier: 4.2.1 - version: 4.2.1(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + version: 4.2.1(vite@5.2.11(@types/node@20.11.5)) examples/react-wagmi: dependencies: @@ -498,7 +498,7 @@ importers: version: 2.17.8(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) wagmi: specifier: 2.12.2 version: 2.12.2(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.20.0)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.17.8(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) @@ -511,10 +511,10 @@ importers: version: 18.2.7 '@vitejs/plugin-react': specifier: 4.2.1 - version: 4.2.1(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + version: 4.2.1(vite@5.2.11(@types/node@20.11.5)) vite-size: specifier: 0.0.4 - version: 0.0.4(@types/node@20.11.5)(terser@5.31.3)(vue@3.4.3(typescript@5.3.3)) + version: 0.0.4(@types/node@20.11.5)(vue@3.4.3(typescript@5.3.3)) examples/vue-ethers5: dependencies: @@ -530,10 +530,10 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: 5.0.2 - version: 5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3)) + version: 5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.6))(vue@3.4.3(typescript@5.3.3)) vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) examples/vue-solana: dependencies: @@ -542,7 +542,7 @@ importers: version: 0.1.14(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-wallets': specifier: 0.19.32 - version: 0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10) + version: 0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10) '@web3modal/solana': specifier: workspace:* version: link:../../packages/solana @@ -552,10 +552,10 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: 5.0.2 - version: 5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3)) + version: 5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.6))(vue@3.4.3(typescript@5.3.3)) vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) examples/vue-wagmi: dependencies: @@ -574,10 +574,10 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: 5.0.2 - version: 5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3)) + version: 5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.6))(vue@3.4.3(typescript@5.3.3)) vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) packages/cdn: dependencies: @@ -598,14 +598,14 @@ importers: version: 2.17.8(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) vite: specifier: 5.2.11 - version: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) devDependencies: typescript: specifier: 5.3.3 version: 5.3.3 vite-plugin-node-polyfills: specifier: 0.22.0 - version: 0.22.0(rollup@4.20.0)(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + version: 0.22.0(rollup@4.20.0)(vite@5.2.11(@types/node@20.11.5)) packages/common: dependencies: @@ -618,10 +618,10 @@ importers: devDependencies: '@vitest/coverage-v8': specifier: 2.0.5 - version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3)) + version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))) vitest: specifier: 2.0.3 - version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3) + version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) packages/core: dependencies: @@ -637,13 +637,13 @@ importers: devDependencies: '@vitest/coverage-v8': specifier: 2.0.5 - version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3)) + version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))) viem: specifier: 2.16.2 version: 2.16.2(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) vitest: specifier: 2.0.3 - version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3) + version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) packages/ethers: dependencies: @@ -971,9 +971,15 @@ importers: '@types/bn.js': specifier: 5.1.5 version: 5.1.5 + '@vitest/coverage-v8': + specifier: 2.0.5 + version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))) '@walletconnect/types': specifier: 2.14.0 version: 2.14.0 + vitest: + specifier: 2.0.3 + version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) packages/ui: dependencies: @@ -989,7 +995,7 @@ importers: version: 1.5.5 '@vitest/coverage-v8': specifier: 2.0.5 - version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3)) + version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))) '@web3modal/common': specifier: workspace:* version: link:../common @@ -1007,7 +1013,7 @@ importers: version: 2.0.4(eslint@8.57.0) vitest: specifier: 2.0.3 - version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3) + version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) packages/wagmi: dependencies: @@ -1081,13 +1087,13 @@ importers: devDependencies: '@vitest/coverage-v8': specifier: 2.0.5 - version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3)) + version: 2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))) jsdom: specifier: 24.1.0 version: 24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) vitest: specifier: 2.0.3 - version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3) + version: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) services/id-allocation-service: dependencies: @@ -3627,11 +3633,11 @@ packages: '@fivebinaries/coin-selection@2.2.1': resolution: {integrity: sha512-iYFsYr7RY7TEvTqP9NKR4p/yf3Iybf9abUDR7lRjzanGsrLwVsREvIuyE05iRYFrvqarlk+gWRPsdR1N2hUBrg==} - '@floating-ui/core@1.6.6': - resolution: {integrity: sha512-Vkvsw6EcpMHjvZZdMkSY+djMGFbt7CRssW99Ne8tar2WLnZ/l3dbxeTShbLQj+/s35h+Qb4cmnob+EzwtjrXGQ==} + '@floating-ui/core@1.6.7': + resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==} - '@floating-ui/dom@1.6.9': - resolution: {integrity: sha512-zB1PcI350t4tkm3rvUhSRKa9sT7vH5CrAbQxW+VaPYJXKAO0gsg4CTueL+6Ajp7XzAQC8CW4Jj1Wgqc0sB6oUQ==} + '@floating-ui/dom@1.6.10': + resolution: {integrity: sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==} '@floating-ui/react-dom@2.1.1': resolution: {integrity: sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==} @@ -3639,8 +3645,8 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/utils@0.2.6': - resolution: {integrity: sha512-0KI3zGxIUs1KDR/pjQPdJH4Z8nGBm0yJ5WRoRfdw1Kzeh45jkIfA0rmD0kBF6fKHH+xaH7g8y4jIXyAV5MGK3g==} + '@floating-ui/utils@0.2.7': + resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==} '@fractalwagmi/popup-connection@1.1.1': resolution: {integrity: sha512-hYL+45iYwNbwjvP2DxP3YzVsrAGtj/RV9LOgMpJyCxsfNoyyOoi2+YrnywKkiANingiG2kJ1nKsizbu1Bd4zZw==} @@ -4012,6 +4018,9 @@ packages: '@noble/curves@1.4.2': resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + '@noble/curves@1.5.0': + resolution: {integrity: sha512-J5EKamIHnKPyClwVrzmaf5wSdQXgdHcPZIZLu3bwnbeCx8/7NPK5q2ZBWF+5FvYGByjiQQsJYX6jfgB2wDPn3A==} + '@noble/hashes@1.3.2': resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} engines: {node: '>= 16'} @@ -5984,8 +5993,8 @@ packages: '@types/node@18.15.13': resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} - '@types/node@18.19.43': - resolution: {integrity: sha512-Mw/YlgXnyJdEwLoFv2dpuJaDFriX+Pc+0qOBJ57jC1H6cDxIj2xc5yUrdtArDVG0m+KV6622a4p2tenEqB3C/g==} + '@types/node@18.19.44': + resolution: {integrity: sha512-ZsbGerYg72WMXUIE9fYxtvfzLEuq6q8mKERdWFnqTmOvudMxnz+CBNRoOwJ2kNpFOncrKjT1hZwxjlFgQ9qvQA==} '@types/node@20.11.5': resolution: {integrity: sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==} @@ -6326,6 +6335,9 @@ packages: '@walletconnect/relay-api@1.0.10': resolution: {integrity: sha512-tqrdd4zU9VBNqUaXXQASaexklv6A54yEyQQEXYOCr+Jz8Ket0dmPBDyg19LVSNUN2cipAghQc45/KVmfFJ0cYw==} + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + '@walletconnect/relay-auth@1.0.4': resolution: {integrity: sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ==} @@ -6987,8 +6999,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001650: - resolution: {integrity: sha512-fgEc7hP/LB7iicdXHUI9VsBsMZmUmlVJeQP2qqQW+3lkqVhbmjEU8zp+h5stWeilX+G7uXuIUIIlWlDw9jdt8g==} + caniuse-lite@1.0.30001651: + resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} capnp-ts@0.7.0: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} @@ -7574,14 +7586,14 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.5: - resolution: {integrity: sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==} + electron-to-chromium@1.5.7: + resolution: {integrity: sha512-6FTNWIWMxMy/ZY6799nBlPtF1DFDQ6VQJ7yyDP27SJNt5lwtQ5ufqVvHylb3fdQefvRcgA3fKcFMJi9OLwBRNw==} elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} - elliptic@6.5.6: - resolution: {integrity: sha512-mpzdtpeCLuS3BmE3pO3Cpp5bbjlOPY2Q0PgoF+Od1XZrHLYI28Xe3ossCmYCQt11FQKEYd9+PF8jymTvtWJSHQ==} + elliptic@6.5.7: + resolution: {integrity: sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==} emoji-regex@7.0.3: resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} @@ -7980,6 +7992,9 @@ packages: resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} engines: {node: '>=0.10.0'} + exponential-backoff@3.1.1: + resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + express@4.19.2: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} @@ -8127,8 +8142,8 @@ packages: flow-enums-runtime@0.0.6: resolution: {integrity: sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==} - flow-parser@0.242.1: - resolution: {integrity: sha512-E3ml21Q1S5cMAyPbtYslkvI6yZO5oCS/S2EoteeFH8Kx9iKOv/YOJ+dGd/yMf+H3YKfhMKjnOpyNwrO7NdddWA==} + flow-parser@0.243.0: + resolution: {integrity: sha512-HCDBfH+kZcY5etWYeAqatjW78gkIryzb9XixRsA8lGI1uyYc7aCpElkkO4H+KIpoyQMiY0VAZPI4cyac3wQe8w==} engines: {node: '>=0.4.0'} focus-lock@1.3.5: @@ -8147,8 +8162,8 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - foreground-child@3.2.1: - resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} form-data@4.0.0: @@ -8452,14 +8467,14 @@ packages: hermes-estree@0.19.1: resolution: {integrity: sha512-daLGV3Q2MKk8w4evNMKwS8zBE/rcpA800nu1Q5kM08IKijoSnPe9Uo1iIxzPKRkn95IxxsgBMPeYHt3VG4ej2g==} - hermes-estree@0.20.1: - resolution: {integrity: sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==} + hermes-estree@0.23.0: + resolution: {integrity: sha512-Rkp0PNLGpORw4ktsttkVbpYJbrYKS3hAnkxu8D9nvQi6LvSbuPa+tYw/t2u3Gjc35lYd/k95YkjqyTcN4zspag==} hermes-parser@0.19.1: resolution: {integrity: sha512-Vp+bXzxYJWrpEuJ/vXxUsLnt0+y4q9zyi4zUlkLqD8FKv4LjIfOvP69R/9Lty3dCyKh0E2BU7Eypqr63/rKT/A==} - hermes-parser@0.20.1: - resolution: {integrity: sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==} + hermes-parser@0.23.0: + resolution: {integrity: sha512-xLwM4ylfHGwrm+2qXfO1JT/fnqEDGSnpS/9hQ4VLtqTexSviu2ZpBgz07U8jVtndq67qdb/ps0qvaWDZ3fkTyg==} hermes-profile-transformer@0.0.6: resolution: {integrity: sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==} @@ -8581,8 +8596,8 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} image-size@1.1.1: @@ -9419,61 +9434,61 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - metro-babel-transformer@0.80.9: - resolution: {integrity: sha512-d76BSm64KZam1nifRZlNJmtwIgAeZhZG3fi3K+EmPOlrR8rDtBxQHDSN3fSGeNB9CirdTyabTMQCkCup6BXFSQ==} + metro-babel-transformer@0.80.10: + resolution: {integrity: sha512-GXHueUzgzcazfzORDxDzWS9jVVRV6u+cR6TGvHOfGdfLzJCj7/D0PretLfyq+MwN20twHxLW+BUXkoaB8sCQBg==} engines: {node: '>=18'} - metro-cache-key@0.80.9: - resolution: {integrity: sha512-hRcYGhEiWIdM87hU0fBlcGr+tHDEAT+7LYNCW89p5JhErFt/QaAkVx4fb5bW3YtXGv5BTV7AspWPERoIb99CXg==} + metro-cache-key@0.80.10: + resolution: {integrity: sha512-57qBhO3zQfoU/hP4ZlLW5hVej2jVfBX6B4NcSfMj4LgDPL3YknWg80IJBxzQfjQY/m+fmMLmPy8aUMHzUp/guA==} engines: {node: '>=18'} - metro-cache@0.80.9: - resolution: {integrity: sha512-ujEdSI43QwI+Dj2xuNax8LMo8UgKuXJEdxJkzGPU6iIx42nYa1byQ+aADv/iPh5sh5a//h5FopraW5voXSgm2w==} + metro-cache@0.80.10: + resolution: {integrity: sha512-8CBtDJwMguIE5RvV3PU1QtxUG8oSSX54mIuAbRZmcQ0MYiOl9JdrMd4JCBvIyhiZLoSStph425SMyCSnjtJsdA==} engines: {node: '>=18'} - metro-config@0.80.9: - resolution: {integrity: sha512-28wW7CqS3eJrunRGnsibWldqgwRP9ywBEf7kg+uzUHkSFJNKPM1K3UNSngHmH0EZjomizqQA2Zi6/y6VdZMolg==} + metro-config@0.80.10: + resolution: {integrity: sha512-0GYAw0LkmGbmA81FepKQepL1KU/85Cyv7sAiWm6QWeV6AcVCpsKg6jGLqGHJ0LLPL60rWzA4TV1DQAlzdJAEtA==} engines: {node: '>=18'} - metro-core@0.80.9: - resolution: {integrity: sha512-tbltWQn+XTdULkGdzHIxlxk4SdnKxttvQQV3wpqqFbHDteR4gwCyTR2RyYJvxgU7HELfHtrVbqgqAdlPByUSbg==} + metro-core@0.80.10: + resolution: {integrity: sha512-nwBB6HbpGlNsZMuzxVqxqGIOsn5F3JKpsp8PziS7Z4mV8a/jA1d44mVOgYmDa2q5WlH5iJfRIIhdz24XRNDlLA==} engines: {node: '>=18'} - metro-file-map@0.80.9: - resolution: {integrity: sha512-sBUjVtQMHagItJH/wGU9sn3k2u0nrCl0CdR4SFMO1tksXLKbkigyQx4cbpcyPVOAmGTVuy3jyvBlELaGCAhplQ==} + metro-file-map@0.80.10: + resolution: {integrity: sha512-ytsUq8coneaN7ZCVk1IogojcGhLIbzWyiI2dNmw2nnBgV/0A+M5WaTTgZ6dJEz3dzjObPryDnkqWPvIGLCPtiw==} engines: {node: '>=18'} - metro-minify-terser@0.80.9: - resolution: {integrity: sha512-FEeCeFbkvvPuhjixZ1FYrXtO0araTpV6UbcnGgDUpH7s7eR5FG/PiJz3TsuuPP/HwCK19cZtQydcA2QrCw446A==} + metro-minify-terser@0.80.10: + resolution: {integrity: sha512-Xyv9pEYpOsAerrld7cSLIcnCCpv8ItwysOmTA+AKf1q4KyE9cxrH2O2SA0FzMCkPzwxzBWmXwHUr+A89BpEM6g==} engines: {node: '>=18'} - metro-resolver@0.80.9: - resolution: {integrity: sha512-wAPIjkN59BQN6gocVsAvvpZ1+LQkkqUaswlT++cJafE/e54GoVkMNCmrR4BsgQHr9DknZ5Um/nKueeN7kaEz9w==} + metro-resolver@0.80.10: + resolution: {integrity: sha512-EYC5CL7f+bSzrqdk1bylKqFNGabfiI5PDctxoPx70jFt89Jz+ThcOscENog8Jb4LEQFG6GkOYlwmPpsi7kx3QA==} engines: {node: '>=18'} - metro-runtime@0.80.9: - resolution: {integrity: sha512-8PTVIgrVcyU+X/rVCy/9yxNlvXsBCk5JwwkbAm/Dm+Abo6NBGtNjWF0M1Xo/NWCb4phamNWcD7cHdR91HhbJvg==} + metro-runtime@0.80.10: + resolution: {integrity: sha512-Xh0N589ZmSIgJYAM+oYwlzTXEHfASZac9TYPCNbvjNTn0EHKqpoJ/+Im5G3MZT4oZzYv4YnvzRtjqS5k0tK94A==} engines: {node: '>=18'} - metro-source-map@0.80.9: - resolution: {integrity: sha512-RMn+XS4VTJIwMPOUSj61xlxgBvPeY4G6s5uIn6kt6HB6A/k9ekhr65UkkDD7WzHYs3a9o869qU8tvOZvqeQzgw==} + metro-source-map@0.80.10: + resolution: {integrity: sha512-EyZswqJW8Uukv/HcQr6K19vkMXW1nzHAZPWJSEyJFKIbgp708QfRZ6vnZGmrtFxeJEaFdNup4bGnu8/mIOYlyA==} engines: {node: '>=18'} - metro-symbolicate@0.80.9: - resolution: {integrity: sha512-Ykae12rdqSs98hg41RKEToojuIW85wNdmSe/eHUgMkzbvCFNVgcC0w3dKZEhSsqQOXapXRlLtHkaHLil0UD/EA==} + metro-symbolicate@0.80.10: + resolution: {integrity: sha512-qAoVUoSxpfZ2DwZV7IdnQGXCSsf2cAUExUcZyuCqGlY5kaWBb0mx2BL/xbMFDJ4wBp3sVvSBPtK/rt4J7a0xBA==} engines: {node: '>=18'} hasBin: true - metro-transform-plugins@0.80.9: - resolution: {integrity: sha512-UlDk/uc8UdfLNJhPbF3tvwajyuuygBcyp+yBuS/q0z3QSuN/EbLllY3rK8OTD9n4h00qZ/qgxGv/lMFJkwP4vg==} + metro-transform-plugins@0.80.10: + resolution: {integrity: sha512-leAx9gtA+2MHLsCeWK6XTLBbv2fBnNFu/QiYhWzMq8HsOAP4u1xQAU0tSgPs8+1vYO34Plyn79xTLUtQCRSSUQ==} engines: {node: '>=18'} - metro-transform-worker@0.80.9: - resolution: {integrity: sha512-c/IrzMUVnI0hSVVit4TXzt3A1GiUltGVlzCmLJWxNrBGHGrJhvgePj38+GXl1Xf4Fd4vx6qLUkKMQ3ux73bFLQ==} + metro-transform-worker@0.80.10: + resolution: {integrity: sha512-zNfNLD8Rz99U+JdOTqtF2o7iTjcDMMYdVS90z6+81Tzd2D0lDWVpls7R1hadS6xwM+ymgXFQTjM6V6wFoZaC0g==} engines: {node: '>=18'} - metro@0.80.9: - resolution: {integrity: sha512-Bc57Xf3GO2Xe4UWQsBj/oW6YfLPABEu8jfDVDiNmJvoQW4CO34oDPuYKe4KlXzXhcuNsqOtSxpbjCRRVjhhREg==} + metro@0.80.10: + resolution: {integrity: sha512-FDPi0X7wpafmDREXe1lgg3WzETxtXh6Kpq8+IwsG35R2tMyp2kFIqDdshdohuvDt1J/qDARcEPq7V/jElTb1kA==} engines: {node: '>=18'} hasBin: true @@ -9785,8 +9800,8 @@ packages: oauth@0.9.15: resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} - ob1@0.80.9: - resolution: {integrity: sha512-v9yOxowkZbxWhKOaaTyLjIm1aLy4ebMNcSn4NYJKOAI/Qv+SkfEfszpLr2GIxsccmb2Y2HA9qtsqiIJ80ucpVA==} + ob1@0.80.10: + resolution: {integrity: sha512-dJHyB0S6JkMorUSfSGcYGkkg9kmq3qDUu3ygZUKIfkr47XOPuG35r2Sk6tbwtHXbdKIXmcMvM8DF2CwgdyaHfQ==} engines: {node: '>=18'} obj-multiplex@1.0.0: @@ -10185,8 +10200,8 @@ packages: peerDependencies: postcss: ^8.2.14 - postcss-selector-parser@6.1.1: - resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==} + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} postcss-value-parser@4.2.0: @@ -10209,8 +10224,8 @@ packages: peerDependencies: preact: '>=10' - preact@10.23.1: - resolution: {integrity: sha512-O5UdRsNh4vdZaTieWe3XOgSpdMAmkIYBCT3VhQDlKrzyCm8lUYsk0fmVEvoQQifoOjFRTaHZO69ylrzTW2BH+A==} + preact@10.23.2: + resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} preact@10.4.1: resolution: {integrity: sha512-WKrRpCSwL2t3tpOOGhf2WfTpcmbpxaWtDbdJdKdjd0aEiTkvOmS4NBkG6kzlaAHI9AkQ3iVqbFWM3Ei7mZ4o1Q==} @@ -11299,8 +11314,8 @@ packages: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} - terser@5.31.3: - resolution: {integrity: sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==} + terser@5.31.6: + resolution: {integrity: sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==} engines: {node: '>=10'} hasBin: true @@ -11384,8 +11399,8 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tocbot@4.28.2: - resolution: {integrity: sha512-/MaSa9xI6mIo84IxqqliSCtPlH0oy7sLcY9s26qPMyH/2CxtZ2vNAXYlIdEQ7kjAkCQnc0rbLygf//F5c663oQ==} + tocbot@4.29.0: + resolution: {integrity: sha512-E+8+lceJpWHJYKq+qFHbi+gmFdXZeOAliHFdgiIAUo68cr8ClReXAx7h9e3TcDM0kw9PSnBn3GAZEpRmRLZ93g==} toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} @@ -11592,8 +11607,8 @@ packages: ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - uglify-js@3.19.1: - resolution: {integrity: sha512-y/2wiW+ceTYR2TSSptAhfnEtpLaQ4Ups5zrjB2d3kuVxHj16j/QJwPl5PvuGy9uARb39J0+iKxcRPvtpsx4A4A==} + uglify-js@3.19.2: + resolution: {integrity: sha512-S8KA6DDI47nQXJSi2ctQ629YzwOVs+bQML6DAtvy0wgNdpi+0ySpQK0g2pxBq2xfF2z3YCscu7NNA8nXT9PlIQ==} engines: {node: '>=0.8.0'} hasBin: true @@ -11676,8 +11691,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unplugin@1.12.0: - resolution: {integrity: sha512-KeczzHl2sATPQUx1gzo+EnUkmN4VmGBYRRVOZSGvGITE9rGHRDGqft6ONceP3vgXcyJ2XjX5axG5jMWUwNCYLw==} + unplugin@1.12.1: + resolution: {integrity: sha512-aXEH9c5qi3uYZHo0niUtxDlT9ylG/luMW/dZslSCkbtC31wCyFkmM0kyoBBh+Grhn7CL+/kvKLfN61/EdxPxMQ==} engines: {node: '>=14.0.0'} unstorage@1.10.2: @@ -12000,8 +12015,8 @@ packages: warning@4.0.3: resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} - watchpack@2.4.1: - resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} engines: {node: '>=10.13.0'} wcwidth@1.0.1: @@ -14593,7 +14608,7 @@ snapshots: eth-json-rpc-filters: 6.0.1 eventemitter3: 5.0.1 keccak: 3.0.4 - preact: 10.23.1 + preact: 10.23.2 sha.js: 2.4.11 transitivePeerDependencies: - supports-color @@ -14604,7 +14619,7 @@ snapshots: clsx: 1.2.1 eventemitter3: 5.0.1 keccak: 3.0.4 - preact: 10.23.1 + preact: 10.23.2 sha.js: 2.4.11 '@coinbase/wallet-sdk@4.0.4': @@ -14613,7 +14628,7 @@ snapshots: clsx: 1.2.1 eventemitter3: 5.0.1 keccak: 3.0.4 - preact: 10.23.1 + preact: 10.23.2 sha.js: 2.4.11 '@colors/colors@1.5.0': @@ -15173,7 +15188,7 @@ snapshots: debug: 4.3.6 espree: 9.6.1 globals: 13.24.0 - ignore: 5.3.1 + ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -15487,22 +15502,22 @@ snapshots: '@emurgo/cardano-serialization-lib-browser': 11.5.0 '@emurgo/cardano-serialization-lib-nodejs': 11.5.0 - '@floating-ui/core@1.6.6': + '@floating-ui/core@1.6.7': dependencies: - '@floating-ui/utils': 0.2.6 + '@floating-ui/utils': 0.2.7 - '@floating-ui/dom@1.6.9': + '@floating-ui/dom@1.6.10': dependencies: - '@floating-ui/core': 1.6.6 - '@floating-ui/utils': 0.2.6 + '@floating-ui/core': 1.6.7 + '@floating-ui/utils': 0.2.7 '@floating-ui/react-dom@2.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@floating-ui/dom': 1.6.9 + '@floating-ui/dom': 1.6.10 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - '@floating-ui/utils@0.2.6': {} + '@floating-ui/utils@0.2.7': {} '@fractalwagmi/popup-connection@1.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: @@ -16085,6 +16100,10 @@ snapshots: dependencies: '@noble/hashes': 1.4.0 + '@noble/curves@1.5.0': + dependencies: + '@noble/hashes': 1.4.0 + '@noble/hashes@1.3.2': {} '@noble/hashes@1.4.0': {} @@ -17006,9 +17025,9 @@ snapshots: '@react-native/metro-babel-transformer': 0.74.87(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2)) chalk: 4.1.2 execa: 5.1.1 - metro: 0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) - metro-config: 0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) - metro-core: 0.80.9 + metro: 0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + metro-config: 0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + metro-core: 0.80.10 node-fetch: 2.7.0 querystring: 0.2.1 readline: 1.3.0 @@ -17070,7 +17089,7 @@ snapshots: '@rnx-kit/chromium-edge-launcher@1.0.0': dependencies: - '@types/node': 18.19.43 + '@types/node': 18.19.44 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -17748,7 +17767,7 @@ snapshots: '@solana/wallet-adapter-unsafe-burner@0.1.7(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: - '@noble/curves': 1.4.2 + '@noble/curves': 1.5.0 '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-standard-features': 1.2.0 '@solana/wallet-standard-util': 1.1.1 @@ -17847,7 +17866,7 @@ snapshots: - uWebSockets.js - utf-8-validate - '@solana/wallet-adapter-wallets@0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-native@0.74.5(@babel/core@7.25.2)(@babel/preset-env@7.25.3(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10)': + '@solana/wallet-adapter-wallets@0.19.32(@babel/core@7.25.2)(@babel/runtime@7.25.0)(@sentry/types@7.92.0)(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(tslib@2.6.3)(utf-8-validate@5.0.10)': dependencies: '@solana/wallet-adapter-alpha': 0.1.10(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-avana': 0.1.13(@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)) @@ -17932,14 +17951,14 @@ snapshots: '@solana/wallet-standard-util@1.1.1': dependencies: - '@noble/curves': 1.4.2 + '@noble/curves': 1.5.0 '@solana/wallet-standard-chains': 1.1.0 '@solana/wallet-standard-features': 1.2.0 '@solana/web3.js@1.91.7(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.25.0 - '@noble/curves': 1.4.2 + '@noble/curves': 1.5.0 '@noble/hashes': 1.4.0 '@solana/buffer-layout': 4.0.1 agentkeepalive: 4.5.0 @@ -18187,7 +18206,7 @@ snapshots: react-colorful: 5.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-dom: 18.2.0(react@18.2.0) telejson: 7.2.0 - tocbot: 4.28.2 + tocbot: 4.29.0 ts-dedent: 2.2.0 util-deprecate: 1.0.2 transitivePeerDependencies: @@ -18218,7 +18237,7 @@ snapshots: - encoding - supports-color - '@storybook/builder-vite@7.6.7(typescript@5.3.3)(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3))': + '@storybook/builder-vite@7.6.7(typescript@5.3.3)(vite@5.2.11(@types/node@20.11.5))': dependencies: '@storybook/channels': 7.6.7 '@storybook/client-logger': 7.6.7 @@ -18236,7 +18255,7 @@ snapshots: fs-extra: 11.2.0 magic-string: 0.30.11 rollup: 3.29.4 - vite: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + vite: 5.2.11(@types/node@20.11.5)(terser@5.31.6) optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: @@ -18353,7 +18372,7 @@ snapshots: '@storybook/node-logger': 7.6.7 '@storybook/types': 7.6.7 '@types/find-cache-dir': 3.2.1 - '@types/node': 18.19.43 + '@types/node': 18.19.44 '@types/node-fetch': 2.6.11 '@types/pretty-hrtime': 1.0.3 chalk: 4.1.2 @@ -18398,7 +18417,7 @@ snapshots: '@storybook/telemetry': 7.6.7 '@storybook/types': 7.6.7 '@types/detect-port': 1.3.5 - '@types/node': 18.19.43 + '@types/node': 18.19.44 '@types/pretty-hrtime': 1.0.3 '@types/semver': 7.5.8 better-opn: 3.0.2 @@ -18421,7 +18440,7 @@ snapshots: ts-dedent: 2.2.0 util: 0.12.5 util-deprecate: 1.0.2 - watchpack: 2.4.1 + watchpack: 2.4.2 ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil @@ -18432,7 +18451,7 @@ snapshots: '@storybook/csf-plugin@7.6.7': dependencies: '@storybook/csf-tools': 7.6.7 - unplugin: 1.12.0 + unplugin: 1.12.1 transitivePeerDependencies: - supports-color @@ -18559,9 +18578,9 @@ snapshots: '@types/express': 4.17.21 file-system-cache: 2.3.0 - '@storybook/web-components-vite@7.6.7(bufferutil@4.0.8)(lit@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10)(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3))': + '@storybook/web-components-vite@7.6.7(bufferutil@4.0.8)(lit@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10)(vite@5.2.11(@types/node@20.11.5))': dependencies: - '@storybook/builder-vite': 7.6.7(typescript@5.3.3)(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)) + '@storybook/builder-vite': 7.6.7(typescript@5.3.3)(vite@5.2.11(@types/node@20.11.5)) '@storybook/core-server': 7.6.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@storybook/node-logger': 7.6.7 '@storybook/web-components': 7.6.7(lit@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -18734,7 +18753,7 @@ snapshots: '@toruslabs/eccrypto@2.2.1': dependencies: - elliptic: 6.5.6 + elliptic: 6.5.7 '@toruslabs/http-helpers@3.4.0(@babel/runtime@7.25.0)(@sentry/types@7.92.0)': dependencies: @@ -18749,7 +18768,7 @@ snapshots: '@babel/runtime': 7.25.0 '@toruslabs/eccrypto': 2.2.1 '@toruslabs/http-helpers': 3.4.0(@babel/runtime@7.25.0)(@sentry/types@7.92.0) - elliptic: 6.5.6 + elliptic: 6.5.7 ethereum-cryptography: 2.2.1 json-stable-stringify: 1.1.1 transitivePeerDependencies: @@ -19146,7 +19165,7 @@ snapshots: '@types/node@18.15.13': {} - '@types/node@18.19.43': + '@types/node@18.19.44': dependencies: undici-types: 5.26.5 @@ -19248,7 +19267,7 @@ snapshots: debug: 4.3.6 eslint: 8.56.0 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 natural-compare: 1.4.0 semver: 7.6.3 ts-api-utils: 1.3.0(typescript@5.3.3) @@ -19349,39 +19368,39 @@ snapshots: - debug - utf-8-validate - '@vitejs/plugin-react@4.2.1(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3))': + '@vitejs/plugin-react@4.2.1(vite@5.2.11(@types/node@20.11.5))': dependencies: '@babel/core': 7.25.2 '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + vite: 5.2.11(@types/node@20.11.5)(terser@5.31.6) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.2.1(vite@5.2.9(@types/node@20.11.5)(terser@5.31.3))': + '@vitejs/plugin-react@4.2.1(vite@5.2.9(@types/node@20.11.5))': dependencies: '@babel/core': 7.25.2 '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.2.9(@types/node@20.11.5)(terser@5.31.3) + vite: 5.2.9(@types/node@20.11.5) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3))': + '@vitejs/plugin-vue@5.0.2(vite@5.2.11(@types/node@20.11.5)(terser@5.31.6))(vue@3.4.3(typescript@5.3.3))': dependencies: - vite: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + vite: 5.2.11(@types/node@20.11.5)(terser@5.31.6) vue: 3.4.3(typescript@5.3.3) - '@vitejs/plugin-vue@5.1.2(vite@5.2.9(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3))': + '@vitejs/plugin-vue@5.1.2(vite@5.2.9(@types/node@20.11.5))(vue@3.4.3(typescript@5.3.3))': dependencies: - vite: 5.2.9(@types/node@20.11.5)(terser@5.31.3) + vite: 5.2.9(@types/node@20.11.5) vue: 3.4.3(typescript@5.3.3) - '@vitest/coverage-v8@1.1.2(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3))': + '@vitest/coverage-v8@1.1.2(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -19396,11 +19415,11 @@ snapshots: std-env: 3.7.0 test-exclude: 6.0.0 v8-to-istanbul: 9.3.0 - vitest: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3) + vitest: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3))': + '@vitest/coverage-v8@2.0.5(vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -19414,7 +19433,7 @@ snapshots: std-env: 3.7.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3) + vitest: 2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) transitivePeerDependencies: - supports-color @@ -19781,6 +19800,10 @@ snapshots: dependencies: '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/relay-auth@1.0.4': dependencies: '@stablelib/ed25519': 1.0.3 @@ -19917,7 +19940,7 @@ snapshots: '@stablelib/random': 1.0.2 '@stablelib/sha256': 1.0.1 '@stablelib/x25519': 1.0.3 - '@walletconnect/relay-api': 1.0.10 + '@walletconnect/relay-api': 1.0.11 '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 '@walletconnect/types': 2.12.0 @@ -20270,7 +20293,7 @@ snapshots: autoprefixer@10.4.18(postcss@8.4.35): dependencies: browserslist: 4.23.3 - caniuse-lite: 1.0.30001650 + caniuse-lite: 1.0.30001651 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.1 @@ -20524,7 +20547,7 @@ snapshots: browserify-rsa: 4.1.0 create-hash: 1.2.0 create-hmac: 1.1.7 - elliptic: 6.5.6 + elliptic: 6.5.7 hash-base: 3.0.4 inherits: 2.0.4 parse-asn1: 5.1.7 @@ -20541,8 +20564,8 @@ snapshots: browserslist@4.23.3: dependencies: - caniuse-lite: 1.0.30001650 - electron-to-chromium: 1.5.5 + caniuse-lite: 1.0.30001651 + electron-to-chromium: 1.5.7 node-releases: 2.0.18 update-browserslist-db: 1.1.0(browserslist@4.23.3) @@ -20669,7 +20692,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001650: {} + caniuse-lite@1.0.30001651: {} capnp-ts@0.7.0: dependencies: @@ -20941,7 +20964,7 @@ snapshots: create-ecdh@4.0.4: dependencies: bn.js: 4.12.0 - elliptic: 6.5.6 + elliptic: 6.5.7 create-hash@1.2.0: dependencies: @@ -21317,7 +21340,7 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.5.5: {} + electron-to-chromium@1.5.7: {} elliptic@6.5.4: dependencies: @@ -21329,7 +21352,7 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - elliptic@6.5.6: + elliptic@6.5.7: dependencies: bn.js: 4.12.0 brorand: 1.1.0 @@ -21999,7 +22022,7 @@ snapshots: glob-parent: 6.0.2 globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -22042,7 +22065,7 @@ snapshots: glob-parent: 6.0.2 globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -22245,6 +22268,8 @@ snapshots: dependencies: homedir-polyfill: 1.0.3 + exponential-backoff@3.1.1: {} + express@4.19.2: dependencies: accepts: 1.3.8 @@ -22291,7 +22316,7 @@ snapshots: extension-port-stream@3.0.0: dependencies: - readable-stream: 4.5.2 + readable-stream: 3.6.2 webextension-polyfill: 0.10.0 external-editor@3.1.0: @@ -22452,7 +22477,7 @@ snapshots: flow-enums-runtime@0.0.6: {} - flow-parser@0.242.1: {} + flow-parser@0.243.0: {} focus-lock@1.3.5: dependencies: @@ -22464,7 +22489,7 @@ snapshots: dependencies: is-callable: 1.2.7 - foreground-child@3.2.1: + foreground-child@3.3.0: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 @@ -22645,7 +22670,7 @@ snapshots: glob@10.3.10: dependencies: - foreground-child: 3.2.1 + foreground-child: 3.3.0 jackspeak: 2.3.6 minimatch: 9.0.5 minipass: 7.1.2 @@ -22653,7 +22678,7 @@ snapshots: glob@10.4.5: dependencies: - foreground-child: 3.2.1 + foreground-child: 3.3.0 jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 @@ -22685,7 +22710,7 @@ snapshots: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.3.1 + ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 @@ -22749,7 +22774,7 @@ snapshots: source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.19.1 + uglify-js: 3.19.2 hard-rejection@2.1.0: {} @@ -22795,15 +22820,15 @@ snapshots: hermes-estree@0.19.1: {} - hermes-estree@0.20.1: {} + hermes-estree@0.23.0: {} hermes-parser@0.19.1: dependencies: hermes-estree: 0.19.1 - hermes-parser@0.20.1: + hermes-parser@0.23.0: dependencies: - hermes-estree: 0.20.1 + hermes-estree: 0.23.0 hermes-profile-transformer@0.0.6: dependencies: @@ -22934,7 +22959,7 @@ snapshots: ieee754@1.2.1: {} - ignore@5.3.1: {} + ignore@5.3.2: {} image-size@1.1.1: dependencies: @@ -23396,7 +23421,7 @@ snapshots: '@babel/register': 7.24.6(@babel/core@7.25.2) babel-core: 7.0.0-bridge.0(@babel/core@7.25.2) chalk: 4.1.2 - flow-parser: 0.242.1 + flow-parser: 0.243.0 graceful-fs: 4.2.11 micromatch: 4.0.7 neo-async: 2.6.2 @@ -23421,7 +23446,7 @@ snapshots: '@babel/register': 7.24.6(@babel/core@7.25.2) babel-core: 7.0.0-bridge.0(@babel/core@7.25.2) chalk: 4.1.2 - flow-parser: 0.242.1 + flow-parser: 0.243.0 graceful-fs: 4.2.11 micromatch: 4.0.7 neo-async: 2.6.2 @@ -23855,46 +23880,53 @@ snapshots: methods@1.1.2: {} - metro-babel-transformer@0.80.9: + metro-babel-transformer@0.80.10: dependencies: '@babel/core': 7.25.2 - hermes-parser: 0.20.1 + flow-enums-runtime: 0.0.6 + hermes-parser: 0.23.0 nullthrows: 1.1.1 transitivePeerDependencies: - supports-color - metro-cache-key@0.80.9: {} + metro-cache-key@0.80.10: + dependencies: + flow-enums-runtime: 0.0.6 - metro-cache@0.80.9: + metro-cache@0.80.10: dependencies: - metro-core: 0.80.9 - rimraf: 3.0.2 + exponential-backoff: 3.1.1 + flow-enums-runtime: 0.0.6 + metro-core: 0.80.10 - metro-config@0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10): + metro-config@0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: connect: 3.7.0 cosmiconfig: 5.2.1 + flow-enums-runtime: 0.0.6 jest-validate: 29.7.0 - metro: 0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) - metro-cache: 0.80.9 - metro-core: 0.80.9 - metro-runtime: 0.80.9 + metro: 0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + metro-cache: 0.80.10 + metro-core: 0.80.10 + metro-runtime: 0.80.10 transitivePeerDependencies: - bufferutil - encoding - supports-color - utf-8-validate - metro-core@0.80.9: + metro-core@0.80.10: dependencies: + flow-enums-runtime: 0.0.6 lodash.throttle: 4.1.1 - metro-resolver: 0.80.9 + metro-resolver: 0.80.10 - metro-file-map@0.80.9: + metro-file-map@0.80.10: dependencies: anymatch: 3.1.3 debug: 2.6.9 fb-watchman: 2.0.2 + flow-enums-runtime: 0.0.6 graceful-fs: 4.2.11 invariant: 2.2.4 jest-worker: 29.7.0 @@ -23907,33 +23939,39 @@ snapshots: transitivePeerDependencies: - supports-color - metro-minify-terser@0.80.9: + metro-minify-terser@0.80.10: dependencies: - terser: 5.31.3 + flow-enums-runtime: 0.0.6 + terser: 5.31.6 - metro-resolver@0.80.9: {} + metro-resolver@0.80.10: + dependencies: + flow-enums-runtime: 0.0.6 - metro-runtime@0.80.9: + metro-runtime@0.80.10: dependencies: '@babel/runtime': 7.25.0 + flow-enums-runtime: 0.0.6 - metro-source-map@0.80.9: + metro-source-map@0.80.10: dependencies: '@babel/traverse': 7.25.3 '@babel/types': 7.25.2 + flow-enums-runtime: 0.0.6 invariant: 2.2.4 - metro-symbolicate: 0.80.9 + metro-symbolicate: 0.80.10 nullthrows: 1.1.1 - ob1: 0.80.9 + ob1: 0.80.10 source-map: 0.5.7 vlq: 1.0.1 transitivePeerDependencies: - supports-color - metro-symbolicate@0.80.9: + metro-symbolicate@0.80.10: dependencies: + flow-enums-runtime: 0.0.6 invariant: 2.2.4 - metro-source-map: 0.80.9 + metro-source-map: 0.80.10 nullthrows: 1.1.1 source-map: 0.5.7 through2: 2.0.5 @@ -23941,29 +23979,31 @@ snapshots: transitivePeerDependencies: - supports-color - metro-transform-plugins@0.80.9: + metro-transform-plugins@0.80.10: dependencies: '@babel/core': 7.25.2 '@babel/generator': 7.25.0 '@babel/template': 7.25.0 '@babel/traverse': 7.25.3 + flow-enums-runtime: 0.0.6 nullthrows: 1.1.1 transitivePeerDependencies: - supports-color - metro-transform-worker@0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10): + metro-transform-worker@0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: '@babel/core': 7.25.2 '@babel/generator': 7.25.0 '@babel/parser': 7.25.3 '@babel/types': 7.25.2 - metro: 0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) - metro-babel-transformer: 0.80.9 - metro-cache: 0.80.9 - metro-cache-key: 0.80.9 - metro-minify-terser: 0.80.9 - metro-source-map: 0.80.9 - metro-transform-plugins: 0.80.9 + flow-enums-runtime: 0.0.6 + metro: 0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + metro-babel-transformer: 0.80.10 + metro-cache: 0.80.10 + metro-cache-key: 0.80.10 + metro-minify-terser: 0.80.10 + metro-source-map: 0.80.10 + metro-transform-plugins: 0.80.10 nullthrows: 1.1.1 transitivePeerDependencies: - bufferutil @@ -23971,7 +24011,7 @@ snapshots: - supports-color - utf-8-validate - metro@0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10): + metro@0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: '@babel/code-frame': 7.24.7 '@babel/core': 7.25.2 @@ -23987,29 +24027,29 @@ snapshots: debug: 2.6.9 denodeify: 1.2.1 error-stack-parser: 2.1.4 + flow-enums-runtime: 0.0.6 graceful-fs: 4.2.11 - hermes-parser: 0.20.1 + hermes-parser: 0.23.0 image-size: 1.1.1 invariant: 2.2.4 jest-worker: 29.7.0 jsc-safe-url: 0.2.4 lodash.throttle: 4.1.1 - metro-babel-transformer: 0.80.9 - metro-cache: 0.80.9 - metro-cache-key: 0.80.9 - metro-config: 0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) - metro-core: 0.80.9 - metro-file-map: 0.80.9 - metro-resolver: 0.80.9 - metro-runtime: 0.80.9 - metro-source-map: 0.80.9 - metro-symbolicate: 0.80.9 - metro-transform-plugins: 0.80.9 - metro-transform-worker: 0.80.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) + metro-babel-transformer: 0.80.10 + metro-cache: 0.80.10 + metro-cache-key: 0.80.10 + metro-config: 0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + metro-core: 0.80.10 + metro-file-map: 0.80.10 + metro-resolver: 0.80.10 + metro-runtime: 0.80.10 + metro-source-map: 0.80.10 + metro-symbolicate: 0.80.10 + metro-transform-plugins: 0.80.10 + metro-transform-worker: 0.80.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) mime-types: 2.1.35 node-fetch: 2.7.0 nullthrows: 1.1.1 - rimraf: 3.0.2 serialize-error: 2.1.0 source-map: 0.5.7 strip-ansi: 6.0.1 @@ -24185,8 +24225,8 @@ snapshots: next: 14.2.3(@babel/core@7.25.2)(@playwright/test@1.44.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) oauth: 0.9.15 openid-client: 5.6.5 - preact: 10.23.1 - preact-render-to-string: 5.2.6(preact@10.23.1) + preact: 10.23.2 + preact-render-to-string: 5.2.6(preact@10.23.2) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) uuid: 8.3.2 @@ -24196,7 +24236,7 @@ snapshots: '@next/env': 14.2.3 '@swc/helpers': 0.5.5 busboy: 1.6.0 - caniuse-lite: 1.0.30001650 + caniuse-lite: 1.0.30001651 graceful-fs: 4.2.11 postcss: 8.4.31 react: 18.2.0 @@ -24319,7 +24359,9 @@ snapshots: oauth@0.9.15: {} - ob1@0.80.9: {} + ob1@0.80.10: + dependencies: + flow-enums-runtime: 0.0.6 obj-multiplex@1.0.0: dependencies: @@ -24707,9 +24749,9 @@ snapshots: postcss-nested@6.2.0(postcss@8.4.35): dependencies: postcss: 8.4.35 - postcss-selector-parser: 6.1.1 + postcss-selector-parser: 6.1.2 - postcss-selector-parser@6.1.1: + postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -24734,12 +24776,12 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 - preact-render-to-string@5.2.6(preact@10.23.1): + preact-render-to-string@5.2.6(preact@10.23.2): dependencies: - preact: 10.23.1 + preact: 10.23.2 pretty-format: 3.8.0 - preact@10.23.1: {} + preact@10.23.2: {} preact@10.4.1: {} @@ -25072,8 +25114,8 @@ snapshots: jest-environment-node: 29.7.0 jsc-android: 250231.0.0 memoize-one: 5.2.1 - metro-runtime: 0.80.9 - metro-source-map: 0.80.9 + metro-runtime: 0.80.10 + metro-source-map: 0.80.10 mkdirp: 0.5.6 nullthrows: 1.1.1 pretty-format: 26.6.2 @@ -25392,7 +25434,7 @@ snapshots: dependencies: bn.js: 5.2.1 brorand: 1.1.0 - elliptic: 6.5.6 + elliptic: 6.5.7 hash.js: 1.1.7 ripple-address-codec: 4.3.1 @@ -25543,7 +25585,7 @@ snapshots: secp256k1@5.0.0: dependencies: - elliptic: 6.5.6 + elliptic: 6.5.7 node-addon-api: 5.1.0 node-gyp-build: 4.8.1 @@ -25996,7 +26038,7 @@ snapshots: postcss-js: 4.0.1(postcss@8.4.35) postcss-load-config: 4.0.2(postcss@8.4.35) postcss-nested: 6.2.0(postcss@8.4.35) - postcss-selector-parser: 6.1.1 + postcss-selector-parser: 6.1.2 resolve: 1.22.8 sucrase: 3.35.0 transitivePeerDependencies: @@ -26048,7 +26090,7 @@ snapshots: term-size@2.2.1: {} - terser@5.31.3: + terser@5.31.6: dependencies: '@jridgewell/source-map': 0.3.6 acorn: 8.12.1 @@ -26103,7 +26145,7 @@ snapshots: bindings: 1.5.0 bn.js: 4.12.0 create-hmac: 1.1.7 - elliptic: 6.5.6 + elliptic: 6.5.7 nan: 2.20.0 tinybench@2.9.0: {} @@ -26133,7 +26175,7 @@ snapshots: dependencies: is-number: 7.0.0 - tocbot@4.28.2: {} + tocbot@4.29.0: {} toggle-selection@1.0.6: {} @@ -26322,7 +26364,7 @@ snapshots: ufo@1.5.4: {} - uglify-js@3.19.1: + uglify-js@3.19.2: optional: true uint8arrays@3.1.0: @@ -26402,7 +26444,7 @@ snapshots: unpipe@1.0.0: {} - unplugin@1.12.0: + unplugin@1.12.1: dependencies: acorn: 8.12.1 chokidar: 3.6.0 @@ -26610,13 +26652,13 @@ snapshots: - utf-8-validate - zod - vite-node@2.0.3(@types/node@20.11.5)(terser@5.31.3): + vite-node@2.0.3(@types/node@20.11.5): dependencies: cac: 6.7.14 debug: 4.3.6 pathe: 1.1.2 tinyrainbow: 1.2.0 - vite: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + vite: 5.2.11(@types/node@20.11.5)(terser@5.31.6) transitivePeerDependencies: - '@types/node' - less @@ -26627,19 +26669,19 @@ snapshots: - supports-color - terser - vite-plugin-node-polyfills@0.22.0(rollup@4.20.0)(vite@5.2.11(@types/node@20.11.5)(terser@5.31.3)): + vite-plugin-node-polyfills@0.22.0(rollup@4.20.0)(vite@5.2.11(@types/node@20.11.5)): dependencies: '@rollup/plugin-inject': 5.0.5(rollup@4.20.0) node-stdlib-browser: 1.2.0 - vite: 5.2.11(@types/node@20.11.5)(terser@5.31.3) + vite: 5.2.11(@types/node@20.11.5)(terser@5.31.6) transitivePeerDependencies: - rollup - vite-size@0.0.4(@types/node@20.11.5)(terser@5.31.3)(vue@3.4.3(typescript@5.3.3)): + vite-size@0.0.4(@types/node@20.11.5)(vue@3.4.3(typescript@5.3.3)): dependencies: - '@vitejs/plugin-react': 4.2.1(vite@5.2.9(@types/node@20.11.5)(terser@5.31.3)) - '@vitejs/plugin-vue': 5.1.2(vite@5.2.9(@types/node@20.11.5)(terser@5.31.3))(vue@3.4.3(typescript@5.3.3)) - vite: 5.2.9(@types/node@20.11.5)(terser@5.31.3) + '@vitejs/plugin-react': 4.2.1(vite@5.2.9(@types/node@20.11.5)) + '@vitejs/plugin-vue': 5.1.2(vite@5.2.9(@types/node@20.11.5))(vue@3.4.3(typescript@5.3.3)) + vite: 5.2.9(@types/node@20.11.5) transitivePeerDependencies: - '@types/node' - less @@ -26651,7 +26693,7 @@ snapshots: - terser - vue - vite@5.2.11(@types/node@20.11.5)(terser@5.31.3): + vite@5.2.11(@types/node@20.11.5)(terser@5.31.6): dependencies: esbuild: 0.20.2 postcss: 8.4.41 @@ -26659,9 +26701,9 @@ snapshots: optionalDependencies: '@types/node': 20.11.5 fsevents: 2.3.3 - terser: 5.31.3 + terser: 5.31.6 - vite@5.2.9(@types/node@20.11.5)(terser@5.31.3): + vite@5.2.9(@types/node@20.11.5): dependencies: esbuild: 0.20.2 postcss: 8.4.41 @@ -26669,9 +26711,8 @@ snapshots: optionalDependencies: '@types/node': 20.11.5 fsevents: 2.3.3 - terser: 5.31.3 - vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.3): + vitest@2.0.3(@types/node@20.11.5)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)): dependencies: '@ampproject/remapping': 2.3.0 '@vitest/expect': 2.0.3 @@ -26689,8 +26730,8 @@ snapshots: tinybench: 2.9.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.2.11(@types/node@20.11.5)(terser@5.31.3) - vite-node: 2.0.3(@types/node@20.11.5)(terser@5.31.3) + vite: 5.2.11(@types/node@20.11.5)(terser@5.31.6) + vite-node: 2.0.3(@types/node@20.11.5) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 20.11.5 @@ -26767,7 +26808,7 @@ snapshots: dependencies: loose-envify: 1.4.0 - watchpack@2.4.1: + watchpack@2.4.2: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -26778,7 +26819,7 @@ snapshots: webauthn-p256@0.0.2: dependencies: - '@noble/curves': 1.4.2 + '@noble/curves': 1.5.0 '@noble/hashes': 1.4.0 webextension-polyfill@0.10.0: {}