@rhinestone/1auth 0.7.4 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/{chunk-IHBVEU33.mjs → chunk-6AHEN3FA.mjs} +1 -1
  2. package/dist/chunk-6AHEN3FA.mjs.map +1 -0
  3. package/dist/{chunk-UXBBB7AV.mjs → chunk-6MUQKHAT.mjs} +7 -31
  4. package/dist/chunk-6MUQKHAT.mjs.map +1 -0
  5. package/dist/{client-CuASptX3.d.ts → client-BqKAd2RZ.d.mts} +17 -17
  6. package/dist/{client-D4HVy1KF.d.mts → client-C9mcj5jN.d.ts} +17 -17
  7. package/dist/headless.d.mts +2 -2
  8. package/dist/headless.d.ts +2 -2
  9. package/dist/headless.js +4 -6
  10. package/dist/headless.js.map +1 -1
  11. package/dist/headless.mjs +4 -6
  12. package/dist/headless.mjs.map +1 -1
  13. package/dist/index.d.mts +12 -21
  14. package/dist/index.d.ts +12 -21
  15. package/dist/index.js +44 -99
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +40 -71
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/{provider-6JoziYDq.d.ts → provider-CCyUBseo.d.ts} +3 -3
  20. package/dist/{provider-CAQT7Gqx.d.mts → provider-CRhZVLg8.d.mts} +3 -3
  21. package/dist/react.d.mts +9 -4
  22. package/dist/react.d.ts +9 -4
  23. package/dist/react.js +4 -7
  24. package/dist/react.js.map +1 -1
  25. package/dist/react.mjs +4 -7
  26. package/dist/react.mjs.map +1 -1
  27. package/dist/server.d.mts +2 -2
  28. package/dist/server.d.ts +2 -2
  29. package/dist/server.js.map +1 -1
  30. package/dist/server.mjs +1 -1
  31. package/dist/{types-C0jKNT_t.d.mts → types-CbhPRY5s.d.mts} +23 -50
  32. package/dist/{types-C0jKNT_t.d.ts → types-CbhPRY5s.d.ts} +23 -50
  33. package/dist/{verify-CnOwPq78.d.ts → verify-DPJR_foR.d.ts} +4 -6
  34. package/dist/{verify-aWdi5O2z.d.mts → verify-DVYDJgOS.d.mts} +4 -6
  35. package/dist/wagmi.d.mts +3 -3
  36. package/dist/wagmi.d.ts +3 -3
  37. package/dist/wagmi.js +6 -30
  38. package/dist/wagmi.js.map +1 -1
  39. package/dist/wagmi.mjs +1 -1
  40. package/package.json +1 -1
  41. package/dist/chunk-IHBVEU33.mjs.map +0 -1
  42. package/dist/chunk-UXBBB7AV.mjs.map +0 -1
package/dist/wagmi.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/wagmi.ts","../src/provider.ts","../src/registry.ts","../src/walletClient/utils.ts"],"sourcesContent":["/**\n * Wagmi connector factory for 1auth passkey authentication.\n *\n * Wraps `createOneAuthProvider` in a wagmi-compatible connector so that\n * passkey-based accounts can participate in the full wagmi ecosystem:\n * `useAccount`, `useConnect`, `useSendTransaction`, hooks, and so on.\n *\n * Import path: `@rhinestone/1auth/wagmi`\n *\n * @module\n */\n\nimport { createConnector, type Connector } from \"@wagmi/core\";\nimport {\n numberToHex,\n type Address,\n type Chain,\n type ProviderConnectInfo,\n} from \"viem\";\nimport { createOneAuthProvider, type OneAuthProvider } from \"./provider\";\nimport type { OneAuthClient } from \"./client\";\n\nexport type OneAuthConnectorOptions = {\n client: OneAuthClient;\n chainId?: number;\n storageKey?: string;\n waitForHash?: boolean;\n hashTimeoutMs?: number;\n hashIntervalMs?: number;\n};\n\n/**\n * Creates a wagmi connector backed by 1auth passkey authentication.\n *\n * The connector lazily instantiates a single `OneAuthProvider` on the first call to\n * `getProvider()` and reuses it for the lifetime of the wagmi config. Event listeners\n * (`accountsChanged`, `chainChanged`, `disconnect`) are attached on connect and torn\n * down on disconnect to prevent memory leaks.\n *\n * @param options - Connector configuration\n * @param options.client - Configured `OneAuthClient` instance\n * @param options.chainId - Override the initial chain ID. When omitted the first chain\n * in the wagmi config's `chains` array is used.\n * @param options.storageKey - localStorage key for persisting the connected user.\n * Forwarded to `createOneAuthProvider`. Defaults to `\"1auth-user\"`.\n * @param options.waitForHash - When true, `sendTransaction` waits for a tx hash before\n * resolving. Forwarded to `createOneAuthProvider`. Defaults to true.\n * @param options.hashTimeoutMs - Maximum milliseconds to wait for a transaction hash.\n * @param options.hashIntervalMs - Polling interval when waiting for a hash.\n * @returns A wagmi connector factory function (pass directly to wagmi `createConfig`)\n *\n * @example\n * ```typescript\n * import { createConfig } from \"wagmi\";\n * import { base, optimism } from \"viem/chains\";\n * import { oneAuth } from \"@rhinestone/1auth/wagmi\";\n * import { OneAuthClient } from \"@rhinestone/1auth\";\n *\n * const client = new OneAuthClient({ clientId: \"my-app\" });\n *\n * export const wagmiConfig = createConfig({\n * chains: [base, optimism],\n * connectors: [\n * oneAuth({ client }),\n * ],\n * });\n * ```\n */\nexport function oneAuth(options: OneAuthConnectorOptions) {\n type Provider = OneAuthProvider;\n\n return createConnector<Provider>((wagmiConfig) => {\n const chains = (wagmiConfig.chains ?? []) as readonly [Chain, ...Chain[]];\n const initialChainId = options.chainId ?? chains[0]?.id;\n\n let provider: Provider | null = null;\n // Bound listener references held so they can be removed by name during disconnect\n let accountsChanged: Connector[\"onAccountsChanged\"] | undefined;\n let chainChanged: Connector[\"onChainChanged\"] | undefined;\n let connect: Connector[\"onConnect\"] | undefined;\n let disconnect: Connector[\"onDisconnect\"] | undefined;\n\n return {\n id: \"1auth\",\n name: \"1auth Passkey\",\n type: \"wallet\",\n\n /**\n * Connects the user and registers provider event listeners.\n *\n * On reconnect (`isReconnecting: true`) attempts to restore accounts from\n * localStorage silently before falling back to the connect modal. Switches to\n * the requested `chainId` if it differs from the provider's current chain.\n * Removes the one-time `connect` listener after the first connection so it is\n * not triggered again on subsequent reconnects.\n *\n * @param params.chainId - Optional chain to switch to after connecting\n * @param params.isReconnecting - True when wagmi is restoring a previous session\n * @param params.withCapabilities - When true, returns accounts with capability maps\n * @returns Connected accounts and the active chain ID\n * @throws If no chain is configured or the user cancels the auth flow\n */\n async connect<withCapabilities extends boolean = false>(\n { chainId, isReconnecting, withCapabilities }:\n | {\n chainId?: number;\n isReconnecting?: boolean;\n withCapabilities?: withCapabilities | boolean;\n }\n | undefined = {}\n ): Promise<{\n accounts: withCapabilities extends true\n ? readonly { address: Address; capabilities: Record<string, unknown> }[]\n : readonly Address[];\n chainId: number;\n }> {\n if (!initialChainId) {\n throw new Error(\"No chain configured for 1auth connector\");\n }\n\n const provider = await this.getProvider({ chainId });\n let accounts: readonly Address[] = [];\n let currentChainId = await this.getChainId();\n\n if (isReconnecting) {\n accounts = await this.getAccounts().catch(() => []);\n }\n\n if (!accounts.length) {\n accounts = (await provider.request({\n method: \"wallet_connect\",\n })) as Address[];\n currentChainId = await this.getChainId();\n }\n\n if (chainId && currentChainId !== chainId) {\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: numberToHex(chainId) }],\n });\n currentChainId = await this.getChainId();\n }\n\n // Remove the one-time connect listener now that connection is established\n if (connect) {\n provider.removeListener(\"connect\", connect as never);\n connect = undefined;\n }\n if (!accountsChanged) {\n accountsChanged = this.onAccountsChanged.bind(this);\n provider.on(\"accountsChanged\", accountsChanged as never);\n }\n if (!chainChanged) {\n chainChanged = this.onChainChanged.bind(this);\n provider.on(\"chainChanged\", chainChanged as never);\n }\n if (!disconnect) {\n disconnect = this.onDisconnect.bind(this);\n provider.on(\"disconnect\", disconnect as never);\n }\n\n const response = withCapabilities\n ? {\n accounts: accounts.map((account) => ({\n address: account,\n capabilities: {},\n })),\n chainId: currentChainId,\n }\n : {\n accounts,\n chainId: currentChainId,\n };\n\n return response as unknown as {\n accounts: withCapabilities extends true\n ? readonly { address: Address; capabilities: Record<string, unknown> }[]\n : readonly Address[];\n chainId: number;\n };\n },\n\n /**\n * Disconnects the user and removes `chainChanged` / `disconnect` event listeners.\n *\n * The `accountsChanged` listener is intentionally left attached so that wagmi\n * receives the empty-accounts event emitted by the underlying provider's\n * `clearStoredUser` path.\n */\n async disconnect() {\n const provider = await this.getProvider();\n await provider.disconnect();\n if (chainChanged) {\n provider.removeListener(\"chainChanged\", chainChanged as never);\n chainChanged = undefined;\n }\n if (disconnect) {\n provider.removeListener(\"disconnect\", disconnect as never);\n disconnect = undefined;\n }\n },\n\n /**\n * Returns the list of currently connected account addresses.\n *\n * Delegates to `eth_accounts` on the underlying provider, which reads from\n * localStorage without opening any dialogs.\n *\n * @returns Array of connected addresses (empty if not connected)\n */\n async getAccounts() {\n const provider = await this.getProvider();\n return (await provider.request({\n method: \"eth_accounts\",\n })) as Address[];\n },\n\n /**\n * Returns the current chain ID as a number.\n *\n * Calls `eth_chainId` on the underlying provider and converts the hex result.\n *\n * @returns The numeric chain ID\n */\n async getChainId() {\n const provider = await this.getProvider();\n const hexChainId = (await provider.request({\n method: \"eth_chainId\",\n })) as string;\n return Number.parseInt(hexChainId, 16);\n },\n\n /**\n * Returns (and lazily creates) the underlying `OneAuthProvider` instance.\n *\n * The provider is a singleton per connector instance — created once and reused.\n * If a `chainId` argument is provided the provider switches to that chain before\n * returning.\n *\n * @param params.chainId - Optional chain ID to switch to before returning\n * @returns The singleton `OneAuthProvider`\n * @throws If no initial chain ID is configured\n */\n async getProvider({ chainId } = {}) {\n if (!provider) {\n if (!initialChainId) {\n throw new Error(\"No chain configured for 1auth connector\");\n }\n provider = createOneAuthProvider({\n client: options.client,\n chainId: initialChainId,\n storageKey: options.storageKey,\n waitForHash: options.waitForHash,\n hashTimeoutMs: options.hashTimeoutMs,\n hashIntervalMs: options.hashIntervalMs,\n });\n }\n if (chainId) {\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: numberToHex(chainId) }],\n });\n }\n return provider;\n },\n\n /**\n * Registers the one-time `connect` event listener used during initial setup.\n *\n * Called by wagmi during config initialization. Attaches `onConnect` to the\n * provider's `connect` event so that wagmi is notified if the user's session\n * is restored from localStorage before an explicit `connect()` call.\n */\n async setup() {\n const provider = await this.getProvider();\n if (!connect) {\n const onConnect = this.onConnect?.bind(this);\n if (onConnect) {\n connect = onConnect;\n provider.on(\"connect\", connect as never);\n }\n }\n },\n\n /**\n * Returns whether the connector has a valid stored session.\n *\n * Used by wagmi on startup to decide whether to attempt auto-reconnect.\n * Returns false (rather than throwing) if account resolution fails.\n *\n * @returns True if at least one account address is available\n */\n async isAuthorized() {\n try {\n const accounts = await this.getAccounts();\n return accounts.length > 0;\n } catch {\n return false;\n }\n },\n\n /**\n * Switches the active chain on the underlying provider.\n *\n * Validates that the requested chain is present in the wagmi config before\n * issuing `wallet_switchEthereumChain` so that an informative error is thrown\n * rather than a silent failure.\n *\n * @param params.chainId - The numeric ID of the chain to switch to\n * @returns The `Chain` object from wagmi config for the new chain\n * @throws If the chain is not in the wagmi config's `chains` array\n */\n async switchChain({ chainId }) {\n const chain = chains.find((chain) => chain.id === chainId);\n if (!chain) {\n throw new Error(\"Chain not configured\");\n }\n const provider = await this.getProvider();\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: numberToHex(chainId) }],\n });\n return chain;\n },\n\n /**\n * Handles the provider `connect` event and forwards it to wagmi's emitter.\n *\n * Called once during the initial connection handshake. Resolves the current\n * accounts and emits a wagmi `connect` event with both accounts and chain ID.\n *\n * @param connectInfo - EIP-1193 connect info containing the hex chain ID\n */\n async onConnect(connectInfo: ProviderConnectInfo) {\n const accounts = await this.getAccounts();\n if (!accounts.length) return;\n const chainId = Number(connectInfo.chainId);\n wagmiConfig.emitter.emit(\"connect\", { accounts, chainId });\n },\n\n /**\n * Handles the provider `accountsChanged` event and forwards it to wagmi.\n *\n * @param accounts - Updated list of account address strings\n */\n onAccountsChanged(accounts: string[]) {\n wagmiConfig.emitter.emit(\"change\", {\n accounts: accounts as Address[],\n });\n },\n\n /**\n * Handles the provider `chainChanged` event and forwards it to wagmi.\n *\n * @param chainId - The new chain ID as a hex string or decimal string\n */\n onChainChanged(chainId: string) {\n wagmiConfig.emitter.emit(\"change\", {\n chainId: Number(chainId),\n });\n },\n\n /**\n * Handles the provider `disconnect` event and forwards it to wagmi.\n *\n * @param _error - Optional error that caused the disconnection (unused)\n */\n onDisconnect(_error?: Error) {\n wagmiConfig.emitter.emit(\"disconnect\");\n },\n };\n });\n}\n","/**\n * EIP-1193 JSON-RPC provider factory for the 1auth passkey authentication system.\n *\n * Creates a browser-side provider object that implements the EIP-1193 standard so any\n * Ethereum library (ethers, viem, wagmi) can use 1auth passkey signing and cross-chain\n * intent execution without modification. All transaction signing is delegated to the\n * passkey service rather than holding private keys in the browser.\n *\n * Supported RPC methods:\n * - eth_chainId, eth_accounts, eth_requestAccounts\n * - personal_sign, eth_sign, eth_signTypedData, eth_signTypedData_v4\n * - eth_sendTransaction\n * - wallet_connect, wallet_disconnect, wallet_switchEthereumChain\n * - wallet_sendCalls, wallet_getCallsStatus, wallet_getCallsHistory (EIP-5792)\n * - wallet_getCapabilities, wallet_getAssets\n *\n * @module\n */\n\nimport {\n hexToString,\n isHex,\n numberToHex,\n type Address,\n type Hex,\n} from \"viem\";\nimport { OneAuthClient } from \"./client\";\nimport { getSupportedChainIds } from \"./registry\";\nimport type { CloseOnStatus, IntentCall, IntentTokenRequest, SignerType } from \"./types\";\nimport { encodeWebAuthnSignature } from \"./walletClient/utils\";\n\ntype ProviderRequest = {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n};\n\ntype Listener = (...args: unknown[]) => void;\n\ntype StoredUser = {\n username?: string;\n address: Address;\n /** Absent = legacy passkey user; populated on new sessions. */\n signerType?: SignerType;\n /** Wagmi connector id for EOA sessions. Iframe-side lookup uses this. */\n connectorId?: string;\n};\n\nexport type OneAuthProvider = {\n request: (args: ProviderRequest) => Promise<unknown>;\n on: (event: string, listener: Listener) => void;\n removeListener: (event: string, listener: Listener) => void;\n disconnect: () => Promise<void>;\n};\n\nexport type OneAuthProviderOptions = {\n client: OneAuthClient;\n chainId: number;\n storageKey?: string;\n /** When to close the dialog and return success. Defaults to \"preconfirmed\" */\n closeOn?: CloseOnStatus;\n waitForHash?: boolean;\n hashTimeoutMs?: number;\n hashIntervalMs?: number;\n};\n\nconst DEFAULT_STORAGE_KEY = \"1auth-user\";\n\n/**\n * Creates an EIP-1193 compatible JSON-RPC provider backed by 1auth passkey authentication.\n *\n * The returned provider object can be used anywhere a standard Ethereum provider is\n * accepted (e.g. passed to `createWalletClient` in viem, used as `window.ethereum`, or\n * supplied to ethers.js `BrowserProvider`). Connection state (address + username) is\n * persisted in `localStorage` under the configured `storageKey`.\n *\n * @param options - Provider configuration\n * @param options.client - Configured `OneAuthClient` instance used to open auth/sign dialogs\n * @param options.chainId - Default chain ID the provider reports via `eth_chainId`\n * @param options.storageKey - localStorage key for persisting the connected user.\n * Defaults to `\"1auth-user\"`. Override to support multiple concurrent connections.\n * @param options.closeOn - Controls when the signing dialog closes and shows the \"Done\" button.\n * `\"preconfirmed\"` (default) closes as soon as the intent is confirmed by the orchestrator.\n * The `waitForHash` option independently controls whether the SDK continues polling for\n * a transaction hash after the dialog closes.\n * @param options.waitForHash - When true, polls the intent status until a transaction hash\n * is available before resolving `eth_sendTransaction` / `wallet_sendCalls`. Defaults to true.\n * @param options.hashTimeoutMs - Maximum milliseconds to wait for a transaction hash.\n * Passed directly to the passkey service intent submission.\n * @param options.hashIntervalMs - Polling interval in milliseconds when waiting for a hash.\n * Passed directly to the passkey service intent submission.\n * @returns An EIP-1193 provider with `request`, `on`, `removeListener`, and `disconnect`.\n *\n * @example\n * ```typescript\n * import { OneAuthClient } from \"@rhinestone/1auth\";\n * import { createOneAuthProvider } from \"@rhinestone/1auth\";\n *\n * const client = new OneAuthClient({ clientId: \"my-app\" });\n * const provider = createOneAuthProvider({ client, chainId: 8453 }); // Base\n *\n * // Use with viem\n * import { createWalletClient, custom } from \"viem\";\n * import { base } from \"viem/chains\";\n * const walletClient = createWalletClient({ chain: base, transport: custom(provider) });\n *\n * // Standard EIP-1193 usage\n * const accounts = await provider.request({ method: \"eth_requestAccounts\" });\n * provider.on(\"accountsChanged\", (accounts) => console.log(accounts));\n * ```\n */\nexport function createOneAuthProvider(\n options: OneAuthProviderOptions\n): OneAuthProvider {\n const { client } = options;\n let chainId = options.chainId;\n const storageKey = options.storageKey || DEFAULT_STORAGE_KEY;\n\n const listeners = new Map<string, Set<Listener>>();\n\n /**\n * Dispatches an event to all registered listeners for the given event name.\n *\n * @param event - EIP-1193 event name (e.g. \"accountsChanged\", \"chainChanged\")\n * @param args - Arguments forwarded to each listener callback\n */\n const emit = (event: string, ...args: unknown[]) => {\n const set = listeners.get(event);\n if (!set) return;\n for (const listener of set) listener(...args);\n };\n\n /**\n * Reads the connected user from localStorage.\n *\n * Returns null in non-browser environments (SSR) and when no user has been\n * persisted yet, or when the stored value is malformed.\n *\n * @returns The stored user object, or null if unavailable\n */\n const getStoredUser = (): StoredUser | null => {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(storageKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as StoredUser;\n if (!parsed?.address) return null;\n return parsed;\n } catch {\n return null;\n }\n };\n\n /**\n * Persists the connected user to localStorage.\n *\n * No-ops in non-browser (SSR) environments.\n *\n * @param user - User object with at minimum an `address` field\n */\n const setStoredUser = (user: StoredUser) => {\n if (typeof window === \"undefined\") return;\n localStorage.setItem(storageKey, JSON.stringify(user));\n };\n\n /**\n * Removes the connected user from localStorage, effectively logging them out\n * from the provider's perspective.\n *\n * No-ops in non-browser (SSR) environments.\n */\n const clearStoredUser = () => {\n if (typeof window === \"undefined\") return;\n localStorage.removeItem(storageKey);\n };\n\n /**\n * Fetches the smart account address for a given username from the passkey service.\n *\n * Called as a fallback when the auth/connect modal returns a username but no address\n * (e.g. during first-time sign-up where the account address is computed server-side).\n *\n * @param username - The 1auth username to look up\n * @returns The EVM address of the user's smart account\n * @throws If the HTTP request fails or the service returns an error\n */\n const resolveAccountAddress = async (username: string): Promise<Address> => {\n const clientId = client.getClientId();\n const response = await fetch(\n `${client.getProviderUrl()}/api/users/${encodeURIComponent(username)}/account`,\n {\n headers: clientId ? { \"x-client-id\": clientId } : {},\n }\n );\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to resolve account address\");\n }\n\n const data = await response.json();\n return data.address as Address;\n };\n\n /**\n * Connects the user by returning a cached address or opening the auth flow.\n *\n * Returns the dapp-side cached address immediately when present. Otherwise\n * opens the auth modal (`/dialog/auth`) directly — the iframe-side\n * returning-user UX lives inside that flow now. On success the address is\n * stored in localStorage and `accountsChanged` / `connect` events are emitted.\n *\n * @returns Array containing the single connected account address\n * @throws If the user cancels or authentication fails\n */\n const connect = async (): Promise<Address[]> => {\n const stored = getStoredUser();\n if (stored) {\n return [stored.address];\n }\n\n const authResult = await client.authWithModal();\n if (!authResult.success) {\n throw new Error(authResult.error?.message || \"Authentication failed\");\n }\n const username = authResult.user?.username;\n let address = authResult.user?.address;\n const signerType = authResult.signerType;\n\n // Use address from result directly, or resolve from username\n if (!address && username) {\n address = await resolveAccountAddress(username);\n }\n if (!address) {\n throw new Error(\"No account address available\");\n }\n\n setStoredUser({ username, address, signerType });\n emit(\"accountsChanged\", [address]);\n emit(\"connect\", { chainId: numberToHex(chainId) });\n return [address];\n };\n\n /**\n * Disconnects the current user by clearing persisted state and emitting events.\n *\n * Emits `accountsChanged` with an empty array and `disconnect` so that consumers\n * (e.g. wagmi) can update their state accordingly.\n */\n const disconnect = async () => {\n clearStoredUser();\n emit(\"accountsChanged\", []);\n emit(\"disconnect\");\n };\n\n /**\n * Returns the currently connected user, triggering the connect flow if needed.\n *\n * Used internally by methods that require an authenticated session (e.g. signing,\n * sending transactions) to guarantee a user is available before proceeding.\n *\n * @returns The stored user object with at minimum an `address` field\n * @throws If connecting fails and no address can be resolved\n */\n const ensureUser = async (): Promise<StoredUser> => {\n const stored = getStoredUser();\n if (stored) return stored;\n const [address] = await connect();\n if (!address) {\n throw new Error(\"Failed to resolve user session\");\n }\n const user = getStoredUser();\n return user || { address };\n };\n\n /**\n * Read an optional wallet_getAssets account address override from RPC params.\n */\n const getAssetsAccountAddress = (\n assetsParams?: unknown[] | Record<string, unknown>,\n ): string | undefined => {\n const raw = Array.isArray(assetsParams) ? assetsParams[0] : assetsParams;\n if (typeof raw === \"string\" && raw.trim()) return raw.trim();\n if (!raw || typeof raw !== \"object\") return undefined;\n\n const request = raw as Record<string, unknown>;\n const candidates = [\n request.accountAddress,\n request.address,\n ];\n for (const candidate of candidates) {\n if (typeof candidate === \"string\" && candidate.trim()) {\n return candidate.trim();\n }\n }\n return undefined;\n };\n\n /**\n * Parses a chain ID value that may arrive as a hex string, decimal string, or number.\n *\n * Handles both `\"0x1\"` (hex) and `\"1\"` / `1` (decimal) representations that are\n * commonly mixed across different wallet_switchEthereumChain implementations.\n *\n * @param value - The raw chain ID value from RPC params\n * @returns The numeric chain ID, or undefined if the value cannot be parsed\n */\n const parseChainId = (value: unknown): number | undefined => {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n if (value.startsWith(\"0x\")) return Number.parseInt(value, 16);\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n };\n\n /**\n * Normalizes a transaction value to a decimal string expected by the intent service.\n *\n * Handles the various formats callers may provide: `bigint`, `number`, hex strings\n * (e.g. `\"0x38d7ea4c68000\"`), or plain decimal strings. Returns undefined for null\n * or unsupported types, allowing callers to fall back to `\"0\"`.\n *\n * @param value - Raw value from an RPC transaction param\n * @returns Decimal string representation, or undefined if the input is not usable\n */\n const normalizeValue = (value: unknown): string | undefined => {\n if (value === undefined || value === null) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value === \"number\") return Math.trunc(value).toString();\n if (typeof value === \"string\") {\n if (value.startsWith(\"0x\")) {\n return BigInt(value).toString();\n }\n return value;\n }\n return undefined;\n };\n\n /**\n * Converts raw EIP-1193 call objects into the strongly-typed `IntentCall` format\n * expected by the passkey service.\n *\n * Fills in missing `data` with `\"0x\"` and missing `value` with `\"0\"` so the\n * intent service never receives undefined fields.\n *\n * @param calls - Raw call objects from `wallet_sendCalls` or `eth_sendTransaction` params\n * @returns Array of normalized `IntentCall` objects\n */\n const normalizeCalls = (calls: unknown[]): IntentCall[] => {\n return calls.map((call) => {\n const c = call as Record<string, unknown>;\n return {\n to: c.to as Address,\n data: (c.data as Hex | undefined) || \"0x\",\n value: normalizeValue(c.value) || \"0\",\n label: c.label as string | undefined,\n sublabel: c.sublabel as string | undefined,\n icon: c.icon as string | undefined,\n abi: c.abi as readonly unknown[] | undefined,\n };\n });\n };\n\n /**\n * Converts raw token request objects into the typed `IntentTokenRequest` format.\n *\n * Token requests allow callers to specify which tokens and amounts should be sourced\n * when funding a cross-chain intent (e.g. \"bridge 10 USDC from Optimism to Base\").\n * Accepts bigint or string/numeric amounts and normalizes them to bigint.\n *\n * @param requests - Raw token request array from RPC params, or a non-array value\n * @returns Array of typed token requests, or undefined if input is not an array\n */\n const normalizeTokenRequests = (\n requests: unknown\n ): IntentTokenRequest[] | undefined => {\n if (!Array.isArray(requests)) return undefined;\n return requests.map((r) => {\n const req = r as Record<string, unknown>;\n return {\n token: req.token as string,\n amount:\n typeof req.amount === \"bigint\"\n ? req.amount\n : BigInt(String(req.amount || \"0\")),\n };\n });\n };\n\n /**\n * Decodes a message that may be hex-encoded into a human-readable string.\n *\n * Some signers (e.g. MetaMask) encode plain-text messages as hex before passing them\n * to `personal_sign`. This helper reverses that encoding so users see the original\n * text in the signing dialog rather than a raw hex string.\n *\n * @param value - A plain string or hex-encoded string (`\"0x...\"`)\n * @returns The decoded UTF-8 string, or the original value if decoding fails\n */\n const decodeMessage = (value: string) => {\n if (!isHex(value)) return value;\n try {\n return hexToString(value as Hex);\n } catch {\n return value;\n }\n };\n\n /**\n * Forwards a raw EIP-1193 request to the iframe at `/dialog/sign-eoa`, which\n * delegates to the active wagmi connector. The wallet's own prompt is the\n * review screen — no in-dialog review step for EOA sessions.\n */\n const forwardToWallet = async (\n method: string,\n params?: unknown[] | Record<string, unknown>,\n expectedAddress?: Address,\n ): Promise<unknown> => {\n const result = await client.requestWithWallet({\n method,\n params,\n expectedAddress,\n });\n if (!result.success) {\n const err = new Error(result.error.message);\n (err as Error & { code?: string }).code = result.error.code;\n throw err;\n }\n return result.result;\n };\n\n /**\n * EIP-1193 methods forwarded verbatim to the EOA connector. All other methods\n * (eth_accounts, eth_chainId, wallet_connect, wallet_disconnect,\n * wallet_switchEthereumChain, wallet_getCapabilities/Assets) are handled\n * locally against the stored session even for EOA sessions.\n */\n const EOA_FORWARDED_METHODS = new Set([\n \"personal_sign\",\n \"eth_sign\",\n \"eth_signTypedData\",\n \"eth_signTypedData_v3\",\n \"eth_signTypedData_v4\",\n \"eth_sendTransaction\",\n \"wallet_sendCalls\",\n \"wallet_getCallsStatus\",\n ]);\n\n /**\n * Signs an arbitrary string message via the passkey service.\n *\n * Ensures a user session exists before delegating to `OneAuthClient.signMessage`.\n * The raw WebAuthn signature components are ABI-encoded for ERC-1271 on-chain\n * verification before being returned.\n *\n * @param message - Plain-text message to sign\n * @returns ABI-encoded WebAuthn signature as a hex string\n * @throws If no user session is available or the signing dialog is cancelled\n */\n const signMessage = async (message: string) => {\n const user = await ensureUser();\n if (!user.username && !user.address) {\n throw new Error(\"Username or address required for signing.\");\n }\n const result = await client.signMessage({\n username: user.username || undefined,\n accountAddress: user.address,\n message,\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Signs EIP-712 typed data via the passkey service.\n *\n * Accepts either a parsed typed-data object or a JSON string (as some libraries\n * serialize the payload before passing it through the provider). The raw WebAuthn\n * signature is ABI-encoded for ERC-1271 on-chain verification.\n *\n * @param typedData - EIP-712 typed data object or its JSON string representation\n * @returns ABI-encoded WebAuthn signature as a hex string\n * @throws If no user session is available or the signing dialog is cancelled\n */\n const signTypedData = async (typedData: unknown) => {\n const user = await ensureUser();\n if (!user.username && !user.address) {\n throw new Error(\"Username or address required for signing.\");\n }\n const data =\n typeof typedData === \"string\" ? JSON.parse(typedData) : typedData;\n const result = await client.signTypedData({\n username: user.username || undefined,\n accountAddress: user.address,\n domain: (data as any).domain,\n types: (data as any).types,\n primaryType: (data as any).primaryType,\n message: (data as any).message,\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Extracts the fields required by `OneAuthClient.sendIntent` from a richer payload.\n *\n * This thin wrapper makes it explicit which fields travel to the intent service and\n * which are local concerns (e.g. `sourceChainId` is handled at the call site).\n *\n * @param payload - Full intent payload including user identity and transaction data\n * @returns Subset of fields forwarded to the intent service\n */\n const resolveIntentPayload = (payload: {\n username?: string;\n accountAddress: Address;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: IntentTokenRequest[];\n }) => ({\n username: payload.username,\n accountAddress: payload.accountAddress,\n targetChain: payload.targetChain,\n calls: payload.calls,\n tokenRequests: payload.tokenRequests,\n });\n\n /**\n * Submits a cross-chain intent through the passkey service and returns the intent ID.\n *\n * Opens the signing dialog, waits for user confirmation, then polls the orchestrator\n * until a transaction hash is available (controlled by `waitForHash` and the timeout\n * options). The returned intent ID is used as the `callsId` in EIP-5792 responses.\n *\n * The dialog closes based on `closeOn` (defaults to `\"preconfirmed\"`). The `waitForHash`\n * option independently polls for a transaction hash after the dialog closes.\n *\n * @param payload - Intent details including target chain, calls, token requests, and\n * an optional `sourceChainId` for cross-chain bridging\n * @returns The orchestrator intent ID string\n * @throws If the user rejects the signing dialog or the intent fails\n */\n const sendIntent = async (payload: {\n username?: string;\n accountAddress: Address;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: IntentTokenRequest[];\n sourceChainId?: number;\n }) => {\n const intentPayload = resolveIntentPayload(payload);\n const result = await client.sendIntent({\n ...intentPayload,\n tokenRequests: payload.tokenRequests,\n sourceChainId: payload.sourceChainId,\n closeOn: options.closeOn,\n waitForHash: options.waitForHash ?? true,\n hashTimeoutMs: options.hashTimeoutMs,\n hashIntervalMs: options.hashIntervalMs,\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || \"Transaction failed\");\n }\n\n // Return intentId as callsId for EIP-5792 compatibility\n return result.intentId;\n };\n\n const accountMismatchError = (): Error & { code?: string } => {\n const err = new Error(\n \"Requested signer does not match the active wallet connection.\",\n ) as Error & { code?: string };\n err.code = \"ACCOUNT_MISMATCH\";\n return err;\n };\n\n const sameAddress = (a: unknown, b: string): boolean =>\n typeof a === \"string\" && a.toLowerCase() === b.toLowerCase();\n\n /**\n * Some wallets (MetaMask, Rabby) reject `eth_sendTransaction` /\n * `wallet_sendCalls` / `personal_sign` / `eth_signTypedData_v4` when the\n * signer address is missing. The dapp doesn't know the EOA address, so the\n * SDK fills it in from the stored session.\n *\n * If the caller supplies a `from` (or address arg) that differs from the\n * connected EOA, we throw `ACCOUNT_MISMATCH` rather than letting the\n * caller's value win. A dapp asking the wallet to sign on behalf of a\n * different account than the user connected is a trust-boundary violation\n * — the user reviewed and approved exactly one address, not whatever the\n * dapp later substitutes.\n */\n const injectEoaSigner = (\n method: string,\n params: unknown[] | Record<string, unknown> | undefined,\n address: Address,\n ): unknown[] | Record<string, unknown> | undefined => {\n const list = Array.isArray(params) ? params.slice() : params;\n if (!Array.isArray(list)) return params;\n\n if (method === \"eth_sendTransaction\") {\n const first = (list[0] || {}) as Record<string, unknown>;\n if (first.from !== undefined && !sameAddress(first.from, address)) {\n throw accountMismatchError();\n }\n list[0] = { ...first, from: address };\n return list;\n }\n if (method === \"wallet_sendCalls\") {\n const first = (list[0] || {}) as Record<string, unknown>;\n if (first.from !== undefined && !sameAddress(first.from, address)) {\n throw accountMismatchError();\n }\n // EIP-5792 lets each call carry its own `from`. Validate every one —\n // a single mismatched call would otherwise sneak through unchecked.\n const calls = first.calls;\n if (Array.isArray(calls)) {\n for (const call of calls) {\n if (!call || typeof call !== \"object\") continue;\n const callFrom = (call as Record<string, unknown>).from;\n if (callFrom !== undefined && !sameAddress(callFrom, address)) {\n throw accountMismatchError();\n }\n }\n }\n list[0] = { ...first, from: address };\n return list;\n }\n if (method === \"personal_sign\") {\n // personal_sign(message, address) — fill address if absent.\n if (list[1] !== undefined && !sameAddress(list[1], address)) {\n throw accountMismatchError();\n }\n if (list[0] && list[1] === undefined) list[1] = address;\n return list;\n }\n if (\n method === \"eth_sign\" ||\n method === \"eth_signTypedData\" ||\n method === \"eth_signTypedData_v3\" ||\n method === \"eth_signTypedData_v4\"\n ) {\n // signTypedData(address, typedData) — fill address if absent.\n if (list[0] !== undefined && !sameAddress(list[0], address)) {\n throw accountMismatchError();\n }\n if (list[0] === undefined && list[1] !== undefined) list[0] = address;\n return list;\n }\n return list;\n };\n\n const request = async ({ method, params }: ProviderRequest) => {\n // For sign/tx methods, resolve the user first — this opens the auth modal\n // on the very first call so we know the signerType before deciding\n // between the passkey path and forwarding to the wagmi connector. Local-\n // only methods (eth_accounts, eth_chainId, wallet_switchEthereumChain,\n // etc.) fall through to the switch below and read stored state directly.\n if (EOA_FORWARDED_METHODS.has(method)) {\n const user = await ensureUser();\n if (user.signerType === \"eoa\") {\n return forwardToWallet(\n method,\n injectEoaSigner(method, params, user.address),\n user.address,\n );\n }\n }\n\n switch (method) {\n case \"eth_chainId\":\n return numberToHex(chainId);\n case \"eth_accounts\": {\n const stored = getStoredUser();\n return stored ? [stored.address] : [];\n }\n case \"eth_requestAccounts\":\n return connect();\n case \"wallet_connect\":\n return connect();\n case \"wallet_disconnect\":\n await disconnect();\n return true;\n case \"wallet_switchEthereumChain\": {\n const [param] = (params as any[]) || [];\n const next = parseChainId(param?.chainId ?? param);\n if (!next) {\n throw new Error(\"Invalid chainId\");\n }\n const stored = getStoredUser();\n if (stored?.signerType === \"eoa\") {\n await forwardToWallet(method, params, stored.address);\n }\n chainId = next;\n emit(\"chainChanged\", numberToHex(chainId));\n return null;\n }\n case \"personal_sign\": {\n const paramList = Array.isArray(params) ? params : [];\n const first = paramList[0];\n const second = paramList[1];\n // personal_sign param order varies: some callers send [message, address],\n // others send [hexEncodedMessage, address]. When the first param is hex and\n // the second is a non-hex string we treat the second as the plain message\n // (MetaMask-style). Otherwise we always decode the first param.\n const message =\n typeof first === \"string\" && first.startsWith(\"0x\") && second\n ? typeof second === \"string\" && !second.startsWith(\"0x\")\n ? second\n : decodeMessage(first)\n : typeof first === \"string\"\n ? decodeMessage(first)\n : typeof second === \"string\"\n ? decodeMessage(second)\n : \"\";\n if (!message) throw new Error(\"Invalid personal_sign payload\");\n return signMessage(message);\n }\n case \"eth_sign\": {\n const paramList = Array.isArray(params) ? params : [];\n const message = typeof paramList[1] === \"string\" ? paramList[1] : \"\";\n if (!message) throw new Error(\"Invalid eth_sign payload\");\n return signMessage(decodeMessage(message));\n }\n case \"eth_signTypedData\":\n case \"eth_signTypedData_v4\": {\n const paramList = Array.isArray(params) ? params : [];\n const typedData = paramList[1] ?? paramList[0];\n return signTypedData(typedData);\n }\n case \"eth_sendTransaction\": {\n const paramList = Array.isArray(params) ? params : [];\n const tx = (paramList[0] || {}) as Record<string, unknown>;\n const user = await ensureUser();\n const targetChain = parseChainId(tx.chainId) ?? chainId;\n const calls = normalizeCalls([tx]);\n const tokenRequests = normalizeTokenRequests(tx.tokenRequests);\n const txSourceChainId = parseChainId(tx.sourceChainId);\n return sendIntent({\n username: user.username || undefined,\n accountAddress: user.address,\n targetChain,\n calls,\n tokenRequests,\n sourceChainId: txSourceChainId,\n });\n }\n case \"wallet_sendCalls\": {\n const paramList = Array.isArray(params) ? params : [];\n const payload = (paramList[0] || {}) as Record<string, unknown>;\n const user = await ensureUser();\n const targetChain = parseChainId(payload.chainId) ?? chainId;\n const calls = normalizeCalls((payload.calls as unknown[]) || []);\n const tokenRequests = normalizeTokenRequests(payload.tokenRequests);\n const sourceChainId = parseChainId(payload.sourceChainId);\n if (!calls.length) throw new Error(\"No calls provided\");\n return sendIntent({\n username: user.username || undefined,\n accountAddress: user.address,\n targetChain,\n calls,\n tokenRequests,\n sourceChainId,\n });\n }\n case \"wallet_getCapabilities\": {\n const stored = getStoredUser();\n if (stored?.signerType === \"eoa\") {\n return {};\n }\n\n const paramList = Array.isArray(params) ? params : [];\n // walletAddress is params[0] - we ignore since all accounts have same capabilities\n const requestedChains = paramList[1] as `0x${string}`[] | undefined;\n\n const chainIds = getSupportedChainIds();\n const capabilities: Record<`0x${string}`, Record<string, unknown>> = {};\n\n for (const chainId of chainIds) {\n const hexChainId = `0x${chainId.toString(16)}` as `0x${string}`;\n\n // Filter if specific chains requested\n if (requestedChains && !requestedChains.includes(hexChainId)) {\n continue;\n }\n\n // All supported chains advertise atomic batching, gasless transactions via\n // paymasters, and cross-chain auxiliary funds (EIP-5792 capability keys).\n capabilities[hexChainId] = {\n atomic: { status: \"supported\" },\n paymasterService: { supported: true },\n auxiliaryFunds: { supported: true },\n };\n }\n\n return capabilities;\n }\n case \"wallet_getAssets\": {\n const explicitAccountAddress = getAssetsAccountAddress(params);\n const user = explicitAccountAddress ? null : await ensureUser();\n // The portfolio endpoint resolves identifiers via resolveUserWhere,\n // and the current SDK account model is address-first. Explicit params\n // let app-level verified sessions query balances without relying on\n // the provider's localStorage cache, while connected EIP-1193 consumers\n // still work with no params.\n const accountAddress = explicitAccountAddress || user?.address;\n if (!accountAddress) {\n throw new Error(\"wallet_getAssets requires accountAddress or a connected account\");\n }\n return client.getAssets({ accountAddress: accountAddress as Address });\n }\n case \"wallet_getCallsStatus\": {\n const paramList = Array.isArray(params) ? params : [];\n const callsId = paramList[0] as string;\n if (!callsId) {\n throw new Error(\"callsId is required\");\n }\n const statusClientId = client.getClientId();\n const response = await fetch(\n `${client.getProviderUrl()}/api/intent/status/${encodeURIComponent(callsId)}`,\n {\n headers: statusClientId ? { \"x-client-id\": statusClientId } : {},\n }\n );\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to get calls status\");\n }\n const data = await response.json();\n // Map intent status to EIP-5792 status strings.\n // Both \"failed\" and \"expired\" map to \"CONFIRMED\" because EIP-5792 uses receipts\n // (and a 0x0 status code) to communicate failure — there is no \"FAILED\" state.\n const statusMap: Record<string, string> = {\n pending: \"PENDING\",\n preconfirmed: \"PENDING\",\n completed: \"CONFIRMED\",\n failed: \"CONFIRMED\",\n expired: \"CONFIRMED\",\n };\n return {\n status: statusMap[data.status] || \"PENDING\",\n receipts: data.transactionHash\n ? [\n {\n logs: [],\n // 0x1 = success, 0x0 = reverted/failed — mirrors EVM receipt status\n status: data.status === \"completed\" ? \"0x1\" : \"0x0\",\n blockHash: data.blockHash,\n blockNumber: data.blockNumber,\n transactionHash: data.transactionHash,\n },\n ]\n : [],\n };\n }\n case \"wallet_getCallsHistory\": {\n const paramList = Array.isArray(params) ? params : [];\n const options = (paramList[0] || {}) as {\n limit?: number;\n offset?: number;\n status?: string;\n from?: string;\n to?: string;\n };\n\n const queryParams = new URLSearchParams();\n if (options.limit) queryParams.set(\"limit\", String(options.limit));\n if (options.offset) queryParams.set(\"offset\", String(options.offset));\n if (options.status) queryParams.set(\"status\", options.status);\n if (options.from) queryParams.set(\"from\", options.from);\n if (options.to) queryParams.set(\"to\", options.to);\n\n const url = `${client.getProviderUrl()}/api/intent/history${\n queryParams.toString() ? `?${queryParams}` : \"\"\n }`;\n\n const historyClientId = client.getClientId();\n const response = await fetch(url, {\n headers: historyClientId ? { \"x-client-id\": historyClientId } : {},\n credentials: \"include\",\n });\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to get calls history\");\n }\n\n const data = await response.json();\n\n // Map intent status to EIP-5792 format\n const statusMap: Record<string, string> = {\n pending: \"PENDING\",\n preconfirmed: \"PENDING\",\n completed: \"CONFIRMED\",\n failed: \"CONFIRMED\",\n expired: \"CONFIRMED\",\n };\n\n // intentId IS the orchestrator's ID (used as callsId in EIP-5792)\n return {\n calls: data.intents.map(\n (intent: {\n intentId: string;\n status: string;\n transactionHash?: string;\n targetChain: number;\n }) => ({\n callsId: intent.intentId, // intentId is the orchestrator's ID\n status: statusMap[intent.status] || \"PENDING\",\n receipts: intent.transactionHash\n ? [{ transactionHash: intent.transactionHash }]\n : [],\n chainId: `0x${intent.targetChain.toString(16)}`,\n })\n ),\n total: data.total,\n hasMore: data.hasMore,\n };\n }\n default:\n throw new Error(`Unsupported method: ${method}`);\n }\n };\n\n return {\n request,\n on(event, listener) {\n const set = listeners.get(event) ?? new Set();\n set.add(listener);\n listeners.set(event, set);\n },\n removeListener(event, listener) {\n const set = listeners.get(event);\n if (!set) return;\n set.delete(listener);\n if (set.size === 0) listeners.delete(event);\n },\n disconnect,\n };\n}\n","/**\n * @file Chain and token registry for the 1auth SDK.\n *\n * Wraps `@rhinestone/shared-configs` chain/token data and combines it with\n * viem's chain definitions to expose a filtered, testnet-aware registry.\n * Consumers can look up supported chains and tokens, resolve token addresses\n * by symbol, and retrieve chain metadata such as explorer URLs and default RPC\n * endpoints.\n *\n * Testnet inclusion is controlled by the `includeTestnets` option on each\n * function or, as a project-wide default, by the environment variables\n * `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` or `ORCHESTRATOR_USE_TESTNETS`.\n */\n\nimport type { Address, Chain } from \"viem\";\nimport { isAddress } from \"viem\";\nimport * as viemChains from \"viem/chains\";\nimport { chainRegistry } from \"@rhinestone/shared-configs\";\n\nexport type TokenConfig = {\n symbol: string;\n address: Address;\n decimals: number;\n};\n\nexport type ChainFilterOptions = {\n includeTestnets?: boolean;\n chainIds?: number[];\n};\n\ntype ChainRegistryEntry = (typeof chainRegistry)[keyof typeof chainRegistry];\n\nconst env: Record<string, string | undefined> =\n typeof process !== \"undefined\" ? process.env : {};\n\n// Build a chain-ID-to-Chain map from viem, resolving collisions by preferring\n// mainnet definitions over testnets. viem exports duplicate numeric IDs (e.g.\n// zoraTestnet and hyperEvm both use 999); a naive Map would silently keep\n// whichever entry happens to appear last in iteration order, which may be the\n// testnet. The loop below only overwrites an existing entry when the incoming\n// chain is NOT a testnet and the existing one IS, ensuring the production chain\n// always wins while still falling back to a testnet entry when no mainnet\n// definition exists for a given ID.\nconst VIEM_CHAIN_BY_ID = new Map<number, Chain>();\nfor (const value of Object.values(viemChains)) {\n if (typeof value !== \"object\" || value === null || !(\"id\" in value) || !(\"name\" in value)) continue;\n const chain = value as Chain;\n const existing = VIEM_CHAIN_BY_ID.get(chain.id);\n if (!existing || (existing.testnet && !chain.testnet)) {\n VIEM_CHAIN_BY_ID.set(chain.id, chain);\n }\n}\n\nfunction isEvmRegistryEntry(\n entry: ChainRegistryEntry | undefined,\n): entry is ChainRegistryEntry & { vmType: \"evm\" } {\n return entry?.vmType === \"evm\";\n}\n\nfunction getEvmRegistryEntry(\n chainId: number,\n): (ChainRegistryEntry & { vmType: \"evm\" }) | undefined {\n const entry = chainRegistry[String(chainId) as keyof typeof chainRegistry];\n return isEvmRegistryEntry(entry) ? entry : undefined;\n}\n\n// The shared-configs registry includes non-EVM chains (Solana, Tron). Filter\n// to EVM entries before exposing supported chains — downstream consumers\n// (viem clients, wallet_getCapabilities, RPC proxy) only handle eip155 chains.\nconst REGISTRY_CHAIN_IDS = Object.entries(chainRegistry)\n .filter(([, entry]) => isEvmRegistryEntry(entry))\n .map(([id]) => Number(id));\nconst SUPPORTED_CHAIN_IDS = new Set(REGISTRY_CHAIN_IDS);\n\nfunction tokensForChain(chainId: number): TokenConfig[] {\n const entry = getEvmRegistryEntry(chainId);\n if (!entry) return [];\n return entry.tokens.map((token) => ({\n symbol: token.symbol,\n address: token.address as Address,\n decimals: token.decimals,\n }));\n}\n\n/** Treat any 20-byte hex string as an address; checksum casing is optional for user inputs. */\nfunction isAddressInput(value: string): value is Address {\n return isAddress(value, { strict: false });\n}\n\n/**\n * Parse a string environment variable into a boolean, returning `undefined`\n * when the value is absent or not a recognised truthy/falsy literal.\n *\n * Accepted truthy values: `\"true\"`, `\"1\"`.\n * Accepted falsy values: `\"false\"`, `\"0\"`.\n */\nfunction parseBool(value?: string): boolean | undefined {\n if (value === \"true\" || value === \"1\") return true;\n if (value === \"false\" || value === \"0\") return false;\n return undefined;\n}\n\n/**\n * Determine whether testnet chains should be included in registry results.\n *\n * Precedence (highest to lowest):\n * 1. `explicit` argument — a caller-supplied boolean always wins.\n * 2. `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` env var — checked first so\n * Next.js browser bundles (which only expose `NEXT_PUBLIC_*` variables)\n * can configure testnet mode without a server-side env var.\n * 3. `ORCHESTRATOR_USE_TESTNETS` env var — server-side / Node.js fallback.\n * 4. Defaults to `false` (testnets excluded) when none of the above is set.\n */\nfunction resolveIncludeTestnets(explicit?: boolean): boolean {\n if (explicit !== undefined) return explicit;\n const envValue =\n parseBool(env.NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS) ??\n parseBool(env.ORCHESTRATOR_USE_TESTNETS);\n return envValue ?? false;\n}\n\nfunction applyChainFilters(chainIds: number[], options?: ChainFilterOptions): number[] {\n const includeTestnets = resolveIncludeTestnets(options?.includeTestnets);\n const allowlist = options?.chainIds;\n let filtered = chainIds;\n\n if (!includeTestnets) {\n filtered = filtered.filter((chainId) => !isTestnet(chainId));\n }\n\n if (allowlist) {\n const allowed = new Set(allowlist);\n filtered = filtered.filter((chainId) => allowed.has(chainId));\n }\n\n return filtered;\n}\n\nexport function getSupportedChainIds(options?: ChainFilterOptions): number[] {\n return applyChainFilters(REGISTRY_CHAIN_IDS, options);\n}\n\nexport function getSupportedChains(options?: ChainFilterOptions): Chain[] {\n return getSupportedChainIds(options)\n .map((chainId) => VIEM_CHAIN_BY_ID.get(chainId))\n .filter((chain): chain is Chain => Boolean(chain));\n}\n\nexport function getAllSupportedChainsAndTokens(options?: ChainFilterOptions): Array<{\n chainId: number;\n tokens: TokenConfig[];\n}> {\n return getSupportedChainIds(options).map((chainId) => ({\n chainId,\n tokens: tokensForChain(chainId),\n }));\n}\n\nexport function getChainById(chainId: number): Chain {\n if (!SUPPORTED_CHAIN_IDS.has(chainId)) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n const chain = VIEM_CHAIN_BY_ID.get(chainId);\n if (!chain) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n return chain;\n}\n\nexport function getChainName(chainId: number): string {\n try {\n return getChainById(chainId).name;\n } catch {\n return `Chain ${chainId}`;\n }\n}\n\nexport function getChainExplorerUrl(chainId: number): string | undefined {\n try {\n return getChainById(chainId).blockExplorers?.default?.url;\n } catch {\n return undefined;\n }\n}\n\nexport function getChainRpcUrl(chainId: number): string | undefined {\n try {\n const chain = getChainById(chainId);\n return chain.rpcUrls?.default?.http?.[0] || chain.rpcUrls?.public?.http?.[0];\n } catch {\n return undefined;\n }\n}\n\nexport function getSupportedTokens(chainId: number): TokenConfig[] {\n return tokensForChain(chainId);\n}\n\nexport function getSupportedTokenSymbols(chainId: number): string[] {\n return getSupportedTokens(chainId).map((token) => token.symbol);\n}\n\nexport function getTokenAddress(symbolOrAddress: string, chainId: number): Address {\n if (isAddressInput(symbolOrAddress)) {\n return symbolOrAddress;\n }\n const match = getSupportedTokens(chainId).find(\n (t) => t.symbol.toUpperCase() === symbolOrAddress.toUpperCase()\n );\n if (!match) {\n throw new Error(`Unsupported token \"${symbolOrAddress}\" on chain ${chainId}`);\n }\n return match.address;\n}\n\nexport function getTokenDecimals(symbolOrAddress: string, chainId: number): number {\n const match = getSupportedTokens(chainId).find(\n (t) =>\n isAddressInput(symbolOrAddress)\n ? t.address.toLowerCase() === symbolOrAddress.toLowerCase()\n : t.symbol.toUpperCase() === symbolOrAddress.toUpperCase()\n );\n if (!match && isAddressInput(symbolOrAddress) && SUPPORTED_CHAIN_IDS.has(chainId)) {\n return 18;\n }\n if (!match) {\n throw new Error(`Unsupported token \"${symbolOrAddress}\" on chain ${chainId}`);\n }\n return match.decimals;\n}\n\nexport function resolveTokenAddress(token: string, chainId: number): Address {\n if (isAddressInput(token)) {\n return token;\n }\n return getTokenAddress(token, chainId);\n}\n\nexport function isTestnet(chainId: number): boolean {\n try {\n return getChainById(chainId).testnet ?? false;\n } catch {\n return false;\n }\n}\n\nexport function getTokenSymbol(tokenAddress: Address, chainId: number): string {\n const token = getSupportedTokens(chainId).find(\n (entry) => entry.address.toLowerCase() === tokenAddress.toLowerCase()\n );\n if (token) {\n return token.symbol;\n }\n if (!SUPPORTED_CHAIN_IDS.has(chainId)) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n return \"Token\";\n}\n\nexport function isTokenAddressSupported(tokenAddress: Address, chainId: number): boolean {\n return isAddressInput(tokenAddress) && SUPPORTED_CHAIN_IDS.has(chainId);\n}\n","import { encodeAbiParameters, keccak256 } from 'viem';\nimport type { Hex } from 'viem';\nimport type { WebAuthnSignature } from '../types';\nimport type { TransactionCall } from './types';\n\n/**\n * P-256 curve order (n)\n * Used for signature malleability normalization\n */\nconst P256_N = BigInt(\n '0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551'\n);\nconst P256_N_DIV_2 = P256_N / 2n;\n\n/**\n * WebAuthnAuth struct type for ABI encoding\n */\nconst WEBAUTHN_AUTH_TYPE = {\n type: 'tuple',\n components: [\n { type: 'bytes', name: 'authenticatorData' },\n { type: 'string', name: 'clientDataJSON' },\n { type: 'uint256', name: 'challengeIndex' },\n { type: 'uint256', name: 'typeIndex' },\n { type: 'uint256', name: 'r' },\n { type: 'uint256', name: 's' },\n ],\n} as const;\n\n/**\n * Encode a WebAuthn signature for ERC-1271 verification on-chain\n *\n * @param sig - The WebAuthn signature from the passkey\n * @returns ABI-encoded signature bytes\n */\nexport function encodeWebAuthnSignature(sig: WebAuthnSignature): Hex {\n // Normalize s to prevent signature malleability\n let s = BigInt(sig.s);\n if (s > P256_N_DIV_2) {\n s = P256_N - s;\n }\n\n return encodeAbiParameters([WEBAUTHN_AUTH_TYPE], [\n {\n authenticatorData: sig.authenticatorData as Hex,\n clientDataJSON: sig.clientDataJSON,\n challengeIndex: BigInt(sig.challengeIndex),\n typeIndex: BigInt(sig.typeIndex),\n r: BigInt(sig.r),\n s,\n },\n ]);\n}\n\n/**\n * Hash an array of transaction calls for signing\n *\n * @param calls - Array of transaction calls\n * @returns keccak256 hash of the encoded calls\n */\nexport function hashCalls(calls: TransactionCall[]): Hex {\n const encoded = encodeAbiParameters(\n [\n {\n type: 'tuple[]',\n components: [\n { type: 'address', name: 'to' },\n { type: 'bytes', name: 'data' },\n { type: 'uint256', name: 'value' },\n ],\n },\n ],\n [\n calls.map((c) => ({\n to: c.to,\n data: c.data || '0x',\n value: c.value || 0n,\n })),\n ]\n );\n return keccak256(encoded);\n}\n\n/**\n * Build transaction review display data from calls\n *\n * @param calls - Array of transaction calls\n * @returns TransactionDetails for the signing modal\n */\nexport function buildTransactionReview(calls: TransactionCall[]) {\n return {\n actions: calls.map((call, i) => ({\n type: 'custom' as const,\n label: call.label || `Contract Call ${i + 1}`,\n sublabel: call.sublabel || `To: ${call.to.slice(0, 10)}...${call.to.slice(-8)}`,\n amount: call.value ? `${call.value} wei` : undefined,\n })),\n };\n}\n"],"mappings":"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","names":["import_viem","import_viem","import_viem","data","request","chainId","options","provider","chain"]}
1
+ {"version":3,"sources":["../src/wagmi.ts","../src/provider.ts","../src/registry.ts","../src/walletClient/utils.ts"],"sourcesContent":["/**\n * Wagmi connector factory for 1auth passkey authentication.\n *\n * Wraps `createOneAuthProvider` in a wagmi-compatible connector so that\n * passkey-based accounts can participate in the full wagmi ecosystem:\n * `useAccount`, `useConnect`, `useSendTransaction`, hooks, and so on.\n *\n * Import path: `@rhinestone/1auth/wagmi`\n *\n * @module\n */\n\nimport { createConnector, type Connector } from \"@wagmi/core\";\nimport {\n numberToHex,\n type Address,\n type Chain,\n type ProviderConnectInfo,\n} from \"viem\";\nimport { createOneAuthProvider, type OneAuthProvider } from \"./provider\";\nimport type { OneAuthClient } from \"./client\";\n\nexport type OneAuthConnectorOptions = {\n client: OneAuthClient;\n chainId?: number;\n storageKey?: string;\n waitForHash?: boolean;\n hashTimeoutMs?: number;\n hashIntervalMs?: number;\n};\n\n/**\n * Creates a wagmi connector backed by 1auth passkey authentication.\n *\n * The connector lazily instantiates a single `OneAuthProvider` on the first call to\n * `getProvider()` and reuses it for the lifetime of the wagmi config. Event listeners\n * (`accountsChanged`, `chainChanged`, `disconnect`) are attached on connect and torn\n * down on disconnect to prevent memory leaks.\n *\n * @param options - Connector configuration\n * @param options.client - Configured `OneAuthClient` instance\n * @param options.chainId - Override the initial chain ID. When omitted the first chain\n * in the wagmi config's `chains` array is used.\n * @param options.storageKey - localStorage key for persisting the connected user.\n * Forwarded to `createOneAuthProvider`. Defaults to `\"1auth-user\"`.\n * @param options.waitForHash - When true, `sendTransaction` waits for a tx hash before\n * resolving. Forwarded to `createOneAuthProvider`. Defaults to true.\n * @param options.hashTimeoutMs - Maximum milliseconds to wait for a transaction hash.\n * @param options.hashIntervalMs - Polling interval when waiting for a hash.\n * @returns A wagmi connector factory function (pass directly to wagmi `createConfig`)\n *\n * @example\n * ```typescript\n * import { createConfig } from \"wagmi\";\n * import { base, optimism } from \"viem/chains\";\n * import { oneAuth } from \"@rhinestone/1auth/wagmi\";\n * import { OneAuthClient } from \"@rhinestone/1auth\";\n *\n * const client = new OneAuthClient({ clientId: \"my-app\" });\n *\n * export const wagmiConfig = createConfig({\n * chains: [base, optimism],\n * connectors: [\n * oneAuth({ client }),\n * ],\n * });\n * ```\n */\nexport function oneAuth(options: OneAuthConnectorOptions) {\n type Provider = OneAuthProvider;\n\n return createConnector<Provider>((wagmiConfig) => {\n const chains = (wagmiConfig.chains ?? []) as readonly [Chain, ...Chain[]];\n const initialChainId = options.chainId ?? chains[0]?.id;\n\n let provider: Provider | null = null;\n // Bound listener references held so they can be removed by name during disconnect\n let accountsChanged: Connector[\"onAccountsChanged\"] | undefined;\n let chainChanged: Connector[\"onChainChanged\"] | undefined;\n let connect: Connector[\"onConnect\"] | undefined;\n let disconnect: Connector[\"onDisconnect\"] | undefined;\n\n return {\n id: \"1auth\",\n name: \"1auth Passkey\",\n type: \"wallet\",\n\n /**\n * Connects the user and registers provider event listeners.\n *\n * On reconnect (`isReconnecting: true`) attempts to restore accounts from\n * localStorage silently before falling back to the connect modal. Switches to\n * the requested `chainId` if it differs from the provider's current chain.\n * Removes the one-time `connect` listener after the first connection so it is\n * not triggered again on subsequent reconnects.\n *\n * @param params.chainId - Optional chain to switch to after connecting\n * @param params.isReconnecting - True when wagmi is restoring a previous session\n * @param params.withCapabilities - When true, returns accounts with capability maps\n * @returns Connected accounts and the active chain ID\n * @throws If no chain is configured or the user cancels the auth flow\n */\n async connect<withCapabilities extends boolean = false>(\n { chainId, isReconnecting, withCapabilities }:\n | {\n chainId?: number;\n isReconnecting?: boolean;\n withCapabilities?: withCapabilities | boolean;\n }\n | undefined = {}\n ): Promise<{\n accounts: withCapabilities extends true\n ? readonly { address: Address; capabilities: Record<string, unknown> }[]\n : readonly Address[];\n chainId: number;\n }> {\n if (!initialChainId) {\n throw new Error(\"No chain configured for 1auth connector\");\n }\n\n const provider = await this.getProvider({ chainId });\n let accounts: readonly Address[] = [];\n let currentChainId = await this.getChainId();\n\n if (isReconnecting) {\n accounts = await this.getAccounts().catch(() => []);\n }\n\n if (!accounts.length) {\n accounts = (await provider.request({\n method: \"wallet_connect\",\n })) as Address[];\n currentChainId = await this.getChainId();\n }\n\n if (chainId && currentChainId !== chainId) {\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: numberToHex(chainId) }],\n });\n currentChainId = await this.getChainId();\n }\n\n // Remove the one-time connect listener now that connection is established\n if (connect) {\n provider.removeListener(\"connect\", connect as never);\n connect = undefined;\n }\n if (!accountsChanged) {\n accountsChanged = this.onAccountsChanged.bind(this);\n provider.on(\"accountsChanged\", accountsChanged as never);\n }\n if (!chainChanged) {\n chainChanged = this.onChainChanged.bind(this);\n provider.on(\"chainChanged\", chainChanged as never);\n }\n if (!disconnect) {\n disconnect = this.onDisconnect.bind(this);\n provider.on(\"disconnect\", disconnect as never);\n }\n\n const response = withCapabilities\n ? {\n accounts: accounts.map((account) => ({\n address: account,\n capabilities: {},\n })),\n chainId: currentChainId,\n }\n : {\n accounts,\n chainId: currentChainId,\n };\n\n return response as unknown as {\n accounts: withCapabilities extends true\n ? readonly { address: Address; capabilities: Record<string, unknown> }[]\n : readonly Address[];\n chainId: number;\n };\n },\n\n /**\n * Disconnects the user and removes `chainChanged` / `disconnect` event listeners.\n *\n * The `accountsChanged` listener is intentionally left attached so that wagmi\n * receives the empty-accounts event emitted by the underlying provider's\n * `clearStoredUser` path.\n */\n async disconnect() {\n const provider = await this.getProvider();\n await provider.disconnect();\n if (chainChanged) {\n provider.removeListener(\"chainChanged\", chainChanged as never);\n chainChanged = undefined;\n }\n if (disconnect) {\n provider.removeListener(\"disconnect\", disconnect as never);\n disconnect = undefined;\n }\n },\n\n /**\n * Returns the list of currently connected account addresses.\n *\n * Delegates to `eth_accounts` on the underlying provider, which reads from\n * localStorage without opening any dialogs.\n *\n * @returns Array of connected addresses (empty if not connected)\n */\n async getAccounts() {\n const provider = await this.getProvider();\n return (await provider.request({\n method: \"eth_accounts\",\n })) as Address[];\n },\n\n /**\n * Returns the current chain ID as a number.\n *\n * Calls `eth_chainId` on the underlying provider and converts the hex result.\n *\n * @returns The numeric chain ID\n */\n async getChainId() {\n const provider = await this.getProvider();\n const hexChainId = (await provider.request({\n method: \"eth_chainId\",\n })) as string;\n return Number.parseInt(hexChainId, 16);\n },\n\n /**\n * Returns (and lazily creates) the underlying `OneAuthProvider` instance.\n *\n * The provider is a singleton per connector instance — created once and reused.\n * If a `chainId` argument is provided the provider switches to that chain before\n * returning.\n *\n * @param params.chainId - Optional chain ID to switch to before returning\n * @returns The singleton `OneAuthProvider`\n * @throws If no initial chain ID is configured\n */\n async getProvider({ chainId } = {}) {\n if (!provider) {\n if (!initialChainId) {\n throw new Error(\"No chain configured for 1auth connector\");\n }\n provider = createOneAuthProvider({\n client: options.client,\n chainId: initialChainId,\n storageKey: options.storageKey,\n waitForHash: options.waitForHash,\n hashTimeoutMs: options.hashTimeoutMs,\n hashIntervalMs: options.hashIntervalMs,\n });\n }\n if (chainId) {\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: numberToHex(chainId) }],\n });\n }\n return provider;\n },\n\n /**\n * Registers the one-time `connect` event listener used during initial setup.\n *\n * Called by wagmi during config initialization. Attaches `onConnect` to the\n * provider's `connect` event so that wagmi is notified if the user's session\n * is restored from localStorage before an explicit `connect()` call.\n */\n async setup() {\n const provider = await this.getProvider();\n if (!connect) {\n const onConnect = this.onConnect?.bind(this);\n if (onConnect) {\n connect = onConnect;\n provider.on(\"connect\", connect as never);\n }\n }\n },\n\n /**\n * Returns whether the connector has a valid stored session.\n *\n * Used by wagmi on startup to decide whether to attempt auto-reconnect.\n * Returns false (rather than throwing) if account resolution fails.\n *\n * @returns True if at least one account address is available\n */\n async isAuthorized() {\n try {\n const accounts = await this.getAccounts();\n return accounts.length > 0;\n } catch {\n return false;\n }\n },\n\n /**\n * Switches the active chain on the underlying provider.\n *\n * Validates that the requested chain is present in the wagmi config before\n * issuing `wallet_switchEthereumChain` so that an informative error is thrown\n * rather than a silent failure.\n *\n * @param params.chainId - The numeric ID of the chain to switch to\n * @returns The `Chain` object from wagmi config for the new chain\n * @throws If the chain is not in the wagmi config's `chains` array\n */\n async switchChain({ chainId }) {\n const chain = chains.find((chain) => chain.id === chainId);\n if (!chain) {\n throw new Error(\"Chain not configured\");\n }\n const provider = await this.getProvider();\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: numberToHex(chainId) }],\n });\n return chain;\n },\n\n /**\n * Handles the provider `connect` event and forwards it to wagmi's emitter.\n *\n * Called once during the initial connection handshake. Resolves the current\n * accounts and emits a wagmi `connect` event with both accounts and chain ID.\n *\n * @param connectInfo - EIP-1193 connect info containing the hex chain ID\n */\n async onConnect(connectInfo: ProviderConnectInfo) {\n const accounts = await this.getAccounts();\n if (!accounts.length) return;\n const chainId = Number(connectInfo.chainId);\n wagmiConfig.emitter.emit(\"connect\", { accounts, chainId });\n },\n\n /**\n * Handles the provider `accountsChanged` event and forwards it to wagmi.\n *\n * @param accounts - Updated list of account address strings\n */\n onAccountsChanged(accounts: string[]) {\n wagmiConfig.emitter.emit(\"change\", {\n accounts: accounts as Address[],\n });\n },\n\n /**\n * Handles the provider `chainChanged` event and forwards it to wagmi.\n *\n * @param chainId - The new chain ID as a hex string or decimal string\n */\n onChainChanged(chainId: string) {\n wagmiConfig.emitter.emit(\"change\", {\n chainId: Number(chainId),\n });\n },\n\n /**\n * Handles the provider `disconnect` event and forwards it to wagmi.\n *\n * @param _error - Optional error that caused the disconnection (unused)\n */\n onDisconnect(_error?: Error) {\n wagmiConfig.emitter.emit(\"disconnect\");\n },\n };\n });\n}\n","/**\n * EIP-1193 JSON-RPC provider factory for the 1auth passkey authentication system.\n *\n * Creates a browser-side provider object that implements the EIP-1193 standard so any\n * Ethereum library (ethers, viem, wagmi) can use 1auth passkey signing and cross-chain\n * intent execution without modification. All transaction signing is delegated to the\n * passkey service rather than holding private keys in the browser.\n *\n * Supported RPC methods:\n * - eth_chainId, eth_accounts, eth_requestAccounts\n * - personal_sign, eth_sign, eth_signTypedData, eth_signTypedData_v4\n * - eth_sendTransaction\n * - wallet_connect, wallet_disconnect, wallet_switchEthereumChain\n * - wallet_sendCalls, wallet_getCallsStatus, wallet_getCallsHistory (EIP-5792)\n * - wallet_getCapabilities, wallet_getAssets\n *\n * @module\n */\n\nimport {\n hexToString,\n isHex,\n numberToHex,\n type Address,\n type Hex,\n} from \"viem\";\nimport { OneAuthClient } from \"./client\";\nimport { getSupportedChainIds } from \"./registry\";\nimport type { CloseOnStatus, IntentCall, IntentTokenRequest, SignerType } from \"./types\";\nimport { encodeWebAuthnSignature } from \"./walletClient/utils\";\n\ntype ProviderRequest = {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n};\n\ntype Listener = (...args: unknown[]) => void;\n\ntype StoredUser = {\n address: Address;\n /** Absent = legacy passkey user; populated on new sessions. */\n signerType?: SignerType;\n /** Wagmi connector id for EOA sessions. Iframe-side lookup uses this. */\n connectorId?: string;\n};\n\nexport type OneAuthProvider = {\n request: (args: ProviderRequest) => Promise<unknown>;\n on: (event: string, listener: Listener) => void;\n removeListener: (event: string, listener: Listener) => void;\n disconnect: () => Promise<void>;\n};\n\nexport type OneAuthProviderOptions = {\n client: OneAuthClient;\n chainId: number;\n storageKey?: string;\n /** When to close the dialog and return success. Defaults to \"preconfirmed\" */\n closeOn?: CloseOnStatus;\n waitForHash?: boolean;\n hashTimeoutMs?: number;\n hashIntervalMs?: number;\n};\n\nconst DEFAULT_STORAGE_KEY = \"1auth-user\";\n\n/**\n * Creates an EIP-1193 compatible JSON-RPC provider backed by 1auth passkey authentication.\n *\n * The returned provider object can be used anywhere a standard Ethereum provider is\n * accepted (e.g. passed to `createWalletClient` in viem, used as `window.ethereum`, or\n * supplied to ethers.js `BrowserProvider`). Connection state (the account address) is\n * persisted in `localStorage` under the configured `storageKey`.\n *\n * @param options - Provider configuration\n * @param options.client - Configured `OneAuthClient` instance used to open auth/sign dialogs\n * @param options.chainId - Default chain ID the provider reports via `eth_chainId`\n * @param options.storageKey - localStorage key for persisting the connected user.\n * Defaults to `\"1auth-user\"`. Override to support multiple concurrent connections.\n * @param options.closeOn - Controls when the signing dialog closes and shows the \"Done\" button.\n * `\"preconfirmed\"` (default) closes as soon as the intent is confirmed by the orchestrator.\n * The `waitForHash` option independently controls whether the SDK continues polling for\n * a transaction hash after the dialog closes.\n * @param options.waitForHash - When true, polls the intent status until a transaction hash\n * is available before resolving `eth_sendTransaction` / `wallet_sendCalls`. Defaults to true.\n * @param options.hashTimeoutMs - Maximum milliseconds to wait for a transaction hash.\n * Passed directly to the passkey service intent submission.\n * @param options.hashIntervalMs - Polling interval in milliseconds when waiting for a hash.\n * Passed directly to the passkey service intent submission.\n * @returns An EIP-1193 provider with `request`, `on`, `removeListener`, and `disconnect`.\n *\n * @example\n * ```typescript\n * import { OneAuthClient } from \"@rhinestone/1auth\";\n * import { createOneAuthProvider } from \"@rhinestone/1auth\";\n *\n * const client = new OneAuthClient({ clientId: \"my-app\" });\n * const provider = createOneAuthProvider({ client, chainId: 8453 }); // Base\n *\n * // Use with viem\n * import { createWalletClient, custom } from \"viem\";\n * import { base } from \"viem/chains\";\n * const walletClient = createWalletClient({ chain: base, transport: custom(provider) });\n *\n * // Standard EIP-1193 usage\n * const accounts = await provider.request({ method: \"eth_requestAccounts\" });\n * provider.on(\"accountsChanged\", (accounts) => console.log(accounts));\n * ```\n */\nexport function createOneAuthProvider(\n options: OneAuthProviderOptions\n): OneAuthProvider {\n const { client } = options;\n let chainId = options.chainId;\n const storageKey = options.storageKey || DEFAULT_STORAGE_KEY;\n\n const listeners = new Map<string, Set<Listener>>();\n\n /**\n * Dispatches an event to all registered listeners for the given event name.\n *\n * @param event - EIP-1193 event name (e.g. \"accountsChanged\", \"chainChanged\")\n * @param args - Arguments forwarded to each listener callback\n */\n const emit = (event: string, ...args: unknown[]) => {\n const set = listeners.get(event);\n if (!set) return;\n for (const listener of set) listener(...args);\n };\n\n /**\n * Reads the connected user from localStorage.\n *\n * Returns null in non-browser environments (SSR) and when no user has been\n * persisted yet, or when the stored value is malformed.\n *\n * @returns The stored user object, or null if unavailable\n */\n const getStoredUser = (): StoredUser | null => {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(storageKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as StoredUser;\n if (!parsed?.address) return null;\n return parsed;\n } catch {\n return null;\n }\n };\n\n /**\n * Persists the connected user to localStorage.\n *\n * No-ops in non-browser (SSR) environments.\n *\n * @param user - User object with at minimum an `address` field\n */\n const setStoredUser = (user: StoredUser) => {\n if (typeof window === \"undefined\") return;\n localStorage.setItem(storageKey, JSON.stringify(user));\n };\n\n /**\n * Removes the connected user from localStorage, effectively logging them out\n * from the provider's perspective.\n *\n * No-ops in non-browser (SSR) environments.\n */\n const clearStoredUser = () => {\n if (typeof window === \"undefined\") return;\n localStorage.removeItem(storageKey);\n };\n\n /**\n * Connects the user by returning a cached address or opening the auth flow.\n *\n * Returns the dapp-side cached address immediately when present. Otherwise\n * opens the auth modal (`/dialog/auth`) directly — the iframe-side\n * returning-user UX lives inside that flow now. On success the address is\n * stored in localStorage and `accountsChanged` / `connect` events are emitted.\n *\n * @returns Array containing the single connected account address\n * @throws If the user cancels or authentication fails\n */\n const connect = async (): Promise<Address[]> => {\n const stored = getStoredUser();\n if (stored) {\n return [stored.address];\n }\n\n const authResult = await client.authWithModal();\n if (!authResult.success) {\n throw new Error(authResult.error?.message || \"Authentication failed\");\n }\n const address = authResult.user?.address;\n const signerType = authResult.signerType;\n\n if (!address) {\n throw new Error(\"No account address available\");\n }\n\n setStoredUser({ address, signerType });\n emit(\"accountsChanged\", [address]);\n emit(\"connect\", { chainId: numberToHex(chainId) });\n return [address];\n };\n\n /**\n * Disconnects the current user by clearing persisted state and emitting events.\n *\n * Emits `accountsChanged` with an empty array and `disconnect` so that consumers\n * (e.g. wagmi) can update their state accordingly.\n */\n const disconnect = async () => {\n clearStoredUser();\n emit(\"accountsChanged\", []);\n emit(\"disconnect\");\n };\n\n /**\n * Returns the currently connected user, triggering the connect flow if needed.\n *\n * Used internally by methods that require an authenticated session (e.g. signing,\n * sending transactions) to guarantee a user is available before proceeding.\n *\n * @returns The stored user object with at minimum an `address` field\n * @throws If connecting fails and no address can be resolved\n */\n const ensureUser = async (): Promise<StoredUser> => {\n const stored = getStoredUser();\n if (stored) return stored;\n const [address] = await connect();\n if (!address) {\n throw new Error(\"Failed to resolve user session\");\n }\n const user = getStoredUser();\n return user || { address };\n };\n\n /**\n * Read an optional wallet_getAssets account address override from RPC params.\n */\n const getAssetsAccountAddress = (\n assetsParams?: unknown[] | Record<string, unknown>,\n ): string | undefined => {\n const raw = Array.isArray(assetsParams) ? assetsParams[0] : assetsParams;\n if (typeof raw === \"string\" && raw.trim()) return raw.trim();\n if (!raw || typeof raw !== \"object\") return undefined;\n\n const request = raw as Record<string, unknown>;\n const candidates = [\n request.accountAddress,\n request.address,\n ];\n for (const candidate of candidates) {\n if (typeof candidate === \"string\" && candidate.trim()) {\n return candidate.trim();\n }\n }\n return undefined;\n };\n\n /**\n * Parses a chain ID value that may arrive as a hex string, decimal string, or number.\n *\n * Handles both `\"0x1\"` (hex) and `\"1\"` / `1` (decimal) representations that are\n * commonly mixed across different wallet_switchEthereumChain implementations.\n *\n * @param value - The raw chain ID value from RPC params\n * @returns The numeric chain ID, or undefined if the value cannot be parsed\n */\n const parseChainId = (value: unknown): number | undefined => {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n if (value.startsWith(\"0x\")) return Number.parseInt(value, 16);\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n };\n\n /**\n * Normalizes a transaction value to a decimal string expected by the intent service.\n *\n * Handles the various formats callers may provide: `bigint`, `number`, hex strings\n * (e.g. `\"0x38d7ea4c68000\"`), or plain decimal strings. Returns undefined for null\n * or unsupported types, allowing callers to fall back to `\"0\"`.\n *\n * @param value - Raw value from an RPC transaction param\n * @returns Decimal string representation, or undefined if the input is not usable\n */\n const normalizeValue = (value: unknown): string | undefined => {\n if (value === undefined || value === null) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value === \"number\") return Math.trunc(value).toString();\n if (typeof value === \"string\") {\n if (value.startsWith(\"0x\")) {\n return BigInt(value).toString();\n }\n return value;\n }\n return undefined;\n };\n\n /**\n * Converts raw EIP-1193 call objects into the strongly-typed `IntentCall` format\n * expected by the passkey service.\n *\n * Fills in missing `data` with `\"0x\"` and missing `value` with `\"0\"` so the\n * intent service never receives undefined fields.\n *\n * @param calls - Raw call objects from `wallet_sendCalls` or `eth_sendTransaction` params\n * @returns Array of normalized `IntentCall` objects\n */\n const normalizeCalls = (calls: unknown[]): IntentCall[] => {\n return calls.map((call) => {\n const c = call as Record<string, unknown>;\n return {\n to: c.to as Address,\n data: (c.data as Hex | undefined) || \"0x\",\n value: normalizeValue(c.value) || \"0\",\n label: c.label as string | undefined,\n sublabel: c.sublabel as string | undefined,\n icon: c.icon as string | undefined,\n abi: c.abi as readonly unknown[] | undefined,\n };\n });\n };\n\n /**\n * Converts raw token request objects into the typed `IntentTokenRequest` format.\n *\n * Token requests allow callers to specify which tokens and amounts should be sourced\n * when funding a cross-chain intent (e.g. \"bridge 10 USDC from Optimism to Base\").\n * Accepts bigint or string/numeric amounts and normalizes them to bigint.\n *\n * @param requests - Raw token request array from RPC params, or a non-array value\n * @returns Array of typed token requests, or undefined if input is not an array\n */\n const normalizeTokenRequests = (\n requests: unknown\n ): IntentTokenRequest[] | undefined => {\n if (!Array.isArray(requests)) return undefined;\n return requests.map((r) => {\n const req = r as Record<string, unknown>;\n return {\n token: req.token as string,\n amount:\n typeof req.amount === \"bigint\"\n ? req.amount\n : BigInt(String(req.amount || \"0\")),\n };\n });\n };\n\n /**\n * Decodes a message that may be hex-encoded into a human-readable string.\n *\n * Some signers (e.g. MetaMask) encode plain-text messages as hex before passing them\n * to `personal_sign`. This helper reverses that encoding so users see the original\n * text in the signing dialog rather than a raw hex string.\n *\n * @param value - A plain string or hex-encoded string (`\"0x...\"`)\n * @returns The decoded UTF-8 string, or the original value if decoding fails\n */\n const decodeMessage = (value: string) => {\n if (!isHex(value)) return value;\n try {\n return hexToString(value as Hex);\n } catch {\n return value;\n }\n };\n\n /**\n * Forwards a raw EIP-1193 request to the iframe at `/dialog/sign-eoa`, which\n * delegates to the active wagmi connector. The wallet's own prompt is the\n * review screen — no in-dialog review step for EOA sessions.\n */\n const forwardToWallet = async (\n method: string,\n params?: unknown[] | Record<string, unknown>,\n expectedAddress?: Address,\n ): Promise<unknown> => {\n const result = await client.requestWithWallet({\n method,\n params,\n expectedAddress,\n });\n if (!result.success) {\n const err = new Error(result.error.message);\n (err as Error & { code?: string }).code = result.error.code;\n throw err;\n }\n return result.result;\n };\n\n /**\n * EIP-1193 methods forwarded verbatim to the EOA connector. All other methods\n * (eth_accounts, eth_chainId, wallet_connect, wallet_disconnect,\n * wallet_switchEthereumChain, wallet_getCapabilities/Assets) are handled\n * locally against the stored session even for EOA sessions.\n */\n const EOA_FORWARDED_METHODS = new Set([\n \"personal_sign\",\n \"eth_sign\",\n \"eth_signTypedData\",\n \"eth_signTypedData_v3\",\n \"eth_signTypedData_v4\",\n \"eth_sendTransaction\",\n \"wallet_sendCalls\",\n \"wallet_getCallsStatus\",\n ]);\n\n /**\n * Signs an arbitrary string message via the passkey service.\n *\n * Ensures a user session exists before delegating to `OneAuthClient.signMessage`.\n * The raw WebAuthn signature components are ABI-encoded for ERC-1271 on-chain\n * verification before being returned.\n *\n * @param message - Plain-text message to sign\n * @returns ABI-encoded WebAuthn signature as a hex string\n * @throws If no user session is available or the signing dialog is cancelled\n */\n const signMessage = async (message: string) => {\n const user = await ensureUser();\n if (!user.address) {\n throw new Error(\"Account address required for signing.\");\n }\n const result = await client.signMessage({\n accountAddress: user.address,\n message,\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Signs EIP-712 typed data via the passkey service.\n *\n * Accepts either a parsed typed-data object or a JSON string (as some libraries\n * serialize the payload before passing it through the provider). The raw WebAuthn\n * signature is ABI-encoded for ERC-1271 on-chain verification.\n *\n * @param typedData - EIP-712 typed data object or its JSON string representation\n * @returns ABI-encoded WebAuthn signature as a hex string\n * @throws If no user session is available or the signing dialog is cancelled\n */\n const signTypedData = async (typedData: unknown) => {\n const user = await ensureUser();\n if (!user.address) {\n throw new Error(\"Account address required for signing.\");\n }\n const data =\n typeof typedData === \"string\" ? JSON.parse(typedData) : typedData;\n const result = await client.signTypedData({\n accountAddress: user.address,\n domain: (data as any).domain,\n types: (data as any).types,\n primaryType: (data as any).primaryType,\n message: (data as any).message,\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Extracts the fields required by `OneAuthClient.sendIntent` from a richer payload.\n *\n * This thin wrapper makes it explicit which fields travel to the intent service and\n * which are local concerns (e.g. `sourceChainId` is handled at the call site).\n *\n * @param payload - Full intent payload including user identity and transaction data\n * @returns Subset of fields forwarded to the intent service\n */\n const resolveIntentPayload = (payload: {\n accountAddress: Address;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: IntentTokenRequest[];\n }) => ({\n accountAddress: payload.accountAddress,\n targetChain: payload.targetChain,\n calls: payload.calls,\n tokenRequests: payload.tokenRequests,\n });\n\n /**\n * Submits a cross-chain intent through the passkey service and returns the intent ID.\n *\n * Opens the signing dialog, waits for user confirmation, then polls the orchestrator\n * until a transaction hash is available (controlled by `waitForHash` and the timeout\n * options). The returned intent ID is used as the `callsId` in EIP-5792 responses.\n *\n * The dialog closes based on `closeOn` (defaults to `\"preconfirmed\"`). The `waitForHash`\n * option independently polls for a transaction hash after the dialog closes.\n *\n * @param payload - Intent details including target chain, calls, token requests, and\n * an optional `sourceChainId` for cross-chain bridging\n * @returns The orchestrator intent ID string\n * @throws If the user rejects the signing dialog or the intent fails\n */\n const sendIntent = async (payload: {\n accountAddress: Address;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: IntentTokenRequest[];\n sourceChainId?: number;\n }) => {\n const intentPayload = resolveIntentPayload(payload);\n const result = await client.sendIntent({\n ...intentPayload,\n tokenRequests: payload.tokenRequests,\n sourceChainId: payload.sourceChainId,\n closeOn: options.closeOn,\n waitForHash: options.waitForHash ?? true,\n hashTimeoutMs: options.hashTimeoutMs,\n hashIntervalMs: options.hashIntervalMs,\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || \"Transaction failed\");\n }\n\n // Return intentId as callsId for EIP-5792 compatibility\n return result.intentId;\n };\n\n const accountMismatchError = (): Error & { code?: string } => {\n const err = new Error(\n \"Requested signer does not match the active wallet connection.\",\n ) as Error & { code?: string };\n err.code = \"ACCOUNT_MISMATCH\";\n return err;\n };\n\n const sameAddress = (a: unknown, b: string): boolean =>\n typeof a === \"string\" && a.toLowerCase() === b.toLowerCase();\n\n /**\n * Some wallets (MetaMask, Rabby) reject `eth_sendTransaction` /\n * `wallet_sendCalls` / `personal_sign` / `eth_signTypedData_v4` when the\n * signer address is missing. The dapp doesn't know the EOA address, so the\n * SDK fills it in from the stored session.\n *\n * If the caller supplies a `from` (or address arg) that differs from the\n * connected EOA, we throw `ACCOUNT_MISMATCH` rather than letting the\n * caller's value win. A dapp asking the wallet to sign on behalf of a\n * different account than the user connected is a trust-boundary violation\n * — the user reviewed and approved exactly one address, not whatever the\n * dapp later substitutes.\n */\n const injectEoaSigner = (\n method: string,\n params: unknown[] | Record<string, unknown> | undefined,\n address: Address,\n ): unknown[] | Record<string, unknown> | undefined => {\n const list = Array.isArray(params) ? params.slice() : params;\n if (!Array.isArray(list)) return params;\n\n if (method === \"eth_sendTransaction\") {\n const first = (list[0] || {}) as Record<string, unknown>;\n if (first.from !== undefined && !sameAddress(first.from, address)) {\n throw accountMismatchError();\n }\n list[0] = { ...first, from: address };\n return list;\n }\n if (method === \"wallet_sendCalls\") {\n const first = (list[0] || {}) as Record<string, unknown>;\n if (first.from !== undefined && !sameAddress(first.from, address)) {\n throw accountMismatchError();\n }\n // EIP-5792 lets each call carry its own `from`. Validate every one —\n // a single mismatched call would otherwise sneak through unchecked.\n const calls = first.calls;\n if (Array.isArray(calls)) {\n for (const call of calls) {\n if (!call || typeof call !== \"object\") continue;\n const callFrom = (call as Record<string, unknown>).from;\n if (callFrom !== undefined && !sameAddress(callFrom, address)) {\n throw accountMismatchError();\n }\n }\n }\n list[0] = { ...first, from: address };\n return list;\n }\n if (method === \"personal_sign\") {\n // personal_sign(message, address) — fill address if absent.\n if (list[1] !== undefined && !sameAddress(list[1], address)) {\n throw accountMismatchError();\n }\n if (list[0] && list[1] === undefined) list[1] = address;\n return list;\n }\n if (\n method === \"eth_sign\" ||\n method === \"eth_signTypedData\" ||\n method === \"eth_signTypedData_v3\" ||\n method === \"eth_signTypedData_v4\"\n ) {\n // signTypedData(address, typedData) — fill address if absent.\n if (list[0] !== undefined && !sameAddress(list[0], address)) {\n throw accountMismatchError();\n }\n if (list[0] === undefined && list[1] !== undefined) list[0] = address;\n return list;\n }\n return list;\n };\n\n const request = async ({ method, params }: ProviderRequest) => {\n // For sign/tx methods, resolve the user first — this opens the auth modal\n // on the very first call so we know the signerType before deciding\n // between the passkey path and forwarding to the wagmi connector. Local-\n // only methods (eth_accounts, eth_chainId, wallet_switchEthereumChain,\n // etc.) fall through to the switch below and read stored state directly.\n if (EOA_FORWARDED_METHODS.has(method)) {\n const user = await ensureUser();\n if (user.signerType === \"eoa\") {\n return forwardToWallet(\n method,\n injectEoaSigner(method, params, user.address),\n user.address,\n );\n }\n }\n\n switch (method) {\n case \"eth_chainId\":\n return numberToHex(chainId);\n case \"eth_accounts\": {\n const stored = getStoredUser();\n return stored ? [stored.address] : [];\n }\n case \"eth_requestAccounts\":\n return connect();\n case \"wallet_connect\":\n return connect();\n case \"wallet_disconnect\":\n await disconnect();\n return true;\n case \"wallet_switchEthereumChain\": {\n const [param] = (params as any[]) || [];\n const next = parseChainId(param?.chainId ?? param);\n if (!next) {\n throw new Error(\"Invalid chainId\");\n }\n const stored = getStoredUser();\n if (stored?.signerType === \"eoa\") {\n await forwardToWallet(method, params, stored.address);\n }\n chainId = next;\n emit(\"chainChanged\", numberToHex(chainId));\n return null;\n }\n case \"personal_sign\": {\n const paramList = Array.isArray(params) ? params : [];\n const first = paramList[0];\n const second = paramList[1];\n // personal_sign param order varies: some callers send [message, address],\n // others send [hexEncodedMessage, address]. When the first param is hex and\n // the second is a non-hex string we treat the second as the plain message\n // (MetaMask-style). Otherwise we always decode the first param.\n const message =\n typeof first === \"string\" && first.startsWith(\"0x\") && second\n ? typeof second === \"string\" && !second.startsWith(\"0x\")\n ? second\n : decodeMessage(first)\n : typeof first === \"string\"\n ? decodeMessage(first)\n : typeof second === \"string\"\n ? decodeMessage(second)\n : \"\";\n if (!message) throw new Error(\"Invalid personal_sign payload\");\n return signMessage(message);\n }\n case \"eth_sign\": {\n const paramList = Array.isArray(params) ? params : [];\n const message = typeof paramList[1] === \"string\" ? paramList[1] : \"\";\n if (!message) throw new Error(\"Invalid eth_sign payload\");\n return signMessage(decodeMessage(message));\n }\n case \"eth_signTypedData\":\n case \"eth_signTypedData_v4\": {\n const paramList = Array.isArray(params) ? params : [];\n const typedData = paramList[1] ?? paramList[0];\n return signTypedData(typedData);\n }\n case \"eth_sendTransaction\": {\n const paramList = Array.isArray(params) ? params : [];\n const tx = (paramList[0] || {}) as Record<string, unknown>;\n const user = await ensureUser();\n const targetChain = parseChainId(tx.chainId) ?? chainId;\n const calls = normalizeCalls([tx]);\n const tokenRequests = normalizeTokenRequests(tx.tokenRequests);\n const txSourceChainId = parseChainId(tx.sourceChainId);\n return sendIntent({\n accountAddress: user.address,\n targetChain,\n calls,\n tokenRequests,\n sourceChainId: txSourceChainId,\n });\n }\n case \"wallet_sendCalls\": {\n const paramList = Array.isArray(params) ? params : [];\n const payload = (paramList[0] || {}) as Record<string, unknown>;\n const user = await ensureUser();\n const targetChain = parseChainId(payload.chainId) ?? chainId;\n const calls = normalizeCalls((payload.calls as unknown[]) || []);\n const tokenRequests = normalizeTokenRequests(payload.tokenRequests);\n const sourceChainId = parseChainId(payload.sourceChainId);\n if (!calls.length) throw new Error(\"No calls provided\");\n return sendIntent({\n accountAddress: user.address,\n targetChain,\n calls,\n tokenRequests,\n sourceChainId,\n });\n }\n case \"wallet_getCapabilities\": {\n const stored = getStoredUser();\n if (stored?.signerType === \"eoa\") {\n return {};\n }\n\n const paramList = Array.isArray(params) ? params : [];\n // walletAddress is params[0] - we ignore since all accounts have same capabilities\n const requestedChains = paramList[1] as `0x${string}`[] | undefined;\n\n const chainIds = getSupportedChainIds();\n const capabilities: Record<`0x${string}`, Record<string, unknown>> = {};\n\n for (const chainId of chainIds) {\n const hexChainId = `0x${chainId.toString(16)}` as `0x${string}`;\n\n // Filter if specific chains requested\n if (requestedChains && !requestedChains.includes(hexChainId)) {\n continue;\n }\n\n // All supported chains advertise atomic batching, gasless transactions via\n // paymasters, and cross-chain auxiliary funds (EIP-5792 capability keys).\n capabilities[hexChainId] = {\n atomic: { status: \"supported\" },\n paymasterService: { supported: true },\n auxiliaryFunds: { supported: true },\n };\n }\n\n return capabilities;\n }\n case \"wallet_getAssets\": {\n const explicitAccountAddress = getAssetsAccountAddress(params);\n const user = explicitAccountAddress ? null : await ensureUser();\n // The portfolio endpoint resolves identifiers via resolveUserWhere,\n // and the current SDK account model is address-first. Explicit params\n // let app-level verified sessions query balances without relying on\n // the provider's localStorage cache, while connected EIP-1193 consumers\n // still work with no params.\n const accountAddress = explicitAccountAddress || user?.address;\n if (!accountAddress) {\n throw new Error(\"wallet_getAssets requires accountAddress or a connected account\");\n }\n return client.getAssets({ accountAddress: accountAddress as Address });\n }\n case \"wallet_getCallsStatus\": {\n const paramList = Array.isArray(params) ? params : [];\n const callsId = paramList[0] as string;\n if (!callsId) {\n throw new Error(\"callsId is required\");\n }\n const statusClientId = client.getClientId();\n const response = await fetch(\n `${client.getProviderUrl()}/api/intent/status/${encodeURIComponent(callsId)}`,\n {\n headers: statusClientId ? { \"x-client-id\": statusClientId } : {},\n }\n );\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to get calls status\");\n }\n const data = await response.json();\n // Map intent status to EIP-5792 status strings.\n // Both \"failed\" and \"expired\" map to \"CONFIRMED\" because EIP-5792 uses receipts\n // (and a 0x0 status code) to communicate failure — there is no \"FAILED\" state.\n const statusMap: Record<string, string> = {\n pending: \"PENDING\",\n preconfirmed: \"PENDING\",\n completed: \"CONFIRMED\",\n failed: \"CONFIRMED\",\n expired: \"CONFIRMED\",\n };\n return {\n status: statusMap[data.status] || \"PENDING\",\n receipts: data.transactionHash\n ? [\n {\n logs: [],\n // 0x1 = success, 0x0 = reverted/failed — mirrors EVM receipt status\n status: data.status === \"completed\" ? \"0x1\" : \"0x0\",\n blockHash: data.blockHash,\n blockNumber: data.blockNumber,\n transactionHash: data.transactionHash,\n },\n ]\n : [],\n };\n }\n case \"wallet_getCallsHistory\": {\n const paramList = Array.isArray(params) ? params : [];\n const options = (paramList[0] || {}) as {\n limit?: number;\n offset?: number;\n status?: string;\n from?: string;\n to?: string;\n };\n\n const queryParams = new URLSearchParams();\n if (options.limit) queryParams.set(\"limit\", String(options.limit));\n if (options.offset) queryParams.set(\"offset\", String(options.offset));\n if (options.status) queryParams.set(\"status\", options.status);\n if (options.from) queryParams.set(\"from\", options.from);\n if (options.to) queryParams.set(\"to\", options.to);\n\n const url = `${client.getProviderUrl()}/api/intent/history${\n queryParams.toString() ? `?${queryParams}` : \"\"\n }`;\n\n const historyClientId = client.getClientId();\n const response = await fetch(url, {\n headers: historyClientId ? { \"x-client-id\": historyClientId } : {},\n credentials: \"include\",\n });\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to get calls history\");\n }\n\n const data = await response.json();\n\n // Map intent status to EIP-5792 format\n const statusMap: Record<string, string> = {\n pending: \"PENDING\",\n preconfirmed: \"PENDING\",\n completed: \"CONFIRMED\",\n failed: \"CONFIRMED\",\n expired: \"CONFIRMED\",\n };\n\n // intentId IS the orchestrator's ID (used as callsId in EIP-5792)\n return {\n calls: data.intents.map(\n (intent: {\n intentId: string;\n status: string;\n transactionHash?: string;\n targetChain: number;\n }) => ({\n callsId: intent.intentId, // intentId is the orchestrator's ID\n status: statusMap[intent.status] || \"PENDING\",\n receipts: intent.transactionHash\n ? [{ transactionHash: intent.transactionHash }]\n : [],\n chainId: `0x${intent.targetChain.toString(16)}`,\n })\n ),\n total: data.total,\n hasMore: data.hasMore,\n };\n }\n default:\n throw new Error(`Unsupported method: ${method}`);\n }\n };\n\n return {\n request,\n on(event, listener) {\n const set = listeners.get(event) ?? new Set();\n set.add(listener);\n listeners.set(event, set);\n },\n removeListener(event, listener) {\n const set = listeners.get(event);\n if (!set) return;\n set.delete(listener);\n if (set.size === 0) listeners.delete(event);\n },\n disconnect,\n };\n}\n","/**\n * @file Chain and token registry for the 1auth SDK.\n *\n * Wraps `@rhinestone/shared-configs` chain/token data and combines it with\n * viem's chain definitions to expose a filtered, testnet-aware registry.\n * Consumers can look up supported chains and tokens, resolve token addresses\n * by symbol, and retrieve chain metadata such as explorer URLs and default RPC\n * endpoints.\n *\n * Testnet inclusion is controlled by the `includeTestnets` option on each\n * function or, as a project-wide default, by the environment variables\n * `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` or `ORCHESTRATOR_USE_TESTNETS`.\n */\n\nimport type { Address, Chain } from \"viem\";\nimport { isAddress } from \"viem\";\nimport * as viemChains from \"viem/chains\";\nimport { chainRegistry } from \"@rhinestone/shared-configs\";\n\nexport type TokenConfig = {\n symbol: string;\n address: Address;\n decimals: number;\n};\n\nexport type ChainFilterOptions = {\n includeTestnets?: boolean;\n chainIds?: number[];\n};\n\ntype ChainRegistryEntry = (typeof chainRegistry)[keyof typeof chainRegistry];\n\nconst env: Record<string, string | undefined> =\n typeof process !== \"undefined\" ? process.env : {};\n\n// Build a chain-ID-to-Chain map from viem, resolving collisions by preferring\n// mainnet definitions over testnets. viem exports duplicate numeric IDs (e.g.\n// zoraTestnet and hyperEvm both use 999); a naive Map would silently keep\n// whichever entry happens to appear last in iteration order, which may be the\n// testnet. The loop below only overwrites an existing entry when the incoming\n// chain is NOT a testnet and the existing one IS, ensuring the production chain\n// always wins while still falling back to a testnet entry when no mainnet\n// definition exists for a given ID.\nconst VIEM_CHAIN_BY_ID = new Map<number, Chain>();\nfor (const value of Object.values(viemChains)) {\n if (typeof value !== \"object\" || value === null || !(\"id\" in value) || !(\"name\" in value)) continue;\n const chain = value as Chain;\n const existing = VIEM_CHAIN_BY_ID.get(chain.id);\n if (!existing || (existing.testnet && !chain.testnet)) {\n VIEM_CHAIN_BY_ID.set(chain.id, chain);\n }\n}\n\nfunction isEvmRegistryEntry(\n entry: ChainRegistryEntry | undefined,\n): entry is ChainRegistryEntry & { vmType: \"evm\" } {\n return entry?.vmType === \"evm\";\n}\n\nfunction getEvmRegistryEntry(\n chainId: number,\n): (ChainRegistryEntry & { vmType: \"evm\" }) | undefined {\n const entry = chainRegistry[String(chainId) as keyof typeof chainRegistry];\n return isEvmRegistryEntry(entry) ? entry : undefined;\n}\n\n// The shared-configs registry includes non-EVM chains (Solana, Tron). Filter\n// to EVM entries before exposing supported chains — downstream consumers\n// (viem clients, wallet_getCapabilities, RPC proxy) only handle eip155 chains.\nconst REGISTRY_CHAIN_IDS = Object.entries(chainRegistry)\n .filter(([, entry]) => isEvmRegistryEntry(entry))\n .map(([id]) => Number(id));\nconst SUPPORTED_CHAIN_IDS = new Set(REGISTRY_CHAIN_IDS);\n\nfunction tokensForChain(chainId: number): TokenConfig[] {\n const entry = getEvmRegistryEntry(chainId);\n if (!entry) return [];\n return entry.tokens.map((token) => ({\n symbol: token.symbol,\n address: token.address as Address,\n decimals: token.decimals,\n }));\n}\n\n/** Treat any 20-byte hex string as an address; checksum casing is optional for user inputs. */\nfunction isAddressInput(value: string): value is Address {\n return isAddress(value, { strict: false });\n}\n\n/**\n * Parse a string environment variable into a boolean, returning `undefined`\n * when the value is absent or not a recognised truthy/falsy literal.\n *\n * Accepted truthy values: `\"true\"`, `\"1\"`.\n * Accepted falsy values: `\"false\"`, `\"0\"`.\n */\nfunction parseBool(value?: string): boolean | undefined {\n if (value === \"true\" || value === \"1\") return true;\n if (value === \"false\" || value === \"0\") return false;\n return undefined;\n}\n\n/**\n * Determine whether testnet chains should be included in registry results.\n *\n * Precedence (highest to lowest):\n * 1. `explicit` argument — a caller-supplied boolean always wins.\n * 2. `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` env var — checked first so\n * Next.js browser bundles (which only expose `NEXT_PUBLIC_*` variables)\n * can configure testnet mode without a server-side env var.\n * 3. `ORCHESTRATOR_USE_TESTNETS` env var — server-side / Node.js fallback.\n * 4. Defaults to `false` (testnets excluded) when none of the above is set.\n */\nfunction resolveIncludeTestnets(explicit?: boolean): boolean {\n if (explicit !== undefined) return explicit;\n const envValue =\n parseBool(env.NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS) ??\n parseBool(env.ORCHESTRATOR_USE_TESTNETS);\n return envValue ?? false;\n}\n\nfunction applyChainFilters(chainIds: number[], options?: ChainFilterOptions): number[] {\n const includeTestnets = resolveIncludeTestnets(options?.includeTestnets);\n const allowlist = options?.chainIds;\n let filtered = chainIds;\n\n if (!includeTestnets) {\n filtered = filtered.filter((chainId) => !isTestnet(chainId));\n }\n\n if (allowlist) {\n const allowed = new Set(allowlist);\n filtered = filtered.filter((chainId) => allowed.has(chainId));\n }\n\n return filtered;\n}\n\nexport function getSupportedChainIds(options?: ChainFilterOptions): number[] {\n return applyChainFilters(REGISTRY_CHAIN_IDS, options);\n}\n\nexport function getSupportedChains(options?: ChainFilterOptions): Chain[] {\n return getSupportedChainIds(options)\n .map((chainId) => VIEM_CHAIN_BY_ID.get(chainId))\n .filter((chain): chain is Chain => Boolean(chain));\n}\n\nexport function getAllSupportedChainsAndTokens(options?: ChainFilterOptions): Array<{\n chainId: number;\n tokens: TokenConfig[];\n}> {\n return getSupportedChainIds(options).map((chainId) => ({\n chainId,\n tokens: tokensForChain(chainId),\n }));\n}\n\nexport function getChainById(chainId: number): Chain {\n if (!SUPPORTED_CHAIN_IDS.has(chainId)) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n const chain = VIEM_CHAIN_BY_ID.get(chainId);\n if (!chain) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n return chain;\n}\n\nexport function getChainName(chainId: number): string {\n try {\n return getChainById(chainId).name;\n } catch {\n return `Chain ${chainId}`;\n }\n}\n\nexport function getChainExplorerUrl(chainId: number): string | undefined {\n try {\n return getChainById(chainId).blockExplorers?.default?.url;\n } catch {\n return undefined;\n }\n}\n\nexport function getChainRpcUrl(chainId: number): string | undefined {\n try {\n const chain = getChainById(chainId);\n return chain.rpcUrls?.default?.http?.[0] || chain.rpcUrls?.public?.http?.[0];\n } catch {\n return undefined;\n }\n}\n\nexport function getSupportedTokens(chainId: number): TokenConfig[] {\n return tokensForChain(chainId);\n}\n\nexport function getSupportedTokenSymbols(chainId: number): string[] {\n return getSupportedTokens(chainId).map((token) => token.symbol);\n}\n\nexport function getTokenAddress(symbolOrAddress: string, chainId: number): Address {\n if (isAddressInput(symbolOrAddress)) {\n return symbolOrAddress;\n }\n const match = getSupportedTokens(chainId).find(\n (t) => t.symbol.toUpperCase() === symbolOrAddress.toUpperCase()\n );\n if (!match) {\n throw new Error(`Unsupported token \"${symbolOrAddress}\" on chain ${chainId}`);\n }\n return match.address;\n}\n\nexport function getTokenDecimals(symbolOrAddress: string, chainId: number): number {\n const match = getSupportedTokens(chainId).find(\n (t) =>\n isAddressInput(symbolOrAddress)\n ? t.address.toLowerCase() === symbolOrAddress.toLowerCase()\n : t.symbol.toUpperCase() === symbolOrAddress.toUpperCase()\n );\n if (!match && isAddressInput(symbolOrAddress) && SUPPORTED_CHAIN_IDS.has(chainId)) {\n return 18;\n }\n if (!match) {\n throw new Error(`Unsupported token \"${symbolOrAddress}\" on chain ${chainId}`);\n }\n return match.decimals;\n}\n\nexport function resolveTokenAddress(token: string, chainId: number): Address {\n if (isAddressInput(token)) {\n return token;\n }\n return getTokenAddress(token, chainId);\n}\n\nexport function isTestnet(chainId: number): boolean {\n try {\n return getChainById(chainId).testnet ?? false;\n } catch {\n return false;\n }\n}\n\nexport function getTokenSymbol(tokenAddress: Address, chainId: number): string {\n const token = getSupportedTokens(chainId).find(\n (entry) => entry.address.toLowerCase() === tokenAddress.toLowerCase()\n );\n if (token) {\n return token.symbol;\n }\n if (!SUPPORTED_CHAIN_IDS.has(chainId)) {\n throw new Error(`Unsupported chain ID: ${chainId}`);\n }\n return \"Token\";\n}\n\nexport function isTokenAddressSupported(tokenAddress: Address, chainId: number): boolean {\n return isAddressInput(tokenAddress) && SUPPORTED_CHAIN_IDS.has(chainId);\n}\n","import { encodeAbiParameters, keccak256 } from 'viem';\nimport type { Hex } from 'viem';\nimport type { WebAuthnSignature } from '../types';\nimport type { TransactionCall } from './types';\n\n/**\n * P-256 curve order (n)\n * Used for signature malleability normalization\n */\nconst P256_N = BigInt(\n '0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551'\n);\nconst P256_N_DIV_2 = P256_N / 2n;\n\n/**\n * WebAuthnAuth struct type for ABI encoding\n */\nconst WEBAUTHN_AUTH_TYPE = {\n type: 'tuple',\n components: [\n { type: 'bytes', name: 'authenticatorData' },\n { type: 'string', name: 'clientDataJSON' },\n { type: 'uint256', name: 'challengeIndex' },\n { type: 'uint256', name: 'typeIndex' },\n { type: 'uint256', name: 'r' },\n { type: 'uint256', name: 's' },\n ],\n} as const;\n\n/**\n * Encode a WebAuthn signature for ERC-1271 verification on-chain\n *\n * @param sig - The WebAuthn signature from the passkey\n * @returns ABI-encoded signature bytes\n */\nexport function encodeWebAuthnSignature(sig: WebAuthnSignature): Hex {\n // Normalize s to prevent signature malleability\n let s = BigInt(sig.s);\n if (s > P256_N_DIV_2) {\n s = P256_N - s;\n }\n\n return encodeAbiParameters([WEBAUTHN_AUTH_TYPE], [\n {\n authenticatorData: sig.authenticatorData as Hex,\n clientDataJSON: sig.clientDataJSON,\n challengeIndex: BigInt(sig.challengeIndex),\n typeIndex: BigInt(sig.typeIndex),\n r: BigInt(sig.r),\n s,\n },\n ]);\n}\n\n/**\n * Hash an array of transaction calls for signing\n *\n * @param calls - Array of transaction calls\n * @returns keccak256 hash of the encoded calls\n */\nexport function hashCalls(calls: TransactionCall[]): Hex {\n const encoded = encodeAbiParameters(\n [\n {\n type: 'tuple[]',\n components: [\n { type: 'address', name: 'to' },\n { type: 'bytes', name: 'data' },\n { type: 'uint256', name: 'value' },\n ],\n },\n ],\n [\n calls.map((c) => ({\n to: c.to,\n data: c.data || '0x',\n value: c.value || 0n,\n })),\n ]\n );\n return keccak256(encoded);\n}\n\n/**\n * Build transaction review display data from calls\n *\n * @param calls - Array of transaction calls\n * @returns TransactionDetails for the signing modal\n */\nexport function buildTransactionReview(calls: TransactionCall[]) {\n return {\n actions: calls.map((call, i) => ({\n type: 'custom' as const,\n label: call.label || `Contract Call ${i + 1}`,\n sublabel: call.sublabel || `To: ${call.to.slice(0, 10)}...${call.to.slice(-8)}`,\n amount: call.value ? `${call.value} wei` : undefined,\n })),\n };\n}\n"],"mappings":"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","names":["import_viem","import_viem","import_viem","request","chainId","data","options","provider","chain"]}
package/dist/wagmi.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createOneAuthProvider
3
- } from "./chunk-UXBBB7AV.mjs";
3
+ } from "./chunk-6MUQKHAT.mjs";
4
4
  import "./chunk-N6KE5CII.mjs";
5
5
  import "./chunk-GUAI55LL.mjs";
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhinestone/1auth",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "Passkey-based authentication SDK for Web3 applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/verify.ts"],"sourcesContent":["import { keccak256, toBytes } from \"viem\";\n\n/**\n * The EIP-191 prefix used for personal message signing.\n * This is the standard Ethereum message prefix for `personal_sign`.\n */\nexport const ETHEREUM_MESSAGE_PREFIX = \"\\x19Ethereum Signed Message:\\n\";\n\n/**\n * Hash a message with the EIP-191 Ethereum prefix.\n *\n * This is the same hashing function used by the passkey sign dialog.\n * Use this to verify that the `signedHash` returned from `signMessage()`\n * matches your original message.\n *\n * Format: keccak256(\"\\x19Ethereum Signed Message:\\n\" + len + message)\n *\n * @example\n * ```typescript\n * const message = \"Sign in to MyApp\\nTimestamp: 1234567890\";\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * // Verify the hash matches\n * const expectedHash = hashMessage(message);\n * if (result.signedHash === expectedHash) {\n * console.log('Hash matches - signature is for this message');\n * }\n * ```\n */\nexport function hashMessage(message: string): `0x${string}` {\n const messageBytes = toBytes(message);\n const prefixed = ETHEREUM_MESSAGE_PREFIX + messageBytes.length.toString() + message;\n return keccak256(toBytes(prefixed));\n}\n\n/**\n * Verify that a signedHash matches the expected message.\n *\n * This is a convenience wrapper around `hashMessage()` that returns\n * a boolean. For full cryptographic verification of the P256 signature,\n * use on-chain verification via the WebAuthn.sol contract.\n *\n * @example\n * ```typescript\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * if (result.success && verifyMessageHash(message, result.signedHash)) {\n * // The signature is for this exact message\n * // For full verification, verify the P256 signature on-chain or server-side\n * }\n * ```\n */\nexport function verifyMessageHash(\n message: string,\n signedHash: string | undefined\n): boolean {\n if (!signedHash) return false;\n const expectedHash = hashMessage(message);\n return expectedHash.toLowerCase() === signedHash.toLowerCase();\n}\n"],"mappings":";AAAA,SAAS,WAAW,eAAe;AAM5B,IAAM,0BAA0B;AAuBhC,SAAS,YAAY,SAAgC;AAC1D,QAAM,eAAe,QAAQ,OAAO;AACpC,QAAM,WAAW,0BAA0B,aAAa,OAAO,SAAS,IAAI;AAC5E,SAAO,UAAU,QAAQ,QAAQ,CAAC;AACpC;AAmBO,SAAS,kBACd,SACA,YACS;AACT,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,eAAe,YAAY,OAAO;AACxC,SAAO,aAAa,YAAY,MAAM,WAAW,YAAY;AAC/D;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/provider.ts"],"sourcesContent":["/**\n * EIP-1193 JSON-RPC provider factory for the 1auth passkey authentication system.\n *\n * Creates a browser-side provider object that implements the EIP-1193 standard so any\n * Ethereum library (ethers, viem, wagmi) can use 1auth passkey signing and cross-chain\n * intent execution without modification. All transaction signing is delegated to the\n * passkey service rather than holding private keys in the browser.\n *\n * Supported RPC methods:\n * - eth_chainId, eth_accounts, eth_requestAccounts\n * - personal_sign, eth_sign, eth_signTypedData, eth_signTypedData_v4\n * - eth_sendTransaction\n * - wallet_connect, wallet_disconnect, wallet_switchEthereumChain\n * - wallet_sendCalls, wallet_getCallsStatus, wallet_getCallsHistory (EIP-5792)\n * - wallet_getCapabilities, wallet_getAssets\n *\n * @module\n */\n\nimport {\n hexToString,\n isHex,\n numberToHex,\n type Address,\n type Hex,\n} from \"viem\";\nimport { OneAuthClient } from \"./client\";\nimport { getSupportedChainIds } from \"./registry\";\nimport type { CloseOnStatus, IntentCall, IntentTokenRequest, SignerType } from \"./types\";\nimport { encodeWebAuthnSignature } from \"./walletClient/utils\";\n\ntype ProviderRequest = {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n};\n\ntype Listener = (...args: unknown[]) => void;\n\ntype StoredUser = {\n username?: string;\n address: Address;\n /** Absent = legacy passkey user; populated on new sessions. */\n signerType?: SignerType;\n /** Wagmi connector id for EOA sessions. Iframe-side lookup uses this. */\n connectorId?: string;\n};\n\nexport type OneAuthProvider = {\n request: (args: ProviderRequest) => Promise<unknown>;\n on: (event: string, listener: Listener) => void;\n removeListener: (event: string, listener: Listener) => void;\n disconnect: () => Promise<void>;\n};\n\nexport type OneAuthProviderOptions = {\n client: OneAuthClient;\n chainId: number;\n storageKey?: string;\n /** When to close the dialog and return success. Defaults to \"preconfirmed\" */\n closeOn?: CloseOnStatus;\n waitForHash?: boolean;\n hashTimeoutMs?: number;\n hashIntervalMs?: number;\n};\n\nconst DEFAULT_STORAGE_KEY = \"1auth-user\";\n\n/**\n * Creates an EIP-1193 compatible JSON-RPC provider backed by 1auth passkey authentication.\n *\n * The returned provider object can be used anywhere a standard Ethereum provider is\n * accepted (e.g. passed to `createWalletClient` in viem, used as `window.ethereum`, or\n * supplied to ethers.js `BrowserProvider`). Connection state (address + username) is\n * persisted in `localStorage` under the configured `storageKey`.\n *\n * @param options - Provider configuration\n * @param options.client - Configured `OneAuthClient` instance used to open auth/sign dialogs\n * @param options.chainId - Default chain ID the provider reports via `eth_chainId`\n * @param options.storageKey - localStorage key for persisting the connected user.\n * Defaults to `\"1auth-user\"`. Override to support multiple concurrent connections.\n * @param options.closeOn - Controls when the signing dialog closes and shows the \"Done\" button.\n * `\"preconfirmed\"` (default) closes as soon as the intent is confirmed by the orchestrator.\n * The `waitForHash` option independently controls whether the SDK continues polling for\n * a transaction hash after the dialog closes.\n * @param options.waitForHash - When true, polls the intent status until a transaction hash\n * is available before resolving `eth_sendTransaction` / `wallet_sendCalls`. Defaults to true.\n * @param options.hashTimeoutMs - Maximum milliseconds to wait for a transaction hash.\n * Passed directly to the passkey service intent submission.\n * @param options.hashIntervalMs - Polling interval in milliseconds when waiting for a hash.\n * Passed directly to the passkey service intent submission.\n * @returns An EIP-1193 provider with `request`, `on`, `removeListener`, and `disconnect`.\n *\n * @example\n * ```typescript\n * import { OneAuthClient } from \"@rhinestone/1auth\";\n * import { createOneAuthProvider } from \"@rhinestone/1auth\";\n *\n * const client = new OneAuthClient({ clientId: \"my-app\" });\n * const provider = createOneAuthProvider({ client, chainId: 8453 }); // Base\n *\n * // Use with viem\n * import { createWalletClient, custom } from \"viem\";\n * import { base } from \"viem/chains\";\n * const walletClient = createWalletClient({ chain: base, transport: custom(provider) });\n *\n * // Standard EIP-1193 usage\n * const accounts = await provider.request({ method: \"eth_requestAccounts\" });\n * provider.on(\"accountsChanged\", (accounts) => console.log(accounts));\n * ```\n */\nexport function createOneAuthProvider(\n options: OneAuthProviderOptions\n): OneAuthProvider {\n const { client } = options;\n let chainId = options.chainId;\n const storageKey = options.storageKey || DEFAULT_STORAGE_KEY;\n\n const listeners = new Map<string, Set<Listener>>();\n\n /**\n * Dispatches an event to all registered listeners for the given event name.\n *\n * @param event - EIP-1193 event name (e.g. \"accountsChanged\", \"chainChanged\")\n * @param args - Arguments forwarded to each listener callback\n */\n const emit = (event: string, ...args: unknown[]) => {\n const set = listeners.get(event);\n if (!set) return;\n for (const listener of set) listener(...args);\n };\n\n /**\n * Reads the connected user from localStorage.\n *\n * Returns null in non-browser environments (SSR) and when no user has been\n * persisted yet, or when the stored value is malformed.\n *\n * @returns The stored user object, or null if unavailable\n */\n const getStoredUser = (): StoredUser | null => {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(storageKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as StoredUser;\n if (!parsed?.address) return null;\n return parsed;\n } catch {\n return null;\n }\n };\n\n /**\n * Persists the connected user to localStorage.\n *\n * No-ops in non-browser (SSR) environments.\n *\n * @param user - User object with at minimum an `address` field\n */\n const setStoredUser = (user: StoredUser) => {\n if (typeof window === \"undefined\") return;\n localStorage.setItem(storageKey, JSON.stringify(user));\n };\n\n /**\n * Removes the connected user from localStorage, effectively logging them out\n * from the provider's perspective.\n *\n * No-ops in non-browser (SSR) environments.\n */\n const clearStoredUser = () => {\n if (typeof window === \"undefined\") return;\n localStorage.removeItem(storageKey);\n };\n\n /**\n * Fetches the smart account address for a given username from the passkey service.\n *\n * Called as a fallback when the auth/connect modal returns a username but no address\n * (e.g. during first-time sign-up where the account address is computed server-side).\n *\n * @param username - The 1auth username to look up\n * @returns The EVM address of the user's smart account\n * @throws If the HTTP request fails or the service returns an error\n */\n const resolveAccountAddress = async (username: string): Promise<Address> => {\n const clientId = client.getClientId();\n const response = await fetch(\n `${client.getProviderUrl()}/api/users/${encodeURIComponent(username)}/account`,\n {\n headers: clientId ? { \"x-client-id\": clientId } : {},\n }\n );\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to resolve account address\");\n }\n\n const data = await response.json();\n return data.address as Address;\n };\n\n /**\n * Connects the user by returning a cached address or opening the auth flow.\n *\n * Returns the dapp-side cached address immediately when present. Otherwise\n * opens the auth modal (`/dialog/auth`) directly — the iframe-side\n * returning-user UX lives inside that flow now. On success the address is\n * stored in localStorage and `accountsChanged` / `connect` events are emitted.\n *\n * @returns Array containing the single connected account address\n * @throws If the user cancels or authentication fails\n */\n const connect = async (): Promise<Address[]> => {\n const stored = getStoredUser();\n if (stored) {\n return [stored.address];\n }\n\n const authResult = await client.authWithModal();\n if (!authResult.success) {\n throw new Error(authResult.error?.message || \"Authentication failed\");\n }\n const username = authResult.user?.username;\n let address = authResult.user?.address;\n const signerType = authResult.signerType;\n\n // Use address from result directly, or resolve from username\n if (!address && username) {\n address = await resolveAccountAddress(username);\n }\n if (!address) {\n throw new Error(\"No account address available\");\n }\n\n setStoredUser({ username, address, signerType });\n emit(\"accountsChanged\", [address]);\n emit(\"connect\", { chainId: numberToHex(chainId) });\n return [address];\n };\n\n /**\n * Disconnects the current user by clearing persisted state and emitting events.\n *\n * Emits `accountsChanged` with an empty array and `disconnect` so that consumers\n * (e.g. wagmi) can update their state accordingly.\n */\n const disconnect = async () => {\n clearStoredUser();\n emit(\"accountsChanged\", []);\n emit(\"disconnect\");\n };\n\n /**\n * Returns the currently connected user, triggering the connect flow if needed.\n *\n * Used internally by methods that require an authenticated session (e.g. signing,\n * sending transactions) to guarantee a user is available before proceeding.\n *\n * @returns The stored user object with at minimum an `address` field\n * @throws If connecting fails and no address can be resolved\n */\n const ensureUser = async (): Promise<StoredUser> => {\n const stored = getStoredUser();\n if (stored) return stored;\n const [address] = await connect();\n if (!address) {\n throw new Error(\"Failed to resolve user session\");\n }\n const user = getStoredUser();\n return user || { address };\n };\n\n /**\n * Read an optional wallet_getAssets account address override from RPC params.\n */\n const getAssetsAccountAddress = (\n assetsParams?: unknown[] | Record<string, unknown>,\n ): string | undefined => {\n const raw = Array.isArray(assetsParams) ? assetsParams[0] : assetsParams;\n if (typeof raw === \"string\" && raw.trim()) return raw.trim();\n if (!raw || typeof raw !== \"object\") return undefined;\n\n const request = raw as Record<string, unknown>;\n const candidates = [\n request.accountAddress,\n request.address,\n ];\n for (const candidate of candidates) {\n if (typeof candidate === \"string\" && candidate.trim()) {\n return candidate.trim();\n }\n }\n return undefined;\n };\n\n /**\n * Parses a chain ID value that may arrive as a hex string, decimal string, or number.\n *\n * Handles both `\"0x1\"` (hex) and `\"1\"` / `1` (decimal) representations that are\n * commonly mixed across different wallet_switchEthereumChain implementations.\n *\n * @param value - The raw chain ID value from RPC params\n * @returns The numeric chain ID, or undefined if the value cannot be parsed\n */\n const parseChainId = (value: unknown): number | undefined => {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n if (value.startsWith(\"0x\")) return Number.parseInt(value, 16);\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n };\n\n /**\n * Normalizes a transaction value to a decimal string expected by the intent service.\n *\n * Handles the various formats callers may provide: `bigint`, `number`, hex strings\n * (e.g. `\"0x38d7ea4c68000\"`), or plain decimal strings. Returns undefined for null\n * or unsupported types, allowing callers to fall back to `\"0\"`.\n *\n * @param value - Raw value from an RPC transaction param\n * @returns Decimal string representation, or undefined if the input is not usable\n */\n const normalizeValue = (value: unknown): string | undefined => {\n if (value === undefined || value === null) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value === \"number\") return Math.trunc(value).toString();\n if (typeof value === \"string\") {\n if (value.startsWith(\"0x\")) {\n return BigInt(value).toString();\n }\n return value;\n }\n return undefined;\n };\n\n /**\n * Converts raw EIP-1193 call objects into the strongly-typed `IntentCall` format\n * expected by the passkey service.\n *\n * Fills in missing `data` with `\"0x\"` and missing `value` with `\"0\"` so the\n * intent service never receives undefined fields.\n *\n * @param calls - Raw call objects from `wallet_sendCalls` or `eth_sendTransaction` params\n * @returns Array of normalized `IntentCall` objects\n */\n const normalizeCalls = (calls: unknown[]): IntentCall[] => {\n return calls.map((call) => {\n const c = call as Record<string, unknown>;\n return {\n to: c.to as Address,\n data: (c.data as Hex | undefined) || \"0x\",\n value: normalizeValue(c.value) || \"0\",\n label: c.label as string | undefined,\n sublabel: c.sublabel as string | undefined,\n icon: c.icon as string | undefined,\n abi: c.abi as readonly unknown[] | undefined,\n };\n });\n };\n\n /**\n * Converts raw token request objects into the typed `IntentTokenRequest` format.\n *\n * Token requests allow callers to specify which tokens and amounts should be sourced\n * when funding a cross-chain intent (e.g. \"bridge 10 USDC from Optimism to Base\").\n * Accepts bigint or string/numeric amounts and normalizes them to bigint.\n *\n * @param requests - Raw token request array from RPC params, or a non-array value\n * @returns Array of typed token requests, or undefined if input is not an array\n */\n const normalizeTokenRequests = (\n requests: unknown\n ): IntentTokenRequest[] | undefined => {\n if (!Array.isArray(requests)) return undefined;\n return requests.map((r) => {\n const req = r as Record<string, unknown>;\n return {\n token: req.token as string,\n amount:\n typeof req.amount === \"bigint\"\n ? req.amount\n : BigInt(String(req.amount || \"0\")),\n };\n });\n };\n\n /**\n * Decodes a message that may be hex-encoded into a human-readable string.\n *\n * Some signers (e.g. MetaMask) encode plain-text messages as hex before passing them\n * to `personal_sign`. This helper reverses that encoding so users see the original\n * text in the signing dialog rather than a raw hex string.\n *\n * @param value - A plain string or hex-encoded string (`\"0x...\"`)\n * @returns The decoded UTF-8 string, or the original value if decoding fails\n */\n const decodeMessage = (value: string) => {\n if (!isHex(value)) return value;\n try {\n return hexToString(value as Hex);\n } catch {\n return value;\n }\n };\n\n /**\n * Forwards a raw EIP-1193 request to the iframe at `/dialog/sign-eoa`, which\n * delegates to the active wagmi connector. The wallet's own prompt is the\n * review screen — no in-dialog review step for EOA sessions.\n */\n const forwardToWallet = async (\n method: string,\n params?: unknown[] | Record<string, unknown>,\n expectedAddress?: Address,\n ): Promise<unknown> => {\n const result = await client.requestWithWallet({\n method,\n params,\n expectedAddress,\n });\n if (!result.success) {\n const err = new Error(result.error.message);\n (err as Error & { code?: string }).code = result.error.code;\n throw err;\n }\n return result.result;\n };\n\n /**\n * EIP-1193 methods forwarded verbatim to the EOA connector. All other methods\n * (eth_accounts, eth_chainId, wallet_connect, wallet_disconnect,\n * wallet_switchEthereumChain, wallet_getCapabilities/Assets) are handled\n * locally against the stored session even for EOA sessions.\n */\n const EOA_FORWARDED_METHODS = new Set([\n \"personal_sign\",\n \"eth_sign\",\n \"eth_signTypedData\",\n \"eth_signTypedData_v3\",\n \"eth_signTypedData_v4\",\n \"eth_sendTransaction\",\n \"wallet_sendCalls\",\n \"wallet_getCallsStatus\",\n ]);\n\n /**\n * Signs an arbitrary string message via the passkey service.\n *\n * Ensures a user session exists before delegating to `OneAuthClient.signMessage`.\n * The raw WebAuthn signature components are ABI-encoded for ERC-1271 on-chain\n * verification before being returned.\n *\n * @param message - Plain-text message to sign\n * @returns ABI-encoded WebAuthn signature as a hex string\n * @throws If no user session is available or the signing dialog is cancelled\n */\n const signMessage = async (message: string) => {\n const user = await ensureUser();\n if (!user.username && !user.address) {\n throw new Error(\"Username or address required for signing.\");\n }\n const result = await client.signMessage({\n username: user.username || undefined,\n accountAddress: user.address,\n message,\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Signs EIP-712 typed data via the passkey service.\n *\n * Accepts either a parsed typed-data object or a JSON string (as some libraries\n * serialize the payload before passing it through the provider). The raw WebAuthn\n * signature is ABI-encoded for ERC-1271 on-chain verification.\n *\n * @param typedData - EIP-712 typed data object or its JSON string representation\n * @returns ABI-encoded WebAuthn signature as a hex string\n * @throws If no user session is available or the signing dialog is cancelled\n */\n const signTypedData = async (typedData: unknown) => {\n const user = await ensureUser();\n if (!user.username && !user.address) {\n throw new Error(\"Username or address required for signing.\");\n }\n const data =\n typeof typedData === \"string\" ? JSON.parse(typedData) : typedData;\n const result = await client.signTypedData({\n username: user.username || undefined,\n accountAddress: user.address,\n domain: (data as any).domain,\n types: (data as any).types,\n primaryType: (data as any).primaryType,\n message: (data as any).message,\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Extracts the fields required by `OneAuthClient.sendIntent` from a richer payload.\n *\n * This thin wrapper makes it explicit which fields travel to the intent service and\n * which are local concerns (e.g. `sourceChainId` is handled at the call site).\n *\n * @param payload - Full intent payload including user identity and transaction data\n * @returns Subset of fields forwarded to the intent service\n */\n const resolveIntentPayload = (payload: {\n username?: string;\n accountAddress: Address;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: IntentTokenRequest[];\n }) => ({\n username: payload.username,\n accountAddress: payload.accountAddress,\n targetChain: payload.targetChain,\n calls: payload.calls,\n tokenRequests: payload.tokenRequests,\n });\n\n /**\n * Submits a cross-chain intent through the passkey service and returns the intent ID.\n *\n * Opens the signing dialog, waits for user confirmation, then polls the orchestrator\n * until a transaction hash is available (controlled by `waitForHash` and the timeout\n * options). The returned intent ID is used as the `callsId` in EIP-5792 responses.\n *\n * The dialog closes based on `closeOn` (defaults to `\"preconfirmed\"`). The `waitForHash`\n * option independently polls for a transaction hash after the dialog closes.\n *\n * @param payload - Intent details including target chain, calls, token requests, and\n * an optional `sourceChainId` for cross-chain bridging\n * @returns The orchestrator intent ID string\n * @throws If the user rejects the signing dialog or the intent fails\n */\n const sendIntent = async (payload: {\n username?: string;\n accountAddress: Address;\n targetChain: number;\n calls: IntentCall[];\n tokenRequests?: IntentTokenRequest[];\n sourceChainId?: number;\n }) => {\n const intentPayload = resolveIntentPayload(payload);\n const result = await client.sendIntent({\n ...intentPayload,\n tokenRequests: payload.tokenRequests,\n sourceChainId: payload.sourceChainId,\n closeOn: options.closeOn,\n waitForHash: options.waitForHash ?? true,\n hashTimeoutMs: options.hashTimeoutMs,\n hashIntervalMs: options.hashIntervalMs,\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || \"Transaction failed\");\n }\n\n // Return intentId as callsId for EIP-5792 compatibility\n return result.intentId;\n };\n\n const accountMismatchError = (): Error & { code?: string } => {\n const err = new Error(\n \"Requested signer does not match the active wallet connection.\",\n ) as Error & { code?: string };\n err.code = \"ACCOUNT_MISMATCH\";\n return err;\n };\n\n const sameAddress = (a: unknown, b: string): boolean =>\n typeof a === \"string\" && a.toLowerCase() === b.toLowerCase();\n\n /**\n * Some wallets (MetaMask, Rabby) reject `eth_sendTransaction` /\n * `wallet_sendCalls` / `personal_sign` / `eth_signTypedData_v4` when the\n * signer address is missing. The dapp doesn't know the EOA address, so the\n * SDK fills it in from the stored session.\n *\n * If the caller supplies a `from` (or address arg) that differs from the\n * connected EOA, we throw `ACCOUNT_MISMATCH` rather than letting the\n * caller's value win. A dapp asking the wallet to sign on behalf of a\n * different account than the user connected is a trust-boundary violation\n * — the user reviewed and approved exactly one address, not whatever the\n * dapp later substitutes.\n */\n const injectEoaSigner = (\n method: string,\n params: unknown[] | Record<string, unknown> | undefined,\n address: Address,\n ): unknown[] | Record<string, unknown> | undefined => {\n const list = Array.isArray(params) ? params.slice() : params;\n if (!Array.isArray(list)) return params;\n\n if (method === \"eth_sendTransaction\") {\n const first = (list[0] || {}) as Record<string, unknown>;\n if (first.from !== undefined && !sameAddress(first.from, address)) {\n throw accountMismatchError();\n }\n list[0] = { ...first, from: address };\n return list;\n }\n if (method === \"wallet_sendCalls\") {\n const first = (list[0] || {}) as Record<string, unknown>;\n if (first.from !== undefined && !sameAddress(first.from, address)) {\n throw accountMismatchError();\n }\n // EIP-5792 lets each call carry its own `from`. Validate every one —\n // a single mismatched call would otherwise sneak through unchecked.\n const calls = first.calls;\n if (Array.isArray(calls)) {\n for (const call of calls) {\n if (!call || typeof call !== \"object\") continue;\n const callFrom = (call as Record<string, unknown>).from;\n if (callFrom !== undefined && !sameAddress(callFrom, address)) {\n throw accountMismatchError();\n }\n }\n }\n list[0] = { ...first, from: address };\n return list;\n }\n if (method === \"personal_sign\") {\n // personal_sign(message, address) — fill address if absent.\n if (list[1] !== undefined && !sameAddress(list[1], address)) {\n throw accountMismatchError();\n }\n if (list[0] && list[1] === undefined) list[1] = address;\n return list;\n }\n if (\n method === \"eth_sign\" ||\n method === \"eth_signTypedData\" ||\n method === \"eth_signTypedData_v3\" ||\n method === \"eth_signTypedData_v4\"\n ) {\n // signTypedData(address, typedData) — fill address if absent.\n if (list[0] !== undefined && !sameAddress(list[0], address)) {\n throw accountMismatchError();\n }\n if (list[0] === undefined && list[1] !== undefined) list[0] = address;\n return list;\n }\n return list;\n };\n\n const request = async ({ method, params }: ProviderRequest) => {\n // For sign/tx methods, resolve the user first — this opens the auth modal\n // on the very first call so we know the signerType before deciding\n // between the passkey path and forwarding to the wagmi connector. Local-\n // only methods (eth_accounts, eth_chainId, wallet_switchEthereumChain,\n // etc.) fall through to the switch below and read stored state directly.\n if (EOA_FORWARDED_METHODS.has(method)) {\n const user = await ensureUser();\n if (user.signerType === \"eoa\") {\n return forwardToWallet(\n method,\n injectEoaSigner(method, params, user.address),\n user.address,\n );\n }\n }\n\n switch (method) {\n case \"eth_chainId\":\n return numberToHex(chainId);\n case \"eth_accounts\": {\n const stored = getStoredUser();\n return stored ? [stored.address] : [];\n }\n case \"eth_requestAccounts\":\n return connect();\n case \"wallet_connect\":\n return connect();\n case \"wallet_disconnect\":\n await disconnect();\n return true;\n case \"wallet_switchEthereumChain\": {\n const [param] = (params as any[]) || [];\n const next = parseChainId(param?.chainId ?? param);\n if (!next) {\n throw new Error(\"Invalid chainId\");\n }\n const stored = getStoredUser();\n if (stored?.signerType === \"eoa\") {\n await forwardToWallet(method, params, stored.address);\n }\n chainId = next;\n emit(\"chainChanged\", numberToHex(chainId));\n return null;\n }\n case \"personal_sign\": {\n const paramList = Array.isArray(params) ? params : [];\n const first = paramList[0];\n const second = paramList[1];\n // personal_sign param order varies: some callers send [message, address],\n // others send [hexEncodedMessage, address]. When the first param is hex and\n // the second is a non-hex string we treat the second as the plain message\n // (MetaMask-style). Otherwise we always decode the first param.\n const message =\n typeof first === \"string\" && first.startsWith(\"0x\") && second\n ? typeof second === \"string\" && !second.startsWith(\"0x\")\n ? second\n : decodeMessage(first)\n : typeof first === \"string\"\n ? decodeMessage(first)\n : typeof second === \"string\"\n ? decodeMessage(second)\n : \"\";\n if (!message) throw new Error(\"Invalid personal_sign payload\");\n return signMessage(message);\n }\n case \"eth_sign\": {\n const paramList = Array.isArray(params) ? params : [];\n const message = typeof paramList[1] === \"string\" ? paramList[1] : \"\";\n if (!message) throw new Error(\"Invalid eth_sign payload\");\n return signMessage(decodeMessage(message));\n }\n case \"eth_signTypedData\":\n case \"eth_signTypedData_v4\": {\n const paramList = Array.isArray(params) ? params : [];\n const typedData = paramList[1] ?? paramList[0];\n return signTypedData(typedData);\n }\n case \"eth_sendTransaction\": {\n const paramList = Array.isArray(params) ? params : [];\n const tx = (paramList[0] || {}) as Record<string, unknown>;\n const user = await ensureUser();\n const targetChain = parseChainId(tx.chainId) ?? chainId;\n const calls = normalizeCalls([tx]);\n const tokenRequests = normalizeTokenRequests(tx.tokenRequests);\n const txSourceChainId = parseChainId(tx.sourceChainId);\n return sendIntent({\n username: user.username || undefined,\n accountAddress: user.address,\n targetChain,\n calls,\n tokenRequests,\n sourceChainId: txSourceChainId,\n });\n }\n case \"wallet_sendCalls\": {\n const paramList = Array.isArray(params) ? params : [];\n const payload = (paramList[0] || {}) as Record<string, unknown>;\n const user = await ensureUser();\n const targetChain = parseChainId(payload.chainId) ?? chainId;\n const calls = normalizeCalls((payload.calls as unknown[]) || []);\n const tokenRequests = normalizeTokenRequests(payload.tokenRequests);\n const sourceChainId = parseChainId(payload.sourceChainId);\n if (!calls.length) throw new Error(\"No calls provided\");\n return sendIntent({\n username: user.username || undefined,\n accountAddress: user.address,\n targetChain,\n calls,\n tokenRequests,\n sourceChainId,\n });\n }\n case \"wallet_getCapabilities\": {\n const stored = getStoredUser();\n if (stored?.signerType === \"eoa\") {\n return {};\n }\n\n const paramList = Array.isArray(params) ? params : [];\n // walletAddress is params[0] - we ignore since all accounts have same capabilities\n const requestedChains = paramList[1] as `0x${string}`[] | undefined;\n\n const chainIds = getSupportedChainIds();\n const capabilities: Record<`0x${string}`, Record<string, unknown>> = {};\n\n for (const chainId of chainIds) {\n const hexChainId = `0x${chainId.toString(16)}` as `0x${string}`;\n\n // Filter if specific chains requested\n if (requestedChains && !requestedChains.includes(hexChainId)) {\n continue;\n }\n\n // All supported chains advertise atomic batching, gasless transactions via\n // paymasters, and cross-chain auxiliary funds (EIP-5792 capability keys).\n capabilities[hexChainId] = {\n atomic: { status: \"supported\" },\n paymasterService: { supported: true },\n auxiliaryFunds: { supported: true },\n };\n }\n\n return capabilities;\n }\n case \"wallet_getAssets\": {\n const explicitAccountAddress = getAssetsAccountAddress(params);\n const user = explicitAccountAddress ? null : await ensureUser();\n // The portfolio endpoint resolves identifiers via resolveUserWhere,\n // and the current SDK account model is address-first. Explicit params\n // let app-level verified sessions query balances without relying on\n // the provider's localStorage cache, while connected EIP-1193 consumers\n // still work with no params.\n const accountAddress = explicitAccountAddress || user?.address;\n if (!accountAddress) {\n throw new Error(\"wallet_getAssets requires accountAddress or a connected account\");\n }\n return client.getAssets({ accountAddress: accountAddress as Address });\n }\n case \"wallet_getCallsStatus\": {\n const paramList = Array.isArray(params) ? params : [];\n const callsId = paramList[0] as string;\n if (!callsId) {\n throw new Error(\"callsId is required\");\n }\n const statusClientId = client.getClientId();\n const response = await fetch(\n `${client.getProviderUrl()}/api/intent/status/${encodeURIComponent(callsId)}`,\n {\n headers: statusClientId ? { \"x-client-id\": statusClientId } : {},\n }\n );\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to get calls status\");\n }\n const data = await response.json();\n // Map intent status to EIP-5792 status strings.\n // Both \"failed\" and \"expired\" map to \"CONFIRMED\" because EIP-5792 uses receipts\n // (and a 0x0 status code) to communicate failure — there is no \"FAILED\" state.\n const statusMap: Record<string, string> = {\n pending: \"PENDING\",\n preconfirmed: \"PENDING\",\n completed: \"CONFIRMED\",\n failed: \"CONFIRMED\",\n expired: \"CONFIRMED\",\n };\n return {\n status: statusMap[data.status] || \"PENDING\",\n receipts: data.transactionHash\n ? [\n {\n logs: [],\n // 0x1 = success, 0x0 = reverted/failed — mirrors EVM receipt status\n status: data.status === \"completed\" ? \"0x1\" : \"0x0\",\n blockHash: data.blockHash,\n blockNumber: data.blockNumber,\n transactionHash: data.transactionHash,\n },\n ]\n : [],\n };\n }\n case \"wallet_getCallsHistory\": {\n const paramList = Array.isArray(params) ? params : [];\n const options = (paramList[0] || {}) as {\n limit?: number;\n offset?: number;\n status?: string;\n from?: string;\n to?: string;\n };\n\n const queryParams = new URLSearchParams();\n if (options.limit) queryParams.set(\"limit\", String(options.limit));\n if (options.offset) queryParams.set(\"offset\", String(options.offset));\n if (options.status) queryParams.set(\"status\", options.status);\n if (options.from) queryParams.set(\"from\", options.from);\n if (options.to) queryParams.set(\"to\", options.to);\n\n const url = `${client.getProviderUrl()}/api/intent/history${\n queryParams.toString() ? `?${queryParams}` : \"\"\n }`;\n\n const historyClientId = client.getClientId();\n const response = await fetch(url, {\n headers: historyClientId ? { \"x-client-id\": historyClientId } : {},\n credentials: \"include\",\n });\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to get calls history\");\n }\n\n const data = await response.json();\n\n // Map intent status to EIP-5792 format\n const statusMap: Record<string, string> = {\n pending: \"PENDING\",\n preconfirmed: \"PENDING\",\n completed: \"CONFIRMED\",\n failed: \"CONFIRMED\",\n expired: \"CONFIRMED\",\n };\n\n // intentId IS the orchestrator's ID (used as callsId in EIP-5792)\n return {\n calls: data.intents.map(\n (intent: {\n intentId: string;\n status: string;\n transactionHash?: string;\n targetChain: number;\n }) => ({\n callsId: intent.intentId, // intentId is the orchestrator's ID\n status: statusMap[intent.status] || \"PENDING\",\n receipts: intent.transactionHash\n ? [{ transactionHash: intent.transactionHash }]\n : [],\n chainId: `0x${intent.targetChain.toString(16)}`,\n })\n ),\n total: data.total,\n hasMore: data.hasMore,\n };\n }\n default:\n throw new Error(`Unsupported method: ${method}`);\n }\n };\n\n return {\n request,\n on(event, listener) {\n const set = listeners.get(event) ?? new Set();\n set.add(listener);\n listeners.set(event, set);\n },\n removeListener(event, listener) {\n const set = listeners.get(event);\n if (!set) return;\n set.delete(listener);\n if (set.size === 0) listeners.delete(event);\n },\n disconnect,\n };\n}\n"],"mappings":"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","names":["data","request","chainId","options"]}