{"version":3,"sources":["../src/wagmi.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"],"mappings":"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","names":["provider","chain"]}