From c2932bba4d7e85b9323feb9e76c8ed89f4029828 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 5 Feb 2025 01:25:08 -0800 Subject: [PATCH 01/14] Format provider errors --- .../fcl-ethereum-provider/src/provider.ts | 10 ++- .../fcl-ethereum-provider/src/util/errors.ts | 69 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 packages/fcl-ethereum-provider/src/util/errors.ts diff --git a/packages/fcl-ethereum-provider/src/provider.ts b/packages/fcl-ethereum-provider/src/provider.ts index 01ab36dc7..d170682d9 100644 --- a/packages/fcl-ethereum-provider/src/provider.ts +++ b/packages/fcl-ethereum-provider/src/provider.ts @@ -7,6 +7,7 @@ import { } from "./types/provider" import {RpcProcessor} from "./rpc/rpc-processor" import {EventDispatcher} from "./events/event-dispatcher" +import {RpcError, RpcErrorCode} from "./util/errors" export class FclEthereumProvider implements Eip1193Provider { constructor( @@ -26,7 +27,14 @@ export class FclEthereumProvider implements Eip1193Provider { const result = await this.rpcProcessor.handleRequest({method, params}) return result } catch (error) { - throw new Error(`Request failed: ${(error as Error).message}`) + if (error instanceof RpcError) { + throw error + } else { + throw new RpcError({ + code: RpcErrorCode.InternalError, + cause: error, + }) + } } } diff --git a/packages/fcl-ethereum-provider/src/util/errors.ts b/packages/fcl-ethereum-provider/src/util/errors.ts new file mode 100644 index 000000000..8ba1f198e --- /dev/null +++ b/packages/fcl-ethereum-provider/src/util/errors.ts @@ -0,0 +1,69 @@ +// EIP-1474 error codes +export enum RpcErrorCode { + ParseError = -32700, + InvalidRequest = -32600, + MethodNotFound = -32601, + InvalidParams = -32602, + InternalError = -32603, +} + +// EIP-1193 error codes +export enum ProviderErrorCode { + UserRejectedRequest = 4001, + Unauthorized = 4100, + UnsupportedMethod = 4200, + Disconnected = 4900, +} + +// EI-1474 error messages used as default +export const RpcErrorMessage: Record = { + [-32700]: "Parse error", + [-32600]: "Invalid request", + [-32601]: "Method not found", + [-32602]: "Invalid params", + [-32603]: "Internal error", +} + +// EIP-1193 error messages used as default +export const ProviderErrorMessage: Record = { + [4001]: "User rejected request", + [4100]: "Unauthorized", + [4200]: "Unsupported method", + [4900]: "Disconnected", +} + +export class RpcError extends Error { + public code: RpcErrorCode + public data?: unknown + + constructor({ + code, + message, + data, + cause, + }: { + code: RpcErrorCode + message?: string + data?: unknown + cause?: any + }) { + if (!RpcErrorMessage[code]) { + throw new Error(`Invalid RPC error code: ${code}`) + } + super(message || RpcErrorMessage[code]) + this.code = code + this.data = data + if (cause) { + this.stack = `${this.stack}\nCaused by: ${cause.stack}` + } + } +} + +export class ProviderError extends Error { + public code: ProviderErrorCode + + constructor(code: ProviderErrorCode, message?: string) { + super(message || ProviderErrorMessage[code]) + this.code = code + } +} From dbbb6daef2926cfaf3f40f9b8f2331f7a10c8431 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 5 Feb 2025 16:03:34 -0800 Subject: [PATCH 02/14] Align RPC errors with EIP-1193 / EIP-1474 spec --- .../src/create-provider.ts | 2 +- .../fcl-ethereum-provider/src/provider.ts | 21 +-- .../src/rpc/rpc-processor.test.ts | 57 ++++++++ .../src/rpc/rpc-processor.ts | 136 ++++++++++-------- .../fcl-ethereum-provider/src/util/errors.ts | 70 +++------ 5 files changed, 158 insertions(+), 128 deletions(-) diff --git a/packages/fcl-ethereum-provider/src/create-provider.ts b/packages/fcl-ethereum-provider/src/create-provider.ts index da1f783df..185f83668 100644 --- a/packages/fcl-ethereum-provider/src/create-provider.ts +++ b/packages/fcl-ethereum-provider/src/create-provider.ts @@ -43,7 +43,7 @@ export function createProvider(config: { ) const networkManager = new NetworkManager(config.config) - const accountManager = new AccountManager(config.user) + const accountManager = new AccountManager(config.user, networkManager) const gateway = new Gateway({ ...defaultRpcUrls, ...(config.rpcUrls || {}), diff --git a/packages/fcl-ethereum-provider/src/provider.ts b/packages/fcl-ethereum-provider/src/provider.ts index e4e6e0b50..617b74f29 100644 --- a/packages/fcl-ethereum-provider/src/provider.ts +++ b/packages/fcl-ethereum-provider/src/provider.ts @@ -7,7 +7,7 @@ import { } from "./types/provider" import {RpcProcessor} from "./rpc/rpc-processor" import {EventDispatcher} from "./events/event-dispatcher" -import {RpcError, RpcErrorCode} from "./util/errors" +import {ProviderError, ProviderErrorCode} from "./util/errors" import {AccountManager} from "./accounts/account-manager" export class FclEthereumProvider implements Eip1193Provider { @@ -22,22 +22,11 @@ export class FclEthereumProvider implements Eip1193Provider { method, params, }: ProviderRequest): Promise> { - try { - if (!method) { - throw new Error("Method is required") - } - const result = await this.rpcProcessor.handleRequest({method, params}) - return result - } catch (error) { - if (error instanceof RpcError) { - throw error - } else { - throw new RpcError({ - code: RpcErrorCode.InternalError, - cause: error, - }) - } + if (!method) { + throw new Error("Method is required") } + const result = await this.rpcProcessor.handleRequest({method, params}) + return result } disconnect(): void { diff --git a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts index eb3749c2e..819c74d98 100644 --- a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts +++ b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts @@ -67,4 +67,61 @@ describe("rpc processor", () => { chainId: 646, }) }) + + test("caught RpcError should be rethrown", async () => { + const gateway: jest.Mocked = new (Gateway as any)() + const accountManager: jest.Mocked = + new (AccountManager as any)() + const networkManager: jest.Mocked = + new (NetworkManager as any)() + const rpcProcessor = new RpcProcessor( + gateway, + accountManager, + networkManager + ) + + const error = new Error("test error") + ;(error as any).code = -32000 + jest.mocked(gateway).request.mockRejectedValue(error) + networkManager.getChainId.mockResolvedValue(747) + + await expect( + rpcProcessor.handleRequest({ + method: "eth_blockNumber", + params: [], + }) + ).rejects.toMatchObject({ + code: -32000, + message: "test error", + }) + }) + + test("caught generic error should be rethrown as an internal error", async () => { + const gateway: jest.Mocked = new (Gateway as any)() + const accountManager: jest.Mocked = + new (AccountManager as any)() + const networkManager: jest.Mocked = + new (NetworkManager as any)() + const rpcProcessor = new RpcProcessor( + gateway, + accountManager, + networkManager + ) + + jest.mocked(gateway).request.mockRejectedValue(new Error("test error")) + networkManager.getChainId.mockResolvedValue(747) + + const promise = rpcProcessor.handleRequest({ + method: "eth_blockNumber", + params: [], + }) + + await expect(promise).rejects.toMatchObject({ + code: -32603, + message: "Internal error", + data: { + cause: new Error("test error"), + }, + }) + }) }) diff --git a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.ts b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.ts index 31516a576..0c73fc5eb 100644 --- a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.ts +++ b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.ts @@ -14,6 +14,7 @@ import { } from "../types/eth" import {signTypedData} from "./handlers/eth-signtypeddata" import {ethChainId} from "./handlers/eth-chain-id" +import {ProviderError, ProviderErrorCode} from "../util/errors" export class RpcProcessor { constructor( @@ -23,76 +24,87 @@ export class RpcProcessor { ) {} async handleRequest({method, params}: ProviderRequest): Promise { - const chainId = await this.networkManager.getChainId() - if (!chainId) { - throw new Error("No active chain") - } + try { + const chainId = await this.networkManager.getChainId() + if (!chainId) { + throw new Error("No active chain") + } - switch (method) { - case "eth_accounts": - return ethAccounts(this.accountManager) - case "eth_requestAccounts": - return ethRequestAccounts(this.accountManager) - case "eth_sendTransaction": - return await ethSendTransaction(this.accountManager, params) - case "eth_signTypedData": - case "eth_signTypedData_v3": - case "eth_signTypedData_v4": { - if (!params || typeof params !== "object") { - throw new Error(`${method} requires valid parameters.`) - } + switch (method) { + case "eth_accounts": + return ethAccounts(this.accountManager) + case "eth_requestAccounts": + return ethRequestAccounts(this.accountManager) + case "eth_sendTransaction": + return await ethSendTransaction(this.accountManager, params) + case "eth_signTypedData": + case "eth_signTypedData_v3": + case "eth_signTypedData_v4": { + if (!params || typeof params !== "object") { + throw new Error(`${method} requires valid parameters.`) + } - const {address, data} = params as {address?: unknown; data?: unknown} + const {address, data} = params as {address?: unknown; data?: unknown} - if ( - typeof address !== "string" || - typeof data !== "object" || - data === null - ) { - throw new Error( - `${method} requires 'address' (string) and a valid 'data' object.` - ) - } + if ( + typeof address !== "string" || + typeof data !== "object" || + data === null + ) { + throw new Error( + `${method} requires 'address' (string) and a valid 'data' object.` + ) + } - const validParams: SignTypedDataParams = { - address, - data: data as TypedData, - } + const validParams: SignTypedDataParams = { + address, + data: data as TypedData, + } - return await signTypedData(this.accountManager, validParams, method) - } - case "personal_sign": - return await personalSign( - this.accountManager, - params as PersonalSignParams - ) - case "wallet_addEthereumChain": - // Expect params to be an array with one chain configuration object. - if (!params || !Array.isArray(params) || !params[0]) { - throw new Error( - "wallet_addEthereumChain requires an array with a chain configuration object." - ) + return await signTypedData(this.accountManager, validParams, method) } - const chainConfig = params[0] as AddEthereumChainParams - - return await this.networkManager.addChain(chainConfig) - case "wallet_switchEthereumChain": - // Expect params to be an array with one object. - if (!params || !Array.isArray(params) || !params[0]) { - throw new Error( - "wallet_switchEthereumChain requires an array with a chain configuration object." + case "personal_sign": + return await personalSign( + this.accountManager, + params as PersonalSignParams ) - } - const switchParams = params[0] as SwitchEthereumChainParams - return await this.networkManager.switchChain(switchParams) - case "eth_chainId": - return ethChainId(this.networkManager) - default: - return await this.gateway.request({ - chainId, - method, - params, + case "wallet_addEthereumChain": + // Expect params to be an array with one chain configuration object. + if (!params || !Array.isArray(params) || !params[0]) { + throw new Error( + "wallet_addEthereumChain requires an array with a chain configuration object." + ) + } + const chainConfig = params[0] as AddEthereumChainParams + + return await this.networkManager.addChain(chainConfig) + case "wallet_switchEthereumChain": + // Expect params to be an array with one object. + if (!params || !Array.isArray(params) || !params[0]) { + throw new Error( + "wallet_switchEthereumChain requires an array with a chain configuration object." + ) + } + const switchParams = params[0] as SwitchEthereumChainParams + return await this.networkManager.switchChain(switchParams) + case "eth_chainId": + return ethChainId(this.networkManager) + default: + return await this.gateway.request({ + chainId, + method, + params, + }) + } + } catch (error: any) { + if (error?.code !== undefined) { + throw error + } else { + throw new ProviderError({ + code: ProviderErrorCode.InternalError, + cause: error, }) + } } } } diff --git a/packages/fcl-ethereum-provider/src/util/errors.ts b/packages/fcl-ethereum-provider/src/util/errors.ts index 8ba1f198e..ca62b9583 100644 --- a/packages/fcl-ethereum-provider/src/util/errors.ts +++ b/packages/fcl-ethereum-provider/src/util/errors.ts @@ -1,69 +1,41 @@ -// EIP-1474 error codes -export enum RpcErrorCode { - ParseError = -32700, - InvalidRequest = -32600, - MethodNotFound = -32601, - InvalidParams = -32602, - InternalError = -32603, -} - -// EIP-1193 error codes export enum ProviderErrorCode { + // EIP-1193 error codes UserRejectedRequest = 4001, Unauthorized = 4100, UnsupportedMethod = 4200, Disconnected = 4900, -} -// EI-1474 error messages used as default -export const RpcErrorMessage: Record = { - [-32700]: "Parse error", - [-32600]: "Invalid request", - [-32601]: "Method not found", - [-32602]: "Invalid params", - [-32603]: "Internal error", + // EIP-1474 / JSON-RPC error codes + ParseError = -32700, + InvalidRequest = -32600, + MethodNotFound = -32601, + InvalidParams = -32602, + InternalError = -32603, } - -// EIP-1193 error messages used as default export const ProviderErrorMessage: Record = { + // EIP-1193 error messages [4001]: "User rejected request", [4100]: "Unauthorized", [4200]: "Unsupported method", [4900]: "Disconnected", -} - -export class RpcError extends Error { - public code: RpcErrorCode - public data?: unknown - - constructor({ - code, - message, - data, - cause, - }: { - code: RpcErrorCode - message?: string - data?: unknown - cause?: any - }) { - if (!RpcErrorMessage[code]) { - throw new Error(`Invalid RPC error code: ${code}`) - } - super(message || RpcErrorMessage[code]) - this.code = code - this.data = data - if (cause) { - this.stack = `${this.stack}\nCaused by: ${cause.stack}` - } - } + // EIP-1474 / JSON-RPC error messages + [-32700]: "Parse error", + [-32600]: "Invalid request", + [-32601]: "Method not found", + [-32602]: "Invalid params", + [-32603]: "Internal error", } export class ProviderError extends Error { public code: ProviderErrorCode + public data?: any - constructor(code: ProviderErrorCode, message?: string) { - super(message || ProviderErrorMessage[code]) + constructor({code, cause}: {code: ProviderErrorCode; cause?: any}) { + super(ProviderErrorMessage[code]) this.code = code + if (cause) { + this.stack = `${this.stack}\nCaused by: ${cause?.stack || cause}` + } + this.data = {cause} } } From 741f43044d2c9bf6a65400032c7dc5c544cec9a5 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 15:00:26 -0800 Subject: [PATCH 03/14] change cause behaviour --- .../fcl-ethereum-provider/src/rpc/rpc-processor.test.ts | 4 +--- packages/fcl-ethereum-provider/src/util/errors.ts | 7 ++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts index 819c74d98..0e0c3480a 100644 --- a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts +++ b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts @@ -119,9 +119,7 @@ describe("rpc processor", () => { await expect(promise).rejects.toMatchObject({ code: -32603, message: "Internal error", - data: { - cause: new Error("test error"), - }, + cause: new Error("test error"), }) }) }) diff --git a/packages/fcl-ethereum-provider/src/util/errors.ts b/packages/fcl-ethereum-provider/src/util/errors.ts index ca62b9583..42466a55f 100644 --- a/packages/fcl-ethereum-provider/src/util/errors.ts +++ b/packages/fcl-ethereum-provider/src/util/errors.ts @@ -28,14 +28,11 @@ export const ProviderErrorMessage: Record = { export class ProviderError extends Error { public code: ProviderErrorCode - public data?: any + public cause?: any constructor({code, cause}: {code: ProviderErrorCode; cause?: any}) { super(ProviderErrorMessage[code]) this.code = code - if (cause) { - this.stack = `${this.stack}\nCaused by: ${cause?.stack || cause}` - } - this.data = {cause} + this.cause = cause } } From 108d40b62029c78db8125b3e66d760139af2ad98 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 15:49:47 -0800 Subject: [PATCH 04/14] Add boilerplate Rainbowkit & Wagmi adapters --- package-lock.json | 2512 ++++++++++++++++- .../fcl-bundle/src/build/get-input-options.js | 15 +- packages/fcl-ethereum-provider/package.json | 5 +- .../src/accounts/account-manager.ts | 16 +- packages/fcl-ethereum-provider/src/cadence.ts | 44 +- .../fcl-ethereum-provider/src/constants.ts | 4 +- .../src/create-provider.ts | 13 +- .../src/events/event-dispatcher.test.ts | 38 +- .../src/events/event-dispatcher.ts | 11 +- .../src/gateway/gateway.test.ts | 4 +- .../fcl-ethereum-provider/src/provider.ts | 4 +- .../src/rpc/handlers/eth-accounts.test.ts | 11 +- .../src/rpc/handlers/eth-accounts.ts | 8 +- .../src/rpc/rpc-processor.test.ts | 55 + .../src/types/provider.ts | 2 + packages/fcl-rainbowkit-adapter/.babelrc | 3 + .../fcl-rainbowkit-adapter/.browserslistrc | 2 + .../fcl-rainbowkit-adapter/.eslintrc.json | 20 + packages/fcl-rainbowkit-adapter/.npmignore | 1 + packages/fcl-rainbowkit-adapter/CHANGELOG.md | 1 + packages/fcl-rainbowkit-adapter/README.md | 15 + packages/fcl-rainbowkit-adapter/package.json | 54 + packages/fcl-rainbowkit-adapter/src/index.ts | 33 + packages/fcl-rainbowkit-adapter/tsconfig.json | 9 + packages/fcl-wagmi-adapter/.babelrc | 3 + packages/fcl-wagmi-adapter/.browserslistrc | 2 + packages/fcl-wagmi-adapter/.eslintrc.json | 20 + packages/fcl-wagmi-adapter/.npmignore | 1 + packages/fcl-wagmi-adapter/CHANGELOG.md | 1 + packages/fcl-wagmi-adapter/README.md | 15 + packages/fcl-wagmi-adapter/package.json | 52 + packages/fcl-wagmi-adapter/src/index.ts | 320 +++ packages/fcl-wagmi-adapter/tsconfig.json | 9 + tsconfig.json | 2 +- 34 files changed, 3176 insertions(+), 129 deletions(-) create mode 100644 packages/fcl-rainbowkit-adapter/.babelrc create mode 100644 packages/fcl-rainbowkit-adapter/.browserslistrc create mode 100644 packages/fcl-rainbowkit-adapter/.eslintrc.json create mode 100644 packages/fcl-rainbowkit-adapter/.npmignore create mode 100644 packages/fcl-rainbowkit-adapter/CHANGELOG.md create mode 100644 packages/fcl-rainbowkit-adapter/README.md create mode 100644 packages/fcl-rainbowkit-adapter/package.json create mode 100644 packages/fcl-rainbowkit-adapter/src/index.ts create mode 100644 packages/fcl-rainbowkit-adapter/tsconfig.json create mode 100644 packages/fcl-wagmi-adapter/.babelrc create mode 100644 packages/fcl-wagmi-adapter/.browserslistrc create mode 100644 packages/fcl-wagmi-adapter/.eslintrc.json create mode 100644 packages/fcl-wagmi-adapter/.npmignore create mode 100644 packages/fcl-wagmi-adapter/CHANGELOG.md create mode 100644 packages/fcl-wagmi-adapter/README.md create mode 100644 packages/fcl-wagmi-adapter/package.json create mode 100644 packages/fcl-wagmi-adapter/src/index.ts create mode 100644 packages/fcl-wagmi-adapter/tsconfig.json diff --git a/package-lock.json b/package-lock.json index 30b629384..858b20412 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,12 @@ "@nx/nx-win32-x64-msvc": "^17.3.2" } }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz", + "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==", + "license": "MIT" + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -1913,7 +1919,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.7", + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", + "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2356,6 +2364,26 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/@coinbase/wallet-sdk": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@coinbase/wallet-sdk/-/wallet-sdk-4.2.3.tgz", + "integrity": "sha512-BcyHZ/Ec84z0emORzqdXDv4P0oV+tV3a0OirfA8Ko1JGBIAVvB+hzLvZzCDvnuZx7MTK+Dd8Y9Tjlo446BpCIg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@noble/hashes": "^1.4.0", + "clsx": "^1.2.1", + "eventemitter3": "^5.0.1", + "preact": "^10.24.2" + } + }, + "node_modules/@coinbase/wallet-sdk/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT", + "peer": true + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "dev": true, @@ -2364,6 +2392,21 @@ "node": ">=10.0.0" } }, + "node_modules/@ecies/ciphers": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@ecies/ciphers/-/ciphers-0.2.2.tgz", + "integrity": "sha512-ylfGR7PyTd+Rm2PqQowG08BCKA22QuX8NzrL+LxAAvazN10DMwdJ2fWwAzRj05FI/M8vNFGm3cv9Wq/GFWCBLg==", + "license": "MIT", + "peer": true, + "engines": { + "bun": ">=1", + "deno": ">=2", + "node": ">=16" + }, + "peerDependencies": { + "@noble/ciphers": "^1.0.0" + } + }, "node_modules/@emnapi/core": { "version": "1.3.1", "dev": true, @@ -2404,6 +2447,13 @@ "dev": true, "license": "0BSD" }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT", + "peer": true + }, "node_modules/@es-joy/jsdoccomment": { "version": "0.41.0", "dev": true, @@ -2530,6 +2580,61 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ethereumjs/common": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-3.2.0.tgz", + "integrity": "sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "crc-32": "^1.2.0" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "license": "MPL-2.0", + "peer": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-4.2.0.tgz", + "integrity": "sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==", + "license": "MPL-2.0", + "peer": true, + "dependencies": { + "@ethereumjs/common": "^3.2.0", + "@ethereumjs/rlp": "^4.0.1", + "@ethereumjs/util": "^8.1.0", + "ethereum-cryptography": "^2.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "license": "MPL-2.0", + "peer": true, + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@ethersproject/abstract-provider": { "version": "5.7.0", "funding": [ @@ -5669,6 +5774,377 @@ "node": ">=6 <7 || >=8" } }, + "node_modules/@metamask/eth-json-rpc-provider": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-json-rpc-provider/-/eth-json-rpc-provider-1.0.1.tgz", + "integrity": "sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==", + "peer": true, + "dependencies": { + "@metamask/json-rpc-engine": "^7.0.0", + "@metamask/safe-event-emitter": "^3.0.0", + "@metamask/utils": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@metamask/eth-json-rpc-provider/node_modules/@metamask/json-rpc-engine": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@metamask/json-rpc-engine/-/json-rpc-engine-7.3.3.tgz", + "integrity": "sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==", + "license": "ISC", + "peer": true, + "dependencies": { + "@metamask/rpc-errors": "^6.2.1", + "@metamask/safe-event-emitter": "^3.0.0", + "@metamask/utils": "^8.3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/eth-json-rpc-provider/node_modules/@metamask/json-rpc-engine/node_modules/@metamask/utils": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-8.5.0.tgz", + "integrity": "sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.0.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" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/eth-json-rpc-provider/node_modules/@metamask/utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-5.0.2.tgz", + "integrity": "sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==", + "license": "ISC", + "peer": true, + "dependencies": { + "@ethereumjs/tx": "^4.1.2", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "semver": "^7.3.8", + "superstruct": "^1.0.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@metamask/eth-json-rpc-provider/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@metamask/json-rpc-engine": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@metamask/json-rpc-engine/-/json-rpc-engine-8.0.2.tgz", + "integrity": "sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==", + "license": "ISC", + "peer": true, + "dependencies": { + "@metamask/rpc-errors": "^6.2.1", + "@metamask/safe-event-emitter": "^3.0.0", + "@metamask/utils": "^8.3.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/json-rpc-middleware-stream": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@metamask/json-rpc-middleware-stream/-/json-rpc-middleware-stream-7.0.2.tgz", + "integrity": "sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==", + "license": "ISC", + "peer": true, + "dependencies": { + "@metamask/json-rpc-engine": "^8.0.2", + "@metamask/safe-event-emitter": "^3.0.0", + "@metamask/utils": "^8.3.0", + "readable-stream": "^3.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/object-multiplex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@metamask/object-multiplex/-/object-multiplex-2.1.0.tgz", + "integrity": "sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==", + "license": "ISC", + "peer": true, + "dependencies": { + "once": "^1.4.0", + "readable-stream": "^3.6.2" + }, + "engines": { + "node": "^16.20 || ^18.16 || >=20" + } + }, + "node_modules/@metamask/onboarding": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@metamask/onboarding/-/onboarding-1.0.1.tgz", + "integrity": "sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "bowser": "^2.9.0" + } + }, + "node_modules/@metamask/providers": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@metamask/providers/-/providers-16.1.0.tgz", + "integrity": "sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@metamask/json-rpc-engine": "^8.0.1", + "@metamask/json-rpc-middleware-stream": "^7.0.1", + "@metamask/object-multiplex": "^2.0.0", + "@metamask/rpc-errors": "^6.2.1", + "@metamask/safe-event-emitter": "^3.1.1", + "@metamask/utils": "^8.3.0", + "detect-browser": "^5.2.0", + "extension-port-stream": "^3.0.0", + "fast-deep-equal": "^3.1.3", + "is-stream": "^2.0.0", + "readable-stream": "^3.6.2", + "webextension-polyfill": "^0.10.0" + }, + "engines": { + "node": "^18.18 || >=20" + } + }, + "node_modules/@metamask/providers/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@metamask/rpc-errors": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@metamask/rpc-errors/-/rpc-errors-6.4.0.tgz", + "integrity": "sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@metamask/utils": "^9.0.0", + "fast-safe-stringify": "^2.0.6" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/rpc-errors/node_modules/@metamask/utils": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-9.3.0.tgz", + "integrity": "sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==", + "license": "ISC", + "peer": true, + "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" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/rpc-errors/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@metamask/safe-event-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@metamask/safe-event-emitter/-/safe-event-emitter-3.1.2.tgz", + "integrity": "sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/sdk": { + "version": "0.31.5", + "resolved": "https://registry.npmjs.org/@metamask/sdk/-/sdk-0.31.5.tgz", + "integrity": "sha512-i7wteqO/fU2JWQrMZz+addHokYThHYznp4nYXviv+QysdxGVgAYvcW/PBA+wpeP3veX7QGfNqMPgSsZbBrASYw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.26.0", + "@metamask/onboarding": "^1.0.1", + "@metamask/providers": "16.1.0", + "@metamask/sdk-communication-layer": "0.31.0", + "@metamask/sdk-install-modal-web": "0.31.5", + "@paulmillr/qr": "^0.2.1", + "bowser": "^2.9.0", + "cross-fetch": "^4.0.0", + "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" + } + }, + "node_modules/@metamask/sdk-install-modal-web": { + "version": "0.31.5", + "resolved": "https://registry.npmjs.org/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.31.5.tgz", + "integrity": "sha512-ZfrVkPAabfH4AIxcTlxQN5oyyzzVXFTLZrm1/BJ+X632d9MiyAVHNtiqa9EZpZYkZGk2icmDVP+xCpvJmVOVpQ==", + "peer": true, + "dependencies": { + "@paulmillr/qr": "^0.2.1" + } + }, + "node_modules/@metamask/sdk/node_modules/@metamask/sdk-communication-layer": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@metamask/sdk-communication-layer/-/sdk-communication-layer-0.31.0.tgz", + "integrity": "sha512-V9CxdzabDPjQVgmKGHsyU3SYt4Af27g+4DbGCx0fLoHqN/i1RBDZqs/LYbJX3ykJCANzE+llz/MolMCMrzM2RA==", + "peer": true, + "dependencies": { + "bufferutil": "^4.0.8", + "date-fns": "^2.29.3", + "debug": "^4.3.4", + "utf-8-validate": "^5.0.2", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "cross-fetch": "^4.0.0", + "eciesjs": "*", + "eventemitter2": "^6.4.9", + "readable-stream": "^3.6.2", + "socket.io-client": "^4.5.1" + } + }, + "node_modules/@metamask/sdk/node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/@metamask/sdk/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "peer": true + }, + "node_modules/@metamask/sdk/node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/@metamask/sdk/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@metamask/superstruct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@metamask/superstruct/-/superstruct-3.1.0.tgz", + "integrity": "sha512-N08M56HdOgBfRKkrgCMZvQppkZGcArEop3kixNEtVbJKm6P9Cfg0YkI6X0s1g78sNrj2fWUwvJADdZuzJgFttA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/utils": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-8.5.0.tgz", + "integrity": "sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.0.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" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/utils/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@motionone/animation": { "version": "10.18.0", "license": "MIT", @@ -5775,8 +6251,36 @@ "@tybys/wasm-util": "^0.9.0" } }, - "node_modules/@noble/hashes": { - "version": "1.7.1", + "node_modules/@noble/ciphers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.2.1.tgz", + "integrity": "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==", + "license": "MIT", + "peer": true, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", + "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.7.1" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.7.1", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", "license": "MIT", @@ -6735,10 +7239,18 @@ "resolved": "packages/fcl-ethereum-provider", "link": true }, + "node_modules/@onflow/fcl-rainbowkit-adapter": { + "resolved": "packages/fcl-rainbowkit-adapter", + "link": true + }, "node_modules/@onflow/fcl-react-native": { "resolved": "packages/fcl-react-native", "link": true }, + "node_modules/@onflow/fcl-wagmi-adapter": { + "resolved": "packages/fcl-wagmi-adapter", + "link": true + }, "node_modules/@onflow/fcl-wc": { "resolved": "packages/fcl-wc", "link": true @@ -6884,6 +7396,16 @@ "inBundle": true, "license": "MIT" }, + "node_modules/@paulmillr/qr": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@paulmillr/qr/-/qr-0.2.1.tgz", + "integrity": "sha512-IHnV6A+zxU7XwmKFinmYjUcwlyK9+xkG3/s9KcQhI9BjQKycrJ1JRO+FbNYPwZiPKW3je/DR0k7w8/gLa5eaxQ==", + "license": "(MIT OR Apache-2.0)", + "peer": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "license": "MIT", @@ -9027,6 +9549,74 @@ "win32" ] }, + "node_modules/@safe-global/safe-apps-provider": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/@safe-global/safe-apps-provider/-/safe-apps-provider-0.18.5.tgz", + "integrity": "sha512-9v9wjBi3TwLsEJ3C2ujYoexp3pFJ0omDLH/GX91e2QB+uwCKTBYyhxFSrTQ9qzoyQd+bfsk4gjOGW87QcJhf7g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@safe-global/safe-apps-sdk": "^9.1.0", + "events": "^3.3.0" + } + }, + "node_modules/@safe-global/safe-apps-sdk": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@safe-global/safe-apps-sdk/-/safe-apps-sdk-9.1.0.tgz", + "integrity": "sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@safe-global/safe-gateway-typescript-sdk": "^3.5.3", + "viem": "^2.1.1" + } + }, + "node_modules/@safe-global/safe-gateway-typescript-sdk": { + "version": "3.22.9", + "resolved": "https://registry.npmjs.org/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.22.9.tgz", + "integrity": "sha512-7ojVK/crhOaGowEO8uYWaopZzcr5rR76emgllGIfjCLR70aY4PbASpi9Pbs+7jIRzPDBBkM0RBo+zYx5UduX8Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@scure/base": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz", + "integrity": "sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", + "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.8.1", + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", + "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@segment/loosely-validate-event": { "version": "2.0.0", "peer": true, @@ -9150,6 +9740,13 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT", + "peer": true + }, "node_modules/@stablelib/aead": { "version": "1.0.1", "license": "MIT" @@ -9278,6 +9875,34 @@ "@stablelib/wipe": "^1.0.1" } }, + "node_modules/@tanstack/query-core": { + "version": "5.66.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.0.tgz", + "integrity": "sha512-J+JeBtthiKxrpzUu7rfIPDzhscXF2p5zE/hVdrqkACBP8Yu0M96mwJ5m/8cPPYQE9aRNvXztXHlNwIh4FEeMZw==", + "license": "MIT", + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.66.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.66.0.tgz", + "integrity": "sha512-z3sYixFQJe8hndFnXgWu7C79ctL+pI0KAelYyW+khaNJ1m22lWrhJU2QrsTcRKMuVPtoZvfBYrTStIdKo+x0Xw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@tanstack/query-core": "5.66.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "dev": true, @@ -9378,6 +10003,16 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "license": "MIT" @@ -9442,6 +10077,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT", + "peer": true + }, "node_modules/@types/node": { "version": "18.19.57", "license": "MIT", @@ -9749,6 +10391,122 @@ "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, + "node_modules/@vanilla-extract/css": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.15.5.tgz", + "integrity": "sha512-N1nQebRWnXvlcmu9fXKVUs145EVwmWtMD95bpiEKtvehHDpUhmO1l2bauS7FGYKbi3dU1IurJbGpQhBclTr1ng==", + "license": "MIT", + "peer": true, + "dependencies": { + "@emotion/hash": "^0.9.0", + "@vanilla-extract/private": "^1.0.6", + "css-what": "^6.1.0", + "cssesc": "^3.0.0", + "csstype": "^3.0.7", + "dedent": "^1.5.3", + "deep-object-diff": "^1.1.9", + "deepmerge": "^4.2.2", + "lru-cache": "^10.4.3", + "media-query-parser": "^2.0.2", + "modern-ahocorasick": "^1.0.0", + "picocolors": "^1.0.0" + } + }, + "node_modules/@vanilla-extract/css/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC", + "peer": true + }, + "node_modules/@vanilla-extract/dynamic": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vanilla-extract/dynamic/-/dynamic-2.1.2.tgz", + "integrity": "sha512-9BGMciD8rO1hdSPIAh1ntsG4LPD3IYKhywR7VOmmz9OO4Lx1hlwkSg3E6X07ujFx7YuBfx0GDQnApG9ESHvB2A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vanilla-extract/private": "^1.0.6" + } + }, + "node_modules/@vanilla-extract/private": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@vanilla-extract/private/-/private-1.0.6.tgz", + "integrity": "sha512-ytsG/JLweEjw7DBuZ/0JCN4WAQgM9erfSTdS1NQY778hFQSZ6cfCDEZZ0sgVm4k54uNz6ImKB33AYvSR//fjxw==", + "license": "MIT", + "peer": true + }, + "node_modules/@vanilla-extract/sprinkles": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@vanilla-extract/sprinkles/-/sprinkles-1.6.3.tgz", + "integrity": "sha512-oCHlQeYOBIJIA2yWy2GnY5wE2A7hGHDyJplJo4lb+KEIBcJWRnDJDg8ywDwQS5VfWJrBBO3drzYZPFpWQjAMiQ==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "@vanilla-extract/css": "^1.0.0" + } + }, + "node_modules/@wagmi/connectors": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/@wagmi/connectors/-/connectors-5.7.5.tgz", + "integrity": "sha512-btqHHUSTzg4BZe9at/7SnRPv4cz8O3pisbeZBh0qxKz7PVm+9vRxY0bSala3xQPDcS0PRTB30Vn/+lM73GCjbw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@coinbase/wallet-sdk": "4.2.3", + "@metamask/sdk": "0.31.5", + "@safe-global/safe-apps-provider": "0.18.5", + "@safe-global/safe-apps-sdk": "9.1.0", + "@walletconnect/ethereum-provider": "2.17.0", + "cbw-sdk": "npm:@coinbase/wallet-sdk@3.9.3" + }, + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "@wagmi/core": "2.16.3", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@wagmi/core": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@wagmi/core/-/core-2.16.3.tgz", + "integrity": "sha512-SVovoWHaQ2AIkmGf+ucNijT6AHXcTMffFcLmcFF6++y21x+ge7Gkh3UoJiU91SDDv8n08eTQ9jbyia3GEgU5jQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "5.0.1", + "mipd": "0.0.7", + "zustand": "5.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "@tanstack/query-core": ">=5.0.0", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "@tanstack/query-core": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@wagmi/core/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, "node_modules/@walletconnect/core": { "version": "2.17.1", "license": "Apache-2.0", @@ -9782,56 +10540,190 @@ "tslib": "1.14.1" } }, - "node_modules/@walletconnect/events": { - "version": "1.0.1", - "license": "MIT", + "node_modules/@walletconnect/ethereum-provider": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/ethereum-provider/-/ethereum-provider-2.17.0.tgz", + "integrity": "sha512-b+KTAXOb6JjoxkwpgYQQKPUcTwENGmdEdZoIDLeRicUmZTn/IQKfkMoC2frClB4YxkyoVMtj1oMV2JAax+yu9A==", + "license": "Apache-2.0", + "peer": true, "dependencies": { - "keyvaluestorage-interface": "^1.0.0", - "tslib": "1.14.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/modal": "2.7.0", + "@walletconnect/sign-client": "2.17.0", + "@walletconnect/types": "2.17.0", + "@walletconnect/universal-provider": "2.17.0", + "@walletconnect/utils": "2.17.0", + "events": "3.3.0" } }, - "node_modules/@walletconnect/heartbeat": { - "version": "1.2.2", - "license": "MIT", + "node_modules/@walletconnect/ethereum-provider/node_modules/@walletconnect/core": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-2.17.0.tgz", + "integrity": "sha512-On+uSaCfWdsMIQsECwWHZBmUXfrnqmv6B8SXRRuTJgd8tUpEvBkLQH4X7XkSm3zW6ozEkQTCagZ2ox2YPn3kbw==", + "license": "Apache-2.0", + "peer": true, "dependencies": { - "@walletconnect/events": "^1.0.1", - "@walletconnect/time": "^1.0.2", - "events": "^3.3.0" + "@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.14", + "@walletconnect/keyvaluestorage": "1.1.1", + "@walletconnect/logger": "2.1.2", + "@walletconnect/relay-api": "1.0.11", + "@walletconnect/relay-auth": "1.0.4", + "@walletconnect/safe-json": "1.0.2", + "@walletconnect/time": "1.0.2", + "@walletconnect/types": "2.17.0", + "@walletconnect/utils": "2.17.0", + "events": "3.3.0", + "lodash.isequal": "4.5.0", + "uint8arrays": "3.1.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@walletconnect/jsonrpc-http-connection": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-http-connection/-/jsonrpc-http-connection-1.0.8.tgz", - "integrity": "sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==", - "license": "MIT", + "node_modules/@walletconnect/ethereum-provider/node_modules/@walletconnect/sign-client": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.17.0.tgz", + "integrity": "sha512-sErYwvSSHQolNXni47L3Bm10ptJc1s1YoJvJd34s5E9h9+d3rj7PrhbiW9X82deN+Dm5oA8X9tC4xty1yIBrVg==", + "license": "Apache-2.0", + "peer": true, "dependencies": { - "@walletconnect/jsonrpc-utils": "^1.0.6", - "@walletconnect/safe-json": "^1.0.1", - "cross-fetch": "^3.1.4", - "events": "^3.3.0" + "@walletconnect/core": "2.17.0", + "@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.17.0", + "@walletconnect/utils": "2.17.0", + "events": "3.3.0" } }, - "node_modules/@walletconnect/jsonrpc-provider": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.14.tgz", - "integrity": "sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==", - "license": "MIT", + "node_modules/@walletconnect/ethereum-provider/node_modules/@walletconnect/types": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-2.17.0.tgz", + "integrity": "sha512-i1pn9URpvt9bcjRDkabuAmpA9K7mzyKoLJlbsAujRVX7pfaG7wur7u9Jz0bk1HxvuABL5LHNncTnVKSXKQ5jZA==", + "license": "Apache-2.0", + "peer": true, "dependencies": { - "@walletconnect/jsonrpc-utils": "^1.0.8", - "@walletconnect/safe-json": "^1.0.2", - "events": "^3.3.0" + "@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" } }, - "node_modules/@walletconnect/jsonrpc-types": { - "version": "1.0.4", - "license": "MIT", + "node_modules/@walletconnect/ethereum-provider/node_modules/@walletconnect/utils": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.17.0.tgz", + "integrity": "sha512-1aeQvjwsXy4Yh9G6g2eGmXrEl+BzkNjHRdCrGdMYqFTFa8ROEJfTGsSH3pLsNDlOY94CoBUvJvM55q/PMoN/FQ==", + "license": "Apache-2.0", + "peer": true, "dependencies": { - "events": "^3.3.0", - "keyvaluestorage-interface": "^1.0.0" + "@stablelib/chacha20poly1305": "1.0.1", + "@stablelib/hkdf": "1.0.1", + "@stablelib/random": "1.0.2", + "@stablelib/sha256": "1.0.1", + "@stablelib/x25519": "1.0.3", + "@walletconnect/relay-api": "1.0.11", + "@walletconnect/relay-auth": "1.0.4", + "@walletconnect/safe-json": "1.0.2", + "@walletconnect/time": "1.0.2", + "@walletconnect/types": "2.17.0", + "@walletconnect/window-getters": "1.0.1", + "@walletconnect/window-metadata": "1.0.1", + "detect-browser": "5.3.0", + "elliptic": "^6.5.7", + "query-string": "7.1.3", + "uint8arrays": "3.1.0" } }, - "node_modules/@walletconnect/jsonrpc-utils": { - "version": "1.0.8", + "node_modules/@walletconnect/ethereum-provider/node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "license": "MIT", + "peer": true, + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@walletconnect/ethereum-provider/node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@walletconnect/events": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "keyvaluestorage-interface": "^1.0.0", + "tslib": "1.14.1" + } + }, + "node_modules/@walletconnect/heartbeat": { + "version": "1.2.2", + "license": "MIT", + "dependencies": { + "@walletconnect/events": "^1.0.1", + "@walletconnect/time": "^1.0.2", + "events": "^3.3.0" + } + }, + "node_modules/@walletconnect/jsonrpc-http-connection": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-http-connection/-/jsonrpc-http-connection-1.0.8.tgz", + "integrity": "sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==", + "license": "MIT", + "dependencies": { + "@walletconnect/jsonrpc-utils": "^1.0.6", + "@walletconnect/safe-json": "^1.0.1", + "cross-fetch": "^3.1.4", + "events": "^3.3.0" + } + }, + "node_modules/@walletconnect/jsonrpc-provider": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.14.tgz", + "integrity": "sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==", + "license": "MIT", + "dependencies": { + "@walletconnect/jsonrpc-utils": "^1.0.8", + "@walletconnect/safe-json": "^1.0.2", + "events": "^3.3.0" + } + }, + "node_modules/@walletconnect/jsonrpc-types": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "events": "^3.3.0", + "keyvaluestorage-interface": "^1.0.0" + } + }, + "node_modules/@walletconnect/jsonrpc-utils": { + "version": "1.0.8", "license": "MIT", "dependencies": { "@walletconnect/environment": "^1.0.1", @@ -9978,6 +10870,139 @@ "events": "3.3.0" } }, + "node_modules/@walletconnect/universal-provider": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/universal-provider/-/universal-provider-2.17.0.tgz", + "integrity": "sha512-d3V5Be7AqLrvzcdMZSBS8DmGDRdqnyLk1DWmRKAGgR6ieUWykhhUKlvfeoZtvJrIXrY7rUGYpH1X41UtFkW5Pw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@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/logger": "2.1.2", + "@walletconnect/sign-client": "2.17.0", + "@walletconnect/types": "2.17.0", + "@walletconnect/utils": "2.17.0", + "events": "3.3.0" + } + }, + "node_modules/@walletconnect/universal-provider/node_modules/@walletconnect/core": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-2.17.0.tgz", + "integrity": "sha512-On+uSaCfWdsMIQsECwWHZBmUXfrnqmv6B8SXRRuTJgd8tUpEvBkLQH4X7XkSm3zW6ozEkQTCagZ2ox2YPn3kbw==", + "license": "Apache-2.0", + "peer": true, + "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.14", + "@walletconnect/keyvaluestorage": "1.1.1", + "@walletconnect/logger": "2.1.2", + "@walletconnect/relay-api": "1.0.11", + "@walletconnect/relay-auth": "1.0.4", + "@walletconnect/safe-json": "1.0.2", + "@walletconnect/time": "1.0.2", + "@walletconnect/types": "2.17.0", + "@walletconnect/utils": "2.17.0", + "events": "3.3.0", + "lodash.isequal": "4.5.0", + "uint8arrays": "3.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@walletconnect/universal-provider/node_modules/@walletconnect/sign-client": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.17.0.tgz", + "integrity": "sha512-sErYwvSSHQolNXni47L3Bm10ptJc1s1YoJvJd34s5E9h9+d3rj7PrhbiW9X82deN+Dm5oA8X9tC4xty1yIBrVg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@walletconnect/core": "2.17.0", + "@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.17.0", + "@walletconnect/utils": "2.17.0", + "events": "3.3.0" + } + }, + "node_modules/@walletconnect/universal-provider/node_modules/@walletconnect/types": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-2.17.0.tgz", + "integrity": "sha512-i1pn9URpvt9bcjRDkabuAmpA9K7mzyKoLJlbsAujRVX7pfaG7wur7u9Jz0bk1HxvuABL5LHNncTnVKSXKQ5jZA==", + "license": "Apache-2.0", + "peer": true, + "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" + } + }, + "node_modules/@walletconnect/universal-provider/node_modules/@walletconnect/utils": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.17.0.tgz", + "integrity": "sha512-1aeQvjwsXy4Yh9G6g2eGmXrEl+BzkNjHRdCrGdMYqFTFa8ROEJfTGsSH3pLsNDlOY94CoBUvJvM55q/PMoN/FQ==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@stablelib/chacha20poly1305": "1.0.1", + "@stablelib/hkdf": "1.0.1", + "@stablelib/random": "1.0.2", + "@stablelib/sha256": "1.0.1", + "@stablelib/x25519": "1.0.3", + "@walletconnect/relay-api": "1.0.11", + "@walletconnect/relay-auth": "1.0.4", + "@walletconnect/safe-json": "1.0.2", + "@walletconnect/time": "1.0.2", + "@walletconnect/types": "2.17.0", + "@walletconnect/window-getters": "1.0.1", + "@walletconnect/window-metadata": "1.0.1", + "detect-browser": "5.3.0", + "elliptic": "^6.5.7", + "query-string": "7.1.3", + "uint8arrays": "3.1.0" + } + }, + "node_modules/@walletconnect/universal-provider/node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "license": "MIT", + "peer": true, + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@walletconnect/universal-provider/node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@walletconnect/utils": { "version": "2.17.1", "license": "Apache-2.0", @@ -10283,6 +11308,27 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/abitype": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", + "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.22.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, "node_modules/abort-controller": { "version": "3.0.0", "license": "MIT", @@ -10639,6 +11685,23 @@ "license": "MIT", "peer": true }, + "node_modules/async-mutex": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.2.6.tgz", + "integrity": "sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.0.0" + } + }, + "node_modules/async-mutex/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "peer": true + }, "node_modules/asynckit": { "version": "0.4.0", "license": "MIT" @@ -11324,6 +12387,13 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", + "license": "MIT", + "peer": true + }, "node_modules/bplist-creator": { "version": "0.0.7", "license": "MIT", @@ -11461,6 +12531,20 @@ "version": "1.1.2", "license": "MIT" }, + "node_modules/bufferutil": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", + "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/builtin-modules": { "version": "3.3.0", "dev": true, @@ -11567,6 +12651,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caller-callsite": { "version": "2.0.0", "license": "MIT", @@ -11665,6 +12780,39 @@ ], "license": "CC-BY-4.0" }, + "node_modules/cbw-sdk": { + "name": "@coinbase/wallet-sdk", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@coinbase/wallet-sdk/-/wallet-sdk-3.9.3.tgz", + "integrity": "sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "bn.js": "^5.2.1", + "buffer": "^6.0.3", + "clsx": "^1.2.1", + "eth-block-tracker": "^7.1.0", + "eth-json-rpc-filters": "^6.0.0", + "eventemitter3": "^5.0.1", + "keccak": "^3.0.3", + "preact": "^10.16.0", + "sha.js": "^2.4.11" + } + }, + "node_modules/cbw-sdk/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "license": "MIT", + "peer": true + }, + "node_modules/cbw-sdk/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT", + "peer": true + }, "node_modules/chalk": { "version": "2.4.2", "license": "MIT", @@ -12008,6 +13156,16 @@ "node": ">=6" } }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/cmd-shim": { "version": "6.0.3", "dev": true, @@ -12486,6 +13644,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/create-jest": { "version": "29.7.0", "dev": true, @@ -12794,6 +13965,13 @@ "dev": true, "license": "MIT" }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT", + "peer": true + }, "node_modules/dag-map": { "version": "1.0.2", "license": "MIT", @@ -12873,6 +14051,23 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/dateformat": { "version": "3.0.3", "dev": true, @@ -12945,7 +14140,6 @@ }, "node_modules/dedent": { "version": "1.5.3", - "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -12969,6 +14163,13 @@ "dev": true, "license": "MIT" }, + "node_modules/deep-object-diff": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz", + "integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==", + "license": "MIT", + "peer": true + }, "node_modules/deepmerge": { "version": "4.3.1", "license": "MIT", @@ -13161,6 +14362,13 @@ "node": ">=8" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT", + "peer": true + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -13316,6 +14524,21 @@ "url": "https://dotenvx.com" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "dev": true, @@ -13335,6 +14558,24 @@ "version": "0.2.0", "license": "MIT" }, + "node_modules/eciesjs": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.13.tgz", + "integrity": "sha512-zBdtR4K+wbj10bWPpIOF9DW+eFYQu8miU5ypunh0t4Bvt83ZPlEWgT5Dq/0G6uwEXumZKjfb5BZxYUZQ2Hzn/Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@ecies/ciphers": "^0.2.2", + "@noble/ciphers": "^1.0.0", + "@noble/curves": "^1.6.0", + "@noble/hashes": "^1.5.0" + }, + "engines": { + "bun": ">=1", + "deno": ">=2", + "node": ">=16" + } + }, "node_modules/ee-first": { "version": "1.1.1", "license": "MIT", @@ -13424,6 +14665,52 @@ "once": "^1.4.0" } }, + "node_modules/engine.io-client": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", + "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "peer": true, + "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 + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.17.1", "dev": true, @@ -13582,12 +14869,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "peer": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -14077,6 +15363,179 @@ "node": ">= 0.6" } }, + "node_modules/eth-block-tracker": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-7.1.0.tgz", + "integrity": "sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@metamask/eth-json-rpc-provider": "^1.0.0", + "@metamask/safe-event-emitter": "^3.0.0", + "@metamask/utils": "^5.0.1", + "json-rpc-random-id": "^1.0.1", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/eth-block-tracker/node_modules/@metamask/utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-5.0.2.tgz", + "integrity": "sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==", + "license": "ISC", + "peer": true, + "dependencies": { + "@ethereumjs/tx": "^4.1.2", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "semver": "^7.3.8", + "superstruct": "^1.0.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/eth-block-tracker/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-block-tracker/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eth-json-rpc-filters": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/eth-json-rpc-filters/-/eth-json-rpc-filters-6.0.1.tgz", + "integrity": "sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==", + "license": "ISC", + "peer": true, + "dependencies": { + "@metamask/safe-event-emitter": "^3.0.0", + "async-mutex": "^0.2.6", + "eth-query": "^2.1.2", + "json-rpc-engine": "^6.1.0", + "pify": "^5.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/eth-query": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", + "integrity": "sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==", + "license": "ISC", + "peer": true, + "dependencies": { + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/eth-rpc-errors": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eth-rpc-errors/-/eth-rpc-errors-4.0.3.tgz", + "integrity": "sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-safe-stringify": "^2.0.6" + } + }, + "node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/event-target-shim": { "version": "5.0.1", "license": "MIT", @@ -14084,6 +15543,13 @@ "node": ">=6" } }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT", + "peer": true + }, "node_modules/eventemitter3": { "version": "4.0.7", "license": "MIT" @@ -14787,6 +16253,20 @@ "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", "dev": true }, + "node_modules/extension-port-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/extension-port-stream/-/extension-port-stream-3.0.0.tgz", + "integrity": "sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==", + "license": "ISC", + "peer": true, + "dependencies": { + "readable-stream": "^3.6.2 || ^4.4.2", + "webextension-polyfill": ">=0.10.0 <1.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/external-editor": { "version": "3.1.0", "dev": true, @@ -14802,7 +16282,6 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, "license": "MIT" }, "node_modules/fast-glob": { @@ -14846,6 +16325,13 @@ "node": ">=6" } }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT", + "peer": true + }, "node_modules/fast-xml-parser": { "version": "4.5.0", "funding": [ @@ -15380,15 +16866,22 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "license": "MIT", "peer": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -15397,6 +16890,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "dev": true, @@ -15496,6 +16999,20 @@ "version": "3.1.2", "license": "MIT" }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "peer": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stdin": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", @@ -15725,11 +17242,13 @@ "license": "(BSD-3-Clause AND Apache-2.0)" }, "node_modules/gopd": { - "version": "1.0.1", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "peer": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15860,7 +17379,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "peer": true, "engines": { @@ -16504,6 +18025,23 @@ "url": "https://github.com/sponsors/brc-dd" } }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-array-buffer": { "version": "3.0.4", "license": "MIT", @@ -16685,6 +18223,25 @@ "node": ">=6" } }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "license": "MIT", @@ -16856,12 +18413,16 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "license": "MIT", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -17062,6 +18623,21 @@ "ws": "*" } }, + "node_modules/isows": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.6.tgz", + "integrity": "sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "dev": true, @@ -19218,6 +20794,34 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/json-rpc-engine": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz", + "integrity": "sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "@metamask/safe-event-emitter": "^2.0.0", + "eth-rpc-errors": "^4.0.2" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/json-rpc-engine/node_modules/@metamask/safe-event-emitter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz", + "integrity": "sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==", + "license": "ISC", + "peer": true + }, + "node_modules/json-rpc-random-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz", + "integrity": "sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==", + "license": "ISC", + "peer": true + }, "node_modules/json-schema-deref-sync": { "version": "0.13.0", "license": "MIT", @@ -19324,6 +20928,29 @@ "dev": true, "license": "MIT" }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keccak/node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "license": "MIT", + "peer": true + }, "node_modules/keyv": { "version": "4.5.4", "dev": true, @@ -20388,6 +22015,16 @@ "license": "Apache-2.0", "peer": true }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/md5": { "version": "2.3.0", "license": "BSD-3-Clause", @@ -20422,6 +22059,16 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" }, + "node_modules/media-query-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/media-query-parser/-/media-query-parser-2.0.2.tgz", + "integrity": "sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.5" + } + }, "node_modules/memoize-one": { "version": "5.2.1", "license": "MIT", @@ -21420,6 +23067,13 @@ } } }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "license": "MIT", + "peer": true + }, "node_modules/micromatch": { "version": "4.0.8", "license": "MIT", @@ -21675,6 +23329,26 @@ "version": "4.0.0", "license": "ISC" }, + "node_modules/mipd": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mipd/-/mipd-0.0.7.tgz", + "integrity": "sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wagmi-dev" + } + ], + "license": "MIT", + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/mkdirp": { "version": "0.5.6", "license": "MIT", @@ -21696,6 +23370,13 @@ "ufo": "^1.5.4" } }, + "node_modules/modern-ahocorasick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modern-ahocorasick/-/modern-ahocorasick-1.1.0.tgz", + "integrity": "sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==", + "license": "MIT", + "peer": true + }, "node_modules/modify-values": { "version": "1.0.1", "dev": true, @@ -21949,6 +23630,18 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "peer": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-gyp/node_modules/glob": { "version": "10.4.5", "dev": true, @@ -22633,6 +24326,51 @@ "node": ">=16" } }, + "node_modules/obj-multiplex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/obj-multiplex/-/obj-multiplex-1.0.0.tgz", + "integrity": "sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==", + "license": "ISC", + "peer": true, + "dependencies": { + "end-of-stream": "^1.4.0", + "once": "^1.4.0", + "readable-stream": "^2.3.3" + } + }, + "node_modules/obj-multiplex/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT", + "peer": true + }, + "node_modules/obj-multiplex/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/obj-multiplex/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "license": "MIT", @@ -22878,6 +24616,41 @@ "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", "dev": true }, + "node_modules/ox": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.7.tgz", + "integrity": "sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.10.1", + "@noble/curves": "^1.6.0", + "@noble/hashes": "^1.5.0", + "@scure/bip32": "^1.5.0", + "@scure/bip39": "^1.4.0", + "abitype": "^1.0.6", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/ox/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, "node_modules/p-filter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", @@ -23374,6 +25147,16 @@ "node": ">=4.0.0" } }, + "node_modules/pony-cause": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-2.1.11.tgz", + "integrity": "sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==", + "license": "0BSD", + "peer": true, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "license": "MIT", @@ -24967,6 +26750,69 @@ "node": ">=0.10.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.2.tgz", + "integrity": "sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==", + "license": "MIT", + "peer": true, + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "peer": true + }, + "node_modules/react-remove-scroll/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "peer": true + }, "node_modules/react-shallow-renderer": { "version": "16.15.0", "license": "MIT", @@ -24979,6 +26825,36 @@ "react": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "peer": true + }, "node_modules/read": { "version": "3.0.1", "dev": true, @@ -25890,13 +27766,15 @@ "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==" }, "node_modules/safe-regex-test": { - "version": "1.0.3", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "license": "MIT", "peer": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -26198,6 +28076,20 @@ "license": "ISC", "peer": true }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "license": "(MIT AND BSD-3-Clause)", + "peer": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, "node_modules/sha3": { "version": "2.1.4", "license": "MIT", @@ -26351,6 +28243,36 @@ "version": "1.5.0", "license": "MIT" }, + "node_modules/socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "license": "MIT", + "peer": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/socks": { "version": "2.8.3", "dev": true, @@ -26922,6 +28844,16 @@ "license": "MIT", "peer": true }, + "node_modules/superstruct": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-1.0.4.tgz", + "integrity": "sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/supports-color": { "version": "5.5.0", "license": "MIT", @@ -28221,23 +30153,98 @@ "license": "MIT", "peer": true }, - "node_modules/use-sync-external-store": { - "version": "1.2.2", + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", "license": "MIT", "peer": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/util": { - "version": "0.10.4", - "dev": true, + "node_modules/use-callback-ref/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "peer": true + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", "license": "MIT", + "peer": true, "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/util-deprecate": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "peer": true + }, + "node_modules/use-sync-external-store": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", + "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/util": { + "version": "0.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { "version": "1.0.2", "license": "MIT" }, @@ -28346,6 +30353,36 @@ "node": ">= 0.8" } }, + "node_modules/viem": { + "version": "2.22.21", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.22.21.tgz", + "integrity": "sha512-CujapStF+F3VP+bKBQOGFk5YHyJKZOY2TGvD1e04CAm8VrtLo3sfTydYW2Rri6LMktqp6ilGB9GvSiZczxvOBQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "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", + "isows": "1.0.6", + "ox": "0.6.7", + "ws": "8.18.0" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/vlq": { "version": "1.0.1", "license": "MIT", @@ -28362,6 +30399,32 @@ "node": ">=14" } }, + "node_modules/wagmi": { + "version": "2.14.9", + "resolved": "https://registry.npmjs.org/wagmi/-/wagmi-2.14.9.tgz", + "integrity": "sha512-nDJ5hwPaiVpn/8Bi82m5K4BCqDiOSnOV976p/jKXt0svQABGdAxUxej0UgDRoVlrp+NutmejN+SyQKmhV477/A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@wagmi/connectors": "5.7.5", + "@wagmi/core": "2.16.3", + "use-sync-external-store": "1.4.0" + }, + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "@tanstack/react-query": ">=5.0.0", + "react": ">=18", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/walk-up-path": { "version": "3.0.1", "dev": true, @@ -28393,6 +30456,13 @@ "defaults": "^1.0.3" } }, + "node_modules/webextension-polyfill": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.10.0.tgz", + "integrity": "sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==", + "license": "MPL-2.0", + "peer": true + }, "node_modules/webidl-conversions": { "version": "7.0.0", "dev": true, @@ -28967,6 +31037,15 @@ "dev": true, "license": "MIT" }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "license": "MIT", @@ -29047,6 +31126,35 @@ "zod": "^3.18.0" } }, + "node_modules/zustand": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0.tgz", + "integrity": "sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + }, "packages/config": { "name": "@onflow/config", "version": "1.5.1", @@ -29222,7 +31330,7 @@ "@babel/runtime": "^7.25.7", "@ethersproject/bytes": "^5.7.0", "@ethersproject/hash": "^5.7.0", - "@onflow/fcl": "1.13.4", + "@noble/hashes": "^1.7.1", "@onflow/rlp": "^1.2.3", "@walletconnect/jsonrpc-http-connection": "^1.0.8", "@walletconnect/jsonrpc-provider": "^1.0.14" @@ -29237,6 +31345,242 @@ "eslint": "^8.57.1", "eslint-plugin-jsdoc": "^46.10.1", "jest": "^29.7.0" + }, + "peerDependencies": { + "@onflow/fcl": "1.13.4" + } + }, + "packages/fcl-rainbowkit-adapter": { + "name": "@onflow/fcl-rainbowkit-adapter", + "version": "0.0.0", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@onflow/fcl-ethereum-provider": "^0.0.0", + "@onflow/fcl-wagmi-adapter": "^0.0.0", + "@onflow/rlp": "^1.2.3", + "@wagmi/core": "^2.16.3", + "@walletconnect/jsonrpc-http-connection": "^1.0.8", + "@walletconnect/jsonrpc-provider": "^1.0.14", + "viem": "^2.22.21" + }, + "devDependencies": { + "@babel/preset-typescript": "^7.25.7", + "@onflow/fcl-bundle": "1.6.0", + "@onflow/typedefs": "^1.4.0", + "@types/jest": "^29.5.13", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.57.1", + "eslint-plugin-jsdoc": "^46.10.1", + "jest": "^29.7.0" + }, + "peerDependencies": { + "@onflow/fcl": "1.13.4", + "@rainbow-me/rainbowkit": "^2.2.3" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/@rainbow-me/rainbowkit": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@rainbow-me/rainbowkit/-/rainbowkit-2.2.3.tgz", + "integrity": "sha512-kXZ+zmKSPZhZdNHey+4TwOIW4p2vIRv5B9+5FoTJv1xktru1RykfAAQY5z+nLUdvc0l6M5hiYH4X88Jl1foXGQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vanilla-extract/css": "1.15.5", + "@vanilla-extract/dynamic": "2.1.2", + "@vanilla-extract/sprinkles": "1.6.3", + "clsx": "2.1.1", + "qrcode": "1.5.4", + "react-remove-scroll": "2.6.2", + "ua-parser-js": "^1.0.37" + }, + "engines": { + "node": ">=12.4" + }, + "peerDependencies": { + "@tanstack/react-query": ">=5.0.0", + "react": ">=18", + "react-dom": ">=18", + "viem": "2.x", + "wagmi": "^2.9.0" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT", + "peer": true + }, + "packages/fcl-rainbowkit-adapter/node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/qrcode": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", + "license": "MIT", + "peer": true, + "dependencies": { + "dijkstrajs": "^1.0.1", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "qrcode": "bin/qrcode" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/react": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/react-dom": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", + "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.25.0" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/scheduler": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT", + "peer": true + }, + "packages/fcl-rainbowkit-adapter/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "license": "ISC", + "peer": true + }, + "packages/fcl-rainbowkit-adapter/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "license": "MIT", + "peer": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "packages/fcl-rainbowkit-adapter/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "license": "ISC", + "peer": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" } }, "packages/fcl-react-native": { @@ -29299,6 +31643,36 @@ "node": ">=4.2.0" } }, + "packages/fcl-wagmi-adapter": { + "name": "@onflow/fcl-wagmi-adapter", + "version": "0.0.0", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@onflow/fcl-ethereum-provider": "^0.0.0", + "@onflow/rlp": "^1.2.3", + "@walletconnect/jsonrpc-http-connection": "^1.0.8", + "@walletconnect/jsonrpc-provider": "^1.0.14", + "viem": "^2.22.21" + }, + "devDependencies": { + "@babel/preset-typescript": "^7.25.7", + "@onflow/fcl-bundle": "1.6.0", + "@onflow/typedefs": "^1.4.0", + "@types/jest": "^29.5.13", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.57.1", + "eslint-plugin-jsdoc": "^46.10.1", + "jest": "^29.7.0" + }, + "peerDependencies": { + "@onflow/fcl": "1.13.4", + "@wagmi/core": "^2.16.3" + } + }, "packages/fcl-wc": { "name": "@onflow/fcl-wc", "version": "5.5.4", diff --git a/packages/fcl-bundle/src/build/get-input-options.js b/packages/fcl-bundle/src/build/get-input-options.js index 936e06066..c42c4b2b0 100644 --- a/packages/fcl-bundle/src/build/get-input-options.js +++ b/packages/fcl-bundle/src/build/get-input-options.js @@ -44,7 +44,7 @@ module.exports = function getInputOptions(package, build) { .concat(Object.keys(package.dependencies || {})) let testExternal = id => { - return ( + let res = build.type !== "umd" && (/@babel\/runtime/g.test(id) || external.reduce((state, ext) => { @@ -54,7 +54,18 @@ module.exports = function getInputOptions(package, build) { (typeof ext === "string" && ext === id) ) }, false)) - ) + + // TODO: REMOVE HACK + if ( + id.startsWith("@ethersproject") || + id.startsWith("@noble") || + id.startsWith("@wagmi") || + id.startsWith("viem") + ) { + res = true + } + + return res } // exclude peer dependencies diff --git a/packages/fcl-ethereum-provider/package.json b/packages/fcl-ethereum-provider/package.json index 9907ac63d..cf9c0a0c5 100644 --- a/packages/fcl-ethereum-provider/package.json +++ b/packages/fcl-ethereum-provider/package.json @@ -39,9 +39,12 @@ "@babel/runtime": "^7.25.7", "@ethersproject/bytes": "^5.7.0", "@ethersproject/hash": "^5.7.0", - "@onflow/fcl": "1.13.4", + "@noble/hashes": "^1.7.1", "@onflow/rlp": "^1.2.3", "@walletconnect/jsonrpc-http-connection": "^1.0.8", "@walletconnect/jsonrpc-provider": "^1.0.14" + }, + "peerDependencies": { + "@onflow/fcl": "1.13.4" } } diff --git a/packages/fcl-ethereum-provider/src/accounts/account-manager.ts b/packages/fcl-ethereum-provider/src/accounts/account-manager.ts index 07aa81c2f..6660de3d7 100644 --- a/packages/fcl-ethereum-provider/src/accounts/account-manager.ts +++ b/packages/fcl-ethereum-provider/src/accounts/account-manager.ts @@ -1,6 +1,6 @@ import * as fcl from "@onflow/fcl" import * as rlp from "@onflow/rlp" -import {CompositeSignature, CurrentUser} from "@onflow/typedefs" +import {CompositeSignature, CurrentUser, Service} from "@onflow/typedefs" import { ContractType, EVENT_IDENTIFIERS, @@ -25,7 +25,6 @@ import { } from "../util/observable" import {EthSignatureResponse} from "../types/eth" import {NetworkManager} from "../network/network-manager" -import {formatChainId, getContractAddress} from "../util/eth" import {createCOATx, getCOAScript, sendTransactionTx} from "../cadence" export class AccountManager { @@ -41,7 +40,8 @@ export class AccountManager { constructor( private user: typeof fcl.currentUser, - private networkManager: NetworkManager + private networkManager: NetworkManager, + private service?: Service ) { // Create an observable from the user const $user = new Observable(subscriber => { @@ -88,12 +88,16 @@ export class AccountManager { .subscribe(this.$addressStore) } - public async authenticate(): Promise { - return await this.user.authenticate() + public async authenticate(): Promise { + await this.user.authenticate({service: this.service}) + return this.getAccounts().then(accounts => { + return accounts + }) } public async unauthenticate(): Promise { await this.user.unauthenticate() + await new Promise(resolve => setTimeout(resolve, 0)) } private async waitForTxResult( @@ -131,7 +135,7 @@ export class AccountManager { if (error) { throw error } - return address + return address || null } public async getAccounts(): Promise { diff --git a/packages/fcl-ethereum-provider/src/cadence.ts b/packages/fcl-ethereum-provider/src/cadence.ts index fc821101f..22ad17f99 100644 --- a/packages/fcl-ethereum-provider/src/cadence.ts +++ b/packages/fcl-ethereum-provider/src/cadence.ts @@ -1,22 +1,23 @@ import {getContractAddress} from "./util/eth" import {ContractType} from "./constants" -export const getCOAScript = (chainId: number) => ` -import EVM from ${getContractAddress(ContractType.EVM, chainId)} - -access(all) -fun main(address: Address): String? { - if let coa = getAuthAccount(address) - .storage - .borrow<&EVM.CadenceOwnedAccount>(from: /storage/evm) { - return coa.address().toString() - } - return nil -} -` - -export const createCOATx = (chainId: number) => ` -import EVM from ${getContractAddress(ContractType.EVM, chainId)} +export const getCOAScript = ( + chainId: number +) => `import EVM from ${getContractAddress(ContractType.EVM, chainId)} + +/// Returns the hex encoded address of the COA in the given Flow address +/// +access(all) fun main(flowAddress: Address): String? { + return getAuthAccount(flowAddress) + .storage.borrow<&EVM.CadenceOwnedAccount>(from: /storage/evm) + ?.address() + ?.toString() + ?? nil +}` + +export const createCOATx = ( + chainId: number +) => `import EVM from ${getContractAddress(ContractType.EVM, chainId)} transaction() { prepare(signer: auth(SaveValue, IssueStorageCapabilityController, PublishCapability) &Account) { @@ -29,11 +30,11 @@ transaction() { let cap = signer.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(storagePath) signer.capabilities.publish(cap, at: publicPath) } -} -` +}` -export const sendTransactionTx = (chainId: number) => ` -import EVM from ${getContractAddress(ContractType.EVM, chainId)} +export const sendTransactionTx = ( + chainId: number +) => `import EVM from ${getContractAddress(ContractType.EVM, chainId)} /// Executes the calldata from the signer's COA transaction(evmContractAddressHex: String, calldata: String, gasLimit: UInt64, value: UInt256) { @@ -58,5 +59,4 @@ transaction(evmContractAddressHex: String, calldata: String, gasLimit: UInt64, v ) assert(callResult.status == EVM.Status.successful, message: "Call failed") } -} -` +}` diff --git a/packages/fcl-ethereum-provider/src/constants.ts b/packages/fcl-ethereum-provider/src/constants.ts index 5493c42a8..a0b530b1a 100644 --- a/packages/fcl-ethereum-provider/src/constants.ts +++ b/packages/fcl-ethereum-provider/src/constants.ts @@ -6,11 +6,11 @@ export enum FlowNetwork { export const FLOW_CHAINS = { [FlowNetwork.MAINNET]: { eip155ChainId: 747, - publicRpcUrl: "https://access.mainnet.nodes.onflow.org", + publicRpcUrl: "https://mainnet.evm.nodes.onflow.org", }, [FlowNetwork.TESTNET]: { eip155ChainId: 545, - publicRpcUrl: "https://access.testnet.nodes.onflow.org", + publicRpcUrl: "https://testnet.evm.nodes.onflow.org", }, } diff --git a/packages/fcl-ethereum-provider/src/create-provider.ts b/packages/fcl-ethereum-provider/src/create-provider.ts index 185f83668..d4e8d47ba 100644 --- a/packages/fcl-ethereum-provider/src/create-provider.ts +++ b/packages/fcl-ethereum-provider/src/create-provider.ts @@ -8,6 +8,7 @@ import {AccountManager} from "./accounts/account-manager" import {FLOW_CHAINS} from "./constants" import {Gateway} from "./gateway/gateway" import {NetworkManager} from "./network/network-manager" +import {Subject} from "./util/observable" /** * Create a new FCL Ethereum provider @@ -43,13 +44,21 @@ export function createProvider(config: { ) const networkManager = new NetworkManager(config.config) - const accountManager = new AccountManager(config.user, networkManager) + const accountManager = new AccountManager( + config.user, + networkManager, + config.service + ) const gateway = new Gateway({ ...defaultRpcUrls, ...(config.rpcUrls || {}), }) const rpcProcessor = new RpcProcessor(gateway, accountManager, networkManager) - const eventProcessor = new EventDispatcher(accountManager, networkManager) + const eventProcessor = new EventDispatcher( + accountManager, + networkManager, + new Subject() + ) const provider = new FclEthereumProvider( accountManager, rpcProcessor, diff --git a/packages/fcl-ethereum-provider/src/events/event-dispatcher.test.ts b/packages/fcl-ethereum-provider/src/events/event-dispatcher.test.ts index 7f338e749..e3d4368c9 100644 --- a/packages/fcl-ethereum-provider/src/events/event-dispatcher.test.ts +++ b/packages/fcl-ethereum-provider/src/events/event-dispatcher.test.ts @@ -8,8 +8,9 @@ jest.mock("../network/network-manager") describe("event dispatcher", () => { let networkManager: jest.Mocked - let accountManager: jest.Mocked let $mockChainId: Subject + let accountManager: jest.Mocked + let mockDisplayUri$: Subject beforeEach(() => { jest.clearAllMocks() @@ -19,6 +20,7 @@ describe("event dispatcher", () => { getChainId: jest.fn(), } as any accountManager = new (AccountManager as any)() + mockDisplayUri$ = new Subject() }) test("unsubscribe should remove listener", () => { let subs: ((accounts: string[]) => void)[] = [] @@ -30,7 +32,11 @@ describe("event dispatcher", () => { }) const listener = jest.fn() - const eventDispatcher = new EventDispatcher(accountManager, networkManager) + const eventDispatcher = new EventDispatcher( + accountManager, + networkManager, + mockDisplayUri$ + ) eventDispatcher.on("accountsChanged", listener) expect(accountManager.subscribe).toHaveBeenCalled() @@ -38,7 +44,7 @@ describe("event dispatcher", () => { expect(accountManager.subscribe).toHaveBeenCalledWith(expect.any(Function)) // Simulate account change from account manager - subs.forEach(sub => sub(["0x1234"])) + subs.forEach(sub => sub(["1234"])) expect(listener).toHaveBeenCalled() expect(listener).toHaveBeenCalledTimes(1) @@ -47,7 +53,7 @@ describe("event dispatcher", () => { eventDispatcher.off("accountsChanged", listener) // Simulate account change from account manager - subs.forEach(sub => sub(["0x5678"])) + subs.forEach(sub => sub(["5678"])) expect(listener).toHaveBeenCalledTimes(1) }) @@ -60,7 +66,11 @@ describe("event dispatcher", () => { }) const listener = jest.fn() - const eventDispatcher = new EventDispatcher(accountManager, networkManager) + const eventDispatcher = new EventDispatcher( + accountManager, + networkManager, + mockDisplayUri$ + ) eventDispatcher.on("accountsChanged", listener) expect(accountManager.subscribe).toHaveBeenCalled() @@ -68,7 +78,7 @@ describe("event dispatcher", () => { expect(accountManager.subscribe).toHaveBeenCalledWith(expect.any(Function)) // Simulate account change from account manager - mockMgrSubCb!(["0x1234"]) + mockMgrSubCb!(["1234"]) expect(listener).toHaveBeenCalled() expect(listener).toHaveBeenCalledTimes(1) @@ -83,7 +93,11 @@ describe("event dispatcher", () => { }) const listener = jest.fn() - const eventDispatcher = new EventDispatcher(accountManager, networkManager) + const eventDispatcher = new EventDispatcher( + accountManager, + networkManager, + mockDisplayUri$ + ) eventDispatcher.on("accountsChanged", listener) expect(accountManager.subscribe).toHaveBeenCalled() @@ -91,8 +105,8 @@ describe("event dispatcher", () => { expect(accountManager.subscribe).toHaveBeenCalledWith(expect.any(Function)) // Simulate account change from account manager - mockMgrSubCb!(["0x1234"]) - mockMgrSubCb!(["0x5678"]) + mockMgrSubCb!(["1234"]) + mockMgrSubCb!(["5678"]) expect(listener).toHaveBeenCalled() expect(listener).toHaveBeenCalledTimes(2) @@ -103,7 +117,11 @@ describe("event dispatcher", () => { test("should emit chainChanged", async () => { const listener = jest.fn() - const eventDispatcher = new EventDispatcher(accountManager, networkManager) + const eventDispatcher = new EventDispatcher( + accountManager, + networkManager, + mockDisplayUri$ + ) eventDispatcher.on("chainChanged", listener) // Initial chain id, should not emit as a change diff --git a/packages/fcl-ethereum-provider/src/events/event-dispatcher.ts b/packages/fcl-ethereum-provider/src/events/event-dispatcher.ts index 081b36c67..627075a22 100644 --- a/packages/fcl-ethereum-provider/src/events/event-dispatcher.ts +++ b/packages/fcl-ethereum-provider/src/events/event-dispatcher.ts @@ -10,6 +10,7 @@ import { takeFirst, } from "../util/observable" import {formatChainId} from "../util/eth" +import {withPrefix} from "@onflow/fcl" export class EventDispatcher { private $emitters: { @@ -22,12 +23,16 @@ export class EventDispatcher { > } - constructor(accountManager: AccountManager, networkManager: NetworkManager) { + constructor( + accountManager: AccountManager, + networkManager: NetworkManager, + displayUri$: Observable + ) { this.$emitters = { // Emit changes to the accounts as an accountsChanged event accountsChanged: new Observable(subscriber => { return accountManager.subscribe(accounts => { - subscriber.next(accounts) + subscriber.next(accounts.map(x => withPrefix(x))) }) }), // Emit changes to the chainId as a chainChanged event @@ -49,6 +54,7 @@ export class EventDispatcher { disconnect: new Observable<{reason: string}>(() => { return () => {} }), + display_uri: displayUri$, } this.subscriptions = { @@ -56,6 +62,7 @@ export class EventDispatcher { chainChanged: new Map(), connect: new Map(), disconnect: new Map(), + display_uri: new Map(), } } diff --git a/packages/fcl-ethereum-provider/src/gateway/gateway.test.ts b/packages/fcl-ethereum-provider/src/gateway/gateway.test.ts index c4b3c0128..174b72f48 100644 --- a/packages/fcl-ethereum-provider/src/gateway/gateway.test.ts +++ b/packages/fcl-ethereum-provider/src/gateway/gateway.test.ts @@ -162,7 +162,7 @@ describe("gateway", () => { jest.mocked(HttpConnection).mock.instances[0] ) expect(HttpConnection).toHaveBeenCalledWith( - "https://access.mainnet.nodes.onflow.org" + "https://mainnet.evm.nodes.onflow.org" ) }) @@ -191,7 +191,7 @@ describe("gateway", () => { jest.mocked(HttpConnection).mock.instances[0] ) expect(HttpConnection).toHaveBeenCalledWith( - "https://access.testnet.nodes.onflow.org" + "https://testnet.evm.nodes.onflow.org" ) }) }) diff --git a/packages/fcl-ethereum-provider/src/provider.ts b/packages/fcl-ethereum-provider/src/provider.ts index 617b74f29..400bd0ade 100644 --- a/packages/fcl-ethereum-provider/src/provider.ts +++ b/packages/fcl-ethereum-provider/src/provider.ts @@ -29,8 +29,8 @@ export class FclEthereumProvider implements Eip1193Provider { return result } - disconnect(): void { - this.acountManager.unauthenticate() + async disconnect(): Promise { + await this.acountManager.unauthenticate() } // Listen to events diff --git a/packages/fcl-ethereum-provider/src/rpc/handlers/eth-accounts.test.ts b/packages/fcl-ethereum-provider/src/rpc/handlers/eth-accounts.test.ts index 523138234..ccc04b7a9 100644 --- a/packages/fcl-ethereum-provider/src/rpc/handlers/eth-accounts.test.ts +++ b/packages/fcl-ethereum-provider/src/rpc/handlers/eth-accounts.test.ts @@ -47,20 +47,21 @@ describe("ethRequestAccounts handler", () => { it("should call authenticate, updateCOAAddress, and return the manager's accounts", async () => { accountManagerMock.getAndCreateAccounts.mockResolvedValue(["0x1234..."]) - const accounts = await ethRequestAccounts(accountManagerMock) + const accounts = await ethRequestAccounts(accountManagerMock, 747) - expect(accountManagerMock.authenticate).toHaveBeenCalled() - expect(accountManagerMock.getAndCreateAccounts).toHaveBeenCalled() expect(accounts).toEqual(["0x1234..."]) + + expect(accountManagerMock.authenticate).toHaveBeenCalled() + expect(accountManagerMock.getAndCreateAccounts).toHaveBeenCalledWith(747) }) it("should handle empty accounts scenario", async () => { accountManagerMock.getAndCreateAccounts.mockResolvedValue([]) - const accounts = await ethRequestAccounts(accountManagerMock) + const accounts = await ethRequestAccounts(accountManagerMock, 747) expect(accountManagerMock.authenticate).toHaveBeenCalled() - expect(accountManagerMock.getAndCreateAccounts).toHaveBeenCalled() + expect(accountManagerMock.getAndCreateAccounts).toHaveBeenCalledWith(747) expect(accounts).toEqual([]) }) }) diff --git a/packages/fcl-ethereum-provider/src/rpc/handlers/eth-accounts.ts b/packages/fcl-ethereum-provider/src/rpc/handlers/eth-accounts.ts index 0e83bd4a4..21c6c01fb 100644 --- a/packages/fcl-ethereum-provider/src/rpc/handlers/eth-accounts.ts +++ b/packages/fcl-ethereum-provider/src/rpc/handlers/eth-accounts.ts @@ -1,9 +1,11 @@ +import {withPrefix} from "@onflow/fcl" import {AccountManager} from "../../accounts/account-manager" export async function ethAccounts( accountManager: AccountManager ): Promise { - return await accountManager.getAccounts() + const accounts = await accountManager.getAccounts() + return accounts.map(x => withPrefix(x)) } export async function ethRequestAccounts( @@ -11,6 +13,6 @@ export async function ethRequestAccounts( chainId: number ): Promise { await accountManager.authenticate() - - return await accountManager.getAndCreateAccounts(chainId) + const accounts = await accountManager.getAndCreateAccounts(chainId) + return accounts.map(x => withPrefix(x)) } diff --git a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts index b292a609c..05d186aed 100644 --- a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts +++ b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.test.ts @@ -122,4 +122,59 @@ describe("rpc processor", () => { cause: new Error("test error"), }) }) + + test("caught RpcError should be rethrown", async () => { + const gateway: jest.Mocked = new (Gateway as any)() + const accountManager: jest.Mocked = + new (AccountManager as any)() + const networkManager: jest.Mocked = + new (NetworkManager as any)() + const rpcProcessor = new RpcProcessor( + gateway, + accountManager, + networkManager + ) + + const error = new Error("test error") + ;(error as any).code = -32000 + jest.mocked(gateway).request.mockRejectedValue(error) + networkManager.getChainId.mockResolvedValue(747) + + await expect( + rpcProcessor.handleRequest({ + method: "eth_blockNumber", + params: [], + }) + ).rejects.toMatchObject({ + code: -32000, + message: "test error", + }) + }) + + test("caught generic error should be rethrown as an internal error", async () => { + const gateway: jest.Mocked = new (Gateway as any)() + const accountManager: jest.Mocked = + new (AccountManager as any)() + const networkManager: jest.Mocked = + new (NetworkManager as any)() + const rpcProcessor = new RpcProcessor( + gateway, + accountManager, + networkManager + ) + + jest.mocked(gateway).request.mockRejectedValue(new Error("test error")) + networkManager.getChainId.mockResolvedValue(747) + + const promise = rpcProcessor.handleRequest({ + method: "eth_blockNumber", + params: [], + }) + + await expect(promise).rejects.toMatchObject({ + code: -32603, + message: "Internal error", + cause: new Error("test error"), + }) + }) }) diff --git a/packages/fcl-ethereum-provider/src/types/provider.ts b/packages/fcl-ethereum-provider/src/types/provider.ts index e49dfbd2e..0b31ef247 100644 --- a/packages/fcl-ethereum-provider/src/types/provider.ts +++ b/packages/fcl-ethereum-provider/src/types/provider.ts @@ -12,6 +12,7 @@ export type ProviderEvents = { disconnect: {reason: string} chainChanged: string accountsChanged: string[] + display_uri: string } // Event callback @@ -28,4 +29,5 @@ export interface Eip1193Provider { event: E, listener: EventCallback ): void + disconnect(): void } diff --git a/packages/fcl-rainbowkit-adapter/.babelrc b/packages/fcl-rainbowkit-adapter/.babelrc new file mode 100644 index 000000000..d766c90b2 --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": [["@babel/preset-env"], "@babel/preset-typescript"] +} diff --git a/packages/fcl-rainbowkit-adapter/.browserslistrc b/packages/fcl-rainbowkit-adapter/.browserslistrc new file mode 100644 index 000000000..6114ba78d --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/.browserslistrc @@ -0,0 +1,2 @@ +defaults and supports es6-module +maintained node versions diff --git a/packages/fcl-rainbowkit-adapter/.eslintrc.json b/packages/fcl-rainbowkit-adapter/.eslintrc.json new file mode 100644 index 000000000..e80c057f5 --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/.eslintrc.json @@ -0,0 +1,20 @@ +{ + "env": { + "browser": true, + "es2021": true, + "jest": true, + "node": true + }, + "extends": [ + "plugin:jsdoc/recommended-typescript", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], + "plugins": ["jsdoc", "@typescript-eslint"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "ignorePatterns": ["**/dist/"] +} diff --git a/packages/fcl-rainbowkit-adapter/.npmignore b/packages/fcl-rainbowkit-adapter/.npmignore new file mode 100644 index 000000000..8eba6c8dd --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/.npmignore @@ -0,0 +1 @@ +src/ diff --git a/packages/fcl-rainbowkit-adapter/CHANGELOG.md b/packages/fcl-rainbowkit-adapter/CHANGELOG.md new file mode 100644 index 000000000..fdb6897bf --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/CHANGELOG.md @@ -0,0 +1 @@ +# @onflow/fcl-ethereum-provider diff --git a/packages/fcl-rainbowkit-adapter/README.md b/packages/fcl-rainbowkit-adapter/README.md new file mode 100644 index 000000000..28b95b8f6 --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/README.md @@ -0,0 +1,15 @@ +# @onflow/fcl-ethereum-provider + +Lightweight utility for transport-agnostic, bidirectional RPC communication. + +# Status + +- **Last Updated:** Aug 20th, 2025 +- **Stable:** No +- **Risk of Breaking Change:** Yes + +# Install + +```bash +npm install --save @onflow/fcl-ethereum-provider +``` \ No newline at end of file diff --git a/packages/fcl-rainbowkit-adapter/package.json b/packages/fcl-rainbowkit-adapter/package.json new file mode 100644 index 000000000..c22b5e7e0 --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/package.json @@ -0,0 +1,54 @@ +{ + "name": "@onflow/fcl-rainbowkit-adapter", + "version": "0.0.0", + "description": "Wagmi adapter for FCL-compatible wallets", + "license": "Apache-2.0", + "author": "Dapper Labs ", + "homepage": "https://onflow.org", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/onflow/flow-js-sdk.git" + }, + "bugs": { + "url": "https://github.com/onflow/flow-js-sdk/issues" + }, + "devDependencies": { + "@babel/preset-typescript": "^7.25.7", + "@onflow/fcl-bundle": "1.6.0", + "@onflow/typedefs": "^1.4.0", + "@types/jest": "^29.5.13", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.57.1", + "eslint-plugin-jsdoc": "^46.10.1", + "jest": "^29.7.0" + }, + "source": "src/index.ts", + "main": "dist/index.js", + "module": "dist/index.module.js", + "unpkg": "dist/index.umd.js", + "types": "types/index.d.ts", + "scripts": { + "prepublishOnly": "npm test && npm run build", + "test": "jest", + "build": "fcl-bundle", + "test:watch": "jest --watch", + "start": "fcl-bundle --watch" + }, + "dependencies": { + "@babel/runtime": "^7.25.7", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@onflow/fcl-ethereum-provider": "^0.0.0", + "@onflow/fcl-wagmi-adapter": "^0.0.0", + "@onflow/rlp": "^1.2.3", + "@wagmi/core": "^2.16.3", + "@walletconnect/jsonrpc-http-connection": "^1.0.8", + "@walletconnect/jsonrpc-provider": "^1.0.14", + "viem": "^2.22.21" + }, + "peerDependencies": { + "@onflow/fcl": "1.13.4", + "@rainbow-me/rainbowkit": "^2.2.3" + } +} diff --git a/packages/fcl-rainbowkit-adapter/src/index.ts b/packages/fcl-rainbowkit-adapter/src/index.ts new file mode 100644 index 000000000..a0496257b --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/src/index.ts @@ -0,0 +1,33 @@ +import {fclWagmiAdapter} from "@onflow/fcl-wagmi-adapter" +import {Wallet} from "@rainbow-me/rainbowkit" +import {createConnector} from "@wagmi/core" + +type FclConnectorOptions = Parameters[0] + +type DefaultWalletOptions = { + projectId: string +} + +const FALLBACK_ICON = + "https://assets.website-files.com/5f6294c0c7a8cdd643b1c820/5f6294c0c7a8cda55cb1c936_Flow_Wordmark.svg" + +export const createFclConnector = (options: FclConnectorOptions) => { + const uid = options.service?.uid + const name = options.service?.provider?.name + const iconUrl = options.service?.provider?.icon! + const iconBackground = options.service?.provider?.color + + return ({projectId}: DefaultWalletOptions): Wallet => ({ + id: uid ? `fcl-${uid}` : "fcl", + name: name || "Cadence Wallet", + iconUrl: iconUrl || FALLBACK_ICON, + iconBackground: iconBackground || "#FFFFFF", + createConnector: walletDetails => { + const connector = fclWagmiAdapter(options) + return createConnector(config => ({ + ...connector(config), + ...walletDetails, + })) + }, + }) +} diff --git a/packages/fcl-rainbowkit-adapter/tsconfig.json b/packages/fcl-rainbowkit-adapter/tsconfig.json new file mode 100644 index 000000000..617d9a8ae --- /dev/null +++ b/packages/fcl-rainbowkit-adapter/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + // Change this to match your project + "include": ["src/**/*"], + "compilerOptions": { + "declarationDir": "types", + "rootDir": "src" + } +} diff --git a/packages/fcl-wagmi-adapter/.babelrc b/packages/fcl-wagmi-adapter/.babelrc new file mode 100644 index 000000000..d766c90b2 --- /dev/null +++ b/packages/fcl-wagmi-adapter/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": [["@babel/preset-env"], "@babel/preset-typescript"] +} diff --git a/packages/fcl-wagmi-adapter/.browserslistrc b/packages/fcl-wagmi-adapter/.browserslistrc new file mode 100644 index 000000000..6114ba78d --- /dev/null +++ b/packages/fcl-wagmi-adapter/.browserslistrc @@ -0,0 +1,2 @@ +defaults and supports es6-module +maintained node versions diff --git a/packages/fcl-wagmi-adapter/.eslintrc.json b/packages/fcl-wagmi-adapter/.eslintrc.json new file mode 100644 index 000000000..e80c057f5 --- /dev/null +++ b/packages/fcl-wagmi-adapter/.eslintrc.json @@ -0,0 +1,20 @@ +{ + "env": { + "browser": true, + "es2021": true, + "jest": true, + "node": true + }, + "extends": [ + "plugin:jsdoc/recommended-typescript", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], + "plugins": ["jsdoc", "@typescript-eslint"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "ignorePatterns": ["**/dist/"] +} diff --git a/packages/fcl-wagmi-adapter/.npmignore b/packages/fcl-wagmi-adapter/.npmignore new file mode 100644 index 000000000..8eba6c8dd --- /dev/null +++ b/packages/fcl-wagmi-adapter/.npmignore @@ -0,0 +1 @@ +src/ diff --git a/packages/fcl-wagmi-adapter/CHANGELOG.md b/packages/fcl-wagmi-adapter/CHANGELOG.md new file mode 100644 index 000000000..fdb6897bf --- /dev/null +++ b/packages/fcl-wagmi-adapter/CHANGELOG.md @@ -0,0 +1 @@ +# @onflow/fcl-ethereum-provider diff --git a/packages/fcl-wagmi-adapter/README.md b/packages/fcl-wagmi-adapter/README.md new file mode 100644 index 000000000..28b95b8f6 --- /dev/null +++ b/packages/fcl-wagmi-adapter/README.md @@ -0,0 +1,15 @@ +# @onflow/fcl-ethereum-provider + +Lightweight utility for transport-agnostic, bidirectional RPC communication. + +# Status + +- **Last Updated:** Aug 20th, 2025 +- **Stable:** No +- **Risk of Breaking Change:** Yes + +# Install + +```bash +npm install --save @onflow/fcl-ethereum-provider +``` \ No newline at end of file diff --git a/packages/fcl-wagmi-adapter/package.json b/packages/fcl-wagmi-adapter/package.json new file mode 100644 index 000000000..4188cf404 --- /dev/null +++ b/packages/fcl-wagmi-adapter/package.json @@ -0,0 +1,52 @@ +{ + "name": "@onflow/fcl-wagmi-adapter", + "version": "0.0.0", + "description": "Wagmi adapter for FCL-compatible wallets", + "license": "Apache-2.0", + "author": "Dapper Labs ", + "homepage": "https://onflow.org", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/onflow/flow-js-sdk.git" + }, + "bugs": { + "url": "https://github.com/onflow/flow-js-sdk/issues" + }, + "devDependencies": { + "@babel/preset-typescript": "^7.25.7", + "@onflow/fcl-bundle": "1.6.0", + "@onflow/typedefs": "^1.4.0", + "@types/jest": "^29.5.13", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.57.1", + "eslint-plugin-jsdoc": "^46.10.1", + "jest": "^29.7.0" + }, + "source": "src/index.ts", + "main": "dist/index.js", + "module": "dist/index.module.js", + "unpkg": "dist/index.umd.js", + "types": "types/index.d.ts", + "scripts": { + "prepublishOnly": "npm test && npm run build", + "test": "jest", + "build": "fcl-bundle", + "test:watch": "jest --watch", + "start": "fcl-bundle --watch" + }, + "dependencies": { + "@babel/runtime": "^7.25.7", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@onflow/fcl-ethereum-provider": "^0.0.0", + "@onflow/rlp": "^1.2.3", + "@walletconnect/jsonrpc-http-connection": "^1.0.8", + "@walletconnect/jsonrpc-provider": "^1.0.14", + "viem": "^2.22.21" + }, + "peerDependencies": { + "@onflow/fcl": "1.13.4", + "@wagmi/core": "^2.16.3" + } +} diff --git a/packages/fcl-wagmi-adapter/src/index.ts b/packages/fcl-wagmi-adapter/src/index.ts new file mode 100644 index 000000000..6dfc04717 --- /dev/null +++ b/packages/fcl-wagmi-adapter/src/index.ts @@ -0,0 +1,320 @@ +import { + ChainNotConfiguredError, + type Connector, + createConnector, +} from "@wagmi/core" +import { + type AddEthereumChainParameter, + type Address, + type Hex, + type ProviderConnectInfo, + ProviderDisconnectedError, + type ProviderRpcError, + type RpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + hexToNumber, + numberToHex, + withRetry, +} from "viem" +import {createProvider} from "@onflow/fcl-ethereum-provider" + +type FclWagmiAdapterParams = Parameters[0] + +export function fclWagmiAdapter(params: FclWagmiAdapterParams) { + type Provider = ReturnType + type Properties = { + onConnect(connectInfo: ProviderConnectInfo): void + onDisplayUri(uri: string): void + } + let provider: Provider | undefined + + let accountsChanged: Connector["onAccountsChanged"] | undefined + let chainChanged: Connector["onChainChanged"] | undefined + let connect: Connector["onConnect"] | undefined + let displayUri: ((uri: string) => void) | undefined + let disconnect: (({reason}: {reason: string}) => void) | undefined + + // Parse and validate service parameters + const id = params.service?.uid || "fcl" + const name = params.service?.provider?.name || "Cadence Wallet" + + return createConnector(config => ({ + id: id, + name: name, + type: "fcl-wagmi-adapter", + async setup() { + const provider = await this.getProvider() + + if (provider?.on) { + if (!connect) { + connect = this.onConnect.bind(this) + provider.on("connect", connect) + } + + // We shouldn't need to listen for `'accountsChanged'` here since the `'connect'` event should suffice (and wallet shouldn't be connected yet). + // Some wallets, like MetaMask, do not implement the `'connect'` event and overload `'accountsChanged'` instead. + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on("accountsChanged", accountsChanged) + } + } + }, + async connect({chainId, isReconnecting}: any = {}) { + const provider = await this.getProvider() + if (!displayUri) { + displayUri = this.onDisplayUri + provider.on("display_uri", displayUri) + } + + let accounts: readonly Address[] = await provider.request({ + method: "eth_requestAccounts", + }) + + if (isReconnecting) accounts = await this.getAccounts() + + // Manage EIP-1193 event listeners + // https://eips.ethereum.org/EIPS/eip-1193#events + if (connect) { + provider.removeListener("connect", connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on("accountsChanged", accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on("chainChanged", chainChanged) + } + if (!disconnect) { + disconnect = (({reason}) => { + throw new ProviderDisconnectedError(new Error(reason)) + }) as ({reason}: {reason: string}) => void + provider.on("disconnect", disconnect) + } + + return {accounts, chainId} + }, + async disconnect() { + const provider = await this.getProvider() + + // Manage EIP-1193 event listeners + if (chainChanged) { + provider.removeListener("chainChanged", chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener("disconnect", disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on("connect", connect) + } + + await provider.disconnect() + }, + async getAccounts() { + const provider = await this.getProvider() + const accounts = (await provider.request({ + method: "eth_accounts", + })) as string[] + return accounts.map(x => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const chainId = await provider?.request({method: "eth_chainId"}) + return Number(chainId) + }, + async getProvider() { + return provider ?? (provider = createProvider(params)) + }, + async isAuthorized() { + // TODO: There may be an issue here if a user without a COA refreshes the page + // We should instead be checking whether FCL itself is authorized + const accounts = await this.getAccounts() + return accounts.length > 0 + }, + async switchChain({addEthereumChainParameter, chainId}: any) { + const provider = await this.getProvider() + + const chain = config.chains.find(x => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + try { + await provider.request({ + method: "wallet_switchEthereumChain", + params: [{chainId: numberToHex(chainId)}], + }) + + // During `'wallet_switchEthereumChain'`, MetaMask makes a `'net_version'` RPC call to the target chain. + // If this request fails, MetaMask does not emit the `'chainChanged'` event, but will still switch the chain. + // To counter this behavior, we request and emit the current chain ID to confirm the chain switch either via + // this callback or an externally emitted `'chainChanged'` event. + // https://github.com/MetaMask/metamask-extension/issues/24247 + await waitForChainIdToSync() + await sendAndWaitForChangeEvent(chainId) + + return chain + } catch (err) { + const error = err as RpcError + + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + + // Indicates chain is not added to provider + if ( + error.code === 4902 || + // Unwrapping for MetaMask Mobile + // https://github.com/MetaMask/metamask-mobile/issues/2944#issuecomment-976988719 + (error as ProviderRpcError<{originalError?: {code: number}}>)?.data + ?.originalError?.code === 4902 + ) { + try { + await provider.request({ + method: "wallet_addEthereumChain", + params: [ + { + blockExplorerUrls: (() => { + const {default: blockExplorer, ...blockExplorers} = + chain.blockExplorers ?? {} + if (addEthereumChainParameter?.blockExplorerUrls) + return addEthereumChainParameter.blockExplorerUrls + if (blockExplorer) + return [ + blockExplorer.url, + ...Object.values(blockExplorers).map(x => x.url), + ] + return + })(), + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls: (() => { + if (addEthereumChainParameter?.rpcUrls?.length) + return addEthereumChainParameter.rpcUrls + return [chain.rpcUrls.default?.http[0] ?? ""] + })(), + } satisfies AddEthereumChainParameter, + ], + }) + + await waitForChainIdToSync() + await sendAndWaitForChangeEvent(chainId) + + return chain + } catch (err) { + const error = err as RpcError + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + throw new SwitchChainError(error) + } + } + + throw new SwitchChainError(error) + } + + async function waitForChainIdToSync() { + // On mobile, there is a race condition between the result of `'wallet_addEthereumChain'` and `'eth_chainId'`. + // To avoid this, we wait for `'eth_chainId'` to return the expected chain ID with a retry loop. + await withRetry( + async () => { + const value = hexToNumber( + // `'eth_chainId'` is cached by the MetaMask SDK side to avoid unnecessary deeplinks + (await provider.request({method: "eth_chainId"})) as Hex + ) + // `value` doesn't match expected `chainId`, throw to trigger retry + if (value !== chainId) + throw new Error("User rejected switch after adding network.") + return value + }, + { + delay: 50, + retryCount: 20, // android device encryption is slower + } + ) + } + + async function sendAndWaitForChangeEvent(chainId: number) { + await new Promise(resolve => { + const listener = (data => { + if ("chainId" in data && data.chainId === chainId) { + config.emitter.off("change", listener) + resolve() + } + }) satisfies Parameters[1] + config.emitter.on("change", listener) + config.emitter.emit("change", {chainId}) + }) + } + }, + onAccountsChanged(accounts: any) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit("change", { + accounts: accounts.map((x: any) => getAddress(x)), + }) + }, + onChainChanged(chain: any) { + const chainId = Number(chain) + config.emitter.emit("change", {chainId}) + }, + async onConnect(connectInfo: any) { + const accounts = await this.getAccounts() + + // TODO: What to do if accounts is empty? not sure this is accurate + if (accounts.length === 0) return + + const chainId = Number(connectInfo.chainId) + config.emitter.emit("connect", {accounts, chainId}) + + const provider = await this.getProvider() + if (connect) { + provider.removeListener("connect", connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on("accountsChanged", accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on("chainChanged", chainChanged) + } + if (!disconnect) { + disconnect = (({reason}) => { + throw new ProviderDisconnectedError(new Error(reason)) + }) as ({reason}: {reason: string}) => void + provider.on("disconnect", disconnect) + } + }, + // TODO: waht to do with error? + async onDisconnect(error: any) { + const provider = await this.getProvider() + + config.emitter.emit("disconnect") + + // Manage EIP-1193 event listeners + if (chainChanged) { + provider.removeListener("chainChanged", chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener("disconnect", disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on("connect", connect) + } + }, + onDisplayUri(uri: string) { + config.emitter.emit("message", {type: "display_uri", data: uri}) + }, + })) +} diff --git a/packages/fcl-wagmi-adapter/tsconfig.json b/packages/fcl-wagmi-adapter/tsconfig.json new file mode 100644 index 000000000..617d9a8ae --- /dev/null +++ b/packages/fcl-wagmi-adapter/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + // Change this to match your project + "include": ["src/**/*"], + "compilerOptions": { + "declarationDir": "types", + "rootDir": "src" + } +} diff --git a/tsconfig.json b/tsconfig.json index e7b5d0a60..d1ed06239 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "compilerOptions": { "moduleResolution": "Bundler", "module": "ESNext", - "target": "ES2015", + "target": "ESNext", "types": ["node", "jest"], // Tells TypeScript to read JS files, as // normally they are ignored as source files From 5a9b2d4b3d4e8f63ad92a382035efffadcb71eba Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 15:51:35 -0800 Subject: [PATCH 05/14] revert es2015 --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index d1ed06239..e7b5d0a60 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "compilerOptions": { "moduleResolution": "Bundler", "module": "ESNext", - "target": "ESNext", + "target": "ES2015", "types": ["node", "jest"], // Tells TypeScript to read JS files, as // normally they are ignored as source files From 5161ebe4779e64448edcd3ca4af07b18e61fd445 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 16:37:23 -0800 Subject: [PATCH 06/14] Remove display_uri --- .../src/create-provider.ts | 6 +---- .../src/events/event-dispatcher.test.ts | 26 +++---------------- .../src/events/event-dispatcher.ts | 8 +----- .../src/types/provider.ts | 1 - packages/fcl-wagmi-adapter/src/index.ts | 5 ++++ 5 files changed, 11 insertions(+), 35 deletions(-) diff --git a/packages/fcl-ethereum-provider/src/create-provider.ts b/packages/fcl-ethereum-provider/src/create-provider.ts index d4e8d47ba..1b1fd3ea4 100644 --- a/packages/fcl-ethereum-provider/src/create-provider.ts +++ b/packages/fcl-ethereum-provider/src/create-provider.ts @@ -54,11 +54,7 @@ export function createProvider(config: { ...(config.rpcUrls || {}), }) const rpcProcessor = new RpcProcessor(gateway, accountManager, networkManager) - const eventProcessor = new EventDispatcher( - accountManager, - networkManager, - new Subject() - ) + const eventProcessor = new EventDispatcher(accountManager, networkManager) const provider = new FclEthereumProvider( accountManager, rpcProcessor, diff --git a/packages/fcl-ethereum-provider/src/events/event-dispatcher.test.ts b/packages/fcl-ethereum-provider/src/events/event-dispatcher.test.ts index e3d4368c9..ef041313e 100644 --- a/packages/fcl-ethereum-provider/src/events/event-dispatcher.test.ts +++ b/packages/fcl-ethereum-provider/src/events/event-dispatcher.test.ts @@ -10,7 +10,6 @@ describe("event dispatcher", () => { let networkManager: jest.Mocked let $mockChainId: Subject let accountManager: jest.Mocked - let mockDisplayUri$: Subject beforeEach(() => { jest.clearAllMocks() @@ -20,7 +19,6 @@ describe("event dispatcher", () => { getChainId: jest.fn(), } as any accountManager = new (AccountManager as any)() - mockDisplayUri$ = new Subject() }) test("unsubscribe should remove listener", () => { let subs: ((accounts: string[]) => void)[] = [] @@ -32,11 +30,7 @@ describe("event dispatcher", () => { }) const listener = jest.fn() - const eventDispatcher = new EventDispatcher( - accountManager, - networkManager, - mockDisplayUri$ - ) + const eventDispatcher = new EventDispatcher(accountManager, networkManager) eventDispatcher.on("accountsChanged", listener) expect(accountManager.subscribe).toHaveBeenCalled() @@ -66,11 +60,7 @@ describe("event dispatcher", () => { }) const listener = jest.fn() - const eventDispatcher = new EventDispatcher( - accountManager, - networkManager, - mockDisplayUri$ - ) + const eventDispatcher = new EventDispatcher(accountManager, networkManager) eventDispatcher.on("accountsChanged", listener) expect(accountManager.subscribe).toHaveBeenCalled() @@ -93,11 +83,7 @@ describe("event dispatcher", () => { }) const listener = jest.fn() - const eventDispatcher = new EventDispatcher( - accountManager, - networkManager, - mockDisplayUri$ - ) + const eventDispatcher = new EventDispatcher(accountManager, networkManager) eventDispatcher.on("accountsChanged", listener) expect(accountManager.subscribe).toHaveBeenCalled() @@ -117,11 +103,7 @@ describe("event dispatcher", () => { test("should emit chainChanged", async () => { const listener = jest.fn() - const eventDispatcher = new EventDispatcher( - accountManager, - networkManager, - mockDisplayUri$ - ) + const eventDispatcher = new EventDispatcher(accountManager, networkManager) eventDispatcher.on("chainChanged", listener) // Initial chain id, should not emit as a change diff --git a/packages/fcl-ethereum-provider/src/events/event-dispatcher.ts b/packages/fcl-ethereum-provider/src/events/event-dispatcher.ts index 627075a22..559fe4d6a 100644 --- a/packages/fcl-ethereum-provider/src/events/event-dispatcher.ts +++ b/packages/fcl-ethereum-provider/src/events/event-dispatcher.ts @@ -23,11 +23,7 @@ export class EventDispatcher { > } - constructor( - accountManager: AccountManager, - networkManager: NetworkManager, - displayUri$: Observable - ) { + constructor(accountManager: AccountManager, networkManager: NetworkManager) { this.$emitters = { // Emit changes to the accounts as an accountsChanged event accountsChanged: new Observable(subscriber => { @@ -54,7 +50,6 @@ export class EventDispatcher { disconnect: new Observable<{reason: string}>(() => { return () => {} }), - display_uri: displayUri$, } this.subscriptions = { @@ -62,7 +57,6 @@ export class EventDispatcher { chainChanged: new Map(), connect: new Map(), disconnect: new Map(), - display_uri: new Map(), } } diff --git a/packages/fcl-ethereum-provider/src/types/provider.ts b/packages/fcl-ethereum-provider/src/types/provider.ts index 0b31ef247..e079176fe 100644 --- a/packages/fcl-ethereum-provider/src/types/provider.ts +++ b/packages/fcl-ethereum-provider/src/types/provider.ts @@ -12,7 +12,6 @@ export type ProviderEvents = { disconnect: {reason: string} chainChanged: string accountsChanged: string[] - display_uri: string } // Event callback diff --git a/packages/fcl-wagmi-adapter/src/index.ts b/packages/fcl-wagmi-adapter/src/index.ts index 6dfc04717..73c28af31 100644 --- a/packages/fcl-wagmi-adapter/src/index.ts +++ b/packages/fcl-wagmi-adapter/src/index.ts @@ -63,11 +63,16 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { }, async connect({chainId, isReconnecting}: any = {}) { const provider = await this.getProvider() + /* + TODO: This will be solved as part of the WalletConnect integration. + if (!displayUri) { displayUri = this.onDisplayUri provider.on("display_uri", displayUri) } + */ + let accounts: readonly Address[] = await provider.request({ method: "eth_requestAccounts", }) From 10c83daf6b576c58b6e7d4b6cdf1d7d2826fd5e9 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 16:38:16 -0800 Subject: [PATCH 07/14] fix disconnect type --- packages/fcl-ethereum-provider/src/types/provider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fcl-ethereum-provider/src/types/provider.ts b/packages/fcl-ethereum-provider/src/types/provider.ts index e079176fe..f2ae42a93 100644 --- a/packages/fcl-ethereum-provider/src/types/provider.ts +++ b/packages/fcl-ethereum-provider/src/types/provider.ts @@ -28,5 +28,5 @@ export interface Eip1193Provider { event: E, listener: EventCallback ): void - disconnect(): void + disconnect(): Promise } From 834a973ed8c9bb9c227598693e06d7183e0f5296 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 16:39:50 -0800 Subject: [PATCH 08/14] fixup --- packages/fcl-rainbowkit-adapter/README.md | 16 +--------------- packages/fcl-rainbowkit-adapter/package.json | 2 +- packages/fcl-wagmi-adapter/README.md | 16 +--------------- 3 files changed, 3 insertions(+), 31 deletions(-) diff --git a/packages/fcl-rainbowkit-adapter/README.md b/packages/fcl-rainbowkit-adapter/README.md index 28b95b8f6..ad868842a 100644 --- a/packages/fcl-rainbowkit-adapter/README.md +++ b/packages/fcl-rainbowkit-adapter/README.md @@ -1,15 +1 @@ -# @onflow/fcl-ethereum-provider - -Lightweight utility for transport-agnostic, bidirectional RPC communication. - -# Status - -- **Last Updated:** Aug 20th, 2025 -- **Stable:** No -- **Risk of Breaking Change:** Yes - -# Install - -```bash -npm install --save @onflow/fcl-ethereum-provider -``` \ No newline at end of file +# @onflow/fcl-rainbowkit-adapter diff --git a/packages/fcl-rainbowkit-adapter/package.json b/packages/fcl-rainbowkit-adapter/package.json index c22b5e7e0..30406fa2d 100644 --- a/packages/fcl-rainbowkit-adapter/package.json +++ b/packages/fcl-rainbowkit-adapter/package.json @@ -1,7 +1,7 @@ { "name": "@onflow/fcl-rainbowkit-adapter", "version": "0.0.0", - "description": "Wagmi adapter for FCL-compatible wallets", + "description": "Rainbowkit adapter for FCL-compatible wallets", "license": "Apache-2.0", "author": "Dapper Labs ", "homepage": "https://onflow.org", diff --git a/packages/fcl-wagmi-adapter/README.md b/packages/fcl-wagmi-adapter/README.md index 28b95b8f6..7e305a98b 100644 --- a/packages/fcl-wagmi-adapter/README.md +++ b/packages/fcl-wagmi-adapter/README.md @@ -1,15 +1 @@ -# @onflow/fcl-ethereum-provider - -Lightweight utility for transport-agnostic, bidirectional RPC communication. - -# Status - -- **Last Updated:** Aug 20th, 2025 -- **Stable:** No -- **Risk of Breaking Change:** Yes - -# Install - -```bash -npm install --save @onflow/fcl-ethereum-provider -``` \ No newline at end of file +# @onflow/fcl-wagmi-adapter \ No newline at end of file From 144e63c18647a9e5ea136b7c09568e68b06a60eb Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 16:40:45 -0800 Subject: [PATCH 09/14] fix peer dep vsn --- packages/fcl-ethereum-provider/package.json | 2 +- packages/fcl-rainbowkit-adapter/package.json | 2 +- packages/fcl-wagmi-adapter/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/fcl-ethereum-provider/package.json b/packages/fcl-ethereum-provider/package.json index cf9c0a0c5..3cd7ea871 100644 --- a/packages/fcl-ethereum-provider/package.json +++ b/packages/fcl-ethereum-provider/package.json @@ -45,6 +45,6 @@ "@walletconnect/jsonrpc-provider": "^1.0.14" }, "peerDependencies": { - "@onflow/fcl": "1.13.4" + "@onflow/fcl": "^1.13.4" } } diff --git a/packages/fcl-rainbowkit-adapter/package.json b/packages/fcl-rainbowkit-adapter/package.json index 30406fa2d..8998b5a3a 100644 --- a/packages/fcl-rainbowkit-adapter/package.json +++ b/packages/fcl-rainbowkit-adapter/package.json @@ -48,7 +48,7 @@ "viem": "^2.22.21" }, "peerDependencies": { - "@onflow/fcl": "1.13.4", + "@onflow/fcl": "^1.13.4", "@rainbow-me/rainbowkit": "^2.2.3" } } diff --git a/packages/fcl-wagmi-adapter/package.json b/packages/fcl-wagmi-adapter/package.json index 4188cf404..27dcc5ce2 100644 --- a/packages/fcl-wagmi-adapter/package.json +++ b/packages/fcl-wagmi-adapter/package.json @@ -46,7 +46,7 @@ "viem": "^2.22.21" }, "peerDependencies": { - "@onflow/fcl": "1.13.4", + "@onflow/fcl": "^1.13.4", "@wagmi/core": "^2.16.3" } } From ade3a6b7ab2a874eb02bbdeb426e0a00c233a2f3 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 16:59:08 -0800 Subject: [PATCH 10/14] fix build hack --- .../fcl-bundle/src/build/get-input-options.js | 26 +++++-------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/packages/fcl-bundle/src/build/get-input-options.js b/packages/fcl-bundle/src/build/get-input-options.js index c42c4b2b0..861a034c6 100644 --- a/packages/fcl-bundle/src/build/get-input-options.js +++ b/packages/fcl-bundle/src/build/get-input-options.js @@ -44,28 +44,14 @@ module.exports = function getInputOptions(package, build) { .concat(Object.keys(package.dependencies || {})) let testExternal = id => { - let res = - build.type !== "umd" && - (/@babel\/runtime/g.test(id) || - external.reduce((state, ext) => { - return ( - state || - (ext instanceof RegExp && ext.test(id)) || - (typeof ext === "string" && ext === id) - ) - }, false)) - - // TODO: REMOVE HACK - if ( - id.startsWith("@ethersproject") || - id.startsWith("@noble") || - id.startsWith("@wagmi") || - id.startsWith("viem") - ) { - res = true + if (build.type !== "umd" && /@babel\/runtime/g.test(id)) return true + + for (let ext of external) { + if (ext instanceof RegExp && ext.test(id)) return true + if (typeof ext === "string" && id.startsWith(ext)) return true } - return res + return false } // exclude peer dependencies From b9c932f8f9ec4571360c3fc6946a6fcf6438f3c2 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Thu, 6 Feb 2025 23:38:00 -0800 Subject: [PATCH 11/14] fix chain ID --- package-lock.json | 6 +- .../src/rpc/handlers/eth-chain-id.test.ts | 8 +- .../src/rpc/handlers/eth-chain-id.ts | 12 +- .../src/rpc/rpc-processor.ts | 2 +- packages/fcl-wagmi-adapter/src/index.ts | 238 ++++++------------ 5 files changed, 85 insertions(+), 181 deletions(-) diff --git a/package-lock.json b/package-lock.json index 858b20412..c4ae5c935 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31347,7 +31347,7 @@ "jest": "^29.7.0" }, "peerDependencies": { - "@onflow/fcl": "1.13.4" + "@onflow/fcl": "^1.13.4" } }, "packages/fcl-rainbowkit-adapter": { @@ -31378,7 +31378,7 @@ "jest": "^29.7.0" }, "peerDependencies": { - "@onflow/fcl": "1.13.4", + "@onflow/fcl": "^1.13.4", "@rainbow-me/rainbowkit": "^2.2.3" } }, @@ -31669,7 +31669,7 @@ "jest": "^29.7.0" }, "peerDependencies": { - "@onflow/fcl": "1.13.4", + "@onflow/fcl": "^1.13.4", "@wagmi/core": "^2.16.3" } }, diff --git a/packages/fcl-ethereum-provider/src/rpc/handlers/eth-chain-id.test.ts b/packages/fcl-ethereum-provider/src/rpc/handlers/eth-chain-id.test.ts index 94d6e578f..212f4cbfc 100644 --- a/packages/fcl-ethereum-provider/src/rpc/handlers/eth-chain-id.test.ts +++ b/packages/fcl-ethereum-provider/src/rpc/handlers/eth-chain-id.test.ts @@ -1,4 +1,4 @@ -import {formatChainId} from "../../util/eth" +import {NetworkManager} from "../../network/network-manager" import {ethChainId} from "./eth-chain-id" jest.mock("../../util/eth", () => ({ @@ -13,7 +13,7 @@ describe("eth_chainId handler", () => { } networkManagerMock.getChainId.mockResolvedValue(747) - const chainId = await ethChainId(networkManagerMock as any)() + const chainId = await ethChainId(networkManagerMock as any) expect(chainId).toEqual("0x747") expect(networkManagerMock.getChainId).toHaveBeenCalled() @@ -22,10 +22,10 @@ describe("eth_chainId handler", () => { test("should throw an error if no chain id is available", async () => { const networkManagerMock = { getChainId: jest.fn(), - } + } as unknown as jest.Mocked networkManagerMock.getChainId.mockResolvedValue(null) - await expect(ethChainId(networkManagerMock as any)()).rejects.toThrow( + await expect(ethChainId(networkManagerMock)).rejects.toThrow( "No active chain" ) expect(networkManagerMock.getChainId).toHaveBeenCalled() diff --git a/packages/fcl-ethereum-provider/src/rpc/handlers/eth-chain-id.ts b/packages/fcl-ethereum-provider/src/rpc/handlers/eth-chain-id.ts index 9246bcfe3..4614af03e 100644 --- a/packages/fcl-ethereum-provider/src/rpc/handlers/eth-chain-id.ts +++ b/packages/fcl-ethereum-provider/src/rpc/handlers/eth-chain-id.ts @@ -1,12 +1,10 @@ import {NetworkManager} from "../../network/network-manager" import {formatChainId} from "../../util/eth" -export function ethChainId(networkManager: NetworkManager) { - return async function () { - const chainId = await networkManager.getChainId() - if (!chainId) { - throw new Error("No active chain") - } - return formatChainId(chainId) +export async function ethChainId(networkManager: NetworkManager) { + const chainId = await networkManager.getChainId() + if (!chainId) { + throw new Error("No active chain") } + return formatChainId(chainId) } diff --git a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.ts b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.ts index ba50102b7..c153c8c43 100644 --- a/packages/fcl-ethereum-provider/src/rpc/rpc-processor.ts +++ b/packages/fcl-ethereum-provider/src/rpc/rpc-processor.ts @@ -88,7 +88,7 @@ export class RpcProcessor { const switchParams = params[0] as SwitchEthereumChainParams return await this.networkManager.switchChain(switchParams) case "eth_chainId": - return ethChainId(this.networkManager) + return await ethChainId(this.networkManager) default: return await this.gateway.request({ chainId, diff --git a/packages/fcl-wagmi-adapter/src/index.ts b/packages/fcl-wagmi-adapter/src/index.ts index 73c28af31..5429598e5 100644 --- a/packages/fcl-wagmi-adapter/src/index.ts +++ b/packages/fcl-wagmi-adapter/src/index.ts @@ -4,19 +4,12 @@ import { createConnector, } from "@wagmi/core" import { - type AddEthereumChainParameter, type Address, - type Hex, type ProviderConnectInfo, ProviderDisconnectedError, - type ProviderRpcError, - type RpcError, SwitchChainError, - UserRejectedRequestError, getAddress, - hexToNumber, numberToHex, - withRetry, } from "viem" import {createProvider} from "@onflow/fcl-ethereum-provider" @@ -47,21 +40,18 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { async setup() { const provider = await this.getProvider() - if (provider?.on) { - if (!connect) { - connect = this.onConnect.bind(this) - provider.on("connect", connect) - } + if (connect) provider.removeListener("connect", connect) + connect = this.onConnect.bind(this) + provider.on("connect", connect) - // We shouldn't need to listen for `'accountsChanged'` here since the `'connect'` event should suffice (and wallet shouldn't be connected yet). - // Some wallets, like MetaMask, do not implement the `'connect'` event and overload `'accountsChanged'` instead. - if (!accountsChanged) { - accountsChanged = this.onAccountsChanged.bind(this) - provider.on("accountsChanged", accountsChanged) - } + // We shouldn't need to listen for `'accountsChanged'` here since the `'connect'` event should suffice (and wallet shouldn't be connected yet). + // Some wallets, like MetaMask, do not implement the `'connect'` event and overload `'accountsChanged'` instead. + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on("accountsChanged", accountsChanged) } }, - async connect({chainId, isReconnecting}: any = {}) { + async connect({isReconnecting}: any = {}) { const provider = await this.getProvider() /* TODO: This will be solved as part of the WalletConnect integration. @@ -73,34 +63,41 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { */ - let accounts: readonly Address[] = await provider.request({ - method: "eth_requestAccounts", - }) - - if (isReconnecting) accounts = await this.getAccounts() + let accounts: readonly Address[] + if (isReconnecting) { + accounts = await this.getAccounts() + } else { + accounts = ( + (await provider.request({ + method: "eth_requestAccounts", + })) as string[] + ).map(x => getAddress(x)) + } // Manage EIP-1193 event listeners // https://eips.ethereum.org/EIPS/eip-1193#events - if (connect) { - provider.removeListener("connect", connect) - connect = undefined - } - if (!accountsChanged) { - accountsChanged = this.onAccountsChanged.bind(this) - provider.on("accountsChanged", accountsChanged) - } - if (!chainChanged) { - chainChanged = this.onChainChanged.bind(this) - provider.on("chainChanged", chainChanged) - } - if (!disconnect) { - disconnect = (({reason}) => { - throw new ProviderDisconnectedError(new Error(reason)) - }) as ({reason}: {reason: string}) => void - provider.on("disconnect", disconnect) - } + if (connect) provider.removeListener("connect", connect) + connect = this.onConnect.bind(this) + provider.on("connect", connect) + + if (accountsChanged) + provider.removeListener("accountsChanged", accountsChanged) + accountsChanged = this.onAccountsChanged.bind(this) + provider.on("accountsChanged", accountsChanged) + + if (chainChanged) provider.removeListener("chainChanged", chainChanged) + chainChanged = this.onChainChanged.bind(this) + provider.on("chainChanged", chainChanged) + + if (disconnect) provider.removeListener("disconnect", disconnect) + disconnect = (({reason}) => { + throw new ProviderDisconnectedError(new Error(reason)) + }) as ({reason}: {reason: string}) => void + provider.on("disconnect", disconnect) - return {accounts, chainId} + console.log("EH CURRENT FUUU", await this.getChainId()) + + return {accounts, chainId: await this.getChainId()} }, async disconnect() { const provider = await this.getProvider() @@ -130,7 +127,8 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { }, async getChainId() { const provider = await this.getProvider() - const chainId = await provider?.request({method: "eth_chainId"}) + const chainId = await provider.request({method: "eth_chainId"}) + console.log("CHAIN ID", chainId) return Number(chainId) }, async getProvider() { @@ -140,9 +138,11 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { // TODO: There may be an issue here if a user without a COA refreshes the page // We should instead be checking whether FCL itself is authorized const accounts = await this.getAccounts() + console.log("RETURNING", accounts.length > 0) return accounts.length > 0 }, async switchChain({addEthereumChainParameter, chainId}: any) { + console.log("HEY") const provider = await this.getProvider() const chain = config.chains.find(x => x.id === chainId) @@ -154,152 +154,58 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { params: [{chainId: numberToHex(chainId)}], }) - // During `'wallet_switchEthereumChain'`, MetaMask makes a `'net_version'` RPC call to the target chain. - // If this request fails, MetaMask does not emit the `'chainChanged'` event, but will still switch the chain. - // To counter this behavior, we request and emit the current chain ID to confirm the chain switch either via - // this callback or an externally emitted `'chainChanged'` event. - // https://github.com/MetaMask/metamask-extension/issues/24247 - await waitForChainIdToSync() - await sendAndWaitForChangeEvent(chainId) - return chain } catch (err) { - const error = err as RpcError - - if (error.code === UserRejectedRequestError.code) - throw new UserRejectedRequestError(error) - - // Indicates chain is not added to provider - if ( - error.code === 4902 || - // Unwrapping for MetaMask Mobile - // https://github.com/MetaMask/metamask-mobile/issues/2944#issuecomment-976988719 - (error as ProviderRpcError<{originalError?: {code: number}}>)?.data - ?.originalError?.code === 4902 - ) { - try { - await provider.request({ - method: "wallet_addEthereumChain", - params: [ - { - blockExplorerUrls: (() => { - const {default: blockExplorer, ...blockExplorers} = - chain.blockExplorers ?? {} - if (addEthereumChainParameter?.blockExplorerUrls) - return addEthereumChainParameter.blockExplorerUrls - if (blockExplorer) - return [ - blockExplorer.url, - ...Object.values(blockExplorers).map(x => x.url), - ] - return - })(), - chainId: numberToHex(chainId), - chainName: addEthereumChainParameter?.chainName ?? chain.name, - iconUrls: addEthereumChainParameter?.iconUrls, - nativeCurrency: - addEthereumChainParameter?.nativeCurrency ?? - chain.nativeCurrency, - rpcUrls: (() => { - if (addEthereumChainParameter?.rpcUrls?.length) - return addEthereumChainParameter.rpcUrls - return [chain.rpcUrls.default?.http[0] ?? ""] - })(), - } satisfies AddEthereumChainParameter, - ], - }) - - await waitForChainIdToSync() - await sendAndWaitForChangeEvent(chainId) - - return chain - } catch (err) { - const error = err as RpcError - if (error.code === UserRejectedRequestError.code) - throw new UserRejectedRequestError(error) - throw new SwitchChainError(error) - } - } - - throw new SwitchChainError(error) - } - - async function waitForChainIdToSync() { - // On mobile, there is a race condition between the result of `'wallet_addEthereumChain'` and `'eth_chainId'`. - // To avoid this, we wait for `'eth_chainId'` to return the expected chain ID with a retry loop. - await withRetry( - async () => { - const value = hexToNumber( - // `'eth_chainId'` is cached by the MetaMask SDK side to avoid unnecessary deeplinks - (await provider.request({method: "eth_chainId"})) as Hex - ) - // `value` doesn't match expected `chainId`, throw to trigger retry - if (value !== chainId) - throw new Error("User rejected switch after adding network.") - return value - }, - { - delay: 50, - retryCount: 20, // android device encryption is slower - } - ) - } - - async function sendAndWaitForChangeEvent(chainId: number) { - await new Promise(resolve => { - const listener = (data => { - if ("chainId" in data && data.chainId === chainId) { - config.emitter.off("change", listener) - resolve() - } - }) satisfies Parameters[1] - config.emitter.on("change", listener) - config.emitter.emit("change", {chainId}) - }) + // TODO: Error handling + throw new SwitchChainError(err as Error) } }, - onAccountsChanged(accounts: any) { + onAccountsChanged(accounts) { if (accounts.length === 0) this.onDisconnect() else config.emitter.emit("change", { accounts: accounts.map((x: any) => getAddress(x)), }) }, - onChainChanged(chain: any) { + onChainChanged(chain) { const chainId = Number(chain) config.emitter.emit("change", {chainId}) }, - async onConnect(connectInfo: any) { + async onConnect(connectInfo) { + console.log("HEY") const accounts = await this.getAccounts() // TODO: What to do if accounts is empty? not sure this is accurate if (accounts.length === 0) return + console.log({accounts, chainId: Number(connectInfo.chainId)}) + const chainId = Number(connectInfo.chainId) + console.log("onConnect", {accounts, chainId}) config.emitter.emit("connect", {accounts, chainId}) const provider = await this.getProvider() - if (connect) { - provider.removeListener("connect", connect) - connect = undefined - } - if (!accountsChanged) { - accountsChanged = this.onAccountsChanged.bind(this) - provider.on("accountsChanged", accountsChanged) - } - if (!chainChanged) { - chainChanged = this.onChainChanged.bind(this) - provider.on("chainChanged", chainChanged) - } - if (!disconnect) { - disconnect = (({reason}) => { - throw new ProviderDisconnectedError(new Error(reason)) - }) as ({reason}: {reason: string}) => void - provider.on("disconnect", disconnect) - } + + if (connect) provider.removeListener("connect", connect) + connect = undefined + + if (accountsChanged) + provider.removeListener("accountsChanged", accountsChanged) + accountsChanged = this.onAccountsChanged.bind(this) + provider.on("accountsChanged", accountsChanged) + + if (chainChanged) provider.removeListener("chainChanged", chainChanged) + chainChanged = this.onChainChanged.bind(this) + provider.on("chainChanged", chainChanged) + + if (disconnect) provider.removeListener("disconnect", disconnect) + disconnect = (({reason}) => { + throw new ProviderDisconnectedError(new Error(reason)) + }) as ({reason}: {reason: string}) => void + provider.on("disconnect", disconnect) }, // TODO: waht to do with error? - async onDisconnect(error: any) { + async onDisconnect(error) { const provider = await this.getProvider() config.emitter.emit("disconnect") From 4c577c4b5ea57c7203cb386d2e1c243f4001fab5 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Fri, 7 Feb 2025 01:06:55 -0800 Subject: [PATCH 12/14] cleanup --- packages/fcl-wagmi-adapter/src/index.ts | 38 ++++++------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/packages/fcl-wagmi-adapter/src/index.ts b/packages/fcl-wagmi-adapter/src/index.ts index 5429598e5..ef82c438f 100644 --- a/packages/fcl-wagmi-adapter/src/index.ts +++ b/packages/fcl-wagmi-adapter/src/index.ts @@ -26,7 +26,6 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { let accountsChanged: Connector["onAccountsChanged"] | undefined let chainChanged: Connector["onChainChanged"] | undefined let connect: Connector["onConnect"] | undefined - let displayUri: ((uri: string) => void) | undefined let disconnect: (({reason}: {reason: string}) => void) | undefined // Parse and validate service parameters @@ -53,15 +52,6 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { }, async connect({isReconnecting}: any = {}) { const provider = await this.getProvider() - /* - TODO: This will be solved as part of the WalletConnect integration. - - if (!displayUri) { - displayUri = this.onDisplayUri - provider.on("display_uri", displayUri) - } - - */ let accounts: readonly Address[] if (isReconnecting) { @@ -95,26 +85,21 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { }) as ({reason}: {reason: string}) => void provider.on("disconnect", disconnect) - console.log("EH CURRENT FUUU", await this.getChainId()) - return {accounts, chainId: await this.getChainId()} }, async disconnect() { const provider = await this.getProvider() // Manage EIP-1193 event listeners - if (chainChanged) { - provider.removeListener("chainChanged", chainChanged) - chainChanged = undefined - } - if (disconnect) { - provider.removeListener("disconnect", disconnect) - disconnect = undefined - } - if (!connect) { - connect = this.onConnect.bind(this) - provider.on("connect", connect) - } + if (chainChanged) provider.removeListener("chainChanged", chainChanged) + chainChanged = undefined + + if (disconnect) provider.removeListener("disconnect", disconnect) + disconnect = undefined + + if (connect) provider.removeListener("connect", connect) + connect = this.onConnect.bind(this) + provider.on("connect", connect) await provider.disconnect() }, @@ -138,7 +123,6 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { // TODO: There may be an issue here if a user without a COA refreshes the page // We should instead be checking whether FCL itself is authorized const accounts = await this.getAccounts() - console.log("RETURNING", accounts.length > 0) return accounts.length > 0 }, async switchChain({addEthereumChainParameter, chainId}: any) { @@ -172,16 +156,12 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { config.emitter.emit("change", {chainId}) }, async onConnect(connectInfo) { - console.log("HEY") const accounts = await this.getAccounts() // TODO: What to do if accounts is empty? not sure this is accurate if (accounts.length === 0) return - console.log({accounts, chainId: Number(connectInfo.chainId)}) - const chainId = Number(connectInfo.chainId) - console.log("onConnect", {accounts, chainId}) config.emitter.emit("connect", {accounts, chainId}) const provider = await this.getProvider() From 443ed2e5fd18cb77a85266e888b27a744238ae98 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Fri, 7 Feb 2025 02:07:01 -0800 Subject: [PATCH 13/14] very good first pass --- packages/fcl-rainbowkit-adapter/src/index.ts | 3 +-- packages/fcl-wagmi-adapter/src/index.ts | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/fcl-rainbowkit-adapter/src/index.ts b/packages/fcl-rainbowkit-adapter/src/index.ts index a0496257b..00ad8b1bc 100644 --- a/packages/fcl-rainbowkit-adapter/src/index.ts +++ b/packages/fcl-rainbowkit-adapter/src/index.ts @@ -15,13 +15,12 @@ export const createFclConnector = (options: FclConnectorOptions) => { const uid = options.service?.uid const name = options.service?.provider?.name const iconUrl = options.service?.provider?.icon! - const iconBackground = options.service?.provider?.color return ({projectId}: DefaultWalletOptions): Wallet => ({ id: uid ? `fcl-${uid}` : "fcl", name: name || "Cadence Wallet", iconUrl: iconUrl || FALLBACK_ICON, - iconBackground: iconBackground || "#FFFFFF", + iconBackground: "#FFFFFF", createConnector: walletDetails => { const connector = fclWagmiAdapter(options) return createConnector(config => ({ diff --git a/packages/fcl-wagmi-adapter/src/index.ts b/packages/fcl-wagmi-adapter/src/index.ts index ef82c438f..615c512ad 100644 --- a/packages/fcl-wagmi-adapter/src/index.ts +++ b/packages/fcl-wagmi-adapter/src/index.ts @@ -32,10 +32,14 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) { const id = params.service?.uid || "fcl" const name = params.service?.provider?.name || "Cadence Wallet" + // TODO: we need to surface this through FCL service configuration + const rdns = (params.service?.provider as any)?.rdns + return createConnector(config => ({ id: id, name: name, type: "fcl-wagmi-adapter", + rdns: rdns, async setup() { const provider = await this.getProvider() From 85e033301ae22db28e960ee14f104794cfb64339 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Fri, 7 Feb 2025 16:12:03 -0800 Subject: [PATCH 14/14] prettier --- .../fcl-ethereum-provider/src/accounts/account-manager.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/fcl-ethereum-provider/src/accounts/account-manager.ts b/packages/fcl-ethereum-provider/src/accounts/account-manager.ts index f2fd9a1f4..3b327ff66 100644 --- a/packages/fcl-ethereum-provider/src/accounts/account-manager.ts +++ b/packages/fcl-ethereum-provider/src/accounts/account-manager.ts @@ -1,6 +1,11 @@ import * as fcl from "@onflow/fcl" import * as rlp from "@onflow/rlp" -import {CompositeSignature, CurrentUser, Service, FvmErrorCode} from "@onflow/typedefs" +import { + CompositeSignature, + CurrentUser, + Service, + FvmErrorCode, +} from "@onflow/typedefs" import { EVENT_IDENTIFIERS, EventType,