diff --git a/package.json b/package.json index bfe435e3..325bcea4 100644 --- a/package.json +++ b/package.json @@ -74,25 +74,30 @@ }, "dependencies": { "@binance/w3w-ethereum-provider": "1.1.8-alpha.0", - "@cowprotocol/cow-sdk": "7.2.5", - "@cowprotocol/sdk-ethers-v6-adapter": "0.3.0", + "@cowprotocol/cow-sdk": "8.0.0", + "@cowprotocol/sdk-ethers-v6-adapter": "0.3.11", "@floating-ui/react": "0.27.16", "@floating-ui/react-dom": "2.1.6", "@headlessui/react": "2.2.4", - "@ledgerhq/hw-app-eth": "6.45.5", + "@ledgerhq/device-management-kit": "0.9.0", + "@ledgerhq/device-signer-kit-ethereum": "1.8.0", + "@ledgerhq/device-transport-kit-web-ble": "1.2.0", + "@ledgerhq/device-transport-kit-web-hid": "1.2.0", + "@ledgerhq/hw-app-eth": "6.46.0", "@ledgerhq/hw-transport-web-ble": "6.29.12", - "@ledgerhq/hw-transport-webhid": "6.30.1", - "@ledgerhq/hw-transport-webusb": "6.29.5", + "@ledgerhq/hw-transport-webhid": "6.30.8", + "@ledgerhq/hw-transport-webusb": "6.29.12", "@ledgerhq/types-live": "6.90.0", "@metamask/onboarding": "1.0.1", "@reduxjs/toolkit": "2.8.2", "@safe-global/safe-apps-provider": "0.18.6", "@safe-global/safe-apps-sdk": "9.1.0", - "@stakewise/v3-sdk": "4.2.2", + "@stakewise/v3-sdk": "4.2.5", "@tailwindcss/postcss": "4.1.7", "@types/react-redux": "7.1.34", - "@wagmi/connectors": "7.1.1", - "@wagmi/core": "3.2.1", + "@wagmi/connectors": "7.2.1", + "@wagmi/core": "3.4.0", + "@walletconnect/ethereum-provider": "2.21.1", "async-mutex": "0.5.0", "autoprefixer": "10.4.21", "circular-dependency-plugin": "5.2.2", @@ -105,6 +110,7 @@ "husky": "9.1.7", "js-cookie": "3.0.5", "lightweight-charts": "5.0.7", + "mipd": "0.0.7", "next": "16.2.6", "react": "19.2.3", "react-dom": "19.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0fcd34ae..1c5fc07b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,11 +16,11 @@ importers: specifier: 1.1.8-alpha.0 version: 1.1.8-alpha.0 '@cowprotocol/cow-sdk': - specifier: 7.2.5 - version: 7.2.5(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0) + specifier: 8.0.0 + version: 8.0.0(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0) '@cowprotocol/sdk-ethers-v6-adapter': - specifier: 0.3.0 - version: 0.3.0(ethers@6.14.3) + specifier: 0.3.11 + version: 0.3.11(ethers@6.14.3) '@floating-ui/react': specifier: 0.27.16 version: 0.27.16(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -30,18 +30,30 @@ importers: '@headlessui/react': specifier: 2.2.4 version: 2.2.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@ledgerhq/device-management-kit': + specifier: 0.9.0 + version: 0.9.0(rxjs@7.8.2) + '@ledgerhq/device-signer-kit-ethereum': + specifier: 1.8.0 + version: 1.8.0(@ledgerhq/context-module@1.8.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2)))(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2)) + '@ledgerhq/device-transport-kit-web-ble': + specifier: 1.2.0 + version: 1.2.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2))(rxjs@7.8.2) + '@ledgerhq/device-transport-kit-web-hid': + specifier: 1.2.0 + version: 1.2.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2))(rxjs@7.8.2) '@ledgerhq/hw-app-eth': - specifier: 6.45.5 - version: 6.45.5(react-redux@9.2.0(@types/react@19.2.3)(react@19.2.3)(redux@5.0.1)) + specifier: 6.46.0 + version: 6.46.0(react-redux@9.2.0(@types/react@19.2.3)(react@19.2.3)(redux@5.0.1)) '@ledgerhq/hw-transport-web-ble': specifier: 6.29.12 version: 6.29.12 '@ledgerhq/hw-transport-webhid': - specifier: 6.30.1 - version: 6.30.1 + specifier: 6.30.8 + version: 6.30.8 '@ledgerhq/hw-transport-webusb': - specifier: 6.29.5 - version: 6.29.5 + specifier: 6.29.12 + version: 6.29.12 '@ledgerhq/types-live': specifier: 6.90.0 version: 6.90.0 @@ -58,8 +70,8 @@ importers: specifier: 9.1.0 version: 9.1.0(typescript@5.8.3)(zod@4.3.5) '@stakewise/v3-sdk': - specifier: 4.2.2 - version: 4.2.2(ethers@6.14.3) + specifier: 4.2.5 + version: 4.2.5(ethers@6.14.3) '@tailwindcss/postcss': specifier: 4.1.7 version: 4.1.7 @@ -67,11 +79,14 @@ importers: specifier: 7.1.34 version: 7.1.34 '@wagmi/connectors': - specifier: 7.1.1 - version: 7.1.1(@safe-global/safe-apps-provider@0.18.6(typescript@5.8.3)(zod@4.3.5))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.8.3)(zod@4.3.5))(@wagmi/core@3.2.1(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)))(typescript@5.8.3)(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)) + specifier: 7.2.1 + version: 7.2.1(@safe-global/safe-apps-provider@0.18.6(typescript@5.8.3)(zod@4.3.5))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.8.3)(zod@4.3.5))(@wagmi/core@3.4.0(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)))(@walletconnect/ethereum-provider@2.21.1(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5))(typescript@5.8.3)(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)) '@wagmi/core': - specifier: 3.2.1 - version: 3.2.1(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)) + specifier: 3.4.0 + version: 3.4.0(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)) + '@walletconnect/ethereum-provider': + specifier: 2.21.1 + version: 2.21.1(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) async-mutex: specifier: 0.5.0 version: 0.5.0 @@ -108,6 +123,9 @@ importers: lightweight-charts: specifier: 5.0.7 version: 5.0.7 + mipd: + specifier: 0.0.7 + version: 0.0.7(typescript@5.8.3) next: specifier: 16.2.6 version: 16.2.6(@babel/core@7.28.5)(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.0) @@ -369,8 +387,8 @@ packages: '@cacheable/utils@2.3.3': resolution: {integrity: sha512-JsXDL70gQ+1Vc2W/KUFfkAJzgb4puKwwKehNLuB+HrNKWf91O736kGfxn4KujXCCSuh6mRRL4XEB0PkAFjWS0A==} - '@cowprotocol/cow-sdk@7.2.5': - resolution: {integrity: sha512-4yf/xZ+dRyt/OhpgRvd2n2l4e9uLdeXf7laBjVjfXhvBAwzsSTbBzzGgo/ZqXn/rxzOzrv3unCIm5ybsQe7O5g==} + '@cowprotocol/cow-sdk@8.0.0': + resolution: {integrity: sha512-vhwEedCx8mZwi1FJCO5gCM1XkoJ5OHM0sclQNZ45UnRrYic55qpAhjpDyN7jui/oxDGX5s4YtXKU+CInFKwbrw==} peerDependencies: '@openzeppelin/merkle-tree': ^1.x cross-fetch: ^3.x @@ -384,36 +402,36 @@ packages: multiformats: optional: true - '@cowprotocol/sdk-app-data@4.3.6': - resolution: {integrity: sha512-ru4h/+oeI1VHhneLX9fX1lvti87c0wcqOL92JIXbX5wGp2M/TuHETeRpwMHc70MR6iIoWgT+WRhhvJzaYpzEhQ==} + '@cowprotocol/sdk-app-data@4.6.8': + resolution: {integrity: sha512-JlHprXVhiqxU6ESBxzLsoVxjfeQi6E0jg27g6nX0t/RlrGQjgxzIe0kV+aaI932Aih5fZoIUhg6VebTab14WlQ==} peerDependencies: ajv: ^8.x cross-fetch: ^3.x ipfs-only-hash: ^4.x multiformats: ^9.x - '@cowprotocol/sdk-common@0.4.0': - resolution: {integrity: sha512-ciXiHzTzj7LKZqMKssgyNooZp1nS/mvRE9oO/6DlMQcxVA7/4ajPmk/XzseX/rjdRbSbYyXIEF1oY5w0tcbVjQ==} + '@cowprotocol/sdk-common@0.7.1': + resolution: {integrity: sha512-YnCrvNGuaE+OI6RwXQ5ZOX2ci2CZT3rLFVgSnUggAS9TmklCfK01EqAAxdzheu/vICv+1DGBuGrzcR0o/+OkJQ==} - '@cowprotocol/sdk-config@0.6.2': - resolution: {integrity: sha512-L6cPT3pQCrHChRUjWffuYielUlw7TXPbI0o3IvimF/DSpPiGuW+A1g7XSLEGUhNcoKNfQf5YUZPaoenAKl9MNg==} + '@cowprotocol/sdk-config@1.0.0': + resolution: {integrity: sha512-iS/9CA8hNA/BAtzXHMRnsmuigc0i2v4FlPiCMKHyYtLhRLFI7Yo/cogZKYL/9Mbt4GamdQeZ+nH92xl3KYyAtg==} - '@cowprotocol/sdk-contracts-ts@0.8.1': - resolution: {integrity: sha512-8yQO11S4R3mAfgKqb5afCo9c+z/sHpKiOZuN+gry46fjBKK3kUd2hKLWNYnQds5xUVJ07DlT0k7jFGgkEnremw==} + '@cowprotocol/sdk-contracts-ts@2.0.0': + resolution: {integrity: sha512-4mH5aEsouRAD9nQr03FcwayqVL89nDDchubm/bXcsz5ucOwPqfS+1aEgT1NrPBAW88KUy6GTrhTHxPbFJylu9A==} - '@cowprotocol/sdk-ethers-v6-adapter@0.3.0': - resolution: {integrity: sha512-1TXtTLB5Zi2MGbCvEB9az0fJL1RDmQOa9sohO3biQNP/crGDb6jwPv30RtR3Sr621Dy8HNrfnJFHC87klPXC2g==} + '@cowprotocol/sdk-ethers-v6-adapter@0.3.11': + resolution: {integrity: sha512-yR1UFj8F/ImrB/TuTlA5pRQUZWZ92aCQGreg4JYTeEX5Fs9o6E8/GsuT0naU1HGSP7cFZWu/mp+537OmR+fuYQ==} peerDependencies: ethers: ^6.13.7 - '@cowprotocol/sdk-order-book@0.4.4': - resolution: {integrity: sha512-iTP2Vfi9h4ACvTnRArA0s3BmJgnUnNcQfsdMva4udkLy1GwjQgju7FkcCmlUxPaPvFgGm9hz8E9yPuNMWp/xWg==} + '@cowprotocol/sdk-order-book@2.0.0': + resolution: {integrity: sha512-4mDIYQc7ro2dm7co9gMfsab1zPpElhmKuqWr6BcCQ4huJI69pzPYj7PNpToIKL7ZNemV7UeAjuu4ftZKFx7ttw==} - '@cowprotocol/sdk-order-signing@0.1.21': - resolution: {integrity: sha512-zGVlo+kybnLLUzIxgHlCRbtcPQZpxt4LEDMz/DjcaJnsZEtooUORWOY1GA4NZ7VNOjY1v513v2nMu9DpU1dIzg==} + '@cowprotocol/sdk-order-signing@0.1.38': + resolution: {integrity: sha512-Kts658oFbe516w1/LNux6hpbavjgjWx0zs6ZZJHKao/FcPKMjueorOFPfSFkfMEpeRsoUazOmaGzIJpWdjz+AA==} - '@cowprotocol/sdk-trading@0.7.1': - resolution: {integrity: sha512-SfCsV1oUjw6cpMFTGk2bIPTTt3xqJ8hPZE/4OPQ5kVUUzHa8gXiclwhae+oJqoRbM5jdDB30Bd7yYSb9Qic+sw==} + '@cowprotocol/sdk-trading@1.0.4': + resolution: {integrity: sha512-DhS06tDpFHSoq1MlkcXmW9cdMK9pkfuxyLbvCFwjoqx2uUxX1l6MGIWwWR/sQkiWK4bDJCxEBHX80L3G4MkLqA==} '@csstools/css-parser-algorithms@3.0.5': resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} @@ -883,6 +901,25 @@ packages: cpu: [x64] os: [win32] + '@inversifyjs/common@1.5.0': + resolution: {integrity: sha512-Qj5BELk11AfI2rgZEAaLPmOftmQRLLmoCXgAjmaF0IngQN5vHomVT5ML7DZ3+CA5fgGcEVMcGbUDAun+Rz+oNg==} + + '@inversifyjs/container@1.9.1': + resolution: {integrity: sha512-8EhjFoAx1LoD7TpCuP9ptitwc+7kVXEpZB0IeoEsCQb9sWaNYYaBi+7Lommu3/1nYxdMbX2t7AJhQnryT1EEsg==} + peerDependencies: + reflect-metadata: ~0.2.2 + + '@inversifyjs/core@5.2.0': + resolution: {integrity: sha512-MMaHGGRjQWT9uAof63sbZyEhRl4XptEAE17DJwrgUcN9LsdIEvecKP3r53pE9VF88PFR41knUKKzagUBvWLHmw==} + + '@inversifyjs/prototype-utils@0.1.0': + resolution: {integrity: sha512-lNz1yyajMRDXBHLvJsYYX81FcmeD15e5Qz1zAZ/3zeYTl+u7ZF/GxNRKJzNOloeMPMtuR8BnvzHA1SZxjR+J9w==} + + '@inversifyjs/reflect-metadata-utils@1.1.0': + resolution: {integrity: sha512-jmuAuC3eL1GnFAYfJGJOMKRDL9q1mgzOyrban6zxfM8Yg1FUHsj25h27bW2G7p8X1Amvhg3MLkaOuogszkrofA==} + peerDependencies: + reflect-metadata: 0.2.2 + '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -938,11 +975,36 @@ packages: '@ledgerhq/client-ids@0.2.1': resolution: {integrity: sha512-IjXJuqoGv2lfTB8QgSMpRDt+C2iOFmvIBxZDHs5XAEEPm1yNsgIB5m+HuzECk/Qll7FyB9My13ueayn7dBZxUQ==} + '@ledgerhq/context-module@1.8.0': + resolution: {integrity: sha512-lsKjhGbSQbyRGhGpoj9QrBM9WEzbFhuMvZirEIBqHBpAfv7GXUECfOsVgaPPnrUa/cDJhvudmCHQlHWId7unMw==} + peerDependencies: + '@ledgerhq/device-management-kit': ^0.9.0 + '@ledgerhq/cryptoassets-evm-signatures@13.7.1': resolution: {integrity: sha512-ehLn62L15fOlTH6u5D1eV1d4/QIju6aaUKWy7CpVLSiRmkWEBaORhOL/l9TvBrRIvNLHVBQEhiBaJcJ4hGrlEw==} - '@ledgerhq/devices@8.4.5': - resolution: {integrity: sha512-wzfX7JRfTPXJl+4BUXxwUFUGghtqQA6V1I6xNxGfXKHjd51rjijL+9xcfZ1oj66dNNm9wiCBBZhMXXusYDUjWg==} + '@ledgerhq/device-management-kit@0.9.0': + resolution: {integrity: sha512-zWcQ0TOerZU4tvBdHd7RWpmYB+nVN3aTZ/hHz5IVnESEmQa2m4YsmOb2vm55k3tvyc5yRW/sOqX83Bnr+y+G+w==} + peerDependencies: + rxjs: 7.8.2 + + '@ledgerhq/device-signer-kit-ethereum@1.8.0': + resolution: {integrity: sha512-rhnjD3R0lhW/ksNcnoFbJStaMVgNkkuoBRzgG2addVab9CxsUE+F/OEZjLc65wt9x5VLyVEMPW/EqXJ5Xglp6Q==} + peerDependencies: + '@ledgerhq/context-module': 1.8.0 + '@ledgerhq/device-management-kit': ^0.9.0 + + '@ledgerhq/device-transport-kit-web-ble@1.2.0': + resolution: {integrity: sha512-tZfMK/xuxQB606sshDjg+b7QVI4GzTqP3yKk/w5SF+mb9ED8jq9nhRohJNJa34NiRQVauGoJsqO9mk5rZ2K/WQ==} + peerDependencies: + '@ledgerhq/device-management-kit': 0.9.0 + rxjs: 7.8.2 + + '@ledgerhq/device-transport-kit-web-hid@1.2.0': + resolution: {integrity: sha512-51kLHqrn1dP+0ZQLRyUBHIPSBNvx74hiIAMHrBkiCAedpmND/W522nslpX42bVf3tU3+I0Y51qn3WFvd8ZtIow==} + peerDependencies: + '@ledgerhq/device-management-kit': 0.8.0 + rxjs: ^7.8.2 '@ledgerhq/devices@8.6.1': resolution: {integrity: sha512-PQR2fyWz7P/wMFHY9ZLz17WgFdxC/Im0RVDcWXpp24+iRQRyxhQeX2iG4mBKUzfaAW6pOIEiWt+vmJh88QP9rQ==} @@ -959,8 +1021,8 @@ packages: '@ledgerhq/evm-tools@1.9.0': resolution: {integrity: sha512-5UjdmnH4DGia8eJE4f5szVLYzBwFIvZyf+xoHKWLaJh8rCEXeEENmvPwbTUDuQ/LRPgfOF6+WVR8pS9LlcTRNw==} - '@ledgerhq/hw-app-eth@6.45.5': - resolution: {integrity: sha512-KN0ZDLuG/PqFuusyynuFvO02keciwuJcFJRTnwCc0IYBRfuOGXkNOYHjecQ6XrLcuwQjDYrA2zCEEuM7FJcmMQ==} + '@ledgerhq/hw-app-eth@6.46.0': + resolution: {integrity: sha512-9kJsm8Mzw5f8MwiMv/f98QalPkC371zjOGui7cKYRvgr9pgqkYoy+C/1UILxf4fuPVeAG79+YSgB6Qs55Thu/w==} '@ledgerhq/hw-transport-mocker@6.30.0': resolution: {integrity: sha512-WsnjNMpDah+JtUhAKOUT480ljN//3OJ+yxPSyg1Ue6QfcD3S5TQiXaCY/bTyCStoQXOYQN3qehXD1NFuw7gfYQ==} @@ -968,11 +1030,11 @@ packages: '@ledgerhq/hw-transport-web-ble@6.29.12': resolution: {integrity: sha512-4twe/cYYEK3z+PhCrXeTbZAWy2FJYckmZh8CuCqn7IJ/PXjey/HDXyby7AzkwmX9bcpVyzEkXHYlYuHe+ex/Bg==} - '@ledgerhq/hw-transport-webhid@6.30.1': - resolution: {integrity: sha512-1lBXfNOhtQNeS6kiBBbknlzN/DAOQheCPkVUBxZZyfO8057H53o1h8hyrRLz04wQoon+AXa4uZ16xBnsjUiKZA==} + '@ledgerhq/hw-transport-webhid@6.30.8': + resolution: {integrity: sha512-2Hc15GjC7BFrpMVJYJ7N2p70A6OzIdcMklwUEYpOcIVYbEWWj84+M5E5pc83ZIBc5j3C8rdtjncPCm2ExGx2LQ==} - '@ledgerhq/hw-transport-webusb@6.29.5': - resolution: {integrity: sha512-yIX38VVXEYnwGD3ZkXBALNODjZljCy4mckdIHs1qzkesbAM9zA8l4cTaidq1wa4r+sNWBR27yCBDbF7q+3qlzA==} + '@ledgerhq/hw-transport-webusb@6.29.12': + resolution: {integrity: sha512-mMGKPYAUz9MNcURe+hSTSHwqPwCli6D0lCl15Z4hDOpcqhZ26vwoeWVKeQp53NNCetHOl0lauPkN43Gt9pIggg==} '@ledgerhq/hw-transport@6.31.15': resolution: {integrity: sha512-I+hzH9XGFPaYq9K+iw+qWJUyVdhN9fdO00Df9zAkOCzju1W5Gc+cDJxbYnZApmY8oMd8mNoXTstEW3Ih5ikaVg==} @@ -983,12 +1045,23 @@ packages: '@ledgerhq/logs@6.13.0': resolution: {integrity: sha512-4+qRW2Pc8V+btL0QEmdB2X+uyx0kOWMWE1/LWsq5sZy3Q5tpi4eItJS6mB0XL3wGW59RQ+8bchNQQ1OW/va8Og==} + '@ledgerhq/signer-utils@1.2.0': + resolution: {integrity: sha512-Ek4/NXGt6gfiZUmiAFE19534f8wnlQSHvZMsjmqCEktbJd/mYbzvTrvYeo0+PQPw2D/kTYD1fRC6ADKQRSBeGw==} + peerDependencies: + '@ledgerhq/device-management-kit': ^1.2.0 + '@ledgerhq/types-live@6.90.0': resolution: {integrity: sha512-F+YyfE0HZoqc8HkaJXEHhMjU4JX6eHzCfXKmJH/MHiymrqg8tOa+c07mWIlvspf5jcpswRM3r1k81y2A8q/aWw==} '@ledgerhq/types-live@6.91.1': resolution: {integrity: sha512-Bp1m286STiDErEv/OF5BgBVniH+EoTzPxIFmmlKfH8c0RUg/5sd/yYkh+Y/t9qT5DmmUbg8jE3w2Q8rjTNZ1xQ==} + '@lit-labs/ssr-dom-shim@1.6.0': + resolution: {integrity: sha512-VHb0ALPMTlgKjM6yIxxoQNnpKyUKLD04VzeQdsiXkMqkvYlAHxq9glGLmgbb889/1GsohSOAjvQYoiBppXFqrQ==} + + '@lit/reactive-element@2.1.2': + resolution: {integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==} + '@metamask/onboarding@1.0.1': resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} @@ -1056,6 +1129,10 @@ packages: cpu: [x64] os: [win32] + '@noble/ciphers@1.2.1': + resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + engines: {node: ^14.21.3 || >=16} + '@noble/ciphers@1.3.0': resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} engines: {node: ^14.21.3 || >=16} @@ -1063,6 +1140,14 @@ packages: '@noble/curves@1.2.0': resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.9.1': resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} engines: {node: ^14.21.3 || >=16} @@ -1071,6 +1156,14 @@ packages: resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} engines: {node: '>= 16'} + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + '@noble/hashes@1.8.0': resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} @@ -1263,6 +1356,35 @@ packages: react-redux: optional: true + '@reown/appkit-common@1.7.8': + resolution: {integrity: sha512-ridIhc/x6JOp7KbDdwGKY4zwf8/iK8EYBl+HtWrruutSLwZyVi5P8WaZa+8iajL6LcDcDF7LoyLwMTym7SRuwQ==} + + '@reown/appkit-controllers@1.7.8': + resolution: {integrity: sha512-IdXlJlivrlj6m63VsGLsjtPHHsTWvKGVzWIP1fXZHVqmK+rZCBDjCi9j267Rb9/nYRGHWBtlFQhO8dK35WfeDA==} + + '@reown/appkit-pay@1.7.8': + resolution: {integrity: sha512-OSGQ+QJkXx0FEEjlpQqIhT8zGJKOoHzVnyy/0QFrl3WrQTjCzg0L6+i91Ad5Iy1zb6V5JjqtfIFpRVRWN4M3pw==} + + '@reown/appkit-polyfills@1.7.8': + resolution: {integrity: sha512-W/kq786dcHHAuJ3IV2prRLEgD/2iOey4ueMHf1sIFjhhCGMynMkhsOhQMUH0tzodPqUgAC494z4bpIDYjwWXaA==} + + '@reown/appkit-scaffold-ui@1.7.8': + resolution: {integrity: sha512-RCeHhAwOrIgcvHwYlNWMcIDibdI91waaoEYBGw71inE0kDB8uZbE7tE6DAXJmDkvl0qPh+DqlC4QbJLF1FVYdQ==} + + '@reown/appkit-ui@1.7.8': + resolution: {integrity: sha512-1hjCKjf6FLMFzrulhl0Y9Vb9Fu4royE+SXCPSWh4VhZhWqlzUFc7kutnZKx8XZFVQH4pbBvY62SpRC93gqoHow==} + + '@reown/appkit-utils@1.7.8': + resolution: {integrity: sha512-8X7UvmE8GiaoitCwNoB86pttHgQtzy4ryHZM9kQpvjQ0ULpiER44t1qpVLXNM4X35O0v18W0Dk60DnYRMH2WRw==} + peerDependencies: + valtio: 1.13.2 + + '@reown/appkit-wallet@1.7.8': + resolution: {integrity: sha512-kspz32EwHIOT/eg/ZQbFPxgXq0B/olDOj3YMu7gvLEFz4xyOFd/wgzxxAXkp5LbG4Cp++s/elh79rVNmVFdB9A==} + + '@reown/appkit@1.7.8': + resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==} + '@rollup/rollup-android-arm-eabi@4.60.3': resolution: {integrity: sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==} cpu: [arm] @@ -1404,21 +1526,43 @@ packages: '@scure/base@1.2.6': resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + '@scure/bip32@1.7.0': resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + '@scure/bip39@1.6.0': resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@sentry/hub@6.19.7': + resolution: {integrity: sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==} + engines: {node: '>=6'} + + '@sentry/minimal@6.19.7': + resolution: {integrity: sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==} + engines: {node: '>=6'} + + '@sentry/types@6.19.7': + resolution: {integrity: sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==} + engines: {node: '>=6'} + + '@sentry/utils@6.19.7': + resolution: {integrity: sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==} + engines: {node: '>=6'} + '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@stakewise/v3-sdk@4.2.2': - resolution: {integrity: sha512-90b12PO4xhYDVwsQ7JRUwfbSOnfq5pp9HuawyiTatSm2tTz2P35ka8y28OJnHQtPBa4Khh5LusxmdMHzw07QaA==} + '@stakewise/v3-sdk@4.2.5': + resolution: {integrity: sha512-SpOfBwcO2ultfetyzpqf5zzrNNMZwQKsiAywMZe7Z+chRAubGGnNnTlVPIGlHgJZwnVUBgV74r2Zg5tV9HFGtQ==} peerDependencies: ethers: ^6.14.3 @@ -1612,6 +1756,9 @@ packages: '@types/react@19.2.3': resolution: {integrity: sha512-k5dJVszUiNr1DSe8Cs+knKR6IrqhqdhpUwzqhkS8ecQTSf3THNtbfIp/umqHMpX2bv+9dkx3fwDv/86LcSfvSg==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/ua-parser-js@0.7.39': resolution: {integrity: sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==} @@ -1785,16 +1932,15 @@ packages: cpu: [x64] os: [win32] - '@wagmi/connectors@7.1.1': - resolution: {integrity: sha512-rkYapSMFeBzZTs7nul1O7UCFMZ/pWIwBTYDJnTGTX2vG0pe3FGZ+SNPgSFL7enLQzZdcif3+9pt7pUJAzJogVw==} + '@wagmi/connectors@7.2.1': + resolution: {integrity: sha512-/tyDepUMDM8eNzNX3ofjqHNRFZ6XcZ3u0+cQp5x0/LHCpMA8tRh7A1/e7dTrYiIJeL7iLgHzfHUXCsU02OKMLQ==} peerDependencies: '@base-org/account': ^2.5.1 '@coinbase/wallet-sdk': ^4.3.6 - '@gemini-wallet/core': ~0.3.1 '@metamask/sdk': ~0.33.1 '@safe-global/safe-apps-provider': ~0.18.6 '@safe-global/safe-apps-sdk': ^9.1.0 - '@wagmi/core': 3.2.1 + '@wagmi/core': 3.4.0 '@walletconnect/ethereum-provider': ^2.21.1 porto: ~0.2.35 typescript: '>=5.7.3' @@ -1804,8 +1950,6 @@ packages: optional: true '@coinbase/wallet-sdk': optional: true - '@gemini-wallet/core': - optional: true '@metamask/sdk': optional: true '@safe-global/safe-apps-provider': @@ -1819,8 +1963,8 @@ packages: typescript: optional: true - '@wagmi/core@3.2.1': - resolution: {integrity: sha512-XfWCVjwQwawJuQDChKECnh+9jFHbTbdEEZzzsX7hNHaNmIttsB0xMwMPSlmS759W8hexgkywM4N8dfo8dj6RAQ==} + '@wagmi/core@3.4.0': + resolution: {integrity: sha512-EU5gDsUp5t7+cuLv12/L8hfyWfCIKsBNiiBqpOqxZJxvAcAiQk4xFe2jMgaQPqApc3Omvxrk032M8AQ4N0cQeg==} peerDependencies: '@tanstack/query-core': '>=5.0.0' ox: '>=0.11.1' @@ -1834,6 +1978,99 @@ packages: typescript: optional: true + '@walletconnect/core@2.21.0': + resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==} + engines: {node: '>=18'} + + '@walletconnect/core@2.21.1': + resolution: {integrity: sha512-Tp4MHJYcdWD846PH//2r+Mu4wz1/ZU/fr9av1UWFiaYQ2t2TPLDiZxjLw54AAEpMqlEHemwCgiRiAmjR1NDdTQ==} + engines: {node: '>=18'} + + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + + '@walletconnect/ethereum-provider@2.21.1': + resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.2': + resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} + + '@walletconnect/jsonrpc-http-connection@1.0.8': + resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==} + + '@walletconnect/jsonrpc-provider@1.0.14': + resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.2': + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.21.0': + resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/sign-client@2.21.1': + resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.21.0': + resolution: {integrity: sha512-ll+9upzqt95ZBWcfkOszXZkfnpbJJ2CmxMfGgE5GmhdxxxCcO5bGhXkI+x8OpiS555RJ/v/sXJYMSOLkmu4fFw==} + + '@walletconnect/types@2.21.1': + resolution: {integrity: sha512-UeefNadqP6IyfwWC1Yi7ux+ljbP2R66PLfDrDm8izmvlPmYlqRerJWJvYO4t0Vvr9wrG4Ko7E0c4M7FaPKT/sQ==} + + '@walletconnect/universal-provider@2.21.0': + resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/universal-provider@2.21.1': + resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/utils@2.21.0': + resolution: {integrity: sha512-zfHLiUoBrQ8rP57HTPXW7rQMnYxYI4gT9yTACxVW6LhIFROTF6/ytm5SKNoIvi4a5nX5dfXG4D9XwQUCu8Ilig==} + + '@walletconnect/utils@2.21.1': + resolution: {integrity: sha512-VPZvTcrNQCkbGOjFRbC24mm/pzbRMUq2DSQoiHlhh0X1U7ZhuIrzVtAoKsrzu6rqjz0EEtGxCr3K1TGRqDG4NA==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -1885,6 +2122,17 @@ packages: '@xtuc/long@4.2.2': resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abitype@1.2.3: resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} peerDependencies: @@ -2085,6 +2333,10 @@ packages: engines: {node: '>= 4.5.0'} hasBin: true + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + autoprefixer@10.4.21: resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} engines: {node: ^10 || ^12 || >=14} @@ -2107,14 +2359,17 @@ packages: axios@0.21.4: resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + axios@1.11.0: + resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} + axios@1.12.2: resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} axios@1.13.2: resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} - axios@1.7.7: - resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + axios@1.8.2: + resolution: {integrity: sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -2129,6 +2384,9 @@ packages: balanced-match@2.0.0: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -2148,6 +2406,9 @@ packages: big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + bignumber.js@9.3.0: resolution: {integrity: sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==} @@ -2195,6 +2456,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -2307,6 +2571,10 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + chownr@3.0.0: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} @@ -2415,6 +2683,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + copy-descriptor@0.1.1: resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} engines: {node: '>=0.10.0'} @@ -2444,6 +2715,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} @@ -2556,6 +2830,9 @@ packages: resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} engines: {node: '>=0.10.0'} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + degit@2.8.4: resolution: {integrity: sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng==} engines: {node: '>=8.0.0'} @@ -2565,9 +2842,20 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + derive-valtio@0.1.0: + resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} + peerDependencies: + valtio: '*' + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + destyle.css@4.0.1: resolution: {integrity: sha512-G9iyW0JfRkgdxhbWQeuLdO1KZ40nzKssHtArbSFvaU/w44G0cZ5v3u4bHY829INSu480J/fxae+lTm225mN3Vw==} + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + detect-europe-js@0.1.2: resolution: {integrity: sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow==} @@ -2623,6 +2911,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + eip1193-provider@1.0.1: resolution: {integrity: sha512-kSuqwQ26d7CzuS/t3yRXo2Su2cVH0QfvyKbr2H7Be7O5YDyIq4hQGCNTo5wRdP07bt+E2R/8nPCzey4ojBHf7g==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. @@ -2649,6 +2940,12 @@ packages: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + enhanced-resolve@5.18.4: resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} engines: {node: '>=10.13.0'} @@ -2659,10 +2956,6 @@ packages: entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - entities@4.3.0: - resolution: {integrity: sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==} - engines: {node: '>=0.12'} - env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -2708,6 +3001,9 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + es-toolkit@1.33.0: + resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==} + esbuild@0.24.2: resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} engines: {node: '>=18'} @@ -2854,6 +3150,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + ethers@6.14.1: + resolution: {integrity: sha512-JnFiPFi3sK2Z6y7jZ3qrafDMwiXmU+6cNZ0M+kPq+mTy9skqEzwqAdFW3nb/em2xjlIVXX6Lz8ID6i3LmS4+fQ==} + engines: {node: '>=14.0.0'} + ethers@6.14.3: resolution: {integrity: sha512-qq7ft/oCJohoTcsNPFaXSQUm457MA5iWqkf1Mb11ujONdg7jBI6sAOrHaTi3j0CBqIGFSCeR/RMc+qwRRub7IA==} engines: {node: '>=14.0.0'} @@ -2919,6 +3219,10 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} @@ -2967,6 +3271,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + find-replace@3.0.0: resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} engines: {node: '>=4.0.0'} @@ -3169,6 +3477,9 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + hamt-sharding@2.0.1: resolution: {integrity: sha512-vnjrmdXG9dDs1m/H4iJ6z0JFI2NtgsW5keRkTcM85NGak69Mkf5PHUqBz+Xs0T4sg0ppvj9O5EGAJo40FTxmmA==} engines: {node: '>=10.0.0', npm: '>=6.0.0'} @@ -3273,6 +3584,9 @@ packages: engines: {node: '>=18'} hasBin: true + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -3339,6 +3653,11 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + inversify@7.5.1: + resolution: {integrity: sha512-oWWFDU2BXiuqZynGcLDDD4tqiWAeaEUCALlCj0vk/QwHGgZY/tzDFPuTmWMY3jwRmDIHxVDkcj9SL3MFTlCEDw==} + peerDependencies: + reflect-metadata: ~0.2.2 + ipfs-only-hash@4.0.0: resolution: {integrity: sha512-TE1DZCvfw8i3gcsTq3P4TFx3cKFJ3sluu/J3XINkJhIN9OwJgNMqKA+WnKx6ByCb1IoPXsTp1KM7tupElb6SyA==} hasBin: true @@ -3356,6 +3675,9 @@ packages: engines: {node: '>=6.0.0', npm: '>=3.0.0'} deprecated: This module has been superseded by @ipld/dag-pb and multiformats + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + is-accessor-descriptor@1.0.1: resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} engines: {node: '>= 0.10'} @@ -3603,6 +3925,16 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + isows@1.0.7: resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} peerDependencies: @@ -3624,9 +3956,6 @@ packages: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} - jest-sonar@0.2.16: - resolution: {integrity: sha512-ES6Z9BbIVDELtbz+/b6pv41B2qOfp38cQpoCLqei21FtlkG/GzhyQ0M3egEIM+erpJOkpRKM8Tc8/YQtHdiTXA==} - jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} @@ -3840,6 +4169,15 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lit-element@4.2.2: + resolution: {integrity: sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==} + + lit-html@3.3.3: + resolution: {integrity: sha512-el8M6jK2o3RXBnrSHX3ZKrsN8zEV63pSExTO1wYJz7QndGYZ8353e2a5PPX+qHe2aGayfnchQmkAojaWAREOIA==} + + lit@3.3.0: + resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} + load-json-file@4.0.0: resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} engines: {node: '>=4'} @@ -3901,6 +4239,10 @@ packages: resolution: {integrity: sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==} engines: {node: '>=0.10.0'} + lru-cache@11.4.0: + resolution: {integrity: sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -4133,6 +4475,9 @@ packages: node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -4146,6 +4491,9 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} @@ -4222,6 +4570,12 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -4241,6 +4595,14 @@ packages: typescript: optional: true + ox@0.6.7: + resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} engines: {node: '>=4'} @@ -4356,6 +4718,16 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -4535,6 +4907,9 @@ packages: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -4546,13 +4921,22 @@ packages: resolution: {integrity: sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==} hasBin: true + proxy-compare@2.6.0: + resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + purify-ts@2.1.0: + resolution: {integrity: sha512-+KNUHV9FxB9BbjadFdvxa+LNJIaqZmSF7CQH5Rv6+f0rBzsxm9FEqrvkALQbWYJobAja2ZCbBDUY7O4fH2znMA==} + qified@0.5.3: resolution: {integrity: sha512-kXuQdQTB6oN3KhI6V4acnBSZx8D2I4xzZvn9+wFLLFCoBNQY/sFnCW6c43OL7pOQ2HvGV4lnWIXNmgfp7cTWhQ==} engines: {node: '>=20'} @@ -4562,14 +4946,30 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + qrcode@1.5.4: resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} engines: {node: '>=10.13.0'} hasBin: true + qs@6.15.2: + resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} + engines: {node: '>=0.6'} + + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + quick-lru@1.1.0: resolution: {integrity: sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==} engines: {node: '>=4'} @@ -4582,6 +4982,9 @@ packages: resolution: {integrity: sha512-uWgQTo7pim1Rnj5TuWcCewRDTf0PEFTSlaUjWP4eY9EbLV9em08v89oCz/WO+wRxpYuO36XEHp4wgYQnAgOHzA==} hasBin: true + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -4658,6 +5061,14 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + redent@2.0.0: resolution: {integrity: sha512-XNwrTx77JQCEMXTeb8movBKuK75MgH0RZkujNuDKCezemx/voapl9i2gCSi8WWm8+ox5ycJi1gxF22fR7c0Ciw==} engines: {node: '>=4'} @@ -4681,6 +5092,9 @@ packages: redux@5.0.1: resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -4801,6 +5215,10 @@ packages: safe-regex@1.1.0: resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + sass-loader@16.0.5: resolution: {integrity: sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==} engines: {node: '>= 18.12.0'} @@ -4849,6 +5267,11 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} @@ -4946,6 +5369,9 @@ packages: resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} engines: {node: '>=0.10.0'} + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -4993,10 +5419,18 @@ packages: resolution: {integrity: sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==} hasBin: true + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + split-string@3.1.0: resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} engines: {node: '>=0.10.0'} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -5022,6 +5456,13 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + string-format@2.0.0: resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} @@ -5242,6 +5683,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} @@ -5314,6 +5758,9 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} @@ -5409,9 +5856,15 @@ packages: resolution: {integrity: sha512-LZyXZdNttONW8LjzEH3Z8+6TE7RfrEiJqDKyh0R11p/kxvrV2o9DrT2FGZO+KVNs3k+drcIQ6C3En6wLnzJGpw==} hasBin: true + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + uint8arrays@2.1.10: resolution: {integrity: sha512-Q9/hhJa2836nQfEJSZTmr+pg9+cDJS9XEAp7N2Vg5MzL3bK/mkMVfjscRGYruP9jNda6MAdf4QD/y78gSzkp6A==} + uint8arrays@3.1.0: + resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==} + uint8arrays@3.1.1: resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} @@ -5419,6 +5872,9 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -5477,6 +5933,68 @@ packages: resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} engines: {node: '>=0.10.0'} + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -5490,6 +6008,15 @@ packages: resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} deprecated: Please see https://github.com/lydell/urix#deprecated + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: @@ -5506,13 +6033,30 @@ packages: resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} engines: {node: '>= 4'} + uuid@11.0.3: + resolution: {integrity: sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==} + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + valtio@1.13.2: + resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + varint@5.0.2: resolution: {integrity: sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==} @@ -5531,6 +6075,14 @@ packages: vfile@3.0.1: resolution: {integrity: sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==} + viem@2.23.2: + resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + viem@2.44.1: resolution: {integrity: sha512-wfQda7PIJeF9hWiGKV628AfBwyYxyoc89OcgF4s4/chs2PY8ibUA7IG+DWdU4oAkjhHm9w47w1m2dwwOPBU+ng==} peerDependencies: @@ -5656,6 +6208,18 @@ packages: utf-8-validate: optional: true + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.18.3: resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} @@ -5688,6 +6252,9 @@ packages: engines: {node: '>=0.8'} hasBin: true + xstate@5.19.2: + resolution: {integrity: sha512-B8fL2aP0ogn5aviAXFzI5oZseAMqN00fg/TeDa3ZtatyDcViYLIfuQl4y8qmHCiKZgGEzmnTyNtNQL9oeJE2gw==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -5746,6 +6313,9 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + zod@4.3.5: resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} @@ -5982,15 +6552,15 @@ snapshots: hashery: 1.4.0 keyv: 5.5.5 - '@cowprotocol/cow-sdk@7.2.5(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0)': + '@cowprotocol/cow-sdk@8.0.0(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0)': dependencies: - '@cowprotocol/sdk-app-data': 4.3.6(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0) - '@cowprotocol/sdk-common': 0.4.0 - '@cowprotocol/sdk-config': 0.6.2 - '@cowprotocol/sdk-contracts-ts': 0.8.1 - '@cowprotocol/sdk-order-book': 0.4.4 - '@cowprotocol/sdk-order-signing': 0.1.21 - '@cowprotocol/sdk-trading': 0.7.1(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0) + '@cowprotocol/sdk-app-data': 4.6.8(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0) + '@cowprotocol/sdk-common': 0.7.1 + '@cowprotocol/sdk-config': 1.0.0 + '@cowprotocol/sdk-contracts-ts': 2.0.0 + '@cowprotocol/sdk-order-book': 2.0.0 + '@cowprotocol/sdk-order-signing': 0.1.38 + '@cowprotocol/sdk-trading': 1.0.4(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0) cross-fetch: 3.2.0 optionalDependencies: ipfs-only-hash: 4.0.0 @@ -5999,59 +6569,61 @@ snapshots: - ajv - encoding - '@cowprotocol/sdk-app-data@4.3.6(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0)': + '@cowprotocol/sdk-app-data@4.6.8(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0)': dependencies: - '@cowprotocol/sdk-common': 0.4.0 + '@cowprotocol/sdk-common': 0.7.1 ajv: 8.17.1 cross-fetch: 3.2.0 ipfs-only-hash: 4.0.0 json-stringify-deterministic: 1.0.12 multiformats: 9.9.0 - '@cowprotocol/sdk-common@0.4.0': {} + '@cowprotocol/sdk-common@0.7.1': + dependencies: + '@cowprotocol/sdk-config': 1.0.0 - '@cowprotocol/sdk-config@0.6.2': + '@cowprotocol/sdk-config@1.0.0': dependencies: exponential-backoff: 3.1.3 limiter: 2.1.0 - '@cowprotocol/sdk-contracts-ts@0.8.1': + '@cowprotocol/sdk-contracts-ts@2.0.0': dependencies: - '@cowprotocol/sdk-common': 0.4.0 - '@cowprotocol/sdk-config': 0.6.2 + '@cowprotocol/sdk-common': 0.7.1 + '@cowprotocol/sdk-config': 1.0.0 - '@cowprotocol/sdk-ethers-v6-adapter@0.3.0(ethers@6.14.3)': + '@cowprotocol/sdk-ethers-v6-adapter@0.3.11(ethers@6.14.3)': dependencies: - '@cowprotocol/sdk-common': 0.4.0 + '@cowprotocol/sdk-common': 0.7.1 ethers: 6.14.3 - '@cowprotocol/sdk-order-book@0.4.4': + '@cowprotocol/sdk-order-book@2.0.0': dependencies: - '@cowprotocol/sdk-common': 0.4.0 - '@cowprotocol/sdk-config': 0.6.2 + '@cowprotocol/sdk-common': 0.7.1 + '@cowprotocol/sdk-config': 1.0.0 cross-fetch: 3.2.0 exponential-backoff: 3.1.3 limiter: 3.0.0 transitivePeerDependencies: - encoding - '@cowprotocol/sdk-order-signing@0.1.21': + '@cowprotocol/sdk-order-signing@0.1.38': dependencies: - '@cowprotocol/sdk-common': 0.4.0 - '@cowprotocol/sdk-config': 0.6.2 - '@cowprotocol/sdk-contracts-ts': 0.8.1 - '@cowprotocol/sdk-order-book': 0.4.4 + '@cowprotocol/sdk-common': 0.7.1 + '@cowprotocol/sdk-config': 1.0.0 + '@cowprotocol/sdk-contracts-ts': 2.0.0 + '@cowprotocol/sdk-order-book': 2.0.0 transitivePeerDependencies: - encoding - '@cowprotocol/sdk-trading@0.7.1(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0)': + '@cowprotocol/sdk-trading@1.0.4(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0)': dependencies: - '@cowprotocol/sdk-app-data': 4.3.6(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0) - '@cowprotocol/sdk-common': 0.4.0 - '@cowprotocol/sdk-config': 0.6.2 - '@cowprotocol/sdk-contracts-ts': 0.8.1 - '@cowprotocol/sdk-order-book': 0.4.4 - '@cowprotocol/sdk-order-signing': 0.1.21 + '@cowprotocol/sdk-app-data': 4.6.8(ajv@8.17.1)(cross-fetch@3.2.0)(ipfs-only-hash@4.0.0)(multiformats@9.9.0) + '@cowprotocol/sdk-common': 0.7.1 + '@cowprotocol/sdk-config': 1.0.0 + '@cowprotocol/sdk-contracts-ts': 2.0.0 + '@cowprotocol/sdk-order-book': 2.0.0 + '@cowprotocol/sdk-order-signing': 0.1.38 deepmerge: 4.3.1 transitivePeerDependencies: - ajv @@ -6490,6 +7062,31 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true + '@inversifyjs/common@1.5.0': {} + + '@inversifyjs/container@1.9.1(reflect-metadata@0.2.2)': + dependencies: + '@inversifyjs/common': 1.5.0 + '@inversifyjs/core': 5.2.0(reflect-metadata@0.2.2) + '@inversifyjs/reflect-metadata-utils': 1.1.0(reflect-metadata@0.2.2) + reflect-metadata: 0.2.2 + + '@inversifyjs/core@5.2.0(reflect-metadata@0.2.2)': + dependencies: + '@inversifyjs/common': 1.5.0 + '@inversifyjs/prototype-utils': 0.1.0 + '@inversifyjs/reflect-metadata-utils': 1.1.0(reflect-metadata@0.2.2) + transitivePeerDependencies: + - reflect-metadata + + '@inversifyjs/prototype-utils@0.1.0': + dependencies: + '@inversifyjs/common': 1.5.0 + + '@inversifyjs/reflect-metadata-utils@1.1.0(reflect-metadata@0.2.2)': + dependencies: + reflect-metadata: 0.2.2 + '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.0': @@ -6561,19 +7158,76 @@ snapshots: - react - react-redux - '@ledgerhq/cryptoassets-evm-signatures@13.7.1': + '@ledgerhq/context-module@1.8.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2))': dependencies: - '@ledgerhq/live-env': 2.23.0 - axios: 1.12.2 + '@ledgerhq/device-management-kit': 0.9.0(rxjs@7.8.2) + axios: 1.8.2 + crypto-js: 4.2.0 + ethers: 6.14.1 + inversify: 7.5.1(reflect-metadata@0.2.2) + purify-ts: 2.1.0 + reflect-metadata: 0.2.2 transitivePeerDependencies: + - bufferutil - debug + - utf-8-validate - '@ledgerhq/devices@8.4.5': + '@ledgerhq/cryptoassets-evm-signatures@13.7.1': dependencies: - '@ledgerhq/errors': 6.28.0 - '@ledgerhq/logs': 6.13.0 + '@ledgerhq/live-env': 2.23.0 + axios: 1.12.2 + transitivePeerDependencies: + - debug + + '@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2)': + dependencies: + '@sentry/minimal': 6.19.7 + axios: 1.8.2 + inversify: 7.5.1(reflect-metadata@0.2.2) + isomorphic-ws: 5.0.0(ws@8.19.0) + purify-ts: 2.1.0 + reflect-metadata: 0.2.2 rxjs: 7.8.2 - semver: 7.7.3 + semver: 7.7.2 + url: 0.11.4 + uuid: 11.0.3 + ws: 8.19.0 + xstate: 5.19.2 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@ledgerhq/device-signer-kit-ethereum@1.8.0(@ledgerhq/context-module@1.8.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2)))(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2))': + dependencies: + '@ledgerhq/context-module': 1.8.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2)) + '@ledgerhq/device-management-kit': 0.9.0(rxjs@7.8.2) + '@ledgerhq/signer-utils': 1.2.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2)) + ethers: 6.14.1 + inversify: 7.5.1(reflect-metadata@0.2.2) + purify-ts: 2.1.0 + reflect-metadata: 0.2.2 + semver: 7.7.2 + xstate: 5.19.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ledgerhq/device-transport-kit-web-ble@1.2.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2))(rxjs@7.8.2)': + dependencies: + '@ledgerhq/device-management-kit': 0.9.0(rxjs@7.8.2) + '@sentry/minimal': 6.19.7 + purify-ts: 2.1.0 + rxjs: 7.8.2 + uuid: 11.0.3 + + '@ledgerhq/device-transport-kit-web-hid@1.2.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2))(rxjs@7.8.2)': + dependencies: + '@ledgerhq/device-management-kit': 0.9.0(rxjs@7.8.2) + '@sentry/minimal': 6.19.7 + purify-ts: 2.1.0 + rxjs: 7.8.2 + uuid: 11.0.3 '@ledgerhq/devices@8.6.1': dependencies: @@ -6614,7 +7268,7 @@ snapshots: transitivePeerDependencies: - debug - '@ledgerhq/hw-app-eth@6.45.5(react-redux@9.2.0(@types/react@19.2.3)(react@19.2.3)(redux@5.0.1))': + '@ledgerhq/hw-app-eth@6.46.0(react-redux@9.2.0(@types/react@19.2.3)(react@19.2.3)(redux@5.0.1))': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/rlp': 5.8.0 @@ -6627,9 +7281,8 @@ snapshots: '@ledgerhq/hw-transport-mocker': 6.30.0 '@ledgerhq/logs': 6.13.0 '@ledgerhq/types-live': 6.90.0 - axios: 1.7.7 + axios: 1.11.0 bignumber.js: 9.3.1 - jest-sonar: 0.2.16 semver: 7.7.3 transitivePeerDependencies: - debug @@ -6649,16 +7302,16 @@ snapshots: '@ledgerhq/logs': 6.13.0 rxjs: 7.8.2 - '@ledgerhq/hw-transport-webhid@6.30.1': + '@ledgerhq/hw-transport-webhid@6.30.8': dependencies: - '@ledgerhq/devices': 8.4.5 + '@ledgerhq/devices': 8.6.1 '@ledgerhq/errors': 6.28.0 '@ledgerhq/hw-transport': 6.31.15 '@ledgerhq/logs': 6.13.0 - '@ledgerhq/hw-transport-webusb@6.29.5': + '@ledgerhq/hw-transport-webusb@6.29.12': dependencies: - '@ledgerhq/devices': 8.4.5 + '@ledgerhq/devices': 8.6.1 '@ledgerhq/errors': 6.28.0 '@ledgerhq/hw-transport': 6.31.15 '@ledgerhq/logs': 6.13.0 @@ -6677,6 +7330,11 @@ snapshots: '@ledgerhq/logs@6.13.0': {} + '@ledgerhq/signer-utils@1.2.0(@ledgerhq/device-management-kit@0.9.0(rxjs@7.8.2))': + dependencies: + '@ledgerhq/device-management-kit': 0.9.0(rxjs@7.8.2) + semver: 7.7.2 + '@ledgerhq/types-live@6.90.0': dependencies: bignumber.js: 9.3.1 @@ -6691,6 +7349,12 @@ snapshots: - react - react-redux + '@lit-labs/ssr-dom-shim@1.6.0': {} + + '@lit/reactive-element@2.1.2': + dependencies: + '@lit-labs/ssr-dom-shim': 1.6.0 + '@metamask/onboarding@1.0.1': dependencies: bowser: 2.13.1 @@ -6739,18 +7403,32 @@ snapshots: '@next/swc-win32-x64-msvc@16.2.6': optional: true + '@noble/ciphers@1.2.1': {} + '@noble/ciphers@1.3.0': {} '@noble/curves@1.2.0': dependencies: '@noble/hashes': 1.3.2 + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + '@noble/curves@1.9.1': dependencies: '@noble/hashes': 1.8.0 '@noble/hashes@1.3.2': {} + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.7.1': {} + '@noble/hashes@1.8.0': {} '@nodelib/fs.scandir@2.1.5': @@ -6932,6 +7610,267 @@ snapshots: react: 19.2.3 react-redux: 9.2.0(@types/react@19.2.3)(react@19.2.3)(redux@5.0.1) + '@reown/appkit-common@1.7.8(typescript@5.8.3)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.44.1(typescript@5.8.3)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-common@1.7.8(typescript@5.8.3)(zod@4.3.5)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.44.1(typescript@5.8.3)(zod@4.3.5) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@reown/appkit-common': 1.7.8(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-wallet': 1.7.8(typescript@5.8.3) + '@walletconnect/universal-provider': 2.21.0(typescript@5.8.3)(zod@4.3.5) + valtio: 1.13.2(@types/react@19.2.3)(react@19.2.3) + viem: 2.44.1(typescript@5.8.3)(zod@4.3.5) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-pay@1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@reown/appkit-common': 1.7.8(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(valtio@1.13.2(@types/react@19.2.3)(react@19.2.3))(zod@4.3.5) + lit: 3.3.0 + valtio: 1.13.2(@types/react@19.2.3)(react@19.2.3) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-polyfills@1.7.8': + dependencies: + buffer: 6.0.3 + + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(valtio@1.13.2(@types/react@19.2.3)(react@19.2.3))(zod@4.3.5)': + dependencies: + '@reown/appkit-common': 1.7.8(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(valtio@1.13.2(@types/react@19.2.3)(react@19.2.3))(zod@4.3.5) + '@reown/appkit-wallet': 1.7.8(typescript@5.8.3) + lit: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - valtio + - zod + + '@reown/appkit-ui@1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@reown/appkit-common': 1.7.8(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-wallet': 1.7.8(typescript@5.8.3) + lit: 3.3.0 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-utils@1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(valtio@1.13.2(@types/react@19.2.3)(react@19.2.3))(zod@4.3.5)': + dependencies: + '@reown/appkit-common': 1.7.8(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-wallet': 1.7.8(typescript@5.8.3) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.21.0(typescript@5.8.3)(zod@4.3.5) + valtio: 1.13.2(@types/react@19.2.3)(react@19.2.3) + viem: 2.44.1(typescript@5.8.3)(zod@4.3.5) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-wallet@1.7.8(typescript@5.8.3)': + dependencies: + '@reown/appkit-common': 1.7.8(typescript@5.8.3)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.8 + '@walletconnect/logger': 2.1.2 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@reown/appkit-common': 1.7.8(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-pay': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(valtio@1.13.2(@types/react@19.2.3)(react@19.2.3))(zod@4.3.5) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(valtio@1.13.2(@types/react@19.2.3)(react@19.2.3))(zod@4.3.5) + '@reown/appkit-wallet': 1.7.8(typescript@5.8.3) + '@walletconnect/types': 2.21.0 + '@walletconnect/universal-provider': 2.21.0(typescript@5.8.3)(zod@4.3.5) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@19.2.3)(react@19.2.3) + viem: 2.44.1(typescript@5.8.3)(zod@4.3.5) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + '@rollup/rollup-android-arm-eabi@4.60.3': optional: true @@ -7033,12 +7972,23 @@ snapshots: '@scure/base@1.2.6': {} + '@scure/bip32@1.6.2': + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.6 + '@scure/bip32@1.7.0': dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 + '@scure/bip39@1.5.4': + dependencies: + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.6 + '@scure/bip39@1.6.0': dependencies: '@noble/hashes': 1.8.0 @@ -7046,9 +7996,28 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} + '@sentry/hub@6.19.7': + dependencies: + '@sentry/types': 6.19.7 + '@sentry/utils': 6.19.7 + tslib: 1.14.1 + + '@sentry/minimal@6.19.7': + dependencies: + '@sentry/hub': 6.19.7 + '@sentry/types': 6.19.7 + tslib: 1.14.1 + + '@sentry/types@6.19.7': {} + + '@sentry/utils@6.19.7': + dependencies: + '@sentry/types': 6.19.7 + tslib: 1.14.1 + '@sindresorhus/merge-streams@4.0.0': {} - '@stakewise/v3-sdk@4.2.2(ethers@6.14.3)': + '@stakewise/v3-sdk@4.2.5(ethers@6.14.3)': dependencies: bignumber.js: 9.3.0 ethers: 6.14.3 @@ -7237,6 +8206,8 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/trusted-types@2.0.7': {} + '@types/ua-parser-js@0.7.39': {} '@types/unist@2.0.11': {} @@ -7405,16 +8376,17 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@wagmi/connectors@7.1.1(@safe-global/safe-apps-provider@0.18.6(typescript@5.8.3)(zod@4.3.5))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.8.3)(zod@4.3.5))(@wagmi/core@3.2.1(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)))(typescript@5.8.3)(viem@2.44.1(typescript@5.8.3)(zod@4.3.5))': + '@wagmi/connectors@7.2.1(@safe-global/safe-apps-provider@0.18.6(typescript@5.8.3)(zod@4.3.5))(@safe-global/safe-apps-sdk@9.1.0(typescript@5.8.3)(zod@4.3.5))(@wagmi/core@3.4.0(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)))(@walletconnect/ethereum-provider@2.21.1(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5))(typescript@5.8.3)(viem@2.44.1(typescript@5.8.3)(zod@4.3.5))': dependencies: - '@wagmi/core': 3.2.1(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)) + '@wagmi/core': 3.4.0(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5)) viem: 2.44.1(typescript@5.8.3)(zod@4.3.5) optionalDependencies: '@safe-global/safe-apps-provider': 0.18.6(typescript@5.8.3)(zod@4.3.5) '@safe-global/safe-apps-sdk': 9.1.0(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) typescript: 5.8.3 - '@wagmi/core@3.2.1(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5))': + '@wagmi/core@3.4.0(@types/react@19.2.3)(immer@10.2.0)(ox@0.11.3(typescript@5.8.3)(zod@4.3.5))(react@19.2.3)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@19.2.3))(viem@2.44.1(typescript@5.8.3)(zod@4.3.5))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.8.3) @@ -7429,6 +8401,543 @@ snapshots: - react - use-sync-external-store + '@walletconnect/core@2.21.0(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/core@2.21.1(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@reown/appkit': 1.7.8(@types/react@19.2.3)(react@19.2.3)(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/sign-client': 2.21.1(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/types': 2.21.1 + '@walletconnect/universal-provider': 2.21.1(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/utils': 2.21.1(typescript@5.8.3)(zod@4.3.5) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-http-connection@1.0.8': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.2.0 + events: 3.3.0 + transitivePeerDependencies: + - encoding + + '@walletconnect/jsonrpc-provider@1.0.14': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.2 + unstorage: 1.17.5(idb-keyval@6.2.2) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/logger@2.1.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.1 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.21.0(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@walletconnect/core': 2.21.0(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(typescript@5.8.3)(zod@4.3.5) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/sign-client@2.21.1(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@walletconnect/core': 2.21.1(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(typescript@5.8.3)(zod@4.3.5) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.21.0': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/types@2.21.1': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/universal-provider@2.21.0(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.0(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(typescript@5.8.3)(zod@4.3.5) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/universal-provider@2.21.1(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.1(typescript@5.8.3)(zod@4.3.5) + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(typescript@5.8.3)(zod@4.3.5) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.21.0(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0 + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(typescript@5.8.3)(zod@4.3.5) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.21.1(typescript@5.8.3)(zod@4.3.5)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1 + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(typescript@5.8.3)(zod@4.3.5) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/window-getters@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/window-metadata@1.0.1': + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -7509,6 +9018,16 @@ snapshots: '@xtuc/long@4.2.2': {} + abitype@1.0.8(typescript@5.8.3)(zod@4.3.5): + optionalDependencies: + typescript: 5.8.3 + zod: 4.3.5 + + abitype@1.2.3(typescript@5.8.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.8.3 + zod: 3.22.4 + abitype@1.2.3(typescript@5.8.3)(zod@4.3.5): optionalDependencies: typescript: 5.8.3 @@ -7693,6 +9212,8 @@ snapshots: atob@2.1.2: {} + atomic-sleep@1.0.0: {} + autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.28.1 @@ -7725,6 +9246,14 @@ snapshots: transitivePeerDependencies: - debug + axios@1.11.0: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axios@1.12.2: dependencies: follow-redirects: 1.15.11 @@ -7741,7 +9270,7 @@ snapshots: transitivePeerDependencies: - debug - axios@1.7.7: + axios@1.8.2: dependencies: follow-redirects: 1.15.11 form-data: 4.0.5 @@ -7757,6 +9286,8 @@ snapshots: balanced-match@2.0.0: {} + base-x@5.0.1: {} + base64-js@1.5.1: {} base@0.11.2: @@ -7775,6 +9306,8 @@ snapshots: big.js@5.2.2: {} + big.js@6.2.2: {} + bignumber.js@9.3.0: {} bignumber.js@9.3.1: {} @@ -7833,6 +9366,10 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) + bs58@6.0.0: + dependencies: + base-x: 5.0.1 + buffer-from@1.1.2: {} buffer@6.0.3: @@ -7960,6 +9497,10 @@ snapshots: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + chownr@3.0.0: {} chrome-trace-event@1.0.4: {} @@ -8068,6 +9609,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie-es@1.2.3: {} + copy-descriptor@0.1.1: {} cosmiconfig@5.2.1: @@ -8100,6 +9643,10 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + crypto-js@4.2.0: {} css-class-generator@2.0.0: {} @@ -8193,12 +9740,22 @@ snapshots: is-descriptor: 1.0.3 isobject: 3.0.1 + defu@6.1.7: {} + degit@2.8.4: {} delayed-stream@1.0.0: {} + derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.2.3)(react@19.2.3)): + dependencies: + valtio: 1.13.2(@types/react@19.2.3)(react@19.2.3) + + destr@2.0.5: {} + destyle.css@4.0.1: {} + detect-browser@5.3.0: {} + detect-europe-js@0.1.2: {} detect-libc@2.1.2: {} @@ -8251,6 +9808,13 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + eip1193-provider@1.0.1: dependencies: '@json-rpc-tools/provider': 1.7.6 @@ -8283,6 +9847,12 @@ snapshots: emojis-list@3.0.0: {} + encode-utf8@1.0.3: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + enhanced-resolve@5.18.4: dependencies: graceful-fs: 4.2.11 @@ -8292,8 +9862,6 @@ snapshots: entities@2.2.0: {} - entities@4.3.0: {} - env-paths@2.2.1: {} err-code@3.0.1: {} @@ -8405,6 +9973,8 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es-toolkit@1.33.0: {} + esbuild@0.24.2: optionalDependencies: '@esbuild/aix-ppc64': 0.24.2 @@ -8651,6 +10221,19 @@ snapshots: esutils@2.0.3: {} + ethers@6.14.1: + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + ethers@6.14.3: dependencies: '@adraffy/ens-normalize': 1.10.1 @@ -8760,6 +10343,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-redact@3.5.0: {} + fast-uri@3.1.0: {} fastest-levenshtein@1.0.16: {} @@ -8805,6 +10390,8 @@ snapshots: dependencies: to-regex-range: 5.0.1 + filter-obj@1.1.0: {} + find-replace@3.0.0: dependencies: array-back: 3.1.0 @@ -9026,6 +10613,18 @@ snapshots: graceful-fs@4.2.11: {} + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.4 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + hamt-sharding@2.0.1: dependencies: sparse-array: 1.3.2 @@ -9126,6 +10725,8 @@ snapshots: husky@9.1.7: {} + idb-keyval@6.2.2: {} + ieee754@1.2.1: {} ignore@4.0.6: {} @@ -9179,6 +10780,13 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 + inversify@7.5.1(reflect-metadata@0.2.2): + dependencies: + '@inversifyjs/common': 1.5.0 + '@inversifyjs/container': 1.9.1(reflect-metadata@0.2.2) + '@inversifyjs/core': 5.2.0(reflect-metadata@0.2.2) + reflect-metadata: 0.2.2 + ipfs-only-hash@4.0.0: dependencies: ipfs-unixfs-importer: 7.0.3 @@ -9222,6 +10830,8 @@ snapshots: stable: 0.1.8 uint8arrays: 2.1.10 + iron-webcrypto@1.2.1: {} + is-accessor-descriptor@1.0.1: dependencies: hasown: 2.0.2 @@ -9437,6 +11047,14 @@ snapshots: isobject@3.0.1: {} + isomorphic-ws@5.0.0(ws@8.19.0): + dependencies: + ws: 8.19.0 + + isows@1.0.6(ws@8.18.0): + dependencies: + ws: 8.18.0 + isows@1.0.7(ws@8.18.3): dependencies: ws: 8.18.3 @@ -9460,11 +11078,6 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 - jest-sonar@0.2.16: - dependencies: - entities: 4.3.0 - strip-ansi: 6.0.1 - jest-worker@27.5.1: dependencies: '@types/node': 22.15.21 @@ -9633,6 +11246,22 @@ snapshots: lines-and-columns@1.2.4: {} + lit-element@4.2.2: + dependencies: + '@lit-labs/ssr-dom-shim': 1.6.0 + '@lit/reactive-element': 2.1.2 + lit-html: 3.3.3 + + lit-html@3.3.3: + dependencies: + '@types/trusted-types': 2.0.7 + + lit@3.3.0: + dependencies: + '@lit/reactive-element': 2.1.2 + lit-element: 4.2.2 + lit-html: 3.3.3 + load-json-file@4.0.0: dependencies: graceful-fs: 4.2.11 @@ -9690,6 +11319,8 @@ snapshots: currently-unhandled: 0.4.1 signal-exit: 3.0.7 + lru-cache@11.4.0: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -9941,12 +11572,16 @@ snapshots: node-addon-api@7.1.1: optional: true + node-fetch-native@1.6.7: {} + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 node-gyp-build@4.8.4: {} + node-mock-http@1.0.4: {} + node-releases@2.0.27: {} normalize-package-data@2.5.0: @@ -10034,6 +11669,14 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + on-exit-leak-free@0.2.0: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -10053,6 +11696,21 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + ox@0.11.3(typescript@5.8.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.8.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + ox@0.11.3(typescript@5.8.3)(zod@4.3.5): dependencies: '@adraffy/ens-normalize': 1.11.1 @@ -10068,6 +11726,20 @@ snapshots: transitivePeerDependencies: - zod + ox@0.6.7(typescript@5.8.3)(zod@4.3.5): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.8.3)(zod@4.3.5) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + p-limit@1.3.0: dependencies: p-try: 1.0.0 @@ -10159,6 +11831,27 @@ snapshots: pify@4.0.1: {} + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + + pino-std-serializers@4.0.0: {} + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + pirates@4.0.7: {} playwright-core@1.57.0: {} @@ -10313,6 +12006,8 @@ snapshots: dependencies: parse-ms: 4.0.0 + process-warning@1.0.0: {} + prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -10340,10 +12035,18 @@ snapshots: '@types/node': 22.15.21 long: 4.0.0 + proxy-compare@2.6.0: {} + proxy-from-env@1.1.0: {} + punycode@1.4.1: {} + punycode@2.3.1: {} + purify-ts@2.1.0: + dependencies: + '@types/json-schema': 7.0.15 + qified@0.5.3: dependencies: hookified: 1.15.0 @@ -10352,14 +12055,34 @@ snapshots: dependencies: react: 18.2.0 + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + qrcode@1.5.4: dependencies: dijkstrajs: 1.0.3 pngjs: 5.0.0 yargs: 15.4.1 + qs@6.15.2: + dependencies: + side-channel: 1.1.0 + + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + queue-microtask@1.2.3: {} + quick-format-unescaped@4.0.4: {} + quick-lru@1.1.0: {} quick-lru@4.0.1: {} @@ -10376,6 +12099,8 @@ snapshots: - encoding - supports-color + radix3@1.1.2: {} + randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 @@ -10458,6 +12183,10 @@ snapshots: readdirp@4.1.2: {} + readdirp@5.0.0: {} + + real-require@0.1.0: {} + redent@2.0.0: dependencies: indent-string: 3.2.0 @@ -10480,6 +12209,8 @@ snapshots: redux@5.0.1: {} + reflect-metadata@0.2.2: {} + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -10656,6 +12387,8 @@ snapshots: dependencies: ret: 0.1.15 + safe-stable-stringify@2.5.0: {} + sass-loader@16.0.5(sass@1.89.0)(webpack@5.104.1): dependencies: neo-async: 2.6.2 @@ -10694,6 +12427,8 @@ snapshots: semver@6.3.1: {} + semver@7.7.2: {} + semver@7.7.3: {} serialize-javascript@6.0.2: @@ -10844,6 +12579,10 @@ snapshots: transitivePeerDependencies: - supports-color + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + source-map-js@1.2.1: {} source-map-resolve@0.5.3: @@ -10887,10 +12626,14 @@ snapshots: specificity@0.4.1: {} + split-on-first@1.1.0: {} + split-string@3.1.0: dependencies: extend-shallow: 3.0.2 + split2@4.2.0: {} + sprintf-js@1.0.3: {} ssf@0.11.2: @@ -10913,6 +12656,10 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + stream-shift@1.0.3: {} + + strict-uri-encode@2.0.0: {} + string-format@2.0.0: {} string-width@3.1.0: @@ -11273,6 +13020,10 @@ snapshots: dependencies: any-promise: 1.3.0 + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + tinyexec@0.3.2: {} tinyglobby@0.2.15: @@ -11342,6 +13093,8 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tslib@1.14.1: {} + tslib@2.7.0: {} tslib@2.8.1: {} @@ -11463,10 +13216,16 @@ snapshots: transitivePeerDependencies: - encoding + ufo@1.6.4: {} + uint8arrays@2.1.10: dependencies: multiformats: 9.9.0 + uint8arrays@3.1.0: + dependencies: + multiformats: 9.9.0 + uint8arrays@3.1.1: dependencies: multiformats: 9.9.0 @@ -11478,6 +13237,8 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + uncrypto@0.1.3: {} + undici-types@6.19.8: {} undici-types@6.20.0: {} @@ -11566,6 +13327,19 @@ snapshots: has-value: 0.3.1 isobject: 3.0.1 + unstorage@1.17.5(idb-keyval@6.2.2): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.4.0 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + optionalDependencies: + idb-keyval: 6.2.2 + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: browserslist: 4.28.1 @@ -11578,6 +13352,15 @@ snapshots: urix@0.1.0: {} + url@0.11.4: + dependencies: + punycode: 1.4.1 + qs: 6.15.2 + + use-sync-external-store@1.2.0(react@19.2.3): + dependencies: + react: 19.2.3 + use-sync-external-store@1.6.0(react@19.2.3): dependencies: react: 19.2.3 @@ -11588,6 +13371,8 @@ snapshots: utility-types@3.11.0: {} + uuid@11.0.3: {} + uuid@9.0.1: {} validate-npm-package-license@3.0.4: @@ -11595,6 +13380,15 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + valtio@1.13.2(@types/react@19.2.3)(react@19.2.3): + dependencies: + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.2.3)(react@19.2.3)) + proxy-compare: 2.6.0 + use-sync-external-store: 1.2.0(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.3 + react: 19.2.3 + varint@5.0.2: {} varint@6.0.0: {} @@ -11617,6 +13411,40 @@ snapshots: unist-util-stringify-position: 1.1.2 vfile-message: 1.1.1 + viem@2.23.2(typescript@5.8.3)(zod@4.3.5): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@4.3.5) + isows: 1.0.6(ws@8.18.0) + ox: 0.6.7(typescript@5.8.3)(zod@4.3.5) + ws: 8.18.0 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.44.1(typescript@5.8.3)(zod@3.22.4): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.8.3)(zod@3.22.4) + isows: 1.0.7(ws@8.18.3) + ox: 0.11.3(typescript@5.8.3)(zod@3.22.4) + ws: 8.18.3 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + viem@2.44.1(typescript@5.8.3)(zod@4.3.5): dependencies: '@noble/curves': 1.9.1 @@ -11777,6 +13605,8 @@ snapshots: ws@8.17.1: {} + ws@8.18.0: {} + ws@8.18.3: {} ws@8.19.0: {} @@ -11793,6 +13623,8 @@ snapshots: wmf: 1.0.2 word: 0.3.0 + xstate@5.19.2: {} + xtend@4.0.2: {} y18n@4.0.3: {} @@ -11850,6 +13682,8 @@ snapshots: dependencies: zod: 4.3.5 + zod@3.22.4: {} + zod@4.3.5: {} zustand@5.0.0(@types/react@19.2.3)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)): diff --git a/public/manifest.json b/public/manifest.json index 050079f0..ec90ff1b 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,7 +1,7 @@ { - "name": "Vaul Interface", - "short_name": "Vaul Interface", - "description": "Vaul Interface", + "name": "Vault Interface", + "short_name": "Vault Interface", + "description": "Vault Interface", "icons": [ { "src": "favicon.ico", diff --git a/src/components/Button/ButtonContent/ButtonContent.tsx b/src/components/Button/ButtonContent/ButtonContent.tsx index 49a9788b..d00dea27 100644 --- a/src/components/Button/ButtonContent/ButtonContent.tsx +++ b/src/components/Button/ButtonContent/ButtonContent.tsx @@ -1,11 +1,11 @@ import React from 'react' import cx from 'classnames' -import Logo from '../../Logo/Logo' import Loading from '../../Loading/Loading' -import Text, { TextSize, TextColor } from '../../Text/Text' import Icon, { IconProps } from '../../Icon/Icon' +import WalletIcon from '../../WalletIcon/WalletIcon' import { IconName, LogoName } from '../../Image/Image' +import Text, { TextSize, TextColor } from '../../Text/Text' export type ButtonContentProps = { @@ -15,7 +15,7 @@ export type ButtonContentProps = { titleSize: TextSize iconSize: IconProps['size'] icon?: IconName - logo?: LogoName + logo?: LogoName | string arrow?: 'up' | 'down' color?: IconProps['color'] loading?: boolean @@ -46,9 +46,8 @@ const ButtonContent: React.FC = (props) => { } { Boolean(logo) && ( - ) diff --git a/src/components/DatePicker/Calendar/Calendar.module.scss b/src/components/DatePicker/Calendar/Calendar.module.scss new file mode 100644 index 00000000..f13cff6e --- /dev/null +++ b/src/components/DatePicker/Calendar/Calendar.module.scss @@ -0,0 +1,3 @@ +.grid { + grid-template-columns: repeat(7, 32px); +} diff --git a/src/components/DatePicker/Calendar/Calendar.tsx b/src/components/DatePicker/Calendar/Calendar.tsx new file mode 100644 index 00000000..9008561f --- /dev/null +++ b/src/components/DatePicker/Calendar/Calendar.tsx @@ -0,0 +1,182 @@ +import React, { useMemo } from 'react' +import forms from 'modules/forms' +import date from 'modules/date' +import cx from 'classnames' + +import Bone from '../../Bone/Bone' +import Icon from '../../Icon/Icon' +import Text from '../../Text/Text' +import ButtonBase from '../../ButtonBase/ButtonBase' + +import Day from './Day/Day' +import { useDays, getDate } from './util' + +import s from './Calendar.module.scss' + + +export type CalendarProps = { + className?: string + field: Forms.Field + minDate?: string + maxDate?: string + onChange?: () => void +} + +const Calendar: React.FC = (props) => { + const { className, field, minDate, maxDate, onChange } = props + + const { value: selectedDay } = forms.useFieldValue(field) + const { days, title, weekDays, yearMonth, weeksOffset, weeksCount, isLocaleFetching, setMonth } = useDays({ + field, + animationDuration: 350, + }) + + const minimalDate = useMemo(() => getDate(minDate), [ minDate ]) + const maximalDate = useMemo(() => getDate(maxDate), [ maxDate ]) + + const [ firstDayOfMonth, lastDayOfMonth ] = useMemo(() => { + const yearMonthDate = date.time(yearMonth, 'YYYY-MM') + + return [ + yearMonthDate.startOf('month'), + yearMonthDate.endOf('month'), + ] + }, [ yearMonth ]) + + const isLeftButtonDisabled = useMemo(() => { + if (minimalDate) { + return !firstDayOfMonth.isAfter(minimalDate) + } + }, [ firstDayOfMonth, minimalDate ]) + + const isRightButtonDisabled = useMemo(() => { + if (maximalDate) { + return !lastDayOfMonth.isBefore(maximalDate) + } + }, [ lastDayOfMonth, maximalDate ]) + + return ( +
+
+ setMonth(-1)} + > + + + { + isLocaleFetching ? ( +
+ +
+ ) : ( + + ) + } + setMonth(1)} + > + + +
+
+ { + weekDays.map((weekDay) => ( + isLocaleFetching ? ( +
+ +
+ ) : ( + + ) + )) + } +
+
+
0 ? `-${weeksOffset * 32}px` : '0', + }} + > + { + days.map((day) => { + const dayDate = getDate(day.fullDate) as Date.Time + + return ( + { + field.setValue(day.fullDate) + + if (typeof onChange === 'function') { + onChange() + } + }} + /> + ) + }) + } +
+
+
+ ) +} + + +export default React.memo(Calendar) diff --git a/src/components/DatePicker/Calendar/Day/Day.module.scss b/src/components/DatePicker/Calendar/Day/Day.module.scss new file mode 100644 index 00000000..6a456e95 --- /dev/null +++ b/src/components/DatePicker/Calendar/Day/Day.module.scss @@ -0,0 +1,12 @@ +.fadeIn { + animation: fadeIn 500ms ease-in-out; +} + +@keyframes fadeIn { + from { + opacity: 0.3; + } + to { + opacity: 1; + } +} diff --git a/src/components/DatePicker/Calendar/Day/Day.tsx b/src/components/DatePicker/Calendar/Day/Day.tsx new file mode 100644 index 00000000..553fd5e9 --- /dev/null +++ b/src/components/DatePicker/Calendar/Day/Day.tsx @@ -0,0 +1,49 @@ +import React from 'react' +import cx from 'classnames' + +import ButtonBase from '../../../ButtonBase/ButtonBase' +import Text from '../../../Text/Text' + +import s from './Day.module.scss' + + +type DayProps = { + className?: string + title: string + isActive?: boolean + isSelected?: boolean + isDisabled?: boolean + onClick: () => void +} + +const Day: React.FC = (props) => { + const { className, title, isActive, isSelected, isDisabled, onClick } = props + + const defaultClassName = cx({ + [s.fadeIn]: isActive, + 'opacity-30': !isActive, + 'bg-primary': isSelected, + 'hover:bg-primary/20': !isSelected && isActive, + 'hover:bg-primary/50': !isSelected && !isActive, + }) + + return ( + + + + ) +} + + +export default React.memo(Day) diff --git a/src/components/DatePicker/Calendar/util/getDate.ts b/src/components/DatePicker/Calendar/util/getDate.ts new file mode 100644 index 00000000..162f8430 --- /dev/null +++ b/src/components/DatePicker/Calendar/util/getDate.ts @@ -0,0 +1,22 @@ +import date from 'modules/date' + + +const getDate = (dateString?: string) => { + if (!dateString) { + return null + } + + let result = date.time(dateString) + + if (result.isValid()) { + return result + } + else { + result = date.time(dateString, 'YYYY-MM-DD') + } + + return result.isValid() ? result : null +} + + +export default getDate diff --git a/src/components/DatePicker/Calendar/util/index.ts b/src/components/DatePicker/Calendar/util/index.ts new file mode 100644 index 00000000..edcafc7b --- /dev/null +++ b/src/components/DatePicker/Calendar/util/index.ts @@ -0,0 +1,2 @@ +export { default as useDays } from './useDays' +export { default as getDate } from './getDate' diff --git a/src/components/DatePicker/Calendar/util/useDays.ts b/src/components/DatePicker/Calendar/util/useDays.ts new file mode 100644 index 00000000..d6abe537 --- /dev/null +++ b/src/components/DatePicker/Calendar/util/useDays.ts @@ -0,0 +1,182 @@ +import { useCallback, useMemo } from 'react' +import intl from 'modules/intl' +import date from 'modules/date' +import { useChangeEffect, useFieldListener, useObjectState } from 'hooks' + + +type GetCalendarRangeInput = { + firstDay: Date.Time + lastDay: Date.Time +} + +type Input = { + field: Forms.Field + animationDuration: number +} + +const format = 'YYYY-MM' + +const useDays = ({ field, animationDuration }: Input) => { + const time = date.useTime() + const { locale } = intl.useIntl() + + const parseFieldDate = useCallback(() => { + const [ year, month ] = field.value?.split('-') || [] + + const result: Record = {} + + if (year?.length === 4) { + result.year = Number(year) + } + if (month?.length === 2) { + result.month = Number(month) + } + + return result + }, [ field ]) + + const getStateFromField = useCallback((initialDate?: string) => { + const { year, month } = parseFieldDate() + + let currentDate = initialDate ? time(initialDate, format) : time() + + if (year) { + currentDate = currentDate.set('year', year) + } + if (month) { + // in day js months are zero-based + currentDate = currentDate.set('month', month - 1) + } + + const yearMonth = currentDate.format(format) + const initialYearMonth = yearMonth + + return { yearMonth, initialYearMonth } + }, [ time, parseFieldDate ]) + + const [ { yearMonth, initialYearMonth }, setState ] = useObjectState(getStateFromField()) + + const onFieldChange = useCallback(() => { + setState({ yearMonth: getStateFromField(yearMonth).yearMonth }) + }, [ yearMonth, setState, getStateFromField ]) + + useFieldListener(field, onFieldChange) + + const setMonth = useCallback((count: number) => { + const nextYearMonth = time(yearMonth, format) + .add(count, 'month') + .format(format) + + setState({ + yearMonth: nextYearMonth, + }) + }, [ yearMonth, time, setState ]) + + const weekDays = useMemo(() => { + return new Array(7) + .fill(null) + .map((_, index) => { + return time().startOf('week').add(index, 'day').format('dd') + }) + }, [ time ]) + + const getCalendarRange = useCallback((yearMonth: string) => { + const selectedMonth = time(yearMonth, format) + const startOfMonth = selectedMonth.startOf('month') + const endOfMonth = selectedMonth.endOf('month') + + const startDiff = weekDays.indexOf(startOfMonth.format('dd')) + const endDiff = 6 - weekDays.indexOf(endOfMonth.format('dd')) + + const firstDay = startOfMonth.subtract(startDiff, 'day') + const lastDay = endOfMonth.add(endDiff, 'day') + + return { + firstDay, + lastDay, + } + }, [ weekDays, time ]) + + const monthRange = useMemo(() => { + return getCalendarRange(yearMonth) + }, [ yearMonth, getCalendarRange ]) + + const initialMonthRange = useMemo(() => { + return getCalendarRange(initialYearMonth) + }, [ initialYearMonth, getCalendarRange ]) + + const getDays = useCallback(({ firstDay, lastDay }: GetCalendarRangeInput) => { + return new Array(lastDay.diff(firstDay, 'day') + 1) + .fill(null) + .map((_, index) => { + const day = firstDay.add(index, 'day') + const fullDate = day.format('YYYY-MM-DD') + const [ yearMonth, date ] = day.format('YYYY-MM D').split(' ') + + return { + date, + fullDate, + yearMonth, + } + }) + }, []) + + const days = useMemo(() => { + const daysDiff = monthRange.firstDay.diff(initialMonthRange.firstDay, 'day') + + const firstDay = daysDiff > 0 + ? initialMonthRange.firstDay + : monthRange.firstDay + + const lastDay = daysDiff > 0 + ? monthRange.lastDay + : initialMonthRange.lastDay + + return getDays({ firstDay, lastDay }) + }, [ monthRange, initialMonthRange, getDays ]) + + const weeksCount = useMemo(() => { + return monthRange.lastDay.diff(monthRange.firstDay, 'week') + 1 + }, [ monthRange ]) + + const weeksOffset = useMemo(() => { + return initialMonthRange.firstDay.diff(monthRange.firstDay, 'week') + }, [ monthRange, initialMonthRange ]) + + const title = useMemo(() => time(yearMonth, format).format('MMMM, YYYY'), [ yearMonth, time ]) + + const isLocaleFetching = useMemo(() => locale !== time().locale(), [ time, locale ]) + + useChangeEffect<[ string, number ]>(() => { + const timeout = setTimeout(() => { + setState({ initialYearMonth: yearMonth }) + }, animationDuration) + + return () => { + clearTimeout(timeout) + } + }, [ yearMonth, animationDuration ]) + + return useMemo(() => ({ + days, + title, + weekDays, + yearMonth, + weeksCount, + weeksOffset, + isLocaleFetching, + setMonth, + }), [ + days, + title, + weekDays, + yearMonth, + weeksCount, + weeksOffset, + isLocaleFetching, + setMonth, + ]) +} + + +export default useDays diff --git a/src/components/DatePicker/DatePicker.tsx b/src/components/DatePicker/DatePicker.tsx new file mode 100644 index 00000000..e82d112a --- /dev/null +++ b/src/components/DatePicker/DatePicker.tsx @@ -0,0 +1,68 @@ +import React, { Fragment } from 'react' +import cx from 'classnames' +import { offset } from '@floating-ui/react' +import { autoUpdate, useFloating } from '@floating-ui/react-dom' +import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react' + +import Input from '../Input/Input' +import type { InputProps } from '../Input/Input' + +import Calendar, { CalendarProps } from './Calendar/Calendar' + + +export type DatePickerProps = Omit & Omit + +const DatePicker: React.FC = (props) => { + const { className, field, minDate, maxDate, ...rest } = props + + const { refs, floatingStyles } = useFloating({ + placement: 'bottom-start', + middleware: [ + offset(10), + ], + whileElementsMounted: autoUpdate, + }) + + return ( + + {({ close }) => ( + <> + + { + ({ open }) => ( +
{ + if (open) { + // prevent popover from closing on the input click + event.preventDefault() + } + }} + > + +
+ ) + } +
+ + + + + )} +
+ ) +} + + +export default React.memo(DatePicker) diff --git a/src/components/Dropdown/DropdownView/DropdownView.tsx b/src/components/Dropdown/DropdownView/DropdownView.tsx index 6e7ea808..e6b4e244 100644 --- a/src/components/Dropdown/DropdownView/DropdownView.tsx +++ b/src/components/Dropdown/DropdownView/DropdownView.tsx @@ -74,7 +74,7 @@ const DropdownView: DropdownViewComponent = (props: DropdownViewProps) => { { ({ open }) => { if (open && !isOpenRef.current && typeof onOpen === 'function') { - onOpen() + setTimeout(onOpen) } if (!open && isOpenRef.current && typeof onClose === 'function') { diff --git a/src/components/Dropdown/Option/Option.tsx b/src/components/Dropdown/Option/Option.tsx index 88352231..1fd629d5 100644 --- a/src/components/Dropdown/Option/Option.tsx +++ b/src/components/Dropdown/Option/Option.tsx @@ -40,7 +40,7 @@ const Option: React.FC = (props) => { > { Boolean(logo || icon) && ( -
+
{ logo ? ( = (props) => { const isClose = closeStatuses.includes(status) const isLast = lastStatuses.includes(status) - const iconClassName = cx('flex items-center justify-center flex-none rounded-full w-32 h-32', { + const iconClassName = cx('mt-8 flex items-center justify-center flex-none rounded-full w-32 h-32', { 'bg-dark/5': !isLast, 'bg-success-light': status === TransactionStatus.Success, 'bg-error': status === TransactionStatus.Fail, @@ -69,7 +69,7 @@ const TransactionView: React.FC = (props) => { return (
Promise + confirm: (values: { hash: string }) => Promise + setTransaction: SetTransaction +} + +const useAction = () => { + return useCallback(async (values: ActionInput) => { + const { step, cancelErrors, isConfirmOptional, action, confirm, setTransaction } = values + + try { + setTransaction(step, TransactionStatus.Confirm) + + const hash = await action() + + if (!hash && !isConfirmOptional) { + return Promise.reject('No transaction hash returned') + } + + setTransaction(step, TransactionStatus.Processing) + + await confirm({ hash }) + + setTransaction(step, TransactionStatus.Success) + } + catch (error: any) { + const isUserRejected = /user rejected action/.test(error?.message || '') + const isCancel = isUserRejected || cancelErrors?.includes(error) + + setTransaction(step, isCancel ? TransactionStatus.Cancel : TransactionStatus.Fail, true) + + error.isCancel = isCancel + + return Promise.reject(error) + } + }, []) +} + + +export default useAction diff --git a/src/components/WalletIcon/WalletIcon.tsx b/src/components/WalletIcon/WalletIcon.tsx new file mode 100644 index 00000000..24e3eb73 --- /dev/null +++ b/src/components/WalletIcon/WalletIcon.tsx @@ -0,0 +1,42 @@ +import React from 'react' +import Image from 'next/image' + +import Logo from '../Logo/Logo' +import type { LogoName } from '../Image/Image' + + +export type WalletIconProps = { + name?: string + size?: number + logo?: LogoName | string +} + +const isExternalLogo = (logo: string) => ( + logo.startsWith('data:') || logo.startsWith('http://') || logo.startsWith('https://') +) + +const WalletIcon: React.FC = (props) => { + const { logo, name = '', size = 48 } = props + + if (!logo) { + return null + } + + if (isExternalLogo(logo)) { + return ( + {`${name} + ) + } + + return +} + + +export default React.memo(WalletIcon) diff --git a/src/components/index.ts b/src/components/index.ts index aac09c9d..98ef860d 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -31,6 +31,9 @@ export type { DropdownProps } from './Dropdown/Dropdown' export { default as DropdownView } from './Dropdown/DropdownView/DropdownView' export type { DropdownViewProps } from './Dropdown/DropdownView/DropdownView' +export { default as DatePicker } from './DatePicker/DatePicker' +export type { DatePickerProps } from './DatePicker/DatePicker' + export { default as FiatAmount } from './FiatAmount/FiatAmount' export type { FiatAmountProps } from './FiatAmount/FiatAmount' @@ -68,6 +71,9 @@ export type { LoadingProps } from './Loading/Loading' export { default as Logo } from './Logo/Logo' export type { LogoProps } from './Logo/Logo' +export { default as WalletIcon } from './WalletIcon/WalletIcon' +export type { WalletIconProps } from './WalletIcon/WalletIcon' + export { default as MagicIcon } from './MagicIcon/MagicIcon' export type { MagicIconProps } from './MagicIcon/MagicIcon' diff --git a/src/config/core/config/createConfig.tsx b/src/config/core/config/createConfig.tsx index 944d2389..52139362 100644 --- a/src/config/core/config/createConfig.tsx +++ b/src/config/core/config/createConfig.tsx @@ -4,12 +4,19 @@ import createContext from './createContext' import useConfigContext, { BaseInput } from './util/useConfigContext' -type ConfigProviderProps = BaseInput & { +type Input = { + middleware?: ConfigProvider.Middleware + networks: ConfigProvider.Networks +} + +type ConfigProviderProps = Omit & { children: React.ReactNode } -const createConfig = (middleware?: ConfigProvider.Middleware) => { - const ConfigContext = createContext({ middleware }) +const createConfig = (values: Input) => { + const { networks, middleware } = values + + const ConfigContext = createContext({ networks, middleware }) const ConfigProvider: React.FC = (props) => { const { @@ -26,8 +33,9 @@ const createConfig = (middleware?: ConfigProvider.Middleware) = } = props const context = useConfigContext({ - supportedNetworkIds, + networks, serverNetworkId, + supportedNetworkIds, onFinishConnect, onChangeAddress, onStartConnect, diff --git a/src/config/core/config/createContext.ts b/src/config/core/config/createContext.ts index 3365be6e..08bfabdd 100644 --- a/src/config/core/config/createContext.ts +++ b/src/config/core/config/createContext.ts @@ -1,17 +1,17 @@ import React from 'react' -import networks from './util/networks' import getInitialState from './util/getInitialState' type Input = { middleware?: ConfigProvider.Middleware + networks: ConfigProvider.Networks } -const createContext = (values: Input = {}): ( +const createContext = (values: Input): ( React.Context> ) => { - const { middleware } = values + const { networks, middleware } = values const initialState = getInitialState() @@ -31,13 +31,15 @@ const createContext = (values: Input = {}): ( disconnect: () => Promise.resolve(), setAddress: () => Promise.resolve(), changeChain: () => Promise.resolve(), + subscribeBeforeChange: () => Promise.resolve(), + unsubscribeBeforeChange: () => Promise.resolve(), }, } let context: ConfigProvider.Context = mockContext if (typeof middleware === 'function') { - context = middleware(mockContext) + context = middleware(mockContext, networks) } return React.createContext>(context) diff --git a/src/config/core/config/index.ts b/src/config/core/config/index.ts index d5464cf5..085f5d42 100644 --- a/src/config/core/config/index.ts +++ b/src/config/core/config/index.ts @@ -1,2 +1 @@ -export { default as networks } from './util/networks' export { default as createConfig } from './createConfig' diff --git a/src/config/core/config/types.d.ts b/src/config/core/config/types.d.ts index 13a7e575..1705ba03 100644 --- a/src/config/core/config/types.d.ts +++ b/src/config/core/config/types.d.ts @@ -1,4 +1,5 @@ import type { BrowserProvider } from 'ethers' +import type { Chain } from 'viem/chains' import useCancelOnChange from './util/useCancelOnChange' import type { Subscription } from './util/useWallet/useCallsOnChange' @@ -10,17 +11,18 @@ declare global { type ConnectorData = { account?: string - chainId?: ChainIds + chainId?: number } type State = { - networkId: NetworkIds + networkId: string address: string | null library?: BrowserProvider accountName: string | null autoConnectChecked: boolean connector: Connectors | null activeWallet: WalletIds | null + walletConnectData: WalletConnectData | null } type ConfigState = { @@ -33,7 +35,7 @@ declare global { type Wallet = { disconnect: () => Promise setAddress: (address: string) => void - changeChain: (networkId: NetworkIds) => Promise + changeChain: (networkId: string) => Promise connect: (walletName: WalletIds, transport?: 'usb' | 'ble') => Promise subscribeBeforeChange: Subscription unsubscribeBeforeChange: Subscription @@ -41,21 +43,58 @@ declare global { type Context = T & State & { wallet: Wallet - chainId: ChainIds + chainId: number isReadOnlyMode: boolean + network: SupportedNetwork + readOnlyProvider: StakeWise.Provider cancelOnChange: ReturnType } type Callbacks = { onStartConnect: (activationMessage: Intl.Message | string) => void onChangeAddress?: () => void - onFinishConnect: () => void onConnectError: () => void onChangeChain?: () => void onDisconnect?: () => void + onFinishConnect: (wallet: string) => void onError?: (message: string, error?: any) => void } - type Middleware = (ctx: Context) => Context + type Middleware = (ctx: Context, networks: Networks) => Context + + type SupportedNetwork = { + id: string + name: string + logo: string + chainId: number + rpc: string | string[] + hexadecimalChainId: string + blockExplorerUrl: string + nativeCurrency: { + name: string + symbol: string + decimals: number + } + viem: Chain + isTestnet: boolean + } + + type Networks = { + configs: Record + default: Record + idByChain: Record + chainById: Record + } + + type WalletConnectData = { + name: string | null + iconUrl: string | null + chains: Array + support: { + eip712: boolean + addChain: boolean + switchChanin: boolean + } + } } } diff --git a/src/config/core/config/util/getInitialState.ts b/src/config/core/config/util/getInitialState.ts index 097bfc0c..6af8a89c 100644 --- a/src/config/core/config/util/getInitialState.ts +++ b/src/config/core/config/util/getInitialState.ts @@ -1,4 +1,4 @@ -const getInitialState = (serverNetworkId?: NetworkIds): ConfigProvider.State => { +const getInitialState = (serverNetworkId?: string): ConfigProvider.State => { const networkId = serverNetworkId || 'mainnet' return { @@ -7,6 +7,7 @@ const getInitialState = (serverNetworkId?: NetworkIds): ConfigProvider.State => connector: null, accountName: null, activeWallet: null, + walletConnectData: null, autoConnectChecked: false, } } diff --git a/src/config/core/config/util/networks.ts b/src/config/core/config/util/networks.ts deleted file mode 100644 index 30a10557..00000000 --- a/src/config/core/config/util/networks.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { chains as sdkChains, Network } from 'sdk' - - -type Ids = keyof typeof supportedConfigs - -// TODO This is the only link between config/core and the SDK to keep the correct ids. But it will have to be removed -const supportedConfigs = { - [sdkChains.gnosis.id]: sdkChains.gnosis, - [sdkChains.mainnet.id]: sdkChains.mainnet, - [sdkChains.hoodi.id]: sdkChains.hoodi, -} as const - -const ids: Ids[] = [] -const chains: ChainIds[] = [] -const chainById: Record = {} as Record -const idByChain: Record = {} as Record - -Object.values(supportedConfigs).forEach(({ id, chainId }) => { - chains.push(chainId) - ids.push(id) - - chainById[id] = chainId - idByChain[chainId] = id -}) - -const networks = { - configs: supportedConfigs, - chainById, - idByChain, - chains, - ids, -} - - -export default networks diff --git a/src/config/core/config/util/useConfigContext.ts b/src/config/core/config/util/useConfigContext.ts index 4ddab4d6..e0f047c5 100644 --- a/src/config/core/config/util/useConfigContext.ts +++ b/src/config/core/config/util/useConfigContext.ts @@ -1,8 +1,8 @@ 'use client' import { useRef, useMemo, useCallback } from 'react' +import getSDK from 'helpers/methods/getSDK' import useObjectState from 'hooks/controls/useObjectState' -import networks from './networks' import useWallet from './useWallet' import wallets from '../../wallets' import getInitialState from './getInitialState' @@ -11,8 +11,9 @@ import useCancelOnChange from './useCancelOnChange' export type BaseInput = ConfigProvider.Callbacks & { - serverNetworkId: NetworkIds + serverNetworkId: string supportedNetworkIds: NetworkIds[] + networks: ConfigProvider.Networks } type Input = BaseInput & { @@ -21,6 +22,7 @@ type Input = BaseInput & { const useConfigContext = (values: Input): ConfigProvider.Context => { const { + networks, serverNetworkId, supportedNetworkIds, onFinishConnect, @@ -65,21 +67,32 @@ const useConfigContext = (values: Input): ConfigProvider.Contex }) }, [ onChangeChain, onChangeAddress, setState ]) - const configState = useMemo(() => ({ - data: state, - dataRef: stateRef, - initialData: initialState, - setData, - }), [ state, stateRef, initialState, setData ]) + const configState = useMemo(() => { + const data = state - useStorageUpdate(configState) + // Fallback to mainnet if current networkId is not supported anymore + if (!networks.configs[state.networkId]) { + data.networkId = 'mainnet' + stateRef.current.networkId = data.networkId + } + + return { + data, + dataRef: stateRef, + initialData: initialState, + setData, + } + }, [ state, stateRef, networks, initialState, setData ]) + + useStorageUpdate({ networks, configState }) const { data } = configState - const config = networks.configs[data.networkId] + const chainId = networks.chainById[data.networkId] const wallet = useWallet({ - chainId: config.chainId, + networks, + chainId, configState, supportedNetworkIds, onFinishConnect, @@ -90,16 +103,28 @@ const useConfigContext = (values: Input): ConfigProvider.Contex }) const cancelOnChange = useCancelOnChange({ - chainId: config.chainId, + chainId: chainId as ChainIds, address: state.address, }) + const detectChain = useCallback((chainId: number) => { + const networkId = networks.idByChain[chainId] + const network = networks.configs[networkId] + + const readOnlyProvider = getSDK({ chainId: network.chainId as ChainIds }).provider + + return { + network, + readOnlyProvider, + } + }, [ networks ]) + return useMemo(() => { - const chainId = config.chainId const isReadOnlyMode = data.activeWallet === wallets.monitorAddress.id const ctx = { ...state, + ...detectChain(chainId), wallet, chainId, isReadOnlyMode, @@ -107,16 +132,18 @@ const useConfigContext = (values: Input): ConfigProvider.Contex } if (typeof middleware === 'function') { - return middleware(ctx) + return middleware(ctx, networks) } return ctx as ConfigProvider.Context }, [ data, - wallet, - config, state, + wallet, + chainId, + networks, middleware, + detectChain, cancelOnChange, ]) } diff --git a/src/config/core/config/util/useStorageUpdate.ts b/src/config/core/config/util/useStorageUpdate.ts index af782bc3..de0889ac 100644 --- a/src/config/core/config/util/useStorageUpdate.ts +++ b/src/config/core/config/util/useStorageUpdate.ts @@ -4,24 +4,29 @@ import cookie from 'helpers/cookie' import * as constants from 'helpers/constants' import wallets from '../../wallets' -import networks from './networks' -const useStorageUpdate = (configState: ConfigProvider.ConfigState) => { +type Input = { + networks: ConfigProvider.Networks + configState: ConfigProvider.ConfigState +} + +const useStorageUpdate = ({ networks, configState }: Input) => { const { networkId, address, activeWallet, autoConnectChecked } = configState.data const chainId = networks.chainById[networkId] // Update cookie network useEffect(() => { - const isSupportedNetwork = networks.ids.includes(networkId as any) && ( - IS_PROD ? !networks.configs[networkId].isTestnet : true + const networkConfig = networks.configs[networkId] + const isSupportedNetwork = Boolean(networkConfig) && ( + IS_PROD ? !networkConfig.isTestnet : true ) if (autoConnectChecked && isSupportedNetwork) { cookie.set(constants.cookieNames.networkId, networkId) } - }, [ networkId, chainId, autoConnectChecked ]) + }, [ networks, networkId, chainId, autoConnectChecked ]) // Update localStorage wallet name useEffect(() => { diff --git a/src/config/core/config/util/useWallet/index.ts b/src/config/core/config/util/useWallet/index.ts index d995fed6..3c31ddb2 100644 --- a/src/config/core/config/util/useWallet/index.ts +++ b/src/config/core/config/util/useWallet/index.ts @@ -17,6 +17,7 @@ type Input = Omit & { const useWallet = (values: Input): ConfigProvider.Wallet => { const { + networks, chainId, configState, supportedNetworkIds, @@ -37,6 +38,7 @@ const useWallet = (values: Input): ConfigProvider.Wallet => { const disconnect = useDisconnect({ configState, onError, onDisconnect }) const changeChain = useChangeChain({ + networks, configState, supportedNetworkIds, onChangeChain, @@ -44,6 +46,7 @@ const useWallet = (values: Input): ConfigProvider.Wallet => { }) const connect = useConnect({ + networks, configState, onError, disconnect, @@ -64,10 +67,12 @@ const useWallet = (values: Input): ConfigProvider.Wallet => { useAutoConnect({ configState, + networks, connect, }) useUpdateWallet({ + networks, supportedNetworkIds, configState, chainId, diff --git a/src/config/core/config/util/useWallet/useAutoConnect.ts b/src/config/core/config/util/useWallet/useAutoConnect.ts index 89cbac14..0135d005 100644 --- a/src/config/core/config/util/useWallet/useAutoConnect.ts +++ b/src/config/core/config/util/useWallet/useAutoConnect.ts @@ -70,10 +70,11 @@ const _getSavedState = (initialState: ConfigProvider.State): ConfigProvider.Stat type UseAutoConnectProps = { configState: ConfigProvider.ConfigState connect: ConfigProvider.Context['wallet']['connect'] + networks: ConfigProvider.Networks } const useAutoConnect = (values: UseAutoConnectProps) => { - const { connect, configState } = values + const { connect, networks, configState } = values const { setData } = configState @@ -98,7 +99,7 @@ const useAutoConnect = (values: UseAutoConnectProps) => { // ATTN: The order in this code is important! if (isFrame) { - const gnosisConnector = await wallets.gnosisSafe.getConnector() + const gnosisConnector = await wallets.gnosisSafe.getConnector(undefined as any, { networks }) as any const isGnosisSafeApp = await gnosisConnector.isSafeApp() if (isGnosisSafeApp) { @@ -126,13 +127,17 @@ const useAutoConnect = (values: UseAutoConnectProps) => { else { setData(savedState) } - }, [ connect, setData ]) + }, [ networks, connect, setData ]) useEffect(() => { + if (configState.data.autoConnectChecked) { + return + } + const savedState = _getSavedState(configState.initialData) handleAutoConnect(savedState) - }, [ handleAutoConnect, configState.initialData ]) + }, [ handleAutoConnect, configState.initialData, configState.data.autoConnectChecked ]) } diff --git a/src/config/core/config/util/useWallet/useChangeChain.ts b/src/config/core/config/util/useWallet/useChangeChain.ts index b9354ffe..780ea1f7 100644 --- a/src/config/core/config/util/useWallet/useChangeChain.ts +++ b/src/config/core/config/util/useWallet/useChangeChain.ts @@ -3,13 +3,13 @@ import { BrowserProvider } from 'ethers' import type { Eip1193Provider } from 'ethers' import notifications from 'modules/notifications' -import networks from '../networks' import wallets from '../../../wallets' import messages from '../../../messages' type Input = { + networks: ConfigProvider.Networks supportedNetworkIds: NetworkIds[] configState: ConfigProvider.ConfigState onError?: ConfigProvider.Callbacks['onError'] @@ -17,7 +17,7 @@ type Input = { } const useChangeChain = (values: Input) => { - const { configState, supportedNetworkIds, onError, onChangeChain } = values + const { networks, configState, supportedNetworkIds, onError, onChangeChain } = values const { dataRef, setData } = configState const { @@ -27,17 +27,17 @@ const useChangeChain = (values: Input) => { handlersOnly: true, }) - return useCallback(async (networkId: NetworkIds): Promise => { - const { activeWallet, connector } = dataRef.current + return useCallback(async (networkId: string): Promise => { + const { activeWallet, walletConnectData, connector } = dataRef.current - const isValid = supportedNetworkIds.includes(networkId) + const isValid = supportedNetworkIds.includes(networkId as NetworkIds) if (!isValid) { return Promise.reject(`Network ${networkId} is not supported`) } const isWalletSupportedChain = activeWallet - ? wallets[activeWallet].networks.includes(networks.chainById[networkId]) + ? (wallets[activeWallet].networks as number[]).includes(networks.chainById[networkId]) : true if (!isWalletSupportedChain) { @@ -45,6 +45,7 @@ const useChangeChain = (values: Input) => { } const chainId = networks.chainById[networkId] + const isWalletConnect = activeWallet === wallets.walletConnect.id const isMonitorAddress = activeWallet === wallets.monitorAddress.id if (!dataRef.current.address || isMonitorAddress) { @@ -58,10 +59,24 @@ const useChangeChain = (values: Input) => { return Promise.reject('The connector has not been connected') } + if (isWalletConnect && Array.isArray(walletConnectData?.chains)) { + const isSupported = walletConnectData.chains.includes(chainId) + + if (!isSupported && !walletConnectData.support.addChain) { + notifications.open({ + text: messages.connectErrors.networkError, + thread: 'connect', + type: 'error', + }) + + return + } + } + const appConnectorNames: WalletIds[] = [ wallets.walletConnect.id, wallets.coinbase.id, - wallets.zenGo.id, + wallets.binance.id, ] const needAppConfirmation = appConnectorNames.includes(activeWallet as WalletIds) @@ -99,6 +114,7 @@ const useChangeChain = (values: Input) => { } }, [ dataRef, + networks, supportedNetworkIds, setNotificationTimeout, clearNotificationTimeout, diff --git a/src/config/core/config/util/useWallet/useConnect.ts b/src/config/core/config/util/useWallet/useConnect.ts index 3236335e..d2d20983 100644 --- a/src/config/core/config/util/useWallet/useConnect.ts +++ b/src/config/core/config/util/useWallet/useConnect.ts @@ -6,20 +6,22 @@ import * as constants from 'helpers/constants' import notifications from 'modules/notifications' import { getAddress, BrowserProvider } from 'ethers' -import networks from '../networks' import wallets from '../../../wallets' import getSpecialErrors from '../getSpecialErrors' +import WalletLinkConnector from '../../../connectors/WalletLinkConnector' import messages from '../../../messages' type Input = Pick & { + networks: ConfigProvider.Networks configState: ConfigProvider.ConfigState disconnect: () => Promise } const useConnect = (values: Input) => { const { + networks, configState, disconnect, onError, @@ -45,6 +47,23 @@ const useConnect = (values: Input) => { window.location.reload() }, [ onConnectError ]) + const resetWCConnection = useCallback(() => { + localStorage.removeItem(constants.localStorageNames.walletName) + + const dbReq = indexedDB.open('WALLET_CONNECT_V2_INDEXED_DB') + + dbReq.onsuccess = () => { + const db = dbReq.result + const tx = db.transaction('keyvaluestorage', 'readwrite') + + tx.objectStore('keyvaluestorage').clear() + tx.oncomplete = () => { + db.close() + window.location.reload() + } + } + }, []) + const connectWallet = useCallback(async (walletName: WalletIds, transport?: 'usb' | 'ble'): Promise => { let resetConnectTimer: NodeJS.Timeout | null = null @@ -63,7 +82,10 @@ const useConnect = (values: Input) => { const { name: chainName } = networks.configs[dataRef.current.networkId] let { chainId } = networks.configs[dataRef.current.networkId] + const isWalletConnect = walletName === wallets.walletConnect.id + const connector = await getConnector(chainId, { + networks, transport, disconnect, }) as Connectors @@ -75,7 +97,8 @@ const useConnect = (values: Input) => { const isLedger = walletName === wallets.ledger.id const isInjected = wallets[walletName].isInjectedWallet const isGnosisSafe = walletName === wallets.gnosisSafe.id - const isWalletConnect = walletName === wallets.walletConnect.id + const isAutoConnect = Boolean(walletName) && !dataRef.current.autoConnectChecked + const isWCReconnect = isWalletConnect && isAutoConnect try { if (isInjected) { @@ -93,7 +116,7 @@ const useConnect = (values: Input) => { resetConnectTimer = setTimeout(resetConnection, 10_000) } - if (isLedger) { + if (isLedger || isWCReconnect) { resetConnectTimer = setTimeout(resetConnection, 10_000) } @@ -111,7 +134,7 @@ const useConnect = (values: Input) => { if (isGnosisSafe) { chainId = connectorChainId - const isSupported = networks.chains.includes(chainId) + const isSupported = Object.values(networks.configs).some((c) => c.chainId === chainId) if (!isSupported) { notifications.open({ @@ -124,7 +147,36 @@ const useConnect = (values: Input) => { } } - const data = await connector.activate(dataRef.current.networkId, intlRef.current.locale) + const data = await connector.activate(dataRef.current.networkId, intlRef.current.locale, isWCReconnect) + + let walletConnectData: ConfigProvider.WalletConnectData | null = null + + if (isWalletConnect) { + walletConnectData = (connector as WalletLinkConnector).getWalletData() + + const isSupportedNetwork = walletConnectData?.chains.includes(chainId) + + if (!isSupportedNetwork) { + inProgressRef.current = false + + onConnectError() + setData({ autoConnectChecked: true }) + localStorage.removeItem(constants.localStorageNames.walletName) + + notifications.open({ + type: 'error', + thread: 'connect', + text: walletConnectData.name ? ({ + ...messages.connectErrors.unsupportedNetwork, + values: { wallet: walletConnectData.name }, + }) : ( + messages.connectErrors.networkError + ), + }) + + return + } + } if (Number(connectorChainId) !== chainId) { await connector.changeChainId(chainId) @@ -174,7 +226,7 @@ const useConnect = (values: Input) => { thread: 'connect', }) - onFinishConnect() + onFinishConnect(walletConnectData?.name || walletName) const networkId = networks.idByChain[chainId] @@ -183,6 +235,7 @@ const useConnect = (values: Input) => { library, connector, networkId, + walletConnectData, activeWallet: walletName, autoConnectChecked: true, }) @@ -203,7 +256,7 @@ const useConnect = (values: Input) => { connector.deactivate?.() if (isWalletConnect) { - localStorage.clearAll() + resetWCConnection() } const isCancelAutoconnectSwitchChain = error.code === 4001 && !dataRef.current.address @@ -238,10 +291,12 @@ const useConnect = (values: Input) => { }, [ intlRef, dataRef, + networks, setData, onError, disconnect, resetConnection, + resetWCConnection, onConnectError, onStartConnect, onFinishConnect, diff --git a/src/config/core/config/util/useWallet/useDisconnect.ts b/src/config/core/config/util/useWallet/useDisconnect.ts index 385ec1bd..1726b2ae 100644 --- a/src/config/core/config/util/useWallet/useDisconnect.ts +++ b/src/config/core/config/util/useWallet/useDisconnect.ts @@ -23,9 +23,12 @@ const useDisconnect = (values: Input) => { return useCallback(async () => { try { - const { activeWallet, connector } = dataRef.current + const { activeWallet, connector, library } = dataRef.current if (activeWallet !== wallets.monitorAddress.id) { + // Stop pending requests that may trigger eth_requestAccounts + library?.destroy() + await connector?.deactivate() } diff --git a/src/config/core/config/util/useWallet/useUpdateWallet.ts b/src/config/core/config/util/useWallet/useUpdateWallet.ts index a74a96c8..ee02ec36 100644 --- a/src/config/core/config/util/useWallet/useUpdateWallet.ts +++ b/src/config/core/config/util/useWallet/useUpdateWallet.ts @@ -1,13 +1,12 @@ import { useEffect, useCallback } from 'react' -import { getAddress, BrowserProvider } from 'ethers' +import { getAddress, toNumber, BrowserProvider } from 'ethers' import type { Eip1193Provider } from 'ethers' import getSDK from 'helpers/methods/getSDK' import ens from 'helpers/methods/ens' -import networks from '../networks' - type Input = { + networks: ConfigProvider.Networks chainId: number supportedNetworkIds: NetworkIds[] configState: ConfigProvider.ConfigState @@ -18,6 +17,7 @@ type Input = { const useUpdateWallet = (values: Input) => { const { + networks, chainId, configState, supportedNetworkIds, @@ -62,29 +62,31 @@ const useUpdateWallet = (values: Input) => { return } - const handleNetworkChanged = async (chainId: ChainIds) => { - const networkId = networks.idByChain[chainId] - const isSupported = supportedNetworkIds.includes(networkId) + const handleNetworkChanged = async (chainId: number | string) => { + const isHex = String(chainId).startsWith('0x') + + if (isHex) { + chainId = toNumber(chainId) + } + + const networkId = networks.idByChain[chainId as number] + const isSupported = Boolean(networkId) && supportedNetworkIds.includes(networkId as NetworkIds) if (isSupported) { const oldChainId = networks.chainById[dataRef.current.networkId] if (chainId !== oldChainId) { - const networkId = networks.idByChain[chainId] + const connector = dataRef.current.connector - if (networkId) { - const connector = dataRef.current.connector - - if (!connector) { - return - } + if (!connector) { + return + } - const provider = await connector.getProvider() - const library = new BrowserProvider(provider as Eip1193Provider) + const provider = await connector.getProvider() + const library = new BrowserProvider(provider as Eip1193Provider) - onChangeChain() - setData({ library, networkId }) - } + onChangeChain() + setData({ library, networkId }) } } else { @@ -134,6 +136,7 @@ const useUpdateWallet = (values: Input) => { }, [ address, dataRef, + networks, autoConnectChecked, supportedNetworkIds, setData, diff --git a/src/config/core/connectors/BinanceConnector.ts b/src/config/core/connectors/BinanceConnector.ts index bb3a970a..901dec19 100644 --- a/src/config/core/connectors/BinanceConnector.ts +++ b/src/config/core/connectors/BinanceConnector.ts @@ -2,23 +2,16 @@ import { getProvider } from '@binance/w3w-ethereum-provider' import EventAggregator from 'modules/event-aggregator' import { AbstractProvider } from 'ethers' -import apiUrls from 'helpers/methods/apiUrls' -import { Network } from 'sdk' - -import networks from '../config/util/networks' +import { Network } from 'sdk' export type Input = { chainId: Network + networks: ConfigProvider.Networks } type Provider = ReturnType -const rpc = Object.values(networks.configs).reduce((acc, config) => ({ - ...acc, - [config.chainId]: apiUrls.getWeb3Url(config.chainId), -}), {} as Record) - const languages: Record = { ru: 'ru-RU', en: 'en-US', @@ -32,18 +25,25 @@ const languages: Record = { class BinanceConnector extends AbstractProvider { events: EventAggregator private chainId?: number + private networks: ConfigProvider.Networks private account: string | null = null private providerInstance?: Provider - constructor({ chainId }: Input) { + constructor({ chainId, networks }: Input) { super() this.chainId = chainId + this.networks = networks this.events = new EventAggregator() } - async activate(networkId: NetworkIds, locale: Intl.LanguagesKeys) { - const chainId = networks.chainById[networkId] + async activate(networkId: string, locale: Intl.LanguagesKeys) { + const chainId = this.networks.chainById[networkId] + + const rpc = Object.values(this.networks.configs).reduce((acc, config) => ({ + ...acc, + [config.chainId]: Array.isArray(config.rpc) ? config.rpc[0] : config.rpc, + }), {} as Record) const providerInstance = getProvider({ lng: languages[locale], @@ -63,7 +63,7 @@ class BinanceConnector extends AbstractProvider { }) }) - this.providerInstance.on('chainChanged', (chainId: ChainIds) => { + this.providerInstance.on('chainChanged', (chainId: number) => { this.events.dispatch('change', { chainId, }) @@ -111,8 +111,8 @@ class BinanceConnector extends AbstractProvider { return } - const networkId = networks.idByChain[chainId] - const { hexadecimalChainId } = networks.configs[networkId] + const networkId = this.networks.idByChain[chainId] + const { hexadecimalChainId } = this.networks.configs[networkId] try { await this.providerInstance.request({ @@ -134,7 +134,7 @@ class BinanceConnector extends AbstractProvider { if (!this.account || force) { const accounts = await this.providerInstance.request({ - method: "eth_accounts", + method: 'eth_accounts', }) this.account = accounts[0] diff --git a/src/config/core/connectors/CoinbaseConnector.ts b/src/config/core/connectors/CoinbaseConnector.ts index d2b6f431..12012795 100644 --- a/src/config/core/connectors/CoinbaseConnector.ts +++ b/src/config/core/connectors/CoinbaseConnector.ts @@ -3,14 +3,18 @@ import { coinbaseWallet } from '@wagmi/connectors' import { WagmiConnector } from './helpers' +type Input = { + networks: ConfigProvider.Networks +} + class CoinbaseConnector extends WagmiConnector { - constructor() { + constructor({ networks }: Input) { const creator = coinbaseWallet({ appLogoUrl: 'https://app.stakewise.io/logo512.png', appName: 'StakeWise', }) - super({ creator }) + super({ creator, networks }) } } diff --git a/src/config/core/connectors/InjectedConnector.ts b/src/config/core/connectors/InjectedConnector.ts index c3a6c199..8fd3a918 100644 --- a/src/config/core/connectors/InjectedConnector.ts +++ b/src/config/core/connectors/InjectedConnector.ts @@ -1,11 +1,13 @@ -import { configs } from 'sdk' import { injected } from '@wagmi/connectors' import type { InjectedParameters } from '@wagmi/connectors' import { WagmiConnector } from './helpers' -import networks from '../config/util/networks' +type Input = InjectedParameters & { + networks: ConfigProvider.Networks +} + type InjectedProvider = { request: (values: { method: string @@ -14,25 +16,27 @@ type InjectedProvider = { } class InjectedConnector extends WagmiConnector { - constructor({ target, shimDisconnect }: InjectedParameters) { + + constructor({ target, networks, shimDisconnect }: Input) { const creator = injected({ target, shimDisconnect }) - super({ creator }) + super({ creator, networks }) } - async activate(networkId: NetworkIds): Promise { + async activate(networkId: string): Promise { const connectorChainId = await this.connector.getChainId() - const chainId = networks.chainById[networkId] + const chainId = this.networks.chainById[networkId] // fix to prevent infinite promise on super.activate - if (chainId !== connectorChainId) { + // skip if wallet doesn't respond before connect (e.g. Infinex returns connectorChainId 0) + if (connectorChainId && chainId !== connectorChainId) { await this.changeChainId(chainId) } return super.activate(networkId) } - async changeChainId(chainId: ChainIds): Promise { + async changeChainId(chainId: number): Promise { try { const provider = await this.getProvider() as InjectedProvider @@ -40,15 +44,18 @@ class InjectedConnector extends WagmiConnector { throw new Error('Provider not found') } - const config = configs[chainId] + const networkId = this.networks.idByChain[chainId] + const config = this.networks.configs[networkId] if (!config) { throw new Error(`Config for "${chainId} chain" not found`) } + const hexadecimalChainId = config.hexadecimalChainId + await provider.request({ method: 'wallet_switchEthereumChain', - params: [ { chainId: config.network.hexadecimalChainId } ], + params: [ { chainId: hexadecimalChainId } ], }) const hexChainId = await provider.request({ diff --git a/src/config/core/connectors/LedgerConnector/index.ts b/src/config/core/connectors/LedgerConnector/index.ts index adfbb3ed..229b11a9 100644 --- a/src/config/core/connectors/LedgerConnector/index.ts +++ b/src/config/core/connectors/LedgerConnector/index.ts @@ -6,36 +6,31 @@ import EventAggregator from 'modules/event-aggregator' import { PathTypes } from './enum' import { Transport } from './types' import LedgerProvider from './LedgerProvider' -import networks from '../../config/util/networks' export type Input = { chainId: Network transport?: Transport - params: Record + networks: ConfigProvider.Networks onError?: () => void } class LedgerConnector extends AbstractProvider { private chainId?: number events: EventAggregator - private params: Input['params'] private transport: Transport = 'usb' private account: string | null = null private providerInstance?: LedgerProvider + private networks: ConfigProvider.Networks private onError?: () => void | null - constructor({ params, transport, chainId, onError }: Input) { + constructor({ transport, chainId, networks, onError }: Input) { super() - this.params = params this.chainId = chainId this.transport = transport || 'usb' this.events = new EventAggregator() + this.networks = networks this.onError = onError this.#initActiveAccount() @@ -49,9 +44,10 @@ class LedgerConnector extends AbstractProvider { return this.providerInstance.pathType } - async activate(networkId: NetworkIds) { - const chainId = networks.chainById[networkId] - const { url } = this.params[chainId] + async activate(networkId: string) { + const { chainId, rpc } = this.networks.configs[networkId] + + const url = Array.isArray(rpc) ? rpc[0] : rpc const providerInstance = this.#initProvider(chainId, url) @@ -89,7 +85,10 @@ class LedgerConnector extends AbstractProvider { } async changeChainId(chainId: number) { - const { url } = this.params[chainId] + const networkId = this.networks.idByChain[chainId] + const { rpc } = this.networks.configs[networkId] + + const url = Array.isArray(rpc) ? rpc[0] : rpc if (!url) { console.error(`Invalid rpc url for chainId: ${chainId}`) diff --git a/src/config/core/connectors/NewLedgerConnector/LedgerProvider.ts b/src/config/core/connectors/NewLedgerConnector/LedgerProvider.ts new file mode 100644 index 00000000..2907f822 --- /dev/null +++ b/src/config/core/connectors/NewLedgerConnector/LedgerProvider.ts @@ -0,0 +1,318 @@ +import { configs, Network } from 'sdk' +import prefix0x from 'helpers/methods/prefix0x' +import { Signature, Transaction, isAddress } from 'ethers' +import type { TransactionLike, Eip1193Provider } from 'ethers' +import { hexaStringToBuffer } from '@ledgerhq/device-management-kit' + +import Signer from './Signer' +import { PathTypes } from './enum' +import LedgerTransport from './LedgerTransport' +import { Payload, TxParams, JSONRPCResponsePayload, ProviderInput } from './types' + + +class LedgerProvider extends LedgerTransport implements Eip1193Provider { + #rpcUrl: string + #chainId: Network + #accountIndex: number = 0 + #pathType: PathTypes = PathTypes.LIVE + + // More info here: https://blog.ledger.com/understanding-crypto-addresses-and-derivation-paths/ + private _paths: Record = { + [PathTypes.LIVE]: "44'/60'/{index}'/0/0", // (default) + [PathTypes.BIP44]: "44'/60'/0'/0/{index}", + [PathTypes.LEGACY]: "44'/60'/0'/{index}", + } + + #derivationPath = this.#getDerivationPath() + + constructor(values: ProviderInput) { + super(values) + const { rpcUrl, chainId } = values + + this.#rpcUrl = rpcUrl + this.#chainId = chainId + } + + get accountIndex() { + return this.#accountIndex + } + + set accountIndex(value) { + this.#accountIndex = value ?? 0 + this.#derivationPath = this.#getDerivationPath() + } + + get pathType() { + return this.#pathType + } + + set pathType(type: PathTypes) { + this.#pathType = type + this.#derivationPath = this.#getDerivationPath() + } + + setChain(values: Pick) { + const { rpcUrl, chainId } = values + + this.#rpcUrl = rpcUrl + this.#chainId = chainId + } + + async jsonRpcRequest(payload: Payload): Promise { + const { method, params } = payload + + const body = { + method, + params, + jsonrpc: '2.0', + id: this.#getRandomId(), + } + + const output = await fetch(this.#rpcUrl, { + body: JSON.stringify(body), + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + method: 'POST', + }) + + const data = await output.json() + + return data.result + } + + async request(payload: Payload): Promise { + const { method, params } = payload + + if (!Array.isArray(params)) { + return this.jsonRpcRequest(payload) + } + + if (method === 'eth_accounts') { + return this.getAccounts() + } + + if (method === 'eth_signTypedData_v4') { + return this.#requestEIP712(payload) + } + + if (method === 'eth_sendTransaction') { + const txParams = params[0] + const sender = txParams.from + + if (sender === undefined || !isAddress(sender)) { + throw new Error('Invalid or missing address') + } + + const data = await this.#fillMissingTxParams(txParams) + const signedTx = await this.signTransaction(data) + const response = await this.#sendRawTransaction(signedTx) + + return response + } + + if (method === 'eth_signTransaction') { + const txParams = params[0] + + const data = await this.#fillMissingTxParams(txParams) + const signedTx = await this.signTransaction(data) + + return { + raw: signedTx, + tx: txParams, + } + } + + if (method === 'eth_sign' || method === 'personal_sign') { + let data: any + + if (method === 'eth_sign') { + [ , data ] = params + } + else { + [ data ] = params + } + + const result = await this.signPersonalMessage(data) + + return result + } + + if (method === 'eth_chainId') { + const hexadecimalChainId = configs[this.#chainId].network.hexadecimalChainId + + const result = await this.jsonRpcRequest(payload) + + return result || hexadecimalChainId + } + + return this.jsonRpcRequest(payload) + } + + async signTransaction(txParams: TxParams) { + return this.connectLedger(async (signer: Signer) => { + const transaction: TransactionLike = { + type: null, + to: txParams.to, + data: txParams.data, + value: txParams.value, + gasLimit: txParams.gas, + gasPrice: txParams.gasPrice, + + // activated EIP-155 + chainId: this.#chainId, + } + + if ('nonce' in txParams) { + transaction.nonce = parseInt(txParams.nonce) + } + + // EIP-2930 + if ('accessList' in txParams) { + transaction.type = 1 + transaction.accessList = txParams.accessList + } + + // EIP-1559 + if (txParams.maxFeePerGas || txParams.maxPriorityFeePerGas) { + delete transaction.gasPrice // The parameter is not supported together with the EIP-1559 + + transaction.type = 2 + transaction.maxFeePerGas = txParams.maxFeePerGas + transaction.maxPriorityFeePerGas = txParams.maxPriorityFeePerGas + } + + const unsignedTx = Transaction.from(transaction).unsignedSerialized + const rawTxHex = hexaStringToBuffer(unsignedTx) + + if (!rawTxHex) { + throw new Error('Invalid transaction') + } + + const address = await signer.getAddress(this.#derivationPath) + const { r, s, v } = await signer.signTransaction(this.#derivationPath, rawTxHex) + + // Saves 1.5 bytes, which reduces the price of gas (EIP-2098) + const compact = Signature.from({ + r, + s, + v, + + // There is no "from" field in the signature parameters, but if you add it, + // then the number of field confirmations before the transaction is reduced + // from 9 to 3 and the price of gas is reduced + // @ts-ignore + from: address, + }).compactSerialized + + const signedTx = Transaction.from({ + ...transaction, + signature: compact, + }).serialized + + return signedTx + }) + } + + async signPersonalMessage(data: string) { + return this.connectLedger(async (signer: Signer) => { + const formattedData = prefix0x.remove(data) + + const result = await signer.signMessage(this.#derivationPath, formattedData) + + return Signature.from(result).compactSerialized + }) + } + + async getAccounts(from = 0, limit = 1) { + const addresses: string[] = [] + + for (let i = from; i < from + limit; i++) { + const path = this.#getDerivationPath(i) + const address = await this.getAccount(path) + + addresses.push(address as string) + } + + return addresses + } + + async #sendRawTransaction(signedTx: string): Promise { + const payload = { + method: 'eth_sendRawTransaction', + params: [ signedTx ], + } + + const result = await this.jsonRpcRequest(payload) + + return result + } + + async #fillMissingTxParams(txParams: TxParams): Promise { + const result = txParams + + if (txParams.gasPrice === undefined) { + const gasPrice = await this.jsonRpcRequest({ + method: 'eth_gasPrice', + params: [], + }) + + result.gasPrice = gasPrice + } + + if (txParams.nonce === undefined) { + const nonce = await this.jsonRpcRequest({ + method: 'eth_getTransactionCount', + params: [ txParams.from, 'pending' ], + }) + + result.nonce = nonce + } + + if (txParams.gas === undefined) { + const gas = await this.jsonRpcRequest({ + method: 'eth_estimateGas', + params: [ txParams ], + }) + + result.gas = gas + } + + return result + } + + async #requestEIP712(payload: Payload) { + if (payload.params && payload.params.length < 2) { + throw new Error('No second parameter in the array') + } + + const typedData = JSON.parse(payload.params[1]) + + return this.connectLedger(async (signer: Signer) => { + // https://app.devicesdk.ledger-test.com/signers/ethereum (if you need to compare signatures) + const result = await signer.signTypedData(this.#derivationPath, { + types: typedData.types, + domain: typedData.domain, + message: typedData.message, + primaryType: typedData.primaryType, + }) + + return Signature.from(result).compactSerialized + }) + } + + #getDerivationPath(index: number = this.#accountIndex) { + return this._paths[this.#pathType].replace('{index}', `${index}`) + } + + #getRandomId(): number { + const datePart = new Date().getTime() * Math.pow(10, 3) + const extraPart = Math.floor(Math.random() * Math.pow(10, 3)) + + return datePart + extraPart + } +} + + +export default LedgerProvider diff --git a/src/config/core/connectors/NewLedgerConnector/LedgerTransport.ts b/src/config/core/connectors/NewLedgerConnector/LedgerTransport.ts new file mode 100644 index 00000000..451be526 --- /dev/null +++ b/src/config/core/connectors/NewLedgerConnector/LedgerTransport.ts @@ -0,0 +1,121 @@ +import { + DiscoveredDevice, + DeviceManagementKit, + DeviceManagementKitBuilder, +} from '@ledgerhq/device-management-kit' +import { + SignerEthBuilder, +} from '@ledgerhq/device-signer-kit-ethereum' +import { webHidTransportFactory, webHidIdentifier } from '@ledgerhq/device-transport-kit-web-hid' +import { webBleTransportFactory, webBleIdentifier } from '@ledgerhq/device-transport-kit-web-ble' + +import Signer from './Signer' + +import { Transport, ProviderInput } from './types' + + +class LedgerTransport { + #dmk: DeviceManagementKit + #transport: Transport = 'usb' + #sessionId: string | null = null + #signer: Signer | null = null + #onError?: () => void + + constructor(values: ProviderInput) { + const { transport, onError } = values + + this.#onError = onError + this.#transport = transport + + this.#dmk = new DeviceManagementKitBuilder() + .addTransport(webHidTransportFactory) + .addTransport(webBleTransportFactory) + .build() + } + + getAvailableDevice(): Promise { + return new Promise((resolve) => { + const transport = this.#transport === 'usb' ? webHidIdentifier : webBleIdentifier + + const devicesSubscription = this.#dmk.listenToAvailableDevices({ transport }).subscribe((devices) => { + if (devices.length) { + devicesSubscription.unsubscribe() + resolve(devices[0]) + } + }) + + setTimeout(() => { + devicesSubscription.unsubscribe() + resolve(null) + }, 500) + }) + } + + async getDevice(): Promise { + const availableDevice = await this.getAvailableDevice() + + if (availableDevice) { + return availableDevice + } + + return new Promise((resolve, reject) => { + const transport = this.#transport === 'usb' ? webHidIdentifier : webBleIdentifier + + const discoverySubscription = this.#dmk.startDiscovering({ transport }).subscribe({ + next: async (device) => { + discoverySubscription.unsubscribe() + resolve(device) + }, + error: (error) => { + discoverySubscription.unsubscribe() + reject(error?.originalError || error) + }, + }) + }) + } + + async getAccount(path?: string) { + if (this.#signer === null) { + throw new Error('Session not found') + } + + return this.#signer.getAddress(path || `44'/60'/0'/0/0`) + } + + async connectLedger(method?: (signer: Signer) => Promise) { + if (!this.#sessionId) { + try { + const device = await this.getDevice() + + this.#sessionId = await this.#dmk.connect({ device }) + + const observableSigner = new SignerEthBuilder({ + dmk: this.#dmk, + sessionId: this.#sessionId, + originToken: 'StakeWise', + }) + .build() + + this.#signer = new Signer({ observableSigner }) + } + catch { + if (typeof this.#onError === 'function') { + this.#onError() + } + } + } + + if (typeof method === 'function' && this.#signer !== null) { + return method(this.#signer) + } + + return '' + } + + deactivate() { + this.#sessionId = null + } +} + + +export default LedgerTransport diff --git a/src/config/core/connectors/NewLedgerConnector/Signer.ts b/src/config/core/connectors/NewLedgerConnector/Signer.ts new file mode 100644 index 00000000..446bb4ee --- /dev/null +++ b/src/config/core/connectors/NewLedgerConnector/Signer.ts @@ -0,0 +1,50 @@ +import { + SignerEthBuilder, + SignTypedDataDAOutput, + SignTransactionDAOutput, + SignPersonalMessageDAOutput, +} from '@ledgerhq/device-signer-kit-ethereum' + +import toPromise from './toPromise' + + +type ObservableSigner = ReturnType +type MethodParams = Parameters + +type TypedData = MethodParams<'signTypedData'>[1] +type MessageOptions = MethodParams<'signMessage'>[2] +type AddressOptions = MethodParams<'getAddress'>[1] +type TypedDataOptions = MethodParams<'signTypedData'>[2] +type TransactionOptions = MethodParams<'signTransaction'>[2] + +type Input = { + observableSigner: ObservableSigner +} + +class Signer { + #signer: ObservableSigner + + constructor({ observableSigner }: Input) { + this.#signer = observableSigner + } + + signTransaction(derivationPath: string, transaction: Uint8Array, options?: TransactionOptions) { + return toPromise(this.#signer.signTransaction(derivationPath, transaction, options)) + } + + signMessage(derivationPath: string, message: string | Uint8Array, options?: MessageOptions) { + return toPromise(this.#signer.signMessage(derivationPath, message, options)) + } + + signTypedData(derivationPath: string, typedData: TypedData, options?: TypedDataOptions) { + return toPromise(this.#signer.signTypedData(derivationPath, typedData, options)) + } + + getAddress(derivationPath: string, options?: AddressOptions): Promise { + return toPromise<{ address: string }>(this.#signer.getAddress(derivationPath, options)) + .then(({ address }) => address) + } +} + + +export default Signer diff --git a/src/config/core/connectors/NewLedgerConnector/enum.ts b/src/config/core/connectors/NewLedgerConnector/enum.ts new file mode 100644 index 00000000..61b32985 --- /dev/null +++ b/src/config/core/connectors/NewLedgerConnector/enum.ts @@ -0,0 +1,5 @@ +export enum PathTypes { + LEGACY = 'legacy', + BIP44 = 'bip44', + LIVE = 'live', +} diff --git a/src/config/core/connectors/NewLedgerConnector/index.ts b/src/config/core/connectors/NewLedgerConnector/index.ts new file mode 100644 index 00000000..138e43a1 --- /dev/null +++ b/src/config/core/connectors/NewLedgerConnector/index.ts @@ -0,0 +1,217 @@ +import { AbstractProvider } from 'ethers' +import { Network , localStorage } from 'sdk' +import { localStorageNames } from 'helpers/constants' +import EventAggregator from 'modules/event-aggregator' + +import { PathTypes } from './enum' +import { Transport } from './types' +import LedgerProvider from './LedgerProvider' + + +export type Input = { + chainId: Network + transport?: Transport + networks: ConfigProvider.Networks + onError?: () => void +} + +class LedgerConnector extends AbstractProvider { + private chainId?: number + events: EventAggregator + private transport: Transport = 'usb' + private account: string | null = null + private providerInstance?: LedgerProvider + private networks: ConfigProvider.Networks + private onError?: () => void | null + + constructor({ transport, chainId, networks, onError }: Input) { + super() + + this.chainId = chainId + this.transport = transport || 'usb' + this.events = new EventAggregator() + this.networks = networks + + this.onError = onError + } + + get pathType(): PathTypes { + if (!this.providerInstance) { + throw new Error('Empty providerInstance') + } + + return this.providerInstance.pathType + } + + async activate(networkId: string) { + const { chainId, rpc } = this.networks.configs[networkId] + + const url = Array.isArray(rpc) ? rpc[0] : rpc + + const providerInstance = this.#initProvider(chainId, url) + + this.chainId = chainId + this.providerInstance = providerInstance + + await providerInstance.connectLedger() + this.#initActiveAccount() + const account = await this.getAccount() + + return { + provider: this.providerInstance, + chainId: this.chainId, + account, + } + } + + deactivate() { + super.destroy() + this.providerInstance?.deactivate() + } + + async getProvider() { + if (!this.providerInstance) { + throw new Error('Empty providerInstance') + } + + return this.providerInstance + } + + async getChainId() { + if (!this.chainId) { + throw new Error('Empty chainId') + } + + return this.chainId + } + + async changeChainId(chainId: number) { + const networkId = this.networks.idByChain[chainId] + const { rpc } = this.networks.configs[networkId] + + const url = Array.isArray(rpc) ? rpc[0] : rpc + + if (!url) { + console.error(`Invalid rpc url for chainId: ${chainId}`) + + return + } + + if (!this.providerInstance) { + console.error('Invalid provider instance') + + return + } + + this.providerInstance.setChain({ + chainId, + rpcUrl: url, + }) + + this.chainId = chainId + } + + async getAccount(force = false) { + if (!this.providerInstance) { + throw new Error('Empty providerInstance') + } + + if (!this.account || force) { + const accounts = await this.getAccounts(this.providerInstance.accountIndex, 1) + + this.account = accounts[0] + } + + return this.account + } + + async setActiveAccount(index: number) { + if (!this.providerInstance) { + throw new Error('Empty providerInstance') + } + + if (this.providerInstance.accountIndex !== index) { + this.providerInstance.accountIndex = index + const account = await this.getAccount(true) + + this.events.dispatch('change', { + provider: this.provider, + chainId: this.chainId, + account, + }) + } + } + + getAccounts(from = 0, limit = 5) { + if (!this.providerInstance) { + throw new Error('Empty providerInstance') + } + + return this.providerInstance.getAccounts(from, limit) + } + + async setPathType(type: PathTypes) { + if (!this.providerInstance) { + throw new Error('Empty providerInstance') + } + + const pathType = this.providerInstance.pathType + + if (pathType === type) { + return + } + + this.providerInstance.pathType = type + + const account = await this.getAccount(true) + + this.events.dispatch('change', { + provider: this.provider, + chainId: this.chainId, + account, + }) + } + + get provider(): any { + if (!this.providerInstance) { + throw new Error('Empty providerInstance') + } + + return this.providerInstance + } + + #initProvider(chainId: number, url: string) { + const providerInstance = new LedgerProvider({ + transport: this.transport, + onError: this.onError, + rpcUrl: url, + chainId, + }) + + this.providerInstance = providerInstance + + return providerInstance + } + + async #initActiveAccount() { + const localStorageName = localStorageNames.ledgerSelectedAccount + const savedLedgerAccount = localStorage.getItem(localStorageName) + + if (savedLedgerAccount) { + const { index, pathType } = savedLedgerAccount + + const promises = [ + this.setActiveAccount(index), + ] + + if (pathType) { + promises.push(this.setPathType(pathType)) + } + + await Promise.all(promises) + } + } +} + + +export default LedgerConnector diff --git a/src/config/core/connectors/NewLedgerConnector/toPromise.ts b/src/config/core/connectors/NewLedgerConnector/toPromise.ts new file mode 100644 index 00000000..8705b1b8 --- /dev/null +++ b/src/config/core/connectors/NewLedgerConnector/toPromise.ts @@ -0,0 +1,18 @@ +import { DeviceActionStatus } from '@ledgerhq/device-management-kit' + + +const toPromise = (observableLike: { observable: { subscribe: (cb: (s: any) => void) => void } }): Promise => { + return new Promise((resolve, reject) => { + observableLike.observable.subscribe((state) => { + if (state.status === DeviceActionStatus.Completed) { + resolve(state.output) + } + if (state.status === DeviceActionStatus.Error) { + reject(state.error) + } + }) + }) +} + + +export default toPromise diff --git a/src/config/core/connectors/NewLedgerConnector/types.ts b/src/config/core/connectors/NewLedgerConnector/types.ts new file mode 100644 index 00000000..31ad1ddd --- /dev/null +++ b/src/config/core/connectors/NewLedgerConnector/types.ts @@ -0,0 +1,49 @@ +import { Network } from 'sdk' + + +export type Payload = { + params: any[] + method: string +} + +export type JSONRPCResponseError = { + message: string + code: number +} + +export type JSONRPCRequestPayload = { + id: number + params: any[] + method: string + jsonrpc: string +} + +export type JSONRPCResponsePayload = { + id: number + result: any + jsonrpc: string + error?: JSONRPCResponseError +} + +export type TxParams = { + to: string + gas: string + from: string + type?: number + nonce: string + data?: string + value?: string + gasPrice?: string + maxFeePerGas?: string + maxPriorityFeePerGas?: string + accessList?: Array<{ address: string, storageKeys: string[] }> +} + +export type Transport = 'usb' | 'ble' + +export type ProviderInput = { + transport: Transport + chainId: Network + rpcUrl: string + onError?: () => void +} diff --git a/src/config/core/connectors/SafeAppConnector.ts b/src/config/core/connectors/SafeAppConnector.ts index 8a6bfe76..ee3f0be4 100644 --- a/src/config/core/connectors/SafeAppConnector.ts +++ b/src/config/core/connectors/SafeAppConnector.ts @@ -8,13 +8,17 @@ import { WagmiConnector } from './helpers' import messages from '../messages' +type Input = { + networks: ConfigProvider.Networks +} + class SafeAppConnector extends WagmiConnector { private sdk: SafeAppsSDK - constructor() { + constructor({ networks }: Input) { const creator = safe() - super({ creator }) + super({ creator, networks }) this.sdk = new SafeAppsSDK() } diff --git a/src/config/core/connectors/WalletLinkConnector.ts b/src/config/core/connectors/WalletLinkConnector.ts index 430e6bed..d695a1d6 100644 --- a/src/config/core/connectors/WalletLinkConnector.ts +++ b/src/config/core/connectors/WalletLinkConnector.ts @@ -3,23 +3,41 @@ import type { SafeAppProvider } from '@safe-global/safe-apps-provider' import type { WalletConnectParameters } from '@wagmi/connectors' import { ChainNotConfiguredError } from '@wagmi/core' import { walletConnect } from '@wagmi/connectors' -import apiUrls from 'helpers/methods/apiUrls' -import { WagmiConnector, chains } from './helpers' -import networks from '../config/util/networks' +import { WagmiConnector } from './helpers' +const initialWalletData = { + name: null, + iconUrl: null, + chains: [], + support: { + eip712: false, + addChain: false, + switchChanin: false, + }, +} + type Provider = { request: (params: any) => Promise } +type Input = WalletConnectParameters & { + networks: ConfigProvider.Networks +} + class WalletLinkConnector extends WagmiConnector { + walletData: ConfigProvider.WalletConnectData = initialWalletData + networks: ConfigProvider.Networks - constructor(values: WalletConnectParameters) { - const creator = walletConnect(values) + constructor(values: Input) { + const { networks, ...rest } = values - super({ creator }) + const creator = walletConnect(rest) + super({ creator, networks }) + + this.networks = networks this.connector.switchChain = this.switchChain.bind(this) } @@ -29,6 +47,46 @@ class WalletLinkConnector extends WagmiConnector { }) } + async activate(networkId: string, _locale?: string, isReconnecting = false) { + return super.activate(networkId, _locale, isReconnecting) + .then(async () => { + const provider = await this.connector.getProvider() as any + + const walletName = provider?.session?.peer?.metadata?.name || null + const walletIcons = provider?.session?.peer?.metadata?.icons || [] + + const supportedChains = Object.values(this.networks.default).map(({ chainId }) => chainId) + + const chains = (provider?.signer?.namespaces?.eip155?.chains || []) + .map((value = '') => Number(value.replace('eip155:', ''))) + .filter((chainId: number) => supportedChains.includes(chainId)) + + const methods = provider?.signer?.namespaces?.eip155?.methods || [] + + const support = { + eip712: methods.includes('eth_signTypedData_v4'), + addChain: methods.includes('wallet_addEthereumChain'), + switchChanin: methods.includes('wallet_switchEthereumChain'), + } + + this.walletData = { + iconUrl: walletIcons[0] || null, + name: walletName, + support, + chains, + } + }) + } + + async deactivate() { + return super.deactivate() + .finally(() => this.walletData = initialWalletData) + } + + getWalletData() { + return this.walletData + } + async getProvider() { const provider = await this.connector.getProvider() as SafeAppProvider @@ -38,6 +96,8 @@ class WalletLinkConnector extends WagmiConnector { if (isGnosisSafe) { const method = provider.request + const chainId = provider.chainId + provider.request = async (data) => { const response = await method.bind(provider)(data) @@ -55,7 +115,15 @@ class WalletLinkConnector extends WagmiConnector { while (true) { let timer = 0 - const safeAPI = 'https://safe-transaction-gnosis-chain.safe.global/api/v1/multisig-transactions' + const chainNames: Record = { + 1: 'eth', + 100: 'gno', + } + + const chainName = chainNames[chainId] + + const safeAPI = `https://api.safe.global/tx-service/${chainName}/api/v1/multisig-transactions` + const response = await fetch(`${safeAPI}/${safeHash}`) if (!response.ok) { @@ -98,21 +166,25 @@ class WalletLinkConnector extends WagmiConnector { const provider = await this.getProvider() if (provider) { - const networkId = networks.idByChain[chainId as ChainIds] - - const network = networks.configs[networkId] + const networkId = this.networks.idByChain[chainId as number] - const url = apiUrls.getWeb3Url(chainId) + const { + rpc, + name, + nativeCurrency, + blockExplorerUrl, + hexadecimalChainId, + } = this.networks.configs[networkId] await (provider as any).request({ method: 'wallet_addEthereumChain', params: [ { - blockExplorerUrls: [ network.blockExplorerUrl ], - nativeCurrency: network.nativeCurrency, - chainId: network.hexadecimalChainId, - rpcUrls: [ url ], - chainName: network.name, + chainName: name, + chainId: hexadecimalChainId, + nativeCurrency: nativeCurrency, + blockExplorerUrls: [ blockExplorerUrl ], + rpcUrls: Array.isArray(rpc) ? rpc : [ rpc ], }, ], }) @@ -132,7 +204,8 @@ class WalletLinkConnector extends WagmiConnector { } async switchChain({ chainId, timeout }: { chainId: number, timeout?: number }) { - const chain = chains.find((chain) => chain.id === chainId) + const networkId = this.networks.idByChain[chainId as number] + const chain = this.networks.configs[networkId as string] if (!chain) { throw new SwitchChainError(new ChainNotConfiguredError()) diff --git a/src/config/core/connectors/helpers/WagmiConnector.ts b/src/config/core/connectors/helpers/WagmiConnector.ts index 7534a435..4afde557 100644 --- a/src/config/core/connectors/helpers/WagmiConnector.ts +++ b/src/config/core/connectors/helpers/WagmiConnector.ts @@ -1,31 +1,7 @@ import { injected, coinbaseWallet, walletConnect, safe } from '@wagmi/connectors' -import { mainnet, hoodi, gnosis } from 'viem/chains' import EventAggregator from 'modules/event-aggregator' -import apiUrls from 'helpers/methods/apiUrls' import type { Chain } from 'viem/chains' -import networks from '../../config/util/networks' - - -const viemChains = [ mainnet, hoodi, gnosis ] - -const chains: Chain[] = [] - -networks.chains.forEach((chainId) => { - const viemChain = viemChains.find((data) => data.id === Number(chainId)) - - if (viemChain) { - const result: Chain = { ...viemChain } - const url = apiUrls.getWeb3Url(chainId) - - // Inside wagmi there is use of contracts as a helper, it looks dangerous, better to remove it - delete result.contracts - - result.rpcUrls.default.http = Array.isArray(url) ? [ url[0] ] : [ url ] - - chains.push(result) - } -}) type Creators = ReturnType< typeof injected @@ -36,11 +12,13 @@ type Creators = ReturnType< type Input = { creator: Creators + networks: ConfigProvider.Networks } class WagmiConnector { events: EventAggregator connector: ReturnType + networks: ConfigProvider.Networks emitter = { emit: (type: string, data: any) => { @@ -59,8 +37,22 @@ class WagmiConnector { } constructor(values: Input) { + this.networks = values.networks this.events = new EventAggregator() + const chains: Chain[] = Object.values(this.networks.default).map(({ viem, id }) => { + const { rpc } = this.networks.configs[id] + + const chain: Chain = { ...viem } + + // Inside wagmi there is use of contracts as a helper, it looks dangerous, better to remove it + delete chain.contracts + + chain.rpcUrls.default.http = Array.isArray(rpc) ? rpc : [ rpc ] + + return chain + }) + this.connector = values.creator({ // @ts-ignore chains, @@ -87,14 +79,14 @@ class WagmiConnector { return accounts[0] } - async activate(networkId: NetworkIds) { - const chainId = networks.chainById[networkId] + async activate(networkId: string, _locale?: string, isReconnecting = false) { + const chainId = this.networks.chainById[networkId] try { const data = await this.connector.connect({ chainId, // ATTN https://github.com/wevm/wagmi/blob/main/packages/core/src/connectors/injected.ts#L167 - isReconnecting: false, + isReconnecting, }) return data @@ -114,21 +106,25 @@ class WagmiConnector { const provider = await this.connector.getProvider() if (provider) { - const networkId = networks.idByChain[chainId as ChainIds] + const networkId = this.networks.idByChain[chainId as number] - const network = networks.configs[networkId] - - const url = apiUrls.getWeb3Url(chainId) + const { + rpc, + name, + nativeCurrency, + blockExplorerUrl, + hexadecimalChainId, + } = this.networks.configs[networkId] await (provider as any).request({ method: 'wallet_addEthereumChain', params: [ { - blockExplorerUrls: [ network.blockExplorerUrl ], - nativeCurrency: network.nativeCurrency, - chainId: network.hexadecimalChainId, - chainName: network.name, - rpcUrls: [ url ], + chainName: name, + chainId: hexadecimalChainId, + nativeCurrency: nativeCurrency, + blockExplorerUrls: [ blockExplorerUrl ], + rpcUrls: Array.isArray(rpc) ? rpc : [ rpc ], }, ], }) @@ -166,6 +162,4 @@ class WagmiConnector { } -export { chains } - export default WagmiConnector diff --git a/src/config/core/connectors/helpers/index.ts b/src/config/core/connectors/helpers/index.ts index ac8c3e58..62ee1f3b 100644 --- a/src/config/core/connectors/helpers/index.ts +++ b/src/config/core/connectors/helpers/index.ts @@ -1,2 +1 @@ -export { chains } from './WagmiConnector' export { default as WagmiConnector } from './WagmiConnector' diff --git a/src/config/core/global.d.ts b/src/config/core/global.d.ts index 301fe69c..0434a0ee 100644 --- a/src/config/core/global.d.ts +++ b/src/config/core/global.d.ts @@ -1,4 +1,3 @@ -import networks from './config/util/networks' import wallets from './wallets' @@ -7,14 +6,15 @@ const walletsIds = Object.values(wallets).map(({ id }) => id) declare global { type WalletIds = typeof walletsIds[number] type ReadOnlyConnector = ReadOnlyConnectorType - type NetworkIds = OneOfArray + type NetworkIds = 'mainnet' | 'gnosis' | 'hoodi' type Connectors = Unpromise> + type RefObject = { current: T } namespace LocalStorageData { type SavedNetwork = { - id: NetworkIds - chainId: ChainIds + id: string + chainId: number } type LedgerSelectedAccount = { @@ -26,5 +26,6 @@ declare global { type GetConnectorOptions = { transport?: 'usb' | 'ble' disconnect?: () => void + networks: ConfigProvider.Networks } } diff --git a/src/config/core/index.ts b/src/config/core/index.ts index 07db207d..5f3b96a5 100644 --- a/src/config/core/index.ts +++ b/src/config/core/index.ts @@ -1,3 +1,2 @@ -export { default as networks } from './config/util/networks' export { default as wallets } from './wallets' export { createConfig } from './config' diff --git a/src/config/core/messages.ts b/src/config/core/messages.ts index 4740d56a..288eaaaa 100644 --- a/src/config/core/messages.ts +++ b/src/config/core/messages.ts @@ -15,7 +15,7 @@ export default { es: 'Desconectado exitosamente de {wallet}', pt: 'Desconectado com sucesso de {wallet}', de: 'Erfolgreich von {wallet} getrennt', - zh: '成功断开连接 {wallet}', + zh: '成功断开与 {wallet} 的连接', }, switchNetwork: { en: 'Please confirm via WalletConnect to switch network', @@ -24,13 +24,13 @@ export default { es: 'Por favor confirme a través de WalletConnect para cambiar de red', pt: 'Por favor, confirme através do WalletConnect para mudar de rede', de: 'Bitte bestätigen Sie über WalletConnect, um das Netzwerk zu wechseln', - zh: '请通过WalletConnect确认以切换网络', + zh: '请通过 WalletConnect 确认以切换网络', }, authMessages: { waitingAuth: { en: 'Waiting for authorization to be completed', ru: 'Ожидание завершения авторизации', - fr: 'En attente de l\'achèvement de l\'autorisation', + fr: 'En attente de l\'autorisation', es: 'Esperando a que se complete la autorización', pt: 'Aguardando a conclusão da autorização', de: 'Warten auf Abschluss der Autorisierung', @@ -39,9 +39,9 @@ export default { waitingAuthByQR: { en: 'Waiting for QR code to be scanned', ru: 'Ожидание сканирования QR-кода', - fr: 'En attente de la numérisation du code QR', + fr: 'En attente du scan du code QR', es: 'Esperando que se escanee el código QR', - pt: 'Aguardando a leitura do código QR', + pt: 'Aguardando o scan do código QR', de: 'Warten auf das Scannen des QR-Codes', zh: '等待扫描二维码', }, @@ -60,7 +60,7 @@ export default { en: 'Your wallet does not support adding the network', ru: 'Ваш кошелек не поддерживает добавление сети', fr: 'Votre portefeuille ne prend pas en charge l\'ajout du réseau', - es: 'Su billetera no admite la adición de la red', + es: 'Su billetera no permite agregar la red', pt: 'Sua carteira não suporta a adição da rede', de: 'Ihr Wallet unterstützt das Hinzufügen des Netzwerks nicht', zh: '您的钱包不支持添加网络', @@ -69,7 +69,7 @@ export default { en: 'Your wallet does not support switching the network', ru: 'Ваш кошелек не поддерживает переключение сети', fr: 'Votre portefeuille ne prend pas en charge le changement de réseau', - es: 'Su billetera no admite cambiar la red', + es: 'Su billetera no permite cambiar la red', pt: 'Sua carteira não suporta a troca de rede', de: 'Ihr Wallet unterstützt das Wechseln des Netzwerks nicht', zh: '您的钱包不支持切换网络', @@ -119,14 +119,23 @@ export default { de: 'Das ausgewählte Netzwerk wird nicht unterstützt', zh: '所选网络不受支持', }, + unsupportedNetwork: { + en: 'The connected {wallet} does not support the selected network.', + ru: 'Подключённый кошелёк {wallet} не поддерживает выбранную сеть.', + fr: 'Le portefeuille {wallet} connecté ne prend pas en charge le réseau sélectionné.', + es: 'La billetera {wallet} conectada no es compatible con la red seleccionada.', + pt: 'A carteira {wallet} conectada não suporta a rede selecionada.', + de: 'Die verbundene {wallet}-Wallet unterstützt das ausgewählte Netzwerk nicht.', + zh: '已连接的 {wallet} 钱包不支持所选网络。', + }, chainIdError: { en: 'Current chain id is not supported', ru: 'Текущий идентификатор цепи не поддерживается', fr: 'L\'identifiant de chaîne actuel n\'est pas supporté', es: 'El ID de cadena actual no es compatible', - pt: 'O ID de corrente atual não é suportado', + pt: 'O ID de cadeia atual não é suportado', de: 'Die aktuelle Ketten-ID wird nicht unterstützt', - zh: '当前链ID不受支持', + zh: '当前链 ID 不受支持', }, authorize: { en: 'Please allow access to your account', @@ -163,7 +172,7 @@ export default { es: 'La aplicación Ledger Ethereum no está abierta', pt: 'O aplicativo Ledger Ethereum não está aberto', de: 'Die Ledger Ethereum App ist nicht geöffnet', - zh: 'Ledger Ethereum应用未打开', + zh: 'Ledger Ethereum 应用未打开', }, lock: { en: 'Please unlock the Ledger', @@ -190,7 +199,7 @@ export default { es: 'Ledger no está conectado o la aplicación Ethereum no está abierta', pt: 'Ledger não está conectado ou o aplicativo Ethereum não está aberto', de: 'Ledger ist nicht verbunden oder die Ethereum-App ist nicht geöffnet', - zh: 'Ledger未连接或Ethereum应用未打开', + zh: 'Ledger 未连接或 Ethereum 应用未打开', }, }, }, diff --git a/src/config/core/providers/eip6963.ts b/src/config/core/providers/eip6963.ts new file mode 100644 index 00000000..6e51a0a1 --- /dev/null +++ b/src/config/core/providers/eip6963.ts @@ -0,0 +1,19 @@ +import { createStore } from 'mipd' + + +const providerStore = typeof window !== 'undefined' + ? createStore() + : null + + +export const findProvider = (rdns: string): any => { + return providerStore?.findProvider({ rdns })?.provider || null +} + +export const findProviderIcon = (rdns: string): string | undefined => { + return providerStore?.findProvider({ rdns })?.info.icon +} + +export const getAutoDetectedProviders = () => { + return providerStore?.getProviders() || [] +} diff --git a/src/config/core/wallets/binance.ts b/src/config/core/wallets/binance.ts index 2b7dfccd..9841905b 100644 --- a/src/config/core/wallets/binance.ts +++ b/src/config/core/wallets/binance.ts @@ -2,6 +2,8 @@ import { Network } from 'sdk' import { Location, IsDisabled } from './types' +import { getInjectedConnector } from './injected/helpers' + import messages from '../messages' @@ -25,23 +27,17 @@ const target = () => { } } -const getConnector = async (chainId: Network) => { +const getConnector = async (chainId: Network, options: GetConnectorOptions) => { // When we access the site through mobile app then we will have injected provider, // but if we visit the site through desktop, then the logic is like wallet connect if (window.ethereum?.isBinance) { - const InjectedConnector = (await import('../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ target, shimDisconnect: false }) - - return connector + return getInjectedConnector({ target, shimDisconnect: false })(chainId, options) } else { const BinanceConnector = (await import('../connectors/BinanceConnector')).default - const connector = new BinanceConnector({ chainId }) - - return connector + return new BinanceConnector({ chainId, ...options }) } } @@ -49,12 +45,16 @@ const binance = { id: 'binance', title: 'Binance', logo: 'connector/binance', + isAutoConnect: false, isAddTokenEnabled: false, isInjectedWallet: false, isLocalStorageSave: false, - isDisableSwitchChain: true, + isDisableSwitchChain: false, activationMessage: messages.authMessages.waitingAuth, - networks: [ Network.Mainnet ] as ChainIds[], + networks: [ + Network.Mainnet, + Network.Gnosis, + ] as ChainIds[], location: [ 'desktop', 'mobile' ] as Location, getConnector, getProvider, diff --git a/src/config/core/wallets/coinbase.ts b/src/config/core/wallets/coinbase.ts index 654bf39b..c471f4c0 100644 --- a/src/config/core/wallets/coinbase.ts +++ b/src/config/core/wallets/coinbase.ts @@ -5,27 +5,26 @@ import { Location } from './types' import messages from '../messages' -const getConnector = async () => { +const getConnector = async (_: any, options: GetConnectorOptions) => { const CoinbaseConnector = (await import('../connectors/CoinbaseConnector')).default - const connector = new CoinbaseConnector() - - return connector + return new CoinbaseConnector(options) } const coinbase = { id: 'coinbase', title: 'Coinbase', logo: 'connector/coinbase', - networks: [ - Network.Mainnet, - Network.Gnosis, - ] as ChainIds[], + isAutoConnect: false, isAddTokenEnabled: false, isInjectedWallet: false, isLocalStorageSave: true, isDisableSwitchChain: false, activationMessage: messages.authMessages.waitingAuth, + networks: [ + Network.Mainnet, + Network.Gnosis, + ] as ChainIds[], location: IS_LIGHTWEIGHT_MODE ? [] as Location : [ 'desktop', 'mobile' ] as Location, diff --git a/src/config/core/wallets/gnosisSafe.ts b/src/config/core/wallets/gnosisSafe.ts index ce658e5c..dcde391a 100644 --- a/src/config/core/wallets/gnosisSafe.ts +++ b/src/config/core/wallets/gnosisSafe.ts @@ -5,18 +5,17 @@ import { Location } from './types' import messages from '../messages' -const getConnector = async () => { +const getConnector = async (_: any, options: GetConnectorOptions) => { const SafeAppConnector = (await import('../connectors/SafeAppConnector')).default - const connector = new SafeAppConnector() - - return connector + return new SafeAppConnector(options) } const gnosisSafe = { id: 'gnosisSafe', title: 'Gnosis Safe', logo: 'connector/gnosisSafe', + isAutoConnect: true, isAddTokenEnabled: false, isInjectedWallet: false, isLocalStorageSave: false, diff --git a/src/config/core/wallets/index.ts b/src/config/core/wallets/index.ts index 4c96fc99..4ce1b860 100644 --- a/src/config/core/wallets/index.ts +++ b/src/config/core/wallets/index.ts @@ -1,34 +1,42 @@ 'use client' -import zenGo from './zenGo' import ledger from './ledger' import binance from './binance' import coinbase from './coinbase' import gnosisSafe from './gnosisSafe' -import walletConnect from './walletConnect' import monitorAddress from './monitorAddress' -import { braveWallet, dAppBrowser, trustWallet, metaMask, rabby, taho, okx, ledgerLive } from './injected' +import { walletConnect } from './walletConnect' +import { dAppBrowser, ledgerLive } from './injected' +import { getAutoDetectedWallets } from './injected/helpers' +type WalletConfig = typeof staticWallets[keyof typeof staticWallets] + +type Wallets = Record + // ATTN The order here is equal to the order in the UI not counting filters -const wallets = { - // Inject wallets - metaMask, - rabby, - braveWallet, - trustWallet, - dAppBrowser, - okx, - taho, +const staticWallets = { + // Inject wallets with custom logic ledgerLive, + dAppBrowser, walletConnect, ledger, binance, coinbase, gnosisSafe, - zenGo, monitorAddress, -} as const +} + +// EIP-6963 detected wallets (MetaMask, Rabby, OKX, etc.) +const autoDetected = getAutoDetectedWallets(staticWallets) + +const detectedWallets: Wallets = {} + +for (const wallet of autoDetected) { + detectedWallets[wallet.id] = wallet as any +} + +const wallets: Wallets = { ...detectedWallets, ...staticWallets } export default wallets diff --git a/src/config/core/wallets/injected/braveWallet.ts b/src/config/core/wallets/injected/braveWallet.ts deleted file mode 100644 index 708b64fe..00000000 --- a/src/config/core/wallets/injected/braveWallet.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Network } from 'sdk' - -import { Location, IsDisabled } from '../types' - -import messages from '../../messages' - - -const getProvider = () => window.braveEthereum as any - -const target = () => ({ - id: 'braveWallet', - name: 'Brave Wallet Provider', - provider: getProvider(), -}) - -const getConnector = async () => { - const InjectedConnector = (await import('../../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ target, shimDisconnect: false }) - - return connector -} - -const braveWallet = { - id: 'braveWallet', - title: 'Brave Wallet', - logo: 'connector/braveBrowser', - isAddTokenEnabled: true, - isInjectedWallet: true, - isLocalStorageSave: true, - isDisableSwitchChain: false, - activationMessage: messages.authMessages.waitingAuth, - networks: [ - Network.Mainnet, - Network.Gnosis, - Network.Hoodi, - ] as ChainIds[], - location: [ 'desktop' ] as Location, - isDisabled: (() => !window.braveEthereum) as IsDisabled, - getConnector, - getProvider, -} as const - - -export default braveWallet diff --git a/src/config/core/wallets/injected/dAppBrowser.ts b/src/config/core/wallets/injected/dAppBrowser.ts index 93f88a52..1c8c52e0 100644 --- a/src/config/core/wallets/injected/dAppBrowser.ts +++ b/src/config/core/wallets/injected/dAppBrowser.ts @@ -1,37 +1,23 @@ import { Network } from 'sdk' -import { Location, IsDisabled } from '../types' +import { createInjectedWallet } from './helpers' -import messages from '../../messages' - -const getConnector = async () => { - const InjectedConnector = (await import('../../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ shimDisconnect: false }) - - return connector -} - -const dAppBrowser = { +const dAppBrowser = createInjectedWallet({ id: 'dAppBrowser', title: 'DApp Browser', logo: 'connector/monitorAddress', - isAddTokenEnabled: false, - isInjectedWallet: true, - isLocalStorageSave: false, - isDisableSwitchChain: false, - activationMessage: messages.authMessages.waitingAuth, networks: [ Network.Mainnet, Network.Gnosis, Network.Hoodi, - ] as ChainIds[], - location: [ 'mobile' ] as Location, - isDisabled: (() => !window.ethereum) as IsDisabled, - getProvider: () => window.ethereum, - getConnector, -} as const + ], + location: [ 'mobile' ], + isAutoConnect: true, + isAddTokenEnabled: false, + isLocalStorageSave: false, + fallbackProvider: () => window.ethereum, +}) export default dAppBrowser diff --git a/src/config/core/wallets/injected/helpers/createInjectedWallet.ts b/src/config/core/wallets/injected/helpers/createInjectedWallet.ts new file mode 100644 index 00000000..034089c4 --- /dev/null +++ b/src/config/core/wallets/injected/helpers/createInjectedWallet.ts @@ -0,0 +1,68 @@ +import type { Location, IsDisabled } from '../../types' + +import { findProvider, findProviderIcon } from '../../../providers/eip6963' + +import getInjectedConnector from './getInjectedConnector' + +import messages from '../../../messages' + + +type InjectedWalletConfig = { + id: string + title: string + rdns?: string + logo?: string + networks: number[] + location?: Location + isAutoConnect?: boolean + isAddTokenEnabled?: boolean + isLocalStorageSave?: boolean + isDisableSwitchChain?: boolean + fallbackProvider?: () => any +} + +const createInjectedWallet = (config: InjectedWalletConfig) => { + const { + id, + rdns, + title, + networks, + isAutoConnect = false, + isAddTokenEnabled = true, + isLocalStorageSave = true, + isDisableSwitchChain = false, + location = [ 'desktop', 'mobile' ] as Location, + fallbackProvider, + } = config + + const getProvider = () => (rdns && findProvider(rdns)) || fallbackProvider?.() + + const logo = config.logo || (rdns && findProviderIcon(rdns)) + + const target = () => ({ + id, + name: `${title} Provider`, + provider: getProvider(), + }) + + return { + id, + rdns, + logo, + title, + networks, + location, + isAutoConnect, + isAddTokenEnabled, + isLocalStorageSave, + isDisableSwitchChain, + isInjectedWallet: true, + activationMessage: messages.authMessages.waitingAuth, + isDisabled: (() => !getProvider()) as IsDisabled, + getConnector: getInjectedConnector({ target, shimDisconnect: false }), + getProvider, + } +} + + +export default createInjectedWallet diff --git a/src/config/core/wallets/injected/helpers/getAutoDetectedWallets.ts b/src/config/core/wallets/injected/helpers/getAutoDetectedWallets.ts new file mode 100644 index 00000000..0f44a1d8 --- /dev/null +++ b/src/config/core/wallets/injected/helpers/getAutoDetectedWallets.ts @@ -0,0 +1,32 @@ +import { Network } from 'sdk' + +import { getAutoDetectedProviders } from '../../../providers/eip6963' + +import createInjectedWallet from './createInjectedWallet' + + +const networks = [ + Network.Mainnet, + Network.Gnosis, + Network.Hoodi, +] + +const getAutoDetectedWallets = (staticWallets: Record) => { + const staticRdns = Object.values(staticWallets) + .map((wallet) => wallet.rdns) + .filter(Boolean) as string[] + + const providers = getAutoDetectedProviders() + + return providers + .filter((detail) => !staticRdns.includes(detail.info.rdns)) + .map((detail) => createInjectedWallet({ + networks, + id: detail.info.rdns, + rdns: detail.info.rdns, + title: detail.info.name, + })) +} + + +export default getAutoDetectedWallets diff --git a/src/config/core/wallets/injected/helpers/getInjectedConnector.ts b/src/config/core/wallets/injected/helpers/getInjectedConnector.ts new file mode 100644 index 00000000..6d262639 --- /dev/null +++ b/src/config/core/wallets/injected/helpers/getInjectedConnector.ts @@ -0,0 +1,11 @@ +import type { InjectedParameters } from '@wagmi/connectors' + + +const getInjectedConnector = (values: InjectedParameters) => async (_: any, options: GetConnectorOptions) => { + const InjectedConnector = (await import('../../../connectors/InjectedConnector')).default + + return new InjectedConnector({ ...values, ...options }) +} + + +export default getInjectedConnector diff --git a/src/config/core/wallets/injected/helpers/index.ts b/src/config/core/wallets/injected/helpers/index.ts new file mode 100644 index 00000000..6bd18948 --- /dev/null +++ b/src/config/core/wallets/injected/helpers/index.ts @@ -0,0 +1,3 @@ +export { default as getAutoDetectedWallets } from './getAutoDetectedWallets' +export { default as createInjectedWallet } from './createInjectedWallet' +export { default as getInjectedConnector } from './getInjectedConnector' diff --git a/src/config/core/wallets/injected/index.ts b/src/config/core/wallets/injected/index.ts index b3a0d4a3..94d359fb 100644 --- a/src/config/core/wallets/injected/index.ts +++ b/src/config/core/wallets/injected/index.ts @@ -1,8 +1,2 @@ -export { default as braveWallet } from './braveWallet' -export { default as dAppBrowser } from './dAppBrowser' -export { default as trustWallet } from './trustWallet' -export { default as metaMask } from './metaMask' -export { default as rabby } from './rabby' -export { default as taho } from './taho' -export { default as okx } from './okx' export { default as ledgerLive } from './ledgerLive' +export { default as dAppBrowser } from './dAppBrowser' diff --git a/src/config/core/wallets/injected/ledgerLive.ts b/src/config/core/wallets/injected/ledgerLive.ts index 0940d3f1..690aeab8 100644 --- a/src/config/core/wallets/injected/ledgerLive.ts +++ b/src/config/core/wallets/injected/ledgerLive.ts @@ -1,35 +1,22 @@ import { Network } from 'sdk' -import { Location, IsDisabled } from '../types' +import { createInjectedWallet } from './helpers' -import messages from '../../messages' - -const getConnector = async () => { - const InjectedConnector = (await import('../../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ shimDisconnect: false }) - - return connector -} - -const ledgerLive = { +const ledgerLive = createInjectedWallet({ id: 'ledgerLive', + rdns: 'com.ledger', title: 'Ledger Live', logo: 'connector/ledgerLive', - isAddTokenEnabled: false, - isInjectedWallet: true, - isLocalStorageSave: true, - activationMessage: messages.authMessages.waitingAuth, networks: [ Network.Mainnet, + Network.Gnosis, Network.Hoodi, - ] as ChainIds[], - location: [ 'desktop', 'mobile' ] as Location, - isDisabled: (() => !window.ethereum?.isLedgerLive) as IsDisabled, - getProvider: () => window.ethereum, - getConnector, -} as const + ], + isAutoConnect: true, + isAddTokenEnabled: false, + fallbackProvider: () => window.ethereum?.isLedgerLive ? window.ethereum : null, +}) export default ledgerLive diff --git a/src/config/core/wallets/injected/metaMask.ts b/src/config/core/wallets/injected/metaMask.ts deleted file mode 100644 index e9832186..00000000 --- a/src/config/core/wallets/injected/metaMask.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Network } from 'sdk' - -import { Location, IsDisabled } from '../types' - -import messages from '../../messages' - - -const getProvider = () => window.ethereum as any - -const target = () => { - let provider = getProvider() - - const providers = provider?.providers - - if (providers?.length) { - provider = providers.find((item: any) => item.isMetaMask) - } - - return { - id: 'metamask', - name: 'MetaMask Provider', - provider, - } -} - -const getConnector = async () => { - const InjectedConnector = (await import('../../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ target, shimDisconnect: false }) - - return connector -} - -const metaMask = { - id: 'metaMask', - title: 'MetaMask', - logo: 'connector/metamask', - isAddTokenEnabled: true, - isInjectedWallet: true, - isLocalStorageSave: true, - isDisableSwitchChain: false, - activationMessage: messages.authMessages.waitingAuth, - networks: [ - Network.Mainnet, - Network.Gnosis, - Network.Hoodi, - ] as ChainIds[], - location: [ 'desktop', 'mobile' ] as Location, - isDisabled: (() => !window.ethereum) as IsDisabled, - getProvider, - getConnector, -} as const - - -export default metaMask diff --git a/src/config/core/wallets/injected/okx.ts b/src/config/core/wallets/injected/okx.ts deleted file mode 100644 index 41c8c6b2..00000000 --- a/src/config/core/wallets/injected/okx.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Network } from 'sdk' - -import { Location, IsDisabled } from '../types' - -import messages from '../../messages' - - -const getProvider = () => window.okxwallet as any - -const target = () => ({ - id: 'okx', - name: 'OKX Provider', - provider: getProvider(), -}) - -const getConnector = async () => { - const InjectedConnector = (await import('../../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ target, shimDisconnect: false }) - - return connector -} - -const okx = { - id: 'okx', - title: 'OKX', - logo: 'connector/okx', - isAddTokenEnabled: true, - isInjectedWallet: true, - isLocalStorageSave: true, - isDisableSwitchChain: false, - activationMessage: messages.authMessages.waitingAuth, - networks: [ - Network.Mainnet, - Network.Gnosis, - Network.Hoodi, - ] as ChainIds[], - location: [ 'desktop', 'mobile' ] as Location, - isDisabled: (() => !window.okxwallet) as IsDisabled, - getProvider, - getConnector, -} as const - - -export default okx diff --git a/src/config/core/wallets/injected/rabby.ts b/src/config/core/wallets/injected/rabby.ts deleted file mode 100644 index 1036c23e..00000000 --- a/src/config/core/wallets/injected/rabby.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Network } from 'sdk' - -import { Location, IsDisabled } from '../types' - -import messages from '../../messages' - - -const getProvider = () => window.rabby as any - -const target = () => ({ - id: 'rabby', - name: 'Rabby Provider', - provider: getProvider(), -}) - -const getConnector = async () => { - const InjectedConnector = (await import('../../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ target, shimDisconnect: false }) - - return connector -} - -const rabby = { - id: 'rabby', - title: 'Rabby Wallet', - logo: 'connector/rabby', - isAddTokenEnabled: true, - isInjectedWallet: true, - isLocalStorageSave: true, - isDisableSwitchChain: false, - activationMessage: messages.authMessages.waitingAuth, - networks: [ - Network.Mainnet, - Network.Gnosis, - Network.Hoodi, - ] as ChainIds[], - location: [ 'desktop' ] as Location, - isDisabled: (() => !window.rabby) as IsDisabled, - getProvider, - getConnector, -} as const - - -export default rabby diff --git a/src/config/core/wallets/injected/taho.ts b/src/config/core/wallets/injected/taho.ts deleted file mode 100644 index 356f6ed8..00000000 --- a/src/config/core/wallets/injected/taho.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Network } from 'sdk' - -import { Location, IsDisabled } from '../types' - -import messages from '../../messages' - - -const getProvider = () => window.taho as any - -const target = () => ({ - id: 'taho', - name: 'Taho Provider', - provider: getProvider(), -}) - -const getConnector = async () => { - const InjectedConnector = (await import('../../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ target, shimDisconnect: false }) - - return connector -} - -const taho = { - id: 'taho', - title: 'Taho', - logo: 'connector/taho', - isAddTokenEnabled: true, - isInjectedWallet: true, - isLocalStorageSave: true, - isDisableSwitchChain: false, - activationMessage: messages.authMessages.waitingAuth, - networks: [ - Network.Mainnet, - Network.Gnosis, - Network.Hoodi, - ] as ChainIds[], - location: [ 'desktop' ] as Location, - isDisabled: (() => !window.taho) as IsDisabled, - getConnector, - getProvider, -} as const - - -export default taho diff --git a/src/config/core/wallets/injected/trustWallet.ts b/src/config/core/wallets/injected/trustWallet.ts deleted file mode 100644 index 3dac4195..00000000 --- a/src/config/core/wallets/injected/trustWallet.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Network } from 'sdk' - -import { Location, IsDisabled } from '../types' - -import messages from '../../messages' - - -const getProvider = () => window.trustwallet as any - -const target = () => ({ - id: 'trustwallet', - name: 'Trust wallet Provider', - provider: getProvider(), -}) - -const getConnector = async () => { - const InjectedConnector = (await import('../../connectors/InjectedConnector')).default - - const connector = new InjectedConnector({ target, shimDisconnect: false }) - - return connector -} - -const trustWallet = { - id: 'trustWallet', - title: 'Trust Wallet', - logo: 'connector/trustWallet', - isAddTokenEnabled: true, - isInjectedWallet: true, - isLocalStorageSave: true, - isDisableSwitchChain: false, - activationMessage: messages.authMessages.waitingAuth, - networks: [ - Network.Mainnet, - Network.Gnosis, - Network.Hoodi, - ] as ChainIds[], - location: [ 'desktop' ] as Location, - isDisabled: (() => !window.trustwallet) as IsDisabled, - getConnector, - getProvider, -} as const - - -export default trustWallet diff --git a/src/config/core/wallets/ledger.ts b/src/config/core/wallets/ledger.ts index f20e4f8d..6979e9ec 100644 --- a/src/config/core/wallets/ledger.ts +++ b/src/config/core/wallets/ledger.ts @@ -1,38 +1,23 @@ import { Network } from 'sdk' -import apiUrls from 'helpers/methods/apiUrls' import { Location } from './types' -import networks from '../config/util/networks' -import type { Input } from '../connectors/LedgerConnector' import messages from '../messages' -const params = Object.values(networks.configs).reduce((acc, config) => { - const url = apiUrls.getWeb3Url(config.chainId) - - return { - ...acc, - [config.chainId]: { - chainId: config.chainId, - name: config.name, - url, - }, - } -}, {} as Input) - -const getConnector = async (chainId: Network, options?: GetConnectorOptions) => { - const { transport, disconnect } = options || {} +const getConnector = async (chainId: Network, options: GetConnectorOptions) => { + const { transport, networks, disconnect } = options const LedgerConnector = (await import('../connectors/LedgerConnector')).default - return new LedgerConnector({ params, chainId, transport, onError: disconnect }) + return new LedgerConnector({ chainId, transport, networks, onError: disconnect }) } const ledger = { id: 'ledger', title: 'Ledger', logo: 'connector/ledger', + isAutoConnect: false, isAddTokenEnabled: false, isInjectedWallet: false, isLocalStorageSave: true, diff --git a/src/config/core/wallets/monitorAddress.ts b/src/config/core/wallets/monitorAddress.ts index 55ddebd7..420121c0 100644 --- a/src/config/core/wallets/monitorAddress.ts +++ b/src/config/core/wallets/monitorAddress.ts @@ -9,6 +9,7 @@ const monitorAddress = { id: 'monitorAddress', title: 'Check wallet', logo: 'connector/monitorAddress', + isAutoConnect: false, isAddTokenEnabled: false, isInjectedWallet: false, isLocalStorageSave: true, diff --git a/src/config/core/wallets/walletConnect.ts b/src/config/core/wallets/walletConnect.ts deleted file mode 100644 index fe4a38b5..00000000 --- a/src/config/core/wallets/walletConnect.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Network } from 'sdk' - -import { Location } from './types' - -import messages from '../messages' - - -const getConnector = async () => { - if (!process.env.NEXT_PUBLIC_WALLET_CONNECT_ID) { - throw new Error("You need to provide NEXT_PUBLIC_WALLET_CONNECT_ID env variable") - } - - const WalletLinkConnector = (await import('../connectors/WalletLinkConnector')).default - - const connector = new WalletLinkConnector({ - projectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_ID as string, - isNewChainsStale: true, - showQrModal: true, - qrModalOptions: { - themeVariables: { - '--wcm-z-index': '999', - }, - }, - }) - - return connector -} - -const walletConnect = { - id: 'walletConnect', - title: 'WalletConnect', - logo: 'connector/walletConnect', - isAddTokenEnabled: false, - isInjectedWallet: false, - isLocalStorageSave: false, - isDisableSwitchChain: false, - activationMessage: messages.authMessages.waitingAuth, - networks: [ - Network.Mainnet, - Network.Gnosis, - Network.Hoodi, - ] as ChainIds[], - location: IS_LIGHTWEIGHT_MODE - ? [] as Location - : [ 'desktop', 'mobile' ] as Location, - getConnector, -} as const - - -export default walletConnect diff --git a/src/config/core/wallets/walletConnect/getConnector.ts b/src/config/core/wallets/walletConnect/getConnector.ts new file mode 100644 index 00000000..9a280c84 --- /dev/null +++ b/src/config/core/wallets/walletConnect/getConnector.ts @@ -0,0 +1,22 @@ +const getConnector = async (_: any, options: GetConnectorOptions) => { + if (!process.env.NEXT_PUBLIC_WALLET_CONNECT_ID) { + throw new Error("You need to provide NEXT_PUBLIC_WALLET_CONNECT_ID env variable") + } + + const WalletLinkConnector = (await import('../../connectors/WalletLinkConnector')).default + + return new WalletLinkConnector({ + ...options, + projectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_ID as string, + isNewChainsStale: false, + showQrModal: true, + qrModalOptions: { + themeVariables: { + '--wcm-z-index': '999', + }, + }, + }) +} + + +export default getConnector diff --git a/src/config/core/wallets/walletConnect/index.ts b/src/config/core/wallets/walletConnect/index.ts new file mode 100644 index 00000000..c6227555 --- /dev/null +++ b/src/config/core/wallets/walletConnect/index.ts @@ -0,0 +1 @@ +export { default as walletConnect } from './walletConnect' diff --git a/src/config/core/wallets/walletConnect/walletConnect.ts b/src/config/core/wallets/walletConnect/walletConnect.ts new file mode 100644 index 00000000..e5ac1763 --- /dev/null +++ b/src/config/core/wallets/walletConnect/walletConnect.ts @@ -0,0 +1,32 @@ +import { Network } from 'sdk' + +import { Location } from '../types' + +import getConnector from './getConnector' + +import messages from '../../messages' + + +const walletConnect = { + id: 'walletConnect', + title: 'WalletConnect', + logo: 'connector/walletConnect', + isAutoConnect: false, + isAddTokenEnabled: false, + isInjectedWallet: false, + isLocalStorageSave: true, + isDisableSwitchChain: false, + activationMessage: messages.authMessages.waitingAuth, + networks: [ + Network.Mainnet, + Network.Gnosis, + Network.Hoodi, + ] as ChainIds[], + location: IS_LIGHTWEIGHT_MODE + ? [] as Location + : [ 'desktop', 'mobile' ] as Location, + getConnector, +} as const + + +export default walletConnect diff --git a/src/config/core/wallets/zenGo.ts b/src/config/core/wallets/zenGo.ts deleted file mode 100644 index 96abb046..00000000 --- a/src/config/core/wallets/zenGo.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Network } from 'sdk' - -import { Location } from './types' - -import messages from '../messages' - - -const getConnector = async () => { - if (!process.env.NEXT_PUBLIC_WALLET_CONNECT_ID) { - throw new Error("You need to provide NEXT_PUBLIC_WALLET_CONNECT_ID env variable") - } - - const WalletLinkConnector = (await import('../connectors/WalletLinkConnector')).default - - const connector = new WalletLinkConnector({ - projectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_ID as string, - isNewChainsStale: true, - showQrModal: true, - qrModalOptions: { - themeVariables: { - '--wcm-z-index': '999', - }, - }, - }) - - return connector -} - -const zenGo = { - id: 'zenGo', - title: 'ZenGo', - logo: 'connector/zengo', - isAddTokenEnabled: false, - isInjectedWallet: false, - isLocalStorageSave: true, - isDisableSwitchChain: true, - activationMessage: messages.authMessages.waitingAuth, - networks: [ - Network.Mainnet, - Network.Gnosis, - ] as ChainIds[], - location: [ 'desktop' ] as Location, - getConnector, -} as const - - -export default zenGo diff --git a/src/config/index.tsx b/src/config/index.tsx index 23d0ead9..429885a0 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -3,13 +3,46 @@ import { configs, chains } from 'sdk' import modal from 'modules/modal' import { methods } from 'helpers' +import networks from './networks' +import { createConfig, wallets } from './core' import useActions from '../hooks/data/useActions' -import { createConfig, networks, wallets } from './core' import connectModalId from '../layouts/modals/ConnectWalletModal/modalId' type SupportedChain = typeof chains.mainnet | typeof chains.hoodi | typeof chains.gnosis +type GetBlockExplorerUrlInput = { + address?: string | null + token?: string + hash?: string +} + +const getBlockExplorerUrl = (blockExplorerUrl: string) => (values: GetBlockExplorerUrlInput) => { + const { hash, token, address } = values + + const value = hash || token || address || '' + + if (/^http/.test(value)) { + return value + } + + let page + + if (address) { + page = 'address' + } + + if (token) { + page = 'token' + } + + if (hash) { + page = 'tx' + } + + return `${blockExplorerUrl}/${page}/${address || hash || token}` +} + const supportedChains: SupportedChain[] = [] if (process.env.NEXT_PUBLIC_MAINNET_VAULT_ADDRESS) { @@ -29,18 +62,14 @@ const middleware = (ctx: ConfigProvider.Context) => { const supportedChain = supportedChains.find((chain) => chain.id === ctx.networkId) || supportedChains[0] - const networkId = supportedChain.id - const chainId = supportedChain.chainId as ConfigProvider.Context['chainId'] + const networkId = supportedChain.id as NetworkIds + const chainId = supportedChain.chainId as ChainIds const sdk = methods.getSDK({ chainId }) const signSDK = methods.getSDK({ chainId, library }) const isGnosis = networkId === networks.configs.gnosis.id - - const isEthereum = ( - networkId === networks.configs.mainnet.id - || networkId === networks.configs.hoodi.id - ) + const isEthereum = networkId === networks.configs.mainnet.id || networkId === networks.configs.hoodi.id return { ...ctx, @@ -52,13 +81,14 @@ const middleware = (ctx: ConfigProvider.Context) => { isEthereum, isTestnet: sdk.config.network.isTestnet, isMainnet: networkId === chains.mainnet.id, + getBlockExplorerUrl: getBlockExplorerUrl(sdk.config.network.blockExplorerUrl), } } const { useConfig, ConfigProvider: InitialConfigProvider, -} = createConfig(middleware) +} = createConfig({ networks, middleware }) type ConfigProviderProps = { serverNetworkId: NetworkIds @@ -117,7 +147,7 @@ const ConfigProvider: React.FC = (props) => { } const getConfig = (networkId: NetworkIds): Config => { - const chainId = networks.chainById[networkId] + const chainId = networks.chainById[networkId] as ChainIds const config = configs[chainId] if (!config) { diff --git a/src/config/networks.ts b/src/config/networks.ts new file mode 100644 index 00000000..8ee23653 --- /dev/null +++ b/src/config/networks.ts @@ -0,0 +1,47 @@ +import { mainnet, hoodi, gnosis } from 'viem/chains' +import { chains, Network } from 'sdk' +import apiUrls from 'helpers/methods/apiUrls' + + +const defaultNetworks: Record = { + [Network.Mainnet]: { + ...chains.mainnet, + viem: mainnet, + logo: 'token/ETH', + rpc: apiUrls.getWeb3Url(Network.Mainnet) as string | string[], + }, + [Network.Gnosis]: { + ...chains.gnosis, + viem: gnosis, + logo: 'token/GNO', + rpc: apiUrls.getWeb3Url(Network.Gnosis) as string | string[], + }, + [Network.Hoodi]: { + ...chains.hoodi, + viem: hoodi, + logo: 'token/ETH', + rpc: apiUrls.getWeb3Url(Network.Hoodi) as string | string[], + }, +} + +const configs = {} as Record +const chainById = {} as Record +const idByChain = {} as Record + +Object.values(defaultNetworks).forEach((config) => { + const { id, chainId } = config + + configs[id] = config + chainById[id] = chainId + idByChain[chainId] = id +}) + +const networks: ConfigProvider.Networks = { + default: defaultNetworks, + chainById, + idByChain, + configs, +} + + +export default networks diff --git a/src/helpers/messages/notification.ts b/src/helpers/messages/notification.ts index 7b2ce6ab..5f76d14b 100644 --- a/src/helpers/messages/notification.ts +++ b/src/helpers/messages/notification.ts @@ -26,6 +26,15 @@ export default { de: 'Fehler beim Senden der Transaktion. Bitte versuchen Sie es erneut.', zh: '交易发送失败。请再试一次。', }, + cancelled: { + en: 'The transaction has been cancelled.', + ru: 'Транзакция была отменена.', + fr: 'La transaction a été annulée.', + es: 'La transacción ha sido cancelada.', + pt: 'A transação foi cancelada.', + de: 'Die Transaktion wurde abgebrochen.', + zh: '交易已被取消。', + }, insufficientFunds: { en: 'Insufficient funds to pay for the transaction', ru: 'Недостаточно средств для оплаты транзакции', diff --git a/src/helpers/methods/apiUrls/data.ts b/src/helpers/methods/apiUrls/data.ts index 211441de..7cbde644 100644 --- a/src/helpers/methods/apiUrls/data.ts +++ b/src/helpers/methods/apiUrls/data.ts @@ -29,7 +29,7 @@ const apiUrls = { }, [Network.Hoodi]: { backend: configs[Network.Hoodi].api.backend, - web3: 'https://ethereum-hoodi-rpc.publicnode.com', + web3: 'https://eth-hoodi.stakewise.io', subgraph: IS_PROD ? configs[Network.Hoodi].api.subgraph : `https://graphs.stakewise.io/hoodi/subgraphs/name/stakewise/${defaultType}`, diff --git a/src/helpers/methods/getSDK/getUrls.ts b/src/helpers/methods/getSDK/getUrls.ts index 325b93ec..5eac83ea 100644 --- a/src/helpers/methods/getSDK/getUrls.ts +++ b/src/helpers/methods/getSDK/getUrls.ts @@ -18,7 +18,10 @@ const getUrls = ({ chainId }: Input): StakeWise.Options['endpoints'] => { const formattedWeb3 = urls.map((url) => ({ url, - headers: {}, + headers: { + // For SSR + Origin: 'https://app.stakewise.io', + }, })) return { diff --git a/src/helpers/requests/_SSR/vault/getVaultBase.ts b/src/helpers/requests/_SSR/vault/getVaultBase.ts index f4570161..061e2b86 100644 --- a/src/helpers/requests/_SSR/vault/getVaultBase.ts +++ b/src/helpers/requests/_SSR/vault/getVaultBase.ts @@ -1,5 +1,5 @@ import { cookies } from 'next/headers' -import { networks } from 'config/core' +import networks from 'config/networks' import { constants, getters, requests } from '../../../index' import { getSDK } from '../../../methods' diff --git a/src/helpers/requests/approve.ts b/src/helpers/requests/approve.ts index 8eddf2cb..abdb311a 100644 --- a/src/helpers/requests/approve.ts +++ b/src/helpers/requests/approve.ts @@ -1,27 +1,28 @@ -import { MaxUint256, parseEther } from 'ethers' +import { BrowserProvider, MaxUint256 } from 'ethers' +import { createErc20Contract } from 'sdk' import { getGasMargin } from '../methods' type Input = { - signSDK: SDK to: string from: string - amount?: string + amount?: bigint tokenAddress: string + provider: BrowserProvider } const approve = async (values: Input) => { - const { from, to, amount, tokenAddress, signSDK } = values + const { from, to, amount, tokenAddress, provider } = values - const tokenContract = signSDK.contracts.helpers.createErc20(tokenAddress) - const signer = await signSDK.provider.getSigner(from) + const tokenContract = createErc20Contract(tokenAddress, provider) + const signer = await provider.getSigner(from) const signedContract = tokenContract.connect(signer) - const value = amount ? parseEther(amount) : MaxUint256 + const value = amount || MaxUint256 const [ gasCost, feeData ] = await Promise.all([ signedContract.approve.estimateGas(to, value), - signSDK.provider.getFeeData(), + provider.getFeeData(), ]) const { maxFeePerGas, maxPriorityFeePerGas } = feeData diff --git a/src/helpers/requests/getApproveGas.ts b/src/helpers/requests/getApproveGas.ts index 42806058..8dcb2030 100644 --- a/src/helpers/requests/getApproveGas.ts +++ b/src/helpers/requests/getApproveGas.ts @@ -1,26 +1,26 @@ -import { MaxUint256, parseEther } from 'ethers' -import { getGas } from 'sdk' +import { getGas, createErc20Contract } from 'sdk' +import { BrowserProvider, MaxUint256, parseEther } from 'ethers' type Input = { - signSDK: SDK to: string from: string amount?: string tokenAddress: string + provider: BrowserProvider } const getApproveGas = async (values: Input) => { - const { from, to, amount, tokenAddress, signSDK } = values + const { from, to, amount, tokenAddress, provider } = values - const tokenContract = signSDK.contracts.helpers.createErc20(tokenAddress) - const signer = await signSDK.provider.getSigner(from) + const tokenContract = createErc20Contract(tokenAddress, provider) + const signer = await provider.getSigner(from) const signedContract = tokenContract.connect(signer) const value = amount ? parseEther(amount) : MaxUint256 const estimatedGas = await signedContract.approve.estimateGas(to, value) - const approveTxGas = await getGas({ estimatedGas, provider: signSDK.provider }) + const approveTxGas = await getGas({ estimatedGas, provider }) return approveTxGas } diff --git a/src/hooks/controls/useAddressChanged.ts b/src/hooks/controls/useAddressChanged.ts index 9b02ae1f..9a481422 100644 --- a/src/hooks/controls/useAddressChanged.ts +++ b/src/hooks/controls/useAddressChanged.ts @@ -3,14 +3,15 @@ import { useConfig } from 'config' import useChangeEffect from './useChangeEffect' -type Callback = () => any +type Address = string | null +type Callback = (address: Address) => any const useAddressChanged = (callback: Callback) => { const { address, autoConnectChecked } = useConfig() - useChangeEffect<[ string | null, boolean, Callback ]>((prevAddress, prevAutoConnectChecked) => { + useChangeEffect<[ Address, boolean, Callback ]>((prevAddress, prevAutoConnectChecked) => { if (prevAutoConnectChecked && prevAddress !== address) { - callback() + callback(address) } }, [ address, autoConnectChecked, callback ]) } diff --git a/src/hooks/controls/useChangeEffect.ts b/src/hooks/controls/useChangeEffect.ts index 69dc582e..31aa7584 100644 --- a/src/hooks/controls/useChangeEffect.ts +++ b/src/hooks/controls/useChangeEffect.ts @@ -11,7 +11,7 @@ const useUpdateEffect: typeof useEffect = (effect, deps) => { firstMount.current = false return } - effect() + return effect() }, deps) } @@ -32,7 +32,7 @@ const useChangeEffect = ( const prevValue = usePrevious(deps) useUpdateEffect(() => { - effect(...prevValue) + return effect(...prevValue) }, deps) } diff --git a/src/hooks/data/useSwapTokenBalances.ts b/src/hooks/data/useSwapTokenBalances.ts index 1ca5eaf4..172cdce9 100644 --- a/src/hooks/data/useSwapTokenBalances.ts +++ b/src/hooks/data/useSwapTokenBalances.ts @@ -1,14 +1,15 @@ import { useCallback } from 'react' -import { useConfig } from 'config' +import { createErc20Contract } from 'sdk' import { swapTokens } from 'helpers' +import { useConfig } from 'config' -type Input = { +type ModifyResultInput = { values: bigint[] chainTokens: Record } -const modifyResult = ({ values, chainTokens }: Input) => { +const modifyResult = ({ values, chainTokens }: ModifyResultInput) => { const result: Record = {} const tokenNames = Object.keys(chainTokens) @@ -22,7 +23,7 @@ const modifyResult = ({ values, chainTokens }: Input) => { } const useSwapTokenBalances = () => { - const { sdk, chainId, address } = useConfig() + const { chainId, address, readOnlyProvider } = useConfig() const fetchSwapTokenBalance = useCallback(async (tokenAddress: string) => { if (!address) { @@ -30,7 +31,8 @@ const useSwapTokenBalances = () => { } try { - const tokenContract = sdk.contracts.helpers.createErc20(tokenAddress) + const tokenContract = createErc20Contract(tokenAddress, readOnlyProvider) + const balance = await tokenContract.balanceOf(address) return balance @@ -40,17 +42,19 @@ const useSwapTokenBalances = () => { return 0n } - }, [ sdk, address ]) + }, [ address, readOnlyProvider ]) - return useCallback(async () => { - const chainTokens = swapTokens[chainId as keyof typeof swapTokens] + return useCallback(async (tokens?: Record) => { + const chainTokens = tokens || swapTokens[chainId as keyof typeof swapTokens] if (!chainTokens) { return {} } const values = await Promise.all( - Object.values(chainTokens).map((tokenAddress) => fetchSwapTokenBalance(tokenAddress)) + Object.values(chainTokens).map((tokenAddress) => ( + fetchSwapTokenBalance(tokenAddress) + )) ) return modifyResult({ values, chainTokens }) diff --git a/src/hooks/fetch/useAllowance.ts b/src/hooks/fetch/useAllowance.ts index 2275ad93..638f745d 100644 --- a/src/hooks/fetch/useAllowance.ts +++ b/src/hooks/fetch/useAllowance.ts @@ -1,6 +1,7 @@ import { useCallback, useEffect, useMemo, useRef } from 'react' import { useConfig } from 'config' import { ZeroAddress } from 'ethers' +import { createErc20Contract } from 'sdk' import { commonMessages } from 'helpers' import notifications from 'modules/notifications' @@ -34,7 +35,7 @@ type Input = { const useAllowance = (values: Input) => { const { recipient, tokenAddress } = values - const { sdk, address } = useConfig() + const { address, readOnlyProvider } = useConfig() const skip = values.skip || !address || !tokenAddress || recipient === ZeroAddress @@ -54,7 +55,7 @@ const useAllowance = (values: Input) => { } try { - const tokenContract = sdk.contracts.helpers.createErc20(tokenAddress) + const tokenContract = createErc20Contract(tokenAddress, readOnlyProvider) const allowance = await tokenContract.allowance(address, recipient) setState({ @@ -76,7 +77,7 @@ const useAllowance = (values: Input) => { return allowanceRef.current } - }, [ sdk, address, tokenAddress, recipient, setState ]) + }, [ address, tokenAddress, recipient, readOnlyProvider, setState ]) useEffect(() => { if (skip) { diff --git a/src/hooks/fetch/useApprove.ts b/src/hooks/fetch/useApprove.ts index e6bc5f37..a95d3c74 100644 --- a/src/hooks/fetch/useApprove.ts +++ b/src/hooks/fetch/useApprove.ts @@ -1,5 +1,5 @@ import { useCallback, useMemo, useState } from 'react' -import { formatEther, MaxInt256 } from 'ethers' +import { formatEther, MaxUint256 } from 'ethers' import { requests } from 'helpers' import { useConfig } from 'config' @@ -18,7 +18,7 @@ type Output = { isFetching: boolean isSubmitting: boolean getGas: (amount?: bigint) => Promise - approve: (amount?: bigint) => Promise + approve: (amount?: bigint) => Promise checkAllowance: (values: CheckAllowanceInput) => Promise } @@ -30,7 +30,7 @@ interface Hook { const useApprove: Hook = (values) => { const { recipient, tokenAddress, skip } = values - const { signSDK, address } = useConfig() + const { library, address } = useConfig() const { refetchNativeTokenBalance } = useBalances() const { allowance, isFetching, checkAllowance } = useAllowance({ @@ -42,13 +42,13 @@ const useApprove: Hook = (values) => { const [ isSubmitting, setSubmitting ] = useState(false) const getGas = useCallback(async (amount?: bigint): Promise => { - if (!address) { + if (!address || !library) { return 0n } try { const gas = await requests.getApproveGas({ - signSDK, + provider: library, from: address, to: recipient, tokenAddress, @@ -64,27 +64,30 @@ const useApprove: Hook = (values) => { } }, [ address, - signSDK, + library, recipient, tokenAddress, ]) const approve = useCallback(async (amount?: bigint) => { if (!address) { - return + return Promise.reject('Address is not defined') + } + if (!library) { + return Promise.reject('Library is not defined') } setSubmitting(true) try { - const approveAmount = amount || MaxInt256 + const approveAmount = amount || MaxUint256 const { hash } = await requests.approve({ - signSDK, + provider: library, from: address, to: recipient, tokenAddress, - amount: amount?.toString(), + amount, }) refetchNativeTokenBalance() @@ -92,7 +95,7 @@ const useApprove: Hook = (values) => { if (hash) { console.log('approve', { - amount: approveAmount === MaxInt256 ? 'MAX' : formatEther(approveAmount), + amount: approveAmount === MaxUint256 ? 'MAX' : formatEther(approveAmount), tokenAddress, recipient, }) @@ -110,7 +113,7 @@ const useApprove: Hook = (values) => { } }, [ address, - signSDK, + library, recipient, tokenAddress, refetchNativeTokenBalance, @@ -138,7 +141,7 @@ useApprove.mock = { isFetching: false, isSubmitting: false, getGas: async () => 0n, - approve: async () => undefined, + approve: async () => '', checkAllowance: async () => undefined, } diff --git a/src/hooks/fetch/useSubgraphUpdate.ts b/src/hooks/fetch/useSubgraphUpdate.ts index 2a05bb2b..1d437c08 100644 --- a/src/hooks/fetch/useSubgraphUpdate.ts +++ b/src/hooks/fetch/useSubgraphUpdate.ts @@ -17,10 +17,10 @@ type ResolveTransactionProps = { const useSubgraphUpdate = () => { const actions = useActions() - const { sdk } = useConfig() + const { sdk, networkId, readOnlyProvider, getBlockExplorerUrl } = useConfig() - const configNetworkIdRef = useRef(sdk.config.network.id) - configNetworkIdRef.current = sdk.config.network.id + const configNetworkIdRef = useRef(networkId) + configNetworkIdRef.current = networkId const fetchTransaction = useCallback(async (hash: string, attempt: number = 0) => { try { @@ -43,7 +43,7 @@ const useSubgraphUpdate = () => { const { hash, expectedCount } = props const count = await fetchTransaction(hash) - const isConfigChanged = configNetworkIdRef.current !== sdk.config.network.id + const isConfigChanged = configNetworkIdRef.current !== networkId if (!isConfigChanged && (!count || count < expectedCount)) { return new Promise((resolve) => { @@ -54,7 +54,7 @@ const useSubgraphUpdate = () => { }, 1000) }) } - }, [ sdk, fetchTransaction ]) + }, [ networkId, fetchTransaction ]) return useCallback(async ({ hash, count = 1 }: Input) => { actions.ui.resetBottomLoader() @@ -63,11 +63,13 @@ const useSubgraphUpdate = () => { return Promise.reject('Empty hash on subgraphUpdate') } - actions.ui.setBottomLoaderTransaction(`${sdk.config.network.blockExplorerUrl}/tx/${hash}`) + const blockExplorerUrl = getBlockExplorerUrl({ hash }) + + actions.ui.setBottomLoaderTransaction(blockExplorerUrl) await waitForTransaction({ hash, - provider: sdk.provider, + provider: readOnlyProvider, onSuccess: () => ( resolveTransaction({ hash, @@ -77,7 +79,7 @@ const useSubgraphUpdate = () => { }) actions.ui.resetBottomLoader() - }, [ sdk, actions, resolveTransaction ]) + }, [ actions, readOnlyProvider, resolveTransaction, getBlockExplorerUrl ]) } diff --git a/src/hooks/fetch/useTransaction.ts b/src/hooks/fetch/useTransaction.ts index 332f0f13..d1ac59f6 100644 --- a/src/hooks/fetch/useTransaction.ts +++ b/src/hooks/fetch/useTransaction.ts @@ -7,10 +7,10 @@ import waitForTransaction from './util/waitForTransaction' const useTransaction = () => { const actions = useActions() - const { sdk } = useConfig() + const { networkId, readOnlyProvider, getBlockExplorerUrl } = useConfig() - const configNetworkIdRef = useRef(sdk.config.network.id) - configNetworkIdRef.current = sdk.config.network.id + const configNetworkIdRef = useRef(networkId) + configNetworkIdRef.current = networkId return useCallback(async (hash: string) => { actions.ui.resetBottomLoader() @@ -19,17 +19,19 @@ const useTransaction = () => { return Promise.reject() } - actions.ui.setBottomLoaderTransaction(`${sdk.config.network.blockExplorerUrl}/tx/${hash}`) + const blockExplorerUrl = getBlockExplorerUrl({ hash }) + + actions.ui.setBottomLoaderTransaction(blockExplorerUrl) const isSuccess = await waitForTransaction({ hash, - provider: sdk.provider, + provider: readOnlyProvider, }) actions.ui.resetBottomLoader() return isSuccess - }, [ sdk, actions ]) + }, [ actions, readOnlyProvider, getBlockExplorerUrl ]) } diff --git a/src/hooks/swap/useFee.ts b/src/hooks/swap/useFee.ts index 079345b2..0d25e2dc 100644 --- a/src/hooks/swap/useFee.ts +++ b/src/hooks/swap/useFee.ts @@ -79,7 +79,7 @@ const useFee = (values: Input) => { .divide(100) .multiply(percent) .decimals(0) - .toNumber() + .toString() return BigInt(result) } diff --git a/src/hooks/swap/useMaxAmount.ts b/src/hooks/swap/useMaxAmount.ts index 0aba5076..538ee9cd 100644 --- a/src/hooks/swap/useMaxAmount.ts +++ b/src/hooks/swap/useMaxAmount.ts @@ -17,10 +17,14 @@ const storeSelector = (store: Store) => ({ const useMaxAmount = (values: Input) => { const { token, transactionPrice } = values - const { activeWallet, isGnosis } = useConfig() + const { address, activeWallet, isGnosis } = useConfig() const { nativeTokenBalance } = useStore(storeSelector) return useMemo(() => { + if (!address) { + return token.emptyBalance + } + if (token?.address) { return token.balance } @@ -34,7 +38,7 @@ const useMaxAmount = (values: Input) => { const maxAmount = nativeTokenBalance - (transactionPrice * 2n) return maxAmount > 0n ? maxAmount : 0n - }, [ token, activeWallet, transactionPrice, nativeTokenBalance, isGnosis ]) + }, [ token, address, activeWallet, transactionPrice, nativeTokenBalance, isGnosis ]) } diff --git a/src/hooks/swap/useOrderId.ts b/src/hooks/swap/useOrderId.ts index b9d8bd54..07d3533e 100644 --- a/src/hooks/swap/useOrderId.ts +++ b/src/hooks/swap/useOrderId.ts @@ -29,7 +29,7 @@ const useOrderId = () => { throw new Error('Order not found') } catch (error) { - if (count < 10) { + if (count < 20) { await new Promise((resolve) => setTimeout(resolve, count * 300)) return fetchOrder(orderId, count + 1) diff --git a/src/layouts/AppLayout/Header/Connect/Account/AccountMenu/AccountMenu.tsx b/src/layouts/AppLayout/Header/Connect/Account/AccountMenu/AccountMenu.tsx index 7c11be71..ef78157a 100644 --- a/src/layouts/AppLayout/Header/Connect/Account/AccountMenu/AccountMenu.tsx +++ b/src/layouts/AppLayout/Header/Connect/Account/AccountMenu/AccountMenu.tsx @@ -2,8 +2,6 @@ import React from 'react' import { useConfig, wallets } from 'config' import { useClaimsTotal } from 'hooks' -import type { LogoProps } from 'components' - import Menu from './Menu/Menu' import Address from './Address/Address' import Balances from './Balances/Balances' @@ -12,7 +10,7 @@ import ClaimAmountButton from './ClaimAmountButton/ClaimAmountButton' type AccountMenuProps = { - logo: LogoProps['name'] + logo: string } const disableDisconnect = new Set([ diff --git a/src/layouts/AppLayout/Header/Connect/Account/AccountMenu/Address/Address.tsx b/src/layouts/AppLayout/Header/Connect/Account/AccountMenu/Address/Address.tsx index 87f02302..d894abb7 100644 --- a/src/layouts/AppLayout/Header/Connect/Account/AccountMenu/Address/Address.tsx +++ b/src/layouts/AppLayout/Header/Connect/Account/AccountMenu/Address/Address.tsx @@ -4,22 +4,21 @@ import { useCopyToClipboard } from 'hooks' import { useConfig } from 'config' import cx from 'classnames' -import { Text, Logo, RoundButton } from 'components' +import { Text, WalletIcon, RoundButton } from 'components' import type { LogoName } from 'components' type AddressProps = { className?: string - logo: LogoName + logo: LogoName | string } const Address: React.FC = (props) => { const { className, logo } = props - const { sdk, address } = useConfig() + const { address, getBlockExplorerUrl } = useConfig() const copyToClipboard = useCopyToClipboard() - const scanLink = `${sdk.config.network.blockExplorerUrl}/address/` const shortAddress = methods.shortenAddress(address) const handleCopy = useCallback(() => { @@ -27,14 +26,14 @@ const Address: React.FC = (props) => { }, [ address, copyToClipboard ]) const handleCLickToLink = useCallback(() => { - window.open(`${scanLink}${address}`, '_blank') - }, [ address, scanLink ]) + window.open(getBlockExplorerUrl({ address }), '_blank') + }, [ address, getBlockExplorerUrl ]) return (
- { const { isDesktop } = device.useData() @@ -12,9 +10,8 @@ const useAccount = () => { const addressOption = accountName || methods.shortenAddress(address) - const logo: LogoProps['name'] = activeWallet - ? wallets[activeWallet].logo - : 'connector/monitorAddress' + const wallet = activeWallet ? wallets[activeWallet] : null + const logo = wallet?.logo || 'connector/monitorAddress' return useMemo(() => ({ logo, diff --git a/src/layouts/AppLayout/Header/Connect/NetworkSelect/NetworkSelect.tsx b/src/layouts/AppLayout/Header/Connect/NetworkSelect/NetworkSelect.tsx index 7152de7c..9af59f3e 100644 --- a/src/layouts/AppLayout/Header/Connect/NetworkSelect/NetworkSelect.tsx +++ b/src/layouts/AppLayout/Header/Connect/NetworkSelect/NetworkSelect.tsx @@ -40,7 +40,7 @@ const NetworkSelect: React.FC = (props) => { const { isDesktop } = device.useData() const isChangeChainDisabled = useChangeChainDisabled() - const { sdk, networkId, wallet, address, isGnosis } = useConfig() + const { network, networkId, wallet, address, isGnosis } = useConfig() const handleChangeChain = useCallback(async (selectedNetworkId: string) => { if (selectedNetworkId !== networkId) { @@ -70,7 +70,7 @@ const NetworkSelect: React.FC = (props) => { className="rounded-8" color="light" dataTestId={`${dataTestId}-button`} - title={!isDesktop ? '' : sdk.config.network.name} + title={!isDesktop ? '' : network.name} logo={isGnosis ? 'token/GNO' : 'token/ETH'} arrow={isDesktop ? arrow : undefined} ariaLabel={commonMessages.accessibility.changeNetwork} diff --git a/src/layouts/AppLayout/Header/Connect/NetworkSelect/util/useChangeChainDisabled.ts b/src/layouts/AppLayout/Header/Connect/NetworkSelect/util/useChangeChainDisabled.ts index 36feb1a4..8e2e117d 100644 --- a/src/layouts/AppLayout/Header/Connect/NetworkSelect/util/useChangeChainDisabled.ts +++ b/src/layouts/AppLayout/Header/Connect/NetworkSelect/util/useChangeChainDisabled.ts @@ -14,7 +14,6 @@ const useChangeChainDisabled = () => { wallets.dAppBrowser.id, wallets.gnosisSafe.id, wallets.ledgerLive.id, - wallets.zenGo.id, ] return ( diff --git a/src/layouts/modals/ConnectWalletModal/ConnectorsView/ConnectorButton/ConnectorButton.tsx b/src/layouts/modals/ConnectWalletModal/ConnectorsView/ConnectorButton/ConnectorButton.tsx index ac02ee66..4452ff1a 100644 --- a/src/layouts/modals/ConnectWalletModal/ConnectorsView/ConnectorButton/ConnectorButton.tsx +++ b/src/layouts/modals/ConnectWalletModal/ConnectorsView/ConnectorButton/ConnectorButton.tsx @@ -1,7 +1,7 @@ import React from 'react' import cx from 'classnames' -import { Href , ButtonBase, Logo, LogoName, Text, Loading } from 'components' +import { Href , ButtonBase, WalletIcon, LogoName, Text, Loading } from 'components' import s from './ConnectorButton.module.scss' @@ -9,7 +9,7 @@ import s from './ConnectorButton.module.scss' type ConnectorButtonProps = { className?: string title: Intl.Message | string - logo: LogoName + logo: LogoName | string isDisabled: boolean isLoading: boolean deepLink?: string @@ -28,8 +28,8 @@ const ConnectorButton: React.FC = (props) => { dataTestId={dataTestId} >
-
@@ -58,8 +58,8 @@ const ConnectorButton: React.FC = (props) => {
) : ( - ) diff --git a/src/layouts/modals/ConnectWalletModal/ConnectorsView/ConnectorsView.tsx b/src/layouts/modals/ConnectWalletModal/ConnectorsView/ConnectorsView.tsx index 6cd8329f..fb69170b 100644 --- a/src/layouts/modals/ConnectWalletModal/ConnectorsView/ConnectorsView.tsx +++ b/src/layouts/modals/ConnectWalletModal/ConnectorsView/ConnectorsView.tsx @@ -6,8 +6,6 @@ import device from 'modules/device' import { useConfig } from 'config' import cx from 'classnames' -import { LogoProps } from 'components' - import ConnectorButton from './ConnectorButton/ConnectorButton' @@ -28,7 +26,7 @@ const ConnectorsView: React.FC = (props) => { const { isDesktop } = device.useData() const setDeepLink = useCallback((id: WalletIds) => { - if (id === wallets.metaMask.id && !isDesktop) { + if (id === 'io.metamask' && !isDesktop) { const hostname = methods.getHostName() return `https://metamask.app.link/dapp/${hostname}${pathname}` @@ -42,7 +40,7 @@ const ConnectorsView: React.FC = (props) => { .filter((wallet) => wallet.networks.includes(chainId)) .map((wallet) => { const title: Intl.Message | string = wallet.title - const logo: LogoProps['name'] = wallet.logo + const logo = wallet.logo as string return { ...wallet, diff --git a/src/layouts/modals/ConnectWalletModal/MonitorAddressView/MonitorAddressView.tsx b/src/layouts/modals/ConnectWalletModal/MonitorAddressView/MonitorAddressView.tsx index ef1b39ea..1ffe3574 100644 --- a/src/layouts/modals/ConnectWalletModal/MonitorAddressView/MonitorAddressView.tsx +++ b/src/layouts/modals/ConnectWalletModal/MonitorAddressView/MonitorAddressView.tsx @@ -19,8 +19,8 @@ type MonitorAddressViewProps = { const MonitorAddressView: React.FC = (props) => { const { className } = props - const { sdk, wallet } = useConfig() const [ isSubmitting, setSubmitting ] = useState(false) + const { chainId, readOnlyProvider, wallet } = useConfig() const addressField = forms.useField({ valueType: 'string', @@ -39,9 +39,9 @@ const MonitorAddressView: React.FC = (props) => { } else if (value) { const result = await methods.ens.fetchAddress({ - provider: sdk.provider, - chainId: sdk.config.network.chainId, + provider: readOnlyProvider, ensName: value, + chainId, }) const isValidAddress = isAddress(result) @@ -61,7 +61,7 @@ const MonitorAddressView: React.FC = (props) => { } setSubmitting(false) - }, [ sdk, wallet, addressField ]) + }, [ chainId, wallet, readOnlyProvider, addressField ]) return (
- -