{"version":3,"file":"walletconnect-service.mjs","names":[],"sources":["../../../src/services/walletconnect-service.ts"],"sourcesContent":["/**\n * WalletConnect Service — manages the WC session lifecycle as a plugin service.\n * \n * This is the core security model: the agent never holds private keys.\n * Every write transaction goes through the user's phone wallet for approval,\n * unless a spending policy auto-approves it.\n * \n * Supports three modes:\n * 1. WalletConnect — human approves from MetaMask/Rainbow/etc. (production)\n * 2. Private key — for headless testing (set CLAWNCHER_PRIVATE_KEY)\n * 3. Bankr — custodial wallet via Bankr Agent API (set BANKR_API_KEY)\n */\n\nimport type { Address } from 'viem';\nimport type {\n  WalletConnectSigner,\n  SpendingPolicy,\n  SessionState,\n  QueuedTransaction,\n} from '@clawnch/sdk';\nimport type { TransactionRecord, WalletState } from '../lib/types.js';\nimport { wrapWithBuilderCode } from './builder-code.js';\nimport { hasKeychainWallet, loadAndDecrypt } from './keychain-wallet.js';\n\n// ─── Singleton State ─────────────────────────────────────────────────────\n// Using `any` for client types to avoid viem version conflicts between\n// the local install and @clawnch/sdk's bundled viem types.\n// All consumers receive the untyped client and pass it directly to\n// external SDKs (ClawnchSwapper, etc.) — no intermediate `as any` casts\n// are needed since the source is already untyped. If viem types align\n// in the future, replace `any` with `WalletClient` / `PublicClient`.\n\n/** viem WalletClient — untyped to avoid cross-package viem version conflicts */\nlet _walletClient: any = null;\n/** viem PublicClient — untyped for the same reason */\nlet _publicClient: any = null;\nlet _wcSigner: WalletConnectSigner | null = null;\nlet _connectedAddress: Address | null = null;\nlet _mode: 'private_key' | 'walletconnect' | 'bankr' | 'none' = 'none';\nlet _transactionHistory: TransactionRecord[] = [];\n\n// Bankr-specific state\nlet _bankrEvmAddress: string | null = null;\nlet _bankrSolAddress: string | null = null;\nlet _bankrClub: boolean = false;\n\n// Account type detection cache (EIP-7702)\nlet _accountType: 'eoa' | 'smart_account' | 'eip7702' | undefined;\nlet _hasCode: boolean | undefined;\nlet _delegationDesignation: Address | undefined;\n\n// ─── Configuration ───────────────────────────────────────────────────────\n\ninterface WalletServiceConfig {\n  privateKey?: string;\n  walletConnectProjectId?: string;\n  bankrApiKey?: string;\n  rpcUrl?: string;\n  network?: 'mainnet' | 'sepolia';\n  sessionPath?: string;\n  policies?: SpendingPolicy[];\n  onSessionChange?: (state: SessionState) => void;\n  onTransactionQueued?: (tx: QueuedTransaction) => void;\n  onTransactionApproved?: (tx: QueuedTransaction, hash: string) => void;\n  onTransactionRejected?: (tx: QueuedTransaction, reason: string) => void;\n}\n\n// ─── Initialization ──────────────────────────────────────────────────────\n\n/**\n * Initialize the wallet service. Called at gateway startup.\n * \n * Priority:\n * 1. Private key env var (headless/testing)\n * 2. WalletConnect (production)\n * 3. Bankr API key (custodial wallet)\n */\nlet _initPromise: Promise<any> | null = null;\n\nexport async function initWalletService(config: WalletServiceConfig): Promise<{\n  mode: 'private_key' | 'walletconnect' | 'bankr' | 'none';\n  pairingUri?: string;\n  address?: Address;\n  solAddress?: string;\n}> {\n  // Mutex: prevent concurrent initialization which can create duplicate WC signers\n  if (_initPromise) return _initPromise;\n  _initPromise = _doInitWalletService(config);\n  try {\n    return await _initPromise;\n  } finally {\n    _initPromise = null;\n  }\n}\n\nasync function _doInitWalletService(config: WalletServiceConfig): Promise<{\n  mode: 'private_key' | 'walletconnect' | 'bankr' | 'none';\n  pairingUri?: string;\n  address?: Address;\n  solAddress?: string;\n}> {\n  const { createPublicClient, http } = await import('viem');\n  const { base, baseSepolia } = await import('viem/chains');\n\n  const chain = config.network === 'sepolia' ? baseSepolia : base;\n  const rpcUrl = config.rpcUrl || undefined; // let viem use default\n\n  // Create public client\n  _publicClient = createPublicClient({\n    chain,\n    transport: http(rpcUrl),\n  });\n\n  // Mode 1: Private key (headless/testing)\n  if (config.privateKey) {\n    const { createWalletClient } = await import('viem');\n    const { privateKeyToAccount } = await import('viem/accounts');\n\n    const account = privateKeyToAccount(config.privateKey as `0x${string}`);\n    _walletClient = createWalletClient({\n      account,\n      chain,\n      transport: http(rpcUrl),\n    });\n\n    // Wrap with ERC-8021 builder code attribution for Base transactions\n    _walletClient = wrapWithBuilderCode(_walletClient, chain.id);\n\n    _connectedAddress = account.address;\n    _mode = 'private_key';\n\n    return { mode: 'private_key', address: account.address };\n  }\n\n  // Mode 1b: Keychain-stored encrypted mnemonic (local wallet generation)\n  // Same runtime path as private_key — identical walletClient, same _mode.\n  // Only the key acquisition differs: Keychain + password vs raw env var.\n  if (!config.privateKey && hasKeychainWallet()) {\n    const walletPassword = process.env.CLAWNCHER_WALLET_PASSWORD;\n    if (walletPassword) {\n      try {\n        const { account: keychainAccount } = await loadAndDecrypt(walletPassword);\n        const { createWalletClient } = await import('viem');\n\n        _walletClient = createWalletClient({\n          account: keychainAccount,\n          chain,\n          transport: http(rpcUrl),\n        });\n        _walletClient = wrapWithBuilderCode(_walletClient, chain.id);\n        _connectedAddress = keychainAccount.address;\n        _mode = 'private_key';\n\n        return { mode: 'private_key', address: keychainAccount.address };\n      } catch (err) {\n        // Wrong password or corrupted data — fall through to WalletConnect/Bankr\n        console.warn(\n          `[wallet] Keychain wallet decrypt failed: ${err instanceof Error ? err.message : String(err)}`,\n        );\n      }\n    } else {\n      // Wallet exists but no password env var — can't unlock headlessly.\n      // Interactive unlock (via onboarding/channel prompt) is handled separately.\n      console.info(\n        '[wallet] Keychain wallet found but CLAWNCHER_WALLET_PASSWORD not set — skipping auto-unlock. ' +\n        'Set CLAWNCHER_WALLET_PASSWORD env var for headless mode, or use onboarding to unlock interactively.',\n      );\n    }\n  }\n\n  // Mode 2: WalletConnect\n  if (config.walletConnectProjectId) {\n    const { WalletConnectSigner } = await import('@clawnch/sdk');\n\n    const sessionPath = config.sessionPath\n      || `${process.env.HOME ?? ''}/.openclawnch/wc-session.json`;\n\n    _wcSigner = new WalletConnectSigner({\n      projectId: config.walletConnectProjectId,\n      chain,\n      sessionPath,\n      policies: config.policies ?? [],\n      metadata: {\n        name: 'OpenClawnch',\n        description: 'OpenClaw for crypto — AI assistant with DeFi capabilities',\n        url: 'https://clawn.ch',\n        icons: ['https://clawn.ch/icon.png'],\n      },\n      requestTimeout: 180_000, // 3 minutes for tx approval\n      onSessionChange: (state) => {\n        if (state.status === 'connected') {\n          _connectedAddress = state.address;\n        } else if (state.status === 'disconnected' || state.status === 'expired') {\n          _connectedAddress = null;\n          _walletClient = null;\n        }\n        config.onSessionChange?.(state);\n      },\n      onTransactionQueued: (tx) => {\n        _transactionHistory.push({\n          id: tx.id,\n          status: 'pending',\n          summary: tx.context?.summary ?? 'Transaction submitted',\n          timestamp: tx.queuedAt,\n          to: tx.transaction.to,\n          value: tx.transaction.value?.toString(),\n        });\n        config.onTransactionQueued?.(tx);\n      },\n      onTransactionApproved: (tx, hash) => {\n        const record = _transactionHistory.find(r => r.id === tx.id);\n        if (record) {\n          record.status = tx.policyLabel ? 'auto_approved' : 'approved';\n          record.hash = hash;\n          record.policyLabel = tx.policyLabel;\n        }\n        config.onTransactionApproved?.(tx, hash);\n      },\n      onTransactionRejected: (tx, reason) => {\n        const record = _transactionHistory.find(r => r.id === tx.id);\n        if (record) {\n          record.status = 'rejected';\n        }\n        config.onTransactionRejected?.(tx, reason);\n      },\n    });\n\n    const { uri, restored } = await _wcSigner.connect();\n\n    if (restored) {\n      // Session restored from disk — create wallet client immediately\n      _walletClient = await _wcSigner.toWalletClient(_publicClient);\n      _walletClient = wrapWithBuilderCode(_walletClient, chain.id);\n      _connectedAddress = _wcSigner.address;\n      _mode = 'walletconnect';\n      return { mode: 'walletconnect', address: _connectedAddress ?? undefined };\n    }\n\n    if (uri) {\n      _mode = 'walletconnect';\n      return { mode: 'walletconnect', pairingUri: uri };\n    }\n  }\n\n  // Mode 3: Bankr custodial wallet\n  if (config.bankrApiKey) {\n    try {\n      const { getBankrUserInfo } = await import('./bankr-api.js');\n\n      // KNOWN TRADE-OFF: We mutate process.env to make the Bankr API key\n      // available to getBankrApiKey() (which reads from credential vault →\n      // process.env). This is idempotent (guarded) and happens once at init.\n      // TODO: Refactor bankr-api to accept an explicit key parameter instead\n      // of reading from process.env, eliminating this env mutation.\n      if (!process.env.BANKR_API_KEY) {\n        process.env.BANKR_API_KEY = config.bankrApiKey;\n      }\n\n      const userInfo = await getBankrUserInfo();\n      const { isBankrClubActive } = await import('./bankr-types.js');\n\n      const evmWallet = userInfo.wallets.find(w => w.chain === 'evm');\n      const solWallet = userInfo.wallets.find(w => w.chain === 'solana');\n\n      _bankrEvmAddress = evmWallet?.address ?? null;\n      _bankrSolAddress = solWallet?.address ?? null;\n      _bankrClub = isBankrClubActive(userInfo);\n      _connectedAddress = (_bankrEvmAddress as Address) ?? null;\n      _mode = 'bankr';\n\n      return {\n        mode: 'bankr',\n        address: _connectedAddress ?? undefined,\n        solAddress: _bankrSolAddress ?? undefined,\n      };\n    } catch (err) {\n      // Bankr init failed — fall through to none\n      console.warn(`[wallet] Bankr init failed: ${err instanceof Error ? err.message : String(err)}`);\n    }\n  }\n\n  // No wallet configured\n  _mode = 'none';\n  return { mode: 'none' };\n}\n\n/**\n * Wait for WalletConnect session to be established (after wallet approval).\n */\nexport async function waitForWalletSession(timeoutMs = 300_000): Promise<{\n  address: Address;\n  chainId: number;\n}> {\n  if (!_wcSigner) {\n    throw new Error('WalletConnect not initialized. Set WALLETCONNECT_PROJECT_ID.');\n  }\n\n  const result = await _wcSigner.waitForSession(timeoutMs);\n  _walletClient = await _wcSigner.toWalletClient(_publicClient!);\n  _walletClient = wrapWithBuilderCode(_walletClient, _publicClient?.chain?.id);\n  _connectedAddress = result.address;\n\n  return result;\n}\n\n// ─── Getters ─────────────────────────────────────────────────────────────\n\nexport function getWalletClient(): any {\n  return _walletClient;\n}\n\nexport function getPublicClient(): any {\n  return _publicClient;\n}\n\nexport function getWCSigner(): WalletConnectSigner | null {\n  return _wcSigner;\n}\n\nexport function getWalletState(): WalletState {\n  return {\n    connected: _connectedAddress !== null,\n    address: _connectedAddress,\n    chainId: _mode === 'bankr' ? 8453 : (_publicClient ? (_publicClient as any).chain?.id ?? null : null),\n    mode: _mode,\n    policies: _wcSigner?.getPolicies() ?? [],\n    wcState: _wcSigner?.getState() ?? null,\n    bankrEvmAddress: _bankrEvmAddress ?? undefined,\n    bankrSolAddress: _bankrSolAddress ?? undefined,\n    bankrClub: _bankrClub || undefined,\n    accountType: _accountType,\n    hasCode: _hasCode,\n    delegationDesignation: _delegationDesignation,\n  };\n}\n\n// ─── Bankr Mode Helpers ──────────────────────────────────────────────────\n\n/**\n * Check if the wallet is in Bankr custodial mode.\n */\nexport function isBankrMode(): boolean {\n  return _mode === 'bankr';\n}\n\n/**\n * Returns the appropriate execution context for tools that support both\n * local wallet and Bankr paths.\n */\nexport function requireBankrOrWallet(): { mode: 'bankr' } | { mode: 'local'; client: any } {\n  if (_mode === 'bankr') {\n    return { mode: 'bankr' };\n  }\n  if (_walletClient) {\n    return { mode: 'local', client: _walletClient };\n  }\n  throw new Error(\n    'No wallet connected. Use /connect or /connect_bankr to connect a wallet first.'\n  );\n}\n\nexport function getTransactionHistory(): TransactionRecord[] {\n  return [..._transactionHistory];\n}\n\nexport function requireWalletClient(): any {\n  if (!_walletClient) {\n    throw new Error(\n      'No wallet connected. Use the clawnchconnect tool with action \"connect\" first, ' +\n      'or set CLAWNCHER_PRIVATE_KEY for headless mode.'\n    );\n  }\n  return _walletClient;\n}\n\nexport function requirePublicClient(): any {\n  if (!_publicClient) {\n    throw new Error('Public client not initialized. The wallet service must be started first.');\n  }\n  return _publicClient;\n}\n\n/**\n * Get a wallet client that routes write transactions through MEV-protected RPCs\n * (Flashbots Protect, MEV Blocker) when available. Protects against sandwich\n * attacks and frontrunning by bypassing the public mempool.\n *\n * Only effective in private_key mode — WalletConnect transactions are broadcast\n * by the phone wallet (out of our control), and Bankr transactions are broadcast\n * by the Bankr API.\n *\n * Falls back to the regular wallet client if:\n * - MEV protection is disabled in RpcManager config\n * - No MEV RPCs are available for the current chain\n * - Mode is not private_key (WC, Bankr)\n */\nexport async function getMevWalletClient(): Promise<any> {\n  const wallet = requireWalletClient();\n\n  // MEV routing only works when we control transaction broadcasting (private_key mode).\n  // WC mode: phone wallet broadcasts. Bankr mode: Bankr API broadcasts.\n  if (_mode !== 'private_key') return wallet;\n\n  try {\n    const { getRpcManager } = await import('./rpc-provider.js');\n    const rpcManager = getRpcManager();\n    const chainId = _publicClient?.chain?.id ?? 8453;\n\n    if (!rpcManager.isMevProtectionEnabled()) return wallet;\n\n    const mevTransport = rpcManager.getMevTransport(chainId);\n    if (!mevTransport) return wallet;\n\n    const { createWalletClient } = await import('viem');\n    const mevClient = createWalletClient({\n      account: wallet.account,\n      chain: _publicClient?.chain,\n      transport: mevTransport,\n    });\n\n    return wrapWithBuilderCode(mevClient, chainId);\n  } catch (err) {\n    // MEV client creation failed — fall back to regular wallet client.\n    // Log so the user knows MEV protection is not active for this tx.\n    console.warn('[wallet] MEV protection unavailable, using standard RPC:', err instanceof Error ? err.message : String(err));\n    return wallet;\n  }\n}\n\n// ─── EIP-7702 Account Type Detection ─────────────────────────────────────\n\n/**\n * EIP-7702 delegation designation prefix.\n * An EIP-7702 delegated EOA has code: 0xef0100 + 20-byte implementation address.\n * Total bytecode length = 23 bytes = 46 hex chars + '0x' prefix = 48 chars.\n */\nconst EIP7702_PREFIX = '0xef0100';\nconst EIP7702_CODE_LENGTH = 48; // '0x' + 46 hex chars (3 prefix + 20 addr bytes)\n\nexport interface AccountTypeResult {\n  /** Account type classification. */\n  accountType: 'eoa' | 'smart_account' | 'eip7702';\n  /** Whether the account has on-chain code deployed. */\n  hasCode: boolean;\n  /** For EIP-7702: the implementation address the EOA delegates to. */\n  delegationDesignation?: Address;\n}\n\n/**\n * Detect the account type of the connected wallet via eth_getCode.\n *\n * - EOA: getCode returns '0x' (no code)\n * - Smart Account: getCode returns arbitrary bytecode (not EIP-7702 prefix)\n * - EIP-7702: getCode returns 0xef0100 + 20-byte implementation address\n *\n * Results are cached on the wallet state. Call with `force: true` to re-detect.\n * Returns null if no wallet is connected or no public client is available.\n */\nexport async function detectAccountType(opts?: { force?: boolean }): Promise<AccountTypeResult | null> {\n  // Return cached result unless forced\n  if (!opts?.force && _accountType !== undefined) {\n    return {\n      accountType: _accountType,\n      hasCode: _hasCode ?? false,\n      delegationDesignation: _delegationDesignation,\n    };\n  }\n\n  if (!_connectedAddress || !_publicClient) {\n    return null;\n  }\n\n  try {\n    const code = await _publicClient.getCode({ address: _connectedAddress });\n    const codeHex = (code as string) ?? '0x';\n\n    if (codeHex === '0x' || codeHex === '0x0') {\n      // No code — standard EOA\n      _accountType = 'eoa';\n      _hasCode = false;\n      _delegationDesignation = undefined;\n    } else if (\n      codeHex.toLowerCase().startsWith(EIP7702_PREFIX) &&\n      codeHex.length === EIP7702_CODE_LENGTH\n    ) {\n      // EIP-7702 delegation designation: 0xef0100 + 20-byte address\n      _accountType = 'eip7702';\n      _hasCode = true;\n      _delegationDesignation = ('0x' + codeHex.slice(8)) as Address; // skip '0xef0100'\n    } else {\n      // Arbitrary bytecode — smart account (Safe, ERC-4337, custom)\n      _accountType = 'smart_account';\n      _hasCode = true;\n      _delegationDesignation = undefined;\n    }\n\n    return {\n      accountType: _accountType,\n      hasCode: _hasCode,\n      delegationDesignation: _delegationDesignation,\n    };\n  } catch {\n    // RPC call failed — can't determine account type\n    return null;\n  }\n}\n\n/**\n * Clear the cached account type detection. Called on disconnect.\n */\nexport function clearAccountTypeCache(): void {\n  _accountType = undefined;\n  _hasCode = undefined;\n  _delegationDesignation = undefined;\n}\n\n// ─── Disconnect ──────────────────────────────────────────────────────────\n\nexport async function disconnectWallet(): Promise<void> {\n  if (_wcSigner) {\n    await _wcSigner.disconnect();\n  }\n  _walletClient = null;\n  _connectedAddress = null;\n  _bankrEvmAddress = null;\n  _bankrSolAddress = null;\n  _bankrClub = false;\n  _mode = 'none';\n  clearAccountTypeCache();\n}\n\n// ─── Policy Management ───────────────────────────────────────────────────\n\nexport function addPolicy(policy: SpendingPolicy): void {\n  _wcSigner?.addPolicy(policy);\n}\n\nexport function removePolicy(label: string): boolean {\n  return _wcSigner?.removePolicy(label) ?? false;\n}\n\nexport function clearPolicies(): void {\n  const policies = _wcSigner?.getPolicies() ?? [];\n  for (const p of policies) {\n    _wcSigner?.removePolicy(p.label);\n  }\n}\n"],"mappings":"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"}