From 70c2d0ebaca1bcba153bdd1255eedd534eeddcfe Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Mon, 4 May 2026 21:16:59 +0700 Subject: [PATCH 1/2] Migrate to @metamask/connect-evm Swap out the legacy @metamask/sdk for the new @metamask/connect-evm client and update package metadata (version bump to 2.3.0). Code changes load connect-evm (handling ESM/CJS shapes), reuse a single client instance, attach a disconnect shim to the provider, and map legacy MetaMask SDK options to the new connect-evm option shape (including Infura/custom RPC merging via getInfuraRpcUrls). README updated to reflect the Connect EVM integration and backwards compatibility notes; package.json dependency updated accordingly. --- packages/metamask/README.md | 28 +- packages/metamask/package.json | 6 +- packages/metamask/src/index.ts | 209 ++++++++++---- yarn.lock | 492 +++++++++++++++++++++++++++++---- 4 files changed, 624 insertions(+), 111 deletions(-) diff --git a/packages/metamask/README.md b/packages/metamask/README.md index fc298b987..322e1f89f 100644 --- a/packages/metamask/README.md +++ b/packages/metamask/README.md @@ -1,8 +1,9 @@ # @web3-onboard/metamask -## Wallet module for connecting MetaMask Wallet SDK to web3-onboard +## Wallet module for connecting MetaMask Connect EVM to web3-onboard The MetaMask Web3-Onboard module provides a reliable, secure, and seamless connection from your dapp to the MetaMask browser extension and MetaMask Mobile. -See [MetaMask SDK Developer Docs](https://docs.metamask.io/wallet/how-to/connect/set-up-sdk/) + +This module uses [MetaMask Connect EVM](https://docs.metamask.io/metamask-connect/evm/) (`@metamask/connect-evm`) under the hood — the successor to the legacy `@metamask/sdk`. The integration surface for `@web3-onboard/metamask` is unchanged: the legacy options below are mapped to their MetaMask Connect EVM equivalents internally so existing dapps keep working without code changes. ![MetaMask SDK ConnectionFlow](https://github.com/blocknative/web3-onboard/blob/develop/assets/metaMaskSDK-connect.gif?raw=true 'MetaMask SDK ConnectionFlow') @@ -12,22 +13,35 @@ See [MetaMask SDK Developer Docs](https://docs.metamask.io/wallet/how-to/connect ### If using this package with the `@web3-onboard/injected-wallets` module _When utilizing this package alongside the `@web3-onboard/injected-wallets` module, ensure to list this package prior to the initialized injected-wallets module within the wallets list of the Web3-Onboard init._ -_This order prioritizes the SDK when a MetaMask browser wallet is detected, allowing the SDK to take precedence._ +_This order prioritizes the MetaMask Connect EVM client when a MetaMask browser wallet is detected, allowing it to take precedence._ ## Options ```typescript -// For a complete list of options check https://docs.metamask.io/wallet/how-to/connect/set-up-sdk/ +// All fields are optional. Legacy MetaMaskSDK option names are accepted for +// backwards compatibility and mapped to MetaMask Connect EVM internally. interface MetaMaskSDKOptions { - dappMetadata: { + dappMetadata?: { url?: string; name?: string; + iconUrl?: string; base64Icon?: string; - }, + }; /** - * If MetaMask browser extension is detected, directly use it without prompting the user. + * If MetaMask browser extension is detected, prefer it over the mobile flow. + * Mapped to `ui.preferExtension`. */ extensionOnly?: boolean; + /** Mapped to `ui.headless`. */ + headless?: boolean; + /** Used to populate `api.supportedNetworks` via `getInfuraRpcUrls`. */ + infuraAPIKey?: string; + /** Merged into `api.supportedNetworks`. */ + readonlyRPCMap?: Record; + /** Mapped to `mobile.preferredOpenLink`. */ + openDeeplink?: (deeplink: string) => void; + /** Mapped to `mobile.useDeeplink`. */ + useDeeplink?: boolean; } ``` diff --git a/packages/metamask/package.json b/packages/metamask/package.json index fcbedc0fb..7bf64124f 100644 --- a/packages/metamask/package.json +++ b/packages/metamask/package.json @@ -1,7 +1,7 @@ { "name": "@web3-onboard/metamask", - "version": "2.2.1", - "description": "MetaMask SDK wallet module for connecting to Web3-Onboard. Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardised spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.", + "version": "2.3.0", + "description": "MetaMask Connect EVM wallet module for connecting to Web3-Onboard. Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardised spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.", "keywords": [ "Ethereum", "Web3", @@ -58,7 +58,7 @@ "typescript": "^5.2.2" }, "dependencies": { - "@metamask/sdk": "^0.32.0", + "@metamask/connect-evm": "^1.0.0", "@web3-onboard/common": "^2.4.1" }, "engines": { diff --git a/packages/metamask/src/index.ts b/packages/metamask/src/index.ts index 6b947c72a..de80fe6df 100644 --- a/packages/metamask/src/index.ts +++ b/packages/metamask/src/index.ts @@ -1,40 +1,75 @@ import type { WalletInit } from '@web3-onboard/common' -import type { MetaMaskSDK, MetaMaskSDKOptions } from '@metamask/sdk' -import type { createEIP1193Provider } from '@web3-onboard/common' +import type { + createEVMClient as CreateEVMClientFn, + getInfuraRpcUrls as GetInfuraRpcUrlsFn, + MetamaskConnectEVM +} from '@metamask/connect-evm' + +/** + * Legacy MetaMask SDK options that this module continues to accept for + * backwards compatibility. Each field is mapped to its + * `@metamask/connect-evm` equivalent inside `getInterface` so callers can + * upgrade transparently without changing their integration code. + */ +export type MetaMaskSDKOptions = { + dappMetadata?: { + name?: string + url?: string + iconUrl?: string + base64Icon?: string + } + /** Maps to `ui.preferExtension` in `@metamask/connect-evm`. */ + extensionOnly?: boolean + /** Maps to `ui.headless` in `@metamask/connect-evm`. */ + headless?: boolean + /** Used to populate `api.supportedNetworks` via `getInfuraRpcUrls`. */ + infuraAPIKey?: string + /** Merged into `api.supportedNetworks`. */ + readonlyRPCMap?: Record + /** Maps to `mobile.preferredOpenLink`. */ + openDeeplink?: (deeplink: string) => void + /** Maps to `mobile.useDeeplink`. */ + useDeeplink?: boolean + // Allow legacy/forward-compat fields (e.g. `i18nOptions`, `_source`, + // `enableAnalytics`) without a type error. They are silently ignored. + [key: string]: unknown +} + +type EvmClientOptions = Parameters[0] -type ImportSDK = { - createEIP1193Provider: typeof createEIP1193Provider - MetaMaskSDKConstructor: typeof MetaMaskSDK +type ConnectEvmImports = { + createEVMClient: typeof CreateEVMClientFn + getInfuraRpcUrls: typeof GetInfuraRpcUrlsFn } -const loadImports = async () => { - if (importPromise) { - return await importPromise - } +let importPromise: Promise | null = null +let client: MetamaskConnectEVM | null = null + +const loadImports = async (): Promise => { + const mmConnect = await import('@metamask/connect-evm') - const { createEIP1193Provider } = await import('@web3-onboard/common') - const importedSDK = await import('@metamask/sdk') - const MetaMaskSDKConstructor = + const createEVMClient = + // @ts-ignore — handle both ESM and CJS default-export shapes + mmConnect.createEVMClient || mmConnect.default?.createEVMClient + + const getInfuraRpcUrls = // @ts-ignore - importedSDK.MetaMaskSDK || importedSDK.default.MetaMaskSDK + mmConnect.getInfuraRpcUrls || mmConnect.default?.getInfuraRpcUrls - if (!MetaMaskSDKConstructor) { - throw new Error('Error importing and initializing MetaMask SDK') + if (!createEVMClient) { + throw new Error('Error importing and initializing @metamask/connect-evm') } - return { createEIP1193Provider, MetaMaskSDKConstructor } + return { createEVMClient, getInfuraRpcUrls } } -let importPromise: Promise | null = null -let sdk: MetaMaskSDK | null = null - function metamask({ options }: { options: Partial }): WalletInit { return () => { - importPromise = loadImports().catch(error => { + importPromise = importPromise ?? loadImports().catch(error => { throw error }) @@ -42,54 +77,128 @@ function metamask({ label: 'MetaMask', getIcon: async () => (await import('./icon.js')).default, getInterface: async ({ appMetadata }) => { - sdk = (window as any).mmsdk || sdk // Prevent conflict with existing mmsdk instances - - if (sdk) { - // Prevent re-initializing instance as it causes issues with MetaMask sdk mobile provider. + // Reuse the existing client/provider if we have already initialized + // it. Re-initializing would needlessly reset state and historically + // caused issues with the MetaMask mobile provider. + if (client) { + const existingProvider = client.getProvider() + attachDisconnectShim(existingProvider) return { - provider: sdk.getProvider() as any, - instance: sdk + provider: existingProvider as any, + instance: client } } - const { name, icon } = appMetadata || {} - const base64 = window.btoa(icon || '') - const appLogoUrl = `data:image/svg+xml;base64,${base64}` const imports = await importPromise - if (!imports?.MetaMaskSDKConstructor) { - throw new Error('Error importing and initializing MetaMask SDK') + if (!imports?.createEVMClient) { + throw new Error( + 'Error importing and initializing @metamask/connect-evm' + ) } - const { MetaMaskSDKConstructor } = imports + const { createEVMClient, getInfuraRpcUrls } = imports + + const { name, icon } = appMetadata || {} + const base64 = window.btoa(icon || '') + const appLogoUrl = `data:image/svg+xml;base64,${base64}` - sdk = new MetaMaskSDKConstructor({ - ...options, - dappMetadata: { - name: options.dappMetadata?.name || name || '', - url: options.dappMetadata?.url || window.location.origin, - base64Icon: appLogoUrl - }, - _source: 'web3-onboard' + const evmOptions = mapLegacyOptions({ + options, + getInfuraRpcUrls, + fallbackName: name, + fallbackBase64Icon: appLogoUrl }) - await sdk.init() - const provider = sdk.getProvider() + client = await createEVMClient(evmOptions) - if (provider) { - ;(provider as any).disconnect = () => { - sdk?.terminate() - } - } - + const provider = client.getProvider() + attachDisconnectShim(provider) return { - provider, - instance: sdk + provider: provider as any, + instance: client } } } } } +function attachDisconnectShim(provider: unknown): void { + // Web3-Onboard expects a `disconnect` method on the provider so it can + // tear down the wallet session when the user disconnects from the dapp. + // The MetaMask Connect EVM client exposes this via `client.disconnect()`. + ;(provider as { disconnect?: () => void }).disconnect = () => { + void client?.disconnect() + } +} + +function mapLegacyOptions({ + options, + getInfuraRpcUrls, + fallbackName, + fallbackBase64Icon +}: { + options: Partial + getInfuraRpcUrls: typeof GetInfuraRpcUrlsFn + fallbackName?: string + fallbackBase64Icon: string +}): EvmClientOptions { + const supportedNetworks: Record = { + ...(typeof options.infuraAPIKey === 'string' && options.infuraAPIKey + ? getInfuraRpcUrls({ infuraApiKey: options.infuraAPIKey }) + : {}), + ...(options.readonlyRPCMap ?? {}) + } + + const evmOptions: EvmClientOptions = { + dapp: { + name: options.dappMetadata?.name || fallbackName || '', + url: options.dappMetadata?.url || window.location.origin, + // Mirror the legacy module's behavior: the rendered web3-onboard logo + // (`appLogoUrl`) is always used as the dapp icon, just like the old + // `MetaMaskSDK` integration that always set `base64Icon: appLogoUrl`. + base64Icon: fallbackBase64Icon + }, + // `api.supportedNetworks` is required by `createEVMClient`. Pass the + // merged Infura + custom RPC map (or an empty object when neither is + // provided — the client still works, with read-only requests routed + // through MetaMask's default transport). + api: { supportedNetworks: supportedNetworks as Record<`0x${string}`, string> } + } + + if ( + typeof options.headless === 'boolean' || + typeof options.extensionOnly === 'boolean' + ) { + evmOptions.ui = { + ...(typeof options.headless === 'boolean' + ? { headless: options.headless } + : {}), + // `extensionOnly: true` semantically meant "prefer the extension when + // available" in the legacy SDK, which is exactly what + // `ui.preferExtension` controls in `@metamask/connect-evm`. + ...(typeof options.extensionOnly === 'boolean' + ? { preferExtension: options.extensionOnly } + : {}) + } + } + + if ( + typeof options.openDeeplink === 'function' || + typeof options.useDeeplink === 'boolean' + ) { + evmOptions.mobile = { + ...(typeof options.openDeeplink === 'function' + ? { preferredOpenLink: options.openDeeplink } + : {}), + ...(typeof options.useDeeplink === 'boolean' + ? { useDeeplink: options.useDeeplink } + : {}) + } + } + + return evmOptions +} + export default metamask diff --git a/yarn.lock b/yarn.lock index b5c8313dd..1b94e6ec3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1028,6 +1028,11 @@ resolved "https://registry.yarnpkg.com/@ecies/ciphers/-/ciphers-0.2.2.tgz#82a15b10a6e502b63fb30915d944b2eaf3ff17ff" integrity sha512-ylfGR7PyTd+Rm2PqQowG08BCKA22QuX8NzrL+LxAAvazN10DMwdJ2fWwAzRj05FI/M8vNFGm3cv9Wq/GFWCBLg== +"@ecies/ciphers@^0.2.5": + version "0.2.6" + resolved "https://registry.yarnpkg.com/@ecies/ciphers/-/ciphers-0.2.6.tgz#e7cdc4688de3c224e03d479e3227bcece44cbeab" + integrity sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g== + "@emotion/is-prop-valid@1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" @@ -2868,6 +2873,100 @@ "@metamask/utils" "^8.0.0" superstruct "^1.0.3" +"@metamask/analytics@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@metamask/analytics/-/analytics-0.4.0.tgz#182d28756b90037b007b8a8f467a862e71781f8e" + integrity sha512-QKjVu8RsbjeSfXXhRLvOVdWJ0jUrVdXFwa4I1VyoI7LapWS6T0apTSjM8nLJKN1NADbpSYm7ctyuTyaHlG/0yA== + dependencies: + openapi-fetch "^0.13.5" + +"@metamask/api-specs@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@metamask/api-specs/-/api-specs-0.14.0.tgz#806f8327d262001dca5e60946f45cc579164a3e2" + integrity sha512-pL3FADJcw/CA5Nsq6k4ePYxrNyscqVJh0XYXStvGPkw9yPdgIRAc+DuMuMMpaahYpKsmWWHpTAuvwVo9DuFXyg== + +"@metamask/approval-controller@^9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@metamask/approval-controller/-/approval-controller-9.0.1.tgz#5d48cd99ef7f507f4f39887ac27e165a1515eae9" + integrity sha512-U2xTxCkAqExpcmDlMUYQgsmI7DxD4IF3Q2wMjlk3xXK5H5mIzwgbCjhvGlZpChtmvXc/QYkzwG91n0X54RgJcQ== + dependencies: + "@metamask/base-controller" "^9.0.1" + "@metamask/messenger" "^1.0.0" + "@metamask/rpc-errors" "^7.0.2" + "@metamask/utils" "^11.9.0" + nanoid "^3.3.8" + +"@metamask/base-controller@^9.0.1": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-9.1.0.tgz#e998419546adf8f34cb9c035904df79699738821" + integrity sha512-iYGzkV7fCSi/BK9nUgF64V4Yd4V6PQ38suh3ewUJsOk2/ksAq0HuugmLFJ7JeUmWUr9wZsGKJ3Z/jB9CJ91o0g== + dependencies: + "@metamask/messenger" "^1.1.1" + "@metamask/utils" "^11.9.0" + immer "^9.0.6" + +"@metamask/chain-agnostic-permission@^1.2.2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@metamask/chain-agnostic-permission/-/chain-agnostic-permission-1.5.0.tgz#21460751923e2c6c5ad0d777ff4bf2ae999bbb40" + integrity sha512-V5VvBKMXk1LfeCDhjBoCEU2s1YEEuEvhZk1WM+Q0bzjiUIxKP43AUeoRDN8KMpdI+U0K2Iw9CLNI10vwFoQ8EQ== + dependencies: + "@metamask/api-specs" "^0.14.0" + "@metamask/controller-utils" "^11.19.0" + "@metamask/permission-controller" "^12.2.1" + "@metamask/rpc-errors" "^7.0.2" + "@metamask/utils" "^11.9.0" + lodash "^4.17.21" + +"@metamask/connect-evm@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@metamask/connect-evm/-/connect-evm-1.0.0.tgz#8af6373d3ae28d572700f841e845cbc75fdb2447" + integrity sha512-Tqn+WcOefgYF4qck4Xzhx1n6TFr+6Sphcn1q6/5GJwMmycRRr6vDP8hfVP7sL7v+yYAkzDSPu7KUduOdLYjX4A== + dependencies: + "@metamask/analytics" "^0.4.0" + "@metamask/chain-agnostic-permission" "^1.2.2" + "@metamask/connect-multichain" "^0.12.1" + "@metamask/utils" "^11.8.1" + +"@metamask/connect-multichain@^0.12.1": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@metamask/connect-multichain/-/connect-multichain-0.12.1.tgz#a579d464e62e8c163f7220db6ee39ca235083be8" + integrity sha512-v8rYIdhrnN3m8HhjIkiRjn0hXSoKEW0dT5idpsJ/q//EBXJfn/s1FWLgNJCwoTFM60wJah0hHk4gz6XZF/BZCg== + dependencies: + "@metamask/analytics" "^0.4.0" + "@metamask/mobile-wallet-protocol-core" "^0.4.0" + "@metamask/mobile-wallet-protocol-dapp-client" "^0.3.0" + "@metamask/multichain-api-client" "^0.10.1" + "@metamask/multichain-ui" "^0.4.1" + "@metamask/onboarding" "^1.0.1" + "@metamask/rpc-errors" "^7.0.3" + "@metamask/utils" "^11.8.1" + "@paulmillr/qr" "^0.2.1" + bowser "^2.11.0" + buffer "^6.0.3" + cross-fetch "^4.1.0" + eciesjs "0.4.17" + eventemitter3 "^5.0.1" + pako "^2.1.0" + uuid "^11.1.0" + ws "^8.18.3" + +"@metamask/controller-utils@^11.19.0": + version "11.20.0" + resolved "https://registry.yarnpkg.com/@metamask/controller-utils/-/controller-utils-11.20.0.tgz#e1d91f2d7a5b79d4d123eac5861e3fe2a52b793c" + integrity sha512-B/6QfotVxSDHSSsreUgjGPRVj5MxgcYIxHjXo4wOAVAYT+KE7/W+F4zQhiwctMXuekD3eW5wXYaN/xp6fnm+kA== + dependencies: + "@metamask/eth-query" "^4.0.0" + "@metamask/ethjs-unit" "^0.3.0" + "@metamask/utils" "^11.9.0" + "@spruceid/siwe-parser" "2.1.0" + "@types/bn.js" "^5.1.5" + bignumber.js "^9.1.2" + bn.js "^5.2.1" + cockatiel "^3.1.2" + eth-ens-namehash "^2.0.8" + fast-deep-equal "^3.1.3" + lodash "^4.17.21" + "@metamask/eth-json-rpc-middleware@^12.0.0": version "12.1.0" resolved "https://registry.yarnpkg.com/@metamask/eth-json-rpc-middleware/-/eth-json-rpc-middleware-12.1.0.tgz#237f018a1a3c99297fcb5a8263b6c669379b168c" @@ -2900,6 +2999,14 @@ "@metamask/safe-event-emitter" "^3.0.0" "@metamask/utils" "^8.3.0" +"@metamask/eth-query@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-query/-/eth-query-4.0.0.tgz#a8c1651b69e298da58628b1c09d31dd504a939b3" + integrity sha512-j2yPO2axYGyxwdqXRRhk2zBijt1Nd/xKCIXQkzvfWac0sKP0L9mSt1ZxMOe/sOF1SwS2R+NSaq+gsQDsQvrC4Q== + dependencies: + json-rpc-random-id "^1.0.0" + xtend "^4.0.1" + "@metamask/eth-sig-util@^7.0.0", "@metamask/eth-sig-util@^7.0.2": version "7.0.2" resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-7.0.2.tgz#741de634b0d6ca96ce1ee3d064ac6a27756d8d21" @@ -2912,6 +3019,27 @@ ethereum-cryptography "^2.1.2" tweetnacl "^1.0.3" +"@metamask/ethjs-unit@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@metamask/ethjs-unit/-/ethjs-unit-0.3.0.tgz#d44d21d3b4ad443fb0cdd0362ea07c6f51e68ec4" + integrity sha512-HZtg69ODXYS9+ovKUYofZuIAwq4fc2/MGazD4vBQRKWMhPu4ySdmgR0EuzbxEK4uhr18KA4pbL+mCYjyjGxY7w== + dependencies: + "@metamask/number-to-bn" "^1.7.1" + bn.js "^5.2.1" + +"@metamask/json-rpc-engine@^10.2.4": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@metamask/json-rpc-engine/-/json-rpc-engine-10.3.0.tgz#b30a6f50b317d24d997e050eb5f65e513fb437e5" + integrity sha512-gZeIVUTXSeaKMVkDNDaHiTZN0XnPrIMTZwyLKsjZ4xJsgWF5qbwlbZ+y1Li+8q3hQclrTQ9jun8CVTQgPetcLw== + dependencies: + "@metamask/messenger" "^1.2.0" + "@metamask/rpc-errors" "^7.0.2" + "@metamask/safe-event-emitter" "^3.0.0" + "@metamask/utils" "^11.9.0" + "@types/deep-freeze-strict" "^1.1.0" + deep-freeze-strict "^1.1.1" + klona "^2.0.6" + "@metamask/json-rpc-engine@^7.1.1", "@metamask/json-rpc-engine@^7.3.2": version "7.3.3" resolved "https://registry.yarnpkg.com/@metamask/json-rpc-engine/-/json-rpc-engine-7.3.3.tgz#f2b30a2164558014bfcca45db10f5af291d989af" @@ -2940,6 +3068,54 @@ "@metamask/utils" "^8.3.0" readable-stream "^3.6.2" +"@metamask/messenger@^1.0.0", "@metamask/messenger@^1.1.1", "@metamask/messenger@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@metamask/messenger/-/messenger-1.2.0.tgz#017eec2c32af392bc046c2b27e791536647135f6" + integrity sha512-vWgqiMswt2f1VSjJKbx744Ft9OEEMTRc6WA4GxYWGUm6I3VuXyZvXEKjZbHv561i9RvJglA+fB0QXnFae0V+eA== + dependencies: + "@metamask/utils" "^11.9.0" + yargs "^17.7.2" + +"@metamask/mobile-wallet-protocol-core@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@metamask/mobile-wallet-protocol-core/-/mobile-wallet-protocol-core-0.4.0.tgz#05ef73ed3a70f7c96f0cba4e461c461e7357317a" + integrity sha512-rB1wMogvSUsFaxyH/eVUCczIkTxVaPPETlD/wgm+gw7EbWP0LlZPY7Bh+DICSfUCJ0zqnoFuwr77WNJvZ6ZiWw== + dependencies: + async-mutex "^0.5.0" + centrifuge "^5.3.5" + eventemitter3 "^5.0.1" + uuid "^11.1.0" + +"@metamask/mobile-wallet-protocol-dapp-client@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@metamask/mobile-wallet-protocol-dapp-client/-/mobile-wallet-protocol-dapp-client-0.3.0.tgz#0fbb5757219edaaaa51ca52e1c9ed91f8278c282" + integrity sha512-rXStrvIa57a8OaeM+3HeR6Z9ETHOvmQi/9s6CLplDwH2hn2MWjI6WW3EUrxq2KGmGuhbO5Oo21ANnD23QKfduw== + dependencies: + "@metamask/mobile-wallet-protocol-core" "^0.4.0" + "@metamask/utils" "^9.1.0" + uuid "^11.1.0" + +"@metamask/multichain-api-client@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@metamask/multichain-api-client/-/multichain-api-client-0.10.1.tgz#b5f891a2c9783b8ebb9f097a04c89939b790545a" + integrity sha512-LsqO2SiDcTgOuXyVYEB0zgBaVNhryhP2tYI3L7tLa7PoeDqMkNIreFhDeu8jM5tPWkCimQvMwCkG3DF4P5dD3A== + +"@metamask/multichain-ui@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@metamask/multichain-ui/-/multichain-ui-0.4.1.tgz#cc832e12a0507d5153bb9401ae9aa6665b7d8b16" + integrity sha512-tJgTot8Pfkda895A6biJu7rE+jlQdVCNVzGgW+2wM9aFG20G+GEbQy3KO7uC4ImUvaKV4SyJ45r6Ir/Yf55mqw== + dependencies: + "@paulmillr/qr" "^0.2.1" + qr-code-styling "^1.9.2" + +"@metamask/number-to-bn@^1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@metamask/number-to-bn/-/number-to-bn-1.7.1.tgz#a449ec8b2edba211e0dc3e1e0428ff2cc2bf7ab4" + integrity sha512-qCN+Au4amvcVii2LdOJNndYhdmk5Lk9tlStJhKpZ8tGeYQDJTghqYXJuSUVPHvfl6FUfKY1i1Or2j2EbnEerSQ== + dependencies: + bn.js "5.2.1" + strip-hex-prefix "1.0.0" + "@metamask/object-multiplex@^1.1.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@metamask/object-multiplex/-/object-multiplex-1.2.0.tgz#38fc15c142f61939391e1b9a8eed679696c7e4f4" @@ -2972,6 +3148,23 @@ dependencies: bowser "^2.9.0" +"@metamask/permission-controller@^12.2.1": + version "12.3.0" + resolved "https://registry.yarnpkg.com/@metamask/permission-controller/-/permission-controller-12.3.0.tgz#a4c5fc1c36375346205f1a88f3d7128a4ff0f8e0" + integrity sha512-scGSOCD6ogHM38GlAprN5S4QvGrM0mCEordg7glASUiQdkO98Vvlsxa2w6mhKFVv4V4K0q2Xhn5YLw5AlFSWTw== + dependencies: + "@metamask/approval-controller" "^9.0.1" + "@metamask/base-controller" "^9.0.1" + "@metamask/controller-utils" "^11.19.0" + "@metamask/json-rpc-engine" "^10.2.4" + "@metamask/messenger" "^1.0.0" + "@metamask/rpc-errors" "^7.0.2" + "@metamask/utils" "^11.9.0" + "@types/deep-freeze-strict" "^1.1.0" + deep-freeze-strict "^1.1.1" + immer "^9.0.6" + nanoid "^3.3.8" + "@metamask/providers@16.1.0": version "16.1.0" resolved "https://registry.yarnpkg.com/@metamask/providers/-/providers-16.1.0.tgz#7da593d17c541580fa3beab8d9d8a9b9ce19ea07" @@ -3024,6 +3217,14 @@ "@metamask/utils" "^8.3.0" fast-safe-stringify "^2.0.6" +"@metamask/rpc-errors@^7.0.2", "@metamask/rpc-errors@^7.0.3": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@metamask/rpc-errors/-/rpc-errors-7.0.3.tgz#68fe7d1dcb7913c7e89ec48f549e2ab498ecff14" + integrity sha512-nrEaeBawm8yFU7hetJKok/CUs0tQsWtTqp3OLbFhPUMXYqU7uI5LAV5vi9o7rTjFkUyof7Nzbw5bea5+1ou+dg== + dependencies: + "@metamask/utils" "^11.4.2" + fast-safe-stringify "^2.0.6" + "@metamask/safe-event-emitter@2.0.0", "@metamask/safe-event-emitter@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" @@ -3050,17 +3251,6 @@ utf-8-validate "^5.0.2" uuid "^8.3.2" -"@metamask/sdk-communication-layer@0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@metamask/sdk-communication-layer/-/sdk-communication-layer-0.32.0.tgz#89710e807806836138ea5018b087731d6acab627" - integrity sha512-dmj/KFjMi1fsdZGIOtbhxdg3amxhKL/A5BqSU4uh/SyDKPub/OT+x5pX8bGjpTL1WPWY/Q0OIlvFyX3VWnT06Q== - dependencies: - bufferutil "^4.0.8" - date-fns "^2.29.3" - debug "^4.3.4" - utf-8-validate "^5.0.2" - uuid "^8.3.2" - "@metamask/sdk-install-modal-web@0.31.5": version "0.31.5" resolved "https://registry.yarnpkg.com/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.31.5.tgz#b5e903b63f936b9ae795f31137b4c9f0873c382d" @@ -3068,13 +3258,6 @@ dependencies: "@paulmillr/qr" "^0.2.1" -"@metamask/sdk-install-modal-web@0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.32.0.tgz#86f80420ca364fa0d7710016fa5c81f95537ab23" - integrity sha512-TFoktj0JgfWnQaL3yFkApqNwcaqJ+dw4xcnrJueMP3aXkSNev2Ido+WVNOg4IIMxnmOrfAC9t0UJ0u/dC9MjOQ== - dependencies: - "@paulmillr/qr" "^0.2.1" - "@metamask/sdk@0.31.5": version "0.31.5" resolved "https://registry.yarnpkg.com/@metamask/sdk/-/sdk-0.31.5.tgz#804b68382d9f4c74ab0296f1b5c54143622ef2c8" @@ -3100,30 +3283,27 @@ util "^0.12.4" uuid "^8.3.2" -"@metamask/sdk@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@metamask/sdk/-/sdk-0.32.0.tgz#f0e179746fe69dccd032a9026884b45b519c1975" - integrity sha512-WmGAlP1oBuD9hk4CsdlG1WJFuPtYJY+dnTHJMeCyohTWD2GgkcLMUUuvu9lO1/NVzuOoSi1OrnjbuY1O/1NZ1g== +"@metamask/superstruct@^3.1.0": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@metamask/superstruct/-/superstruct-3.2.1.tgz#fca933017c5b78529f8f525560cef32c57e889d2" + integrity sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g== + +"@metamask/utils@^11.4.2", "@metamask/utils@^11.8.1", "@metamask/utils@^11.9.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-11.11.0.tgz#6675946df767da6cbe306c7b5e76685320a6c826" + integrity sha512-0nF2CWjWQr/m0Y2t2lJnBTU1/CZPPTvKvcESLplyWe/tyeb8zFOi/FeneDmaFnML6LYRIGZU6f+xR0jKAIUZfw== dependencies: - "@babel/runtime" "^7.26.0" - "@metamask/onboarding" "^1.0.1" - "@metamask/providers" "16.1.0" - "@metamask/sdk-communication-layer" "0.32.0" - "@metamask/sdk-install-modal-web" "0.32.0" - "@paulmillr/qr" "^0.2.1" - bowser "^2.9.0" - cross-fetch "^4.0.0" + "@ethereumjs/tx" "^4.2.0" + "@metamask/superstruct" "^3.1.0" + "@noble/hashes" "^1.3.1" + "@scure/base" "^1.1.3" + "@types/debug" "^4.1.7" + "@types/lodash" "^4.17.20" debug "^4.3.4" - eciesjs "^0.4.11" - eth-rpc-errors "^4.0.3" - eventemitter2 "^6.4.9" - obj-multiplex "^1.0.0" - pump "^3.0.0" - readable-stream "^3.6.2" - socket.io-client "^4.5.1" - tslib "^2.6.0" - util "^0.12.4" - uuid "^8.3.2" + lodash "^4.17.21" + pony-cause "^2.1.10" + semver "^7.5.4" + uuid "^9.0.1" "@metamask/utils@^5.0.0", "@metamask/utils@^5.0.1": version "5.0.2" @@ -3165,6 +3345,21 @@ semver "^7.5.4" superstruct "^1.0.3" +"@metamask/utils@^9.1.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-9.3.0.tgz#4726bd7f5d6a43ea8425b6d663ab9207f617c2d1" + integrity sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g== + dependencies: + "@ethereumjs/tx" "^4.2.0" + "@metamask/superstruct" "^3.1.0" + "@noble/hashes" "^1.3.1" + "@scure/base" "^1.1.3" + "@types/debug" "^4.1.7" + debug "^4.3.4" + pony-cause "^2.1.10" + semver "^7.5.4" + uuid "^9.0.1" + "@mobily/ts-belt@^3.13.1": version "3.13.1" resolved "https://registry.yarnpkg.com/@mobily/ts-belt/-/ts-belt-3.13.1.tgz#8f8ce2a2eca41d88c2ca70c84d0f47d0f7f5cd5f" @@ -3386,7 +3581,7 @@ dependencies: "@noble/hashes" "1.8.0" -"@noble/curves@1.9.7", "@noble/curves@^1.9.1", "@noble/curves@~1.9.0": +"@noble/curves@1.9.7", "@noble/curves@^1.9.1", "@noble/curves@^1.9.7", "@noble/curves@~1.9.0": version "1.9.7" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.7.tgz#79d04b4758a43e4bca2cbdc62e7771352fa6b951" integrity sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw== @@ -3440,7 +3635,7 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f" integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== -"@noble/hashes@1.8.0", "@noble/hashes@^1.8.0", "@noble/hashes@~1.8.0": +"@noble/hashes@1.8.0", "@noble/hashes@^1.1.2", "@noble/hashes@^1.8.0", "@noble/hashes@~1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== @@ -3656,6 +3851,11 @@ resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== +"@protobufjs/codegen@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.5.tgz#d9315ad7cf3f30aac70bda3c068443dc6f143659" + integrity sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g== + "@protobufjs/eventemitter@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" @@ -3679,6 +3879,11 @@ resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== +"@protobufjs/inquire@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.1.tgz#6cb936f4ac50965230af1e9d0bbfd57ea3675aa4" + integrity sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew== + "@protobufjs/path@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" @@ -3694,6 +3899,11 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== +"@protobufjs/utf8@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.1.tgz#eaee5900122c110a3dbcb728c0597014a2621774" + integrity sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg== + "@ramp-network/ramp-instant-sdk@^4.0.5": version "4.0.7" resolved "https://registry.yarnpkg.com/@ramp-network/ramp-instant-sdk/-/ramp-instant-sdk-4.0.7.tgz#a474ec091afef5a2f3aa37c8bbc90dfff9aa880e" @@ -4887,6 +5097,16 @@ resolved "https://registry.yarnpkg.com/@solid-primitives/utils/-/utils-6.2.1.tgz#320fb2180743031622b40fc43b0e63bf55686cfb" integrity sha512-TsecNzxiO5bLfzqb4OOuzfUmdOROcssuGqgh5rXMMaasoFZ3GoveUgdY1wcf17frMJM7kCNGNuK34EjErneZkg== +"@spruceid/siwe-parser@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@spruceid/siwe-parser/-/siwe-parser-2.1.0.tgz#59859ccfd02403179bcf115d9e02a7dc953a0820" + integrity sha512-tFQwY2oQLa4qvHE6npKsVgVdVLQOCGP1zJM3yjZOHut43LqCwdSwitZndFLrJHZLpqru9FnmYHRakvsPvrI+qA== + dependencies: + "@noble/hashes" "^1.1.2" + apg-js "^4.1.1" + uri-js "^4.4.1" + valid-url "^1.0.9" + "@stablelib/aead@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" @@ -5492,6 +5712,13 @@ dependencies: "@types/node" "*" +"@types/bn.js@^5.1.5": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.2.0.tgz#4349b9710e98f9ab3cdc50f1c5e4dcbd8ef29c80" + integrity sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q== + dependencies: + "@types/node" "*" + "@types/body-parser@*": version "1.19.2" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" @@ -5552,6 +5779,11 @@ dependencies: "@types/ms" "*" +"@types/deep-freeze-strict@^1.1.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@types/deep-freeze-strict/-/deep-freeze-strict-1.1.2.tgz#707d1f9721aea9251ca6188111c272c61fc5490f" + integrity sha512-VvMETBojHvhX4f+ocYTySQlXMZfxKV3Jyb7iCWlWaC+exbedkv6Iv2bZZqI736qXjVguH6IH7bzwMBMfTT+zuQ== + "@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" @@ -5691,6 +5923,11 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== +"@types/lodash@^4.17.20": + version "4.17.24" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.24.tgz#4ae334fc62c0e915ca8ed8e35dcc6d4eeb29215f" + integrity sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ== + "@types/mime@^1": version "1.3.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" @@ -7805,6 +8042,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +apg-js@^4.1.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/apg-js/-/apg-js-4.4.0.tgz#09dcecab0731fbde233b9f2352fdd2d07e56b2cf" + integrity sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q== + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -8256,6 +8498,11 @@ bn.js@4.11.8: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== +bn.js@5.2.1, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.4.0: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -8266,11 +8513,6 @@ bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.2.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== -bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - bnb-javascript-sdk-nobroadcast@^2.16.14: version "2.16.15" resolved "https://registry.yarnpkg.com/bnb-javascript-sdk-nobroadcast/-/bnb-javascript-sdk-nobroadcast-2.16.15.tgz#712723911081fbde48251d59e6074fac5dd24044" @@ -8737,6 +8979,14 @@ cbor-web@8.1.0: preact "^10.16.0" sha.js "^2.4.11" +centrifuge@^5.3.5: + version "5.5.3" + resolved "https://registry.yarnpkg.com/centrifuge/-/centrifuge-5.5.3.tgz#d08155a950b81d2fce3a6309d2f2a611a5642da4" + integrity sha512-LPkWnsAxu7JaE5S738XiREzJIko3Pf/qnWb3kd0q/OR0OJONUbSdnZ5pKsEI2yFi/odQ89SYsHPhLuEeZFhp/g== + dependencies: + events "^3.3.0" + protobufjs "^7.2.5" + chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -8870,6 +9120,15 @@ cliui@^6.0.0: strip-ansi "^6.0.0" wrap-ansi "^6.2.0" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" @@ -8906,6 +9165,11 @@ cluster-key-slot@^1.1.0: resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== +cockatiel@^3.1.2: + version "3.2.1" + resolved "https://registry.yarnpkg.com/cockatiel/-/cockatiel-3.2.1.tgz#575f937bc4040a20ae27352a6d07c9c5a741981f" + integrity sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q== + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -9246,6 +9510,13 @@ cross-fetch@^4.0.0: dependencies: node-fetch "^2.6.12" +cross-fetch@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.1.0.tgz#8f69355007ee182e47fa692ecbaa37a52e43c3d2" + integrity sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw== + dependencies: + node-fetch "^2.7.0" + cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -9495,6 +9766,11 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +deep-freeze-strict@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-freeze-strict/-/deep-freeze-strict-1.1.1.tgz#77d0583ca24a69be4bbd9ac2fae415d55523e5b0" + integrity sha512-QemROZMM2IvhAcCFvahdX2Vbm4S/txeq5rFYU9fh4mQP79WTMW5c/HkQ2ICl1zuzcDZdPZ6zarDxQeQMsVYoNA== + deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -9792,6 +10068,16 @@ eccrypto@1.1.6, eccrypto@^1.1.6: optionalDependencies: secp256k1 "3.7.1" +eciesjs@0.4.17: + version "0.4.17" + resolved "https://registry.yarnpkg.com/eciesjs/-/eciesjs-0.4.17.tgz#5aca58bf8c794ec6cf971ce51b10c8d21292189a" + integrity sha512-TOOURki4G7sD1wDCjj7NfLaXZZ49dFOeEb5y39IXpb8p0hRzVvfvzZHOi5JcT+PpyAbi/Y+lxPb8eTag2WYH8w== + dependencies: + "@ecies/ciphers" "^0.2.5" + "@noble/ciphers" "^1.3.0" + "@noble/curves" "^1.9.7" + "@noble/hashes" "^1.8.0" + eciesjs@^0.4.11: version "0.4.13" resolved "https://registry.yarnpkg.com/eciesjs/-/eciesjs-0.4.13.tgz#89fbe2bc37d6dced8c3d1bccac21cceb20bcdcf3" @@ -10181,7 +10467,7 @@ esbuild@^0.19.2: "@esbuild/win32-ia32" "0.19.12" "@esbuild/win32-x64" "0.19.12" -escalade@^3.1.2: +escalade@^3.1.1, escalade@^3.1.2: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== @@ -10437,7 +10723,7 @@ eth-dcent-keyring@^0.2.2: dcent-web-connector "^0.11.2" ethereumjs-util "7.0.9" -eth-ens-namehash@2.0.8: +eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88= @@ -11387,7 +11673,7 @@ get-browser-rtc@^1.1.0: resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz#d1494e299b00f33fc8e9d6d3343ba4ba99711a2c" integrity sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ== -get-caller-file@^2.0.1: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -12005,6 +12291,11 @@ immediate@~3.0.5: resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= +immer@^9.0.6: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -13702,6 +13993,11 @@ nanoid@^3.3.6: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== +nanoid@^3.3.8: + version "3.3.12" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.12.tgz#ab3d912e217a6d0a514f00a72a16543a28982c05" + integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ== + nanoid@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.0.tgz#6e144dee117609232c3f415c34b0e550e64999a5" @@ -14068,6 +14364,18 @@ open@^8.0.9: is-docker "^2.1.1" is-wsl "^2.2.0" +openapi-fetch@^0.13.5: + version "0.13.8" + resolved "https://registry.yarnpkg.com/openapi-fetch/-/openapi-fetch-0.13.8.tgz#1769da06e30d19f7568cd0e60db8ca61ea83a2fa" + integrity sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ== + dependencies: + openapi-typescript-helpers "^0.0.15" + +openapi-typescript-helpers@^0.0.15: + version "0.0.15" + resolved "https://registry.yarnpkg.com/openapi-typescript-helpers/-/openapi-typescript-helpers-0.0.15.tgz#96ffa762a5e01ef66a661b163d5f1109ed1967ed" + integrity sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw== + optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -14234,6 +14542,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +pako@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -14655,6 +14968,24 @@ protobufjs@7.4.0: "@types/node" ">=13.7.0" long "^5.0.0" +protobufjs@^7.2.5: + version "7.5.6" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.5.6.tgz#11af832ebc4b4326f658a5b1308e6141eb57edfd" + integrity sha512-M71sTMB146U3u0di3yup8iM+zv8yPRNQVr1KK4tyBitl3qFvEGucq/rGDRShD2rsJhtN02RJaJ7j5X5hmy8SJg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.5" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.1" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.1" + "@types/node" ">=13.7.0" + long "^5.0.0" + protocol-buffers-encodings@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/protocol-buffers-encodings/-/protocol-buffers-encodings-1.1.1.tgz#f1e4a386711823137330171d2c82b49d062e75d3" @@ -14747,6 +15078,13 @@ pushdata-bitcoin@^1.0.1: dependencies: bitcoin-ops "^1.3.0" +qr-code-styling@^1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/qr-code-styling/-/qr-code-styling-1.9.2.tgz#071714860a7e59829e8822c9575e989042139d2d" + integrity sha512-RgJaZJ1/RrXJ6N0j7a+pdw3zMBmzZU4VN2dtAZf8ZggCfRB5stEQ3IoDNGaNhYY3nnZKYlYSLl5YkfWN5dPutg== + dependencies: + qrcode-generator "^1.4.4" + qr.js@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f" @@ -14757,6 +15095,11 @@ qrcode-generator@^1.4.1: resolved "https://registry.yarnpkg.com/qrcode-generator/-/qrcode-generator-1.4.4.tgz#63f771224854759329a99048806a53ed278740e7" integrity sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw== +qrcode-generator@^1.4.4: + version "1.5.2" + resolved "https://registry.yarnpkg.com/qrcode-generator/-/qrcode-generator-1.5.2.tgz#43faea8061a60d2b4ca5e9b0c0c0fb99e2d93e3a" + integrity sha512-pItrW0Z9HnDBnFmgiNrY1uxRdri32Uh9EjNYLPVC2zZ3ZRIIEqBoDgm4DkvDwNNDHTK7FNkmr8zAa77BYc9xNw== + qrcode-with-logos@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/qrcode-with-logos/-/qrcode-with-logos-1.1.1.tgz#87b04fb2606b81391c94b60cd600c9c81fb1adec" @@ -17169,7 +17512,7 @@ uqr@^0.1.2: resolved "https://registry.yarnpkg.com/uqr/-/uqr-0.1.2.tgz#5c6cd5dcff9581f9bb35b982cb89e2c483a41d7d" integrity sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA== -uri-js@^4.2.2: +uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== @@ -17278,6 +17621,11 @@ uuid@9.0.1, uuid@^9.0.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== +uuid@^11.1.0: + version "11.1.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.1.tgz#f6d81d2e1c65d00762e5e29b16c5d2d995e208ad" + integrity sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ== + uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -17306,6 +17654,11 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +valid-url@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + integrity sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA== + validate-html-nesting@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz#2d74de14b598a0de671fad01bd71deabb93b8aca" @@ -18771,6 +19124,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -18868,6 +19230,11 @@ ws@^7.5.3: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== +ws@^8.18.3: + version "8.20.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.0.tgz#4cd9532358eba60bc863aad1623dfb045a4d4af8" + integrity sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA== + ws@^8.4.2: version "8.5.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" @@ -18972,6 +19339,11 @@ y18n@^4.0.0: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + yaeti@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" @@ -19008,6 +19380,11 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + yargs@^13.0.0, yargs@^13.2.4: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" @@ -19041,6 +19418,19 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" From 734c77edba1c973e4729e7102ef73d33879d2427 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Mon, 4 May 2026 21:29:49 +0700 Subject: [PATCH 2/2] metamask: add chain RPC fallback & options Bump @web3-onboard/metamask to v2.4.0 and enhance SDK initialization. - Add a fallback Mainnet RPC and ensure api.supportedNetworks is always non-empty by deriving RPCs in priority order: Infura, readonlyRPCMap, web3-onboard chains, then public fallback. - Accept and normalize web3-onboard chains (toHexChainId + chainsToRpcMap) and thread them into getInterface/mapLegacyOptions so the client can use configured chains. - Improve dynamic import caching with retry semantics to avoid permanently failing on transient import errors. - Add showInstallModal option (defaults to false) and update legacy options handling (extensionOnly only maps to preferExtension when true; headless preserved). - Minor README formatting and example tweaks. --- packages/metamask/README.md | 38 +++++---- packages/metamask/package.json | 132 ++++++++++++++++--------------- packages/metamask/src/index.ts | 140 +++++++++++++++++++++++++-------- 3 files changed, 197 insertions(+), 113 deletions(-) diff --git a/packages/metamask/README.md b/packages/metamask/README.md index 322e1f89f..fe453e4f6 100644 --- a/packages/metamask/README.md +++ b/packages/metamask/README.md @@ -1,6 +1,7 @@ # @web3-onboard/metamask ## Wallet module for connecting MetaMask Connect EVM to web3-onboard + The MetaMask Web3-Onboard module provides a reliable, secure, and seamless connection from your dapp to the MetaMask browser extension and MetaMask Mobile. This module uses [MetaMask Connect EVM](https://docs.metamask.io/metamask-connect/evm/) (`@metamask/connect-evm`) under the hood — the successor to the legacy `@metamask/sdk`. The integration surface for `@web3-onboard/metamask` is unchanged: the legacy options below are mapped to their MetaMask Connect EVM equivalents internally so existing dapps keep working without code changes. @@ -12,7 +13,8 @@ This module uses [MetaMask Connect EVM](https://docs.metamask.io/metamask-connec `npm i @web3-onboard/metamask` ### If using this package with the `@web3-onboard/injected-wallets` module -_When utilizing this package alongside the `@web3-onboard/injected-wallets` module, ensure to list this package prior to the initialized injected-wallets module within the wallets list of the Web3-Onboard init._ + +_When utilizing this package alongside the `@web3-onboard/injected-wallets` module, ensure to list this package prior to the initialized injected-wallets module within the wallets list of the Web3-Onboard init._ _This order prioritizes the MetaMask Connect EVM client when a MetaMask browser wallet is detected, allowing it to take precedence._ ## Options @@ -22,26 +24,26 @@ _This order prioritizes the MetaMask Connect EVM client when a MetaMask browser // backwards compatibility and mapped to MetaMask Connect EVM internally. interface MetaMaskSDKOptions { dappMetadata?: { - url?: string; - name?: string; - iconUrl?: string; - base64Icon?: string; - }; + url?: string + name?: string + iconUrl?: string + base64Icon?: string + } /** * If MetaMask browser extension is detected, prefer it over the mobile flow. * Mapped to `ui.preferExtension`. */ - extensionOnly?: boolean; + extensionOnly?: boolean /** Mapped to `ui.headless`. */ - headless?: boolean; + headless?: boolean /** Used to populate `api.supportedNetworks` via `getInfuraRpcUrls`. */ - infuraAPIKey?: string; + infuraAPIKey?: string /** Merged into `api.supportedNetworks`. */ - readonlyRPCMap?: Record; + readonlyRPCMap?: Record /** Mapped to `mobile.preferredOpenLink`. */ - openDeeplink?: (deeplink: string) => void; + openDeeplink?: (deeplink: string) => void /** Mapped to `mobile.useDeeplink`. */ - useDeeplink?: boolean; + useDeeplink?: boolean } ``` @@ -52,12 +54,14 @@ import Onboard from '@web3-onboard/core' import metamaskSDK from '@web3-onboard/metamask' // initialize the module with options -const metamaskSDKWallet = metamaskSDK({options: { - extensionOnly: false, - dappMetadata: { - name: 'Demo Web3Onboard' +const metamaskSDKWallet = metamaskSDK({ + options: { + extensionOnly: false, + dappMetadata: { + name: 'Demo Web3Onboard' + } } -}}) +}) const onboard = Onboard({ // ... other Onboard options diff --git a/packages/metamask/package.json b/packages/metamask/package.json index 7bf64124f..aec30203a 100644 --- a/packages/metamask/package.json +++ b/packages/metamask/package.json @@ -1,67 +1,69 @@ { - "name": "@web3-onboard/metamask", - "version": "2.3.0", - "description": "MetaMask Connect EVM wallet module for connecting to Web3-Onboard. Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardised spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.", - "keywords": [ - "Ethereum", - "Web3", - "EVM", - "dapp", - "Multichain", - "Wallet", - "Transaction", - "Provider", - "Hardware Wallet", - "Notifications", - "React", - "Svelte", - "Vue", - "Next", - "Nuxt", - "MetaMask", - "Coinbase", - "WalletConnect", - "Ledger", - "Trezor", - "Connect Wallet", - "Ethereum Hooks", - "Blocknative", - "Mempool", - "pending", - "confirmed", - "Injected Wallet", - "Crypto", - "Crypto Wallet" - ], - "repository": { - "type": "git", - "url": "https://github.com/blocknative/web3-onboard.git", - "directory": "packages/metamask" - }, - "homepage": "https://web3onboard.thirdweb.com", - "bugs": "https://github.com/blocknative/web3-onboard/issues", - "module": "dist/index.js", - "browser": "dist/index.js", - "main": "dist/index.js", - "type": "module", - "typings": "dist/index.d.ts", - "files": ["dist"], - "license": "MIT", - "scripts": { - "build": "tsc", - "dev": "tsc -w", - "type-check": "tsc --noEmit" - }, - "devDependencies": { - "@types/node": "^20.5.7", - "ts-node": "^10.9.1", - "typescript": "^5.2.2" - }, - "dependencies": { - "@metamask/connect-evm": "^1.0.0", - "@web3-onboard/common": "^2.4.1" - }, - "engines": { - "node": ">=18.18" - } + "name": "@web3-onboard/metamask", + "version": "2.4.0", + "description": "MetaMask Connect EVM wallet module for connecting to Web3-Onboard. Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardised spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.", + "keywords": [ + "Ethereum", + "Web3", + "EVM", + "dapp", + "Multichain", + "Wallet", + "Transaction", + "Provider", + "Hardware Wallet", + "Notifications", + "React", + "Svelte", + "Vue", + "Next", + "Nuxt", + "MetaMask", + "Coinbase", + "WalletConnect", + "Ledger", + "Trezor", + "Connect Wallet", + "Ethereum Hooks", + "Blocknative", + "Mempool", + "pending", + "confirmed", + "Injected Wallet", + "Crypto", + "Crypto Wallet" + ], + "repository": { + "type": "git", + "url": "https://github.com/blocknative/web3-onboard.git", + "directory": "packages/metamask" + }, + "homepage": "https://web3onboard.thirdweb.com", + "bugs": "https://github.com/blocknative/web3-onboard/issues", + "module": "dist/index.js", + "browser": "dist/index.js", + "main": "dist/index.js", + "type": "module", + "typings": "dist/index.d.ts", + "files": [ + "dist" + ], + "license": "MIT", + "scripts": { + "build": "tsc", + "dev": "tsc -w", + "type-check": "tsc --noEmit" + }, + "devDependencies": { + "@types/node": "^20.5.7", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + }, + "dependencies": { + "@metamask/connect-evm": "^1.0.0", + "@web3-onboard/common": "^2.4.1" + }, + "engines": { + "node": ">=18.18" + } } diff --git a/packages/metamask/src/index.ts b/packages/metamask/src/index.ts index de80fe6df..fcf7a7df6 100644 --- a/packages/metamask/src/index.ts +++ b/packages/metamask/src/index.ts @@ -1,10 +1,18 @@ -import type { WalletInit } from '@web3-onboard/common' +import type { Chain, WalletInit } from '@web3-onboard/common' import type { createEVMClient as CreateEVMClientFn, getInfuraRpcUrls as GetInfuraRpcUrlsFn, MetamaskConnectEVM } from '@metamask/connect-evm' +/** + * Public Mainnet RPC used as a last-resort fallback when no + * `supportedNetworks` can be derived from user options or the chains web3- + * onboard was configured with. `@metamask/connect-evm` requires the map to + * contain at least one chain. + */ +const FALLBACK_MAINNET_RPC = 'https://1.rpc.thirdweb.com' + /** * Legacy MetaMask SDK options that this module continues to accept for * backwards compatibility. Each field is mapped to its @@ -18,10 +26,21 @@ export type MetaMaskSDKOptions = { iconUrl?: string base64Icon?: string } - /** Maps to `ui.preferExtension` in `@metamask/connect-evm`. */ + /** + * When `true`, prefer the MetaMask browser extension over the mobile/QR + * flow. Maps to `ui.preferExtension`. The default mirrors the new + * `@metamask/connect-evm` default (extension is preferred when installed). + */ extensionOnly?: boolean /** Maps to `ui.headless` in `@metamask/connect-evm`. */ headless?: boolean + /** + * When `true`, allow `@metamask/connect-evm` to render its own + * install/QR modal. Defaults to `false` because web3-onboard already + * supplies the surrounding wallet-selection UI and a second modal would + * sit on top of it. + */ + showInstallModal?: boolean /** Used to populate `api.supportedNetworks` via `getInfuraRpcUrls`. */ infuraAPIKey?: string /** Merged into `api.supportedNetworks`. */ @@ -69,14 +88,21 @@ function metamask({ options: Partial }): WalletInit { return () => { - importPromise = importPromise ?? loadImports().catch(error => { - throw error - }) + // Cache the dynamic import so we only fetch the SDK once per page load. + // On rejection (e.g. transient network failure during `import(...)`) + // clear the cache so the next `getInterface` call can retry instead of + // permanently surfacing the original error. + if (!importPromise) { + importPromise = loadImports().catch(error => { + importPromise = null + throw error + }) + } return { label: 'MetaMask', getIcon: async () => (await import('./icon.js')).default, - getInterface: async ({ appMetadata }) => { + getInterface: async ({ appMetadata, chains }) => { // Reuse the existing client/provider if we have already initialized // it. Re-initializing would needlessly reset state and historically // caused issues with the MetaMask mobile provider. @@ -107,7 +133,8 @@ function metamask({ options, getInfuraRpcUrls, fallbackName: name, - fallbackBase64Icon: appLogoUrl + fallbackBase64Icon: appLogoUrl, + chains }) client = await createEVMClient(evmOptions) @@ -133,24 +160,70 @@ function attachDisconnectShim(provider: unknown): void { } } +/** + * Build a `{ '0xHexChainId': rpcUrl }` map from web3-onboard's `chains` + * config, normalizing chain IDs to lower-case hex (the format + * `@metamask/connect-evm` expects). + */ +function chainsToRpcMap(chains: Chain[]): Record { + const map: Record = {} + for (const chain of chains) { + if (!chain.rpcUrl) continue + const hexId = toHexChainId(chain.id) + if (!hexId) continue + map[hexId] = chain.rpcUrl + } + return map +} + +function toHexChainId(id: string | number): string | null { + if (typeof id === 'number') { + return Number.isFinite(id) ? `0x${id.toString(16)}` : null + } + const trimmed = id.trim().toLowerCase() + if (trimmed.startsWith('0x')) return trimmed + if (/^\d+$/.test(trimmed)) { + return `0x${BigInt(trimmed).toString(16)}` + } + return null +} + function mapLegacyOptions({ options, getInfuraRpcUrls, fallbackName, - fallbackBase64Icon + fallbackBase64Icon, + chains }: { options: Partial getInfuraRpcUrls: typeof GetInfuraRpcUrlsFn fallbackName?: string fallbackBase64Icon: string + chains: Chain[] }): EvmClientOptions { - const supportedNetworks: Record = { - ...(typeof options.infuraAPIKey === 'string' && options.infuraAPIKey + // `api.supportedNetworks` must be a non-empty `Record`. + // We derive it from (in priority order): + // 1. `options.infuraAPIKey` -> `getInfuraRpcUrls` + // 2. `options.readonlyRPCMap` + // 3. RPC URLs of the chains web3-onboard itself was configured with + // 4. A public Mainnet RPC, so the client always has at least one chain. + const fromInfura = + typeof options.infuraAPIKey === 'string' && options.infuraAPIKey ? getInfuraRpcUrls({ infuraApiKey: options.infuraAPIKey }) - : {}), + : {} + + const fromChains = chainsToRpcMap(chains) + + const supportedNetworks: Record = { + ...fromInfura, + ...fromChains, ...(options.readonlyRPCMap ?? {}) } + if (Object.keys(supportedNetworks).length === 0) { + supportedNetworks['0x1'] = FALLBACK_MAINNET_RPC + } + const evmOptions: EvmClientOptions = { dapp: { name: options.dappMetadata?.name || fallbackName || '', @@ -160,28 +233,33 @@ function mapLegacyOptions({ // `MetaMaskSDK` integration that always set `base64Icon: appLogoUrl`. base64Icon: fallbackBase64Icon }, - // `api.supportedNetworks` is required by `createEVMClient`. Pass the - // merged Infura + custom RPC map (or an empty object when neither is - // provided — the client still works, with read-only requests routed - // through MetaMask's default transport). - api: { supportedNetworks: supportedNetworks as Record<`0x${string}`, string> } + api: { + supportedNetworks: supportedNetworks as Record<`0x${string}`, string> + } } - if ( - typeof options.headless === 'boolean' || - typeof options.extensionOnly === 'boolean' - ) { - evmOptions.ui = { - ...(typeof options.headless === 'boolean' - ? { headless: options.headless } - : {}), - // `extensionOnly: true` semantically meant "prefer the extension when - // available" in the legacy SDK, which is exactly what - // `ui.preferExtension` controls in `@metamask/connect-evm`. - ...(typeof options.extensionOnly === 'boolean' - ? { preferExtension: options.extensionOnly } - : {}) - } + // Build the `ui` block. + // + // - The legacy `extensionOnly` option is intentionally only honored when + // set to `true`, mapping to `preferExtension: true`. The legacy default + // (`false`) meant "fall back to mobile/QR if no extension"; in the new + // client that behavior is the default of `preferExtension: true` (use + // the extension when present, otherwise the modal). Mapping + // `extensionOnly: false` to `preferExtension: false` would force the + // install/QR modal to open even when the extension is installed, which + // matches what users have been reporting. + // - `showInstallModal` defaults to `false` because web3-onboard already + // renders its own connect modal; layering the MetaMask install modal on + // top breaks click-through. + evmOptions.ui = { + ...(typeof options.headless === 'boolean' + ? { headless: options.headless } + : {}), + ...(options.extensionOnly === true ? { preferExtension: true } : {}), + showInstallModal: + typeof options.showInstallModal === 'boolean' + ? options.showInstallModal + : false } if (