{"version":3,"file":"dist-CXAY4yCt.mjs","names":["DEFAULT_API_BASE","ZERO_ADDRESS","DEFAULT_API_URL","DEFAULT_TIMEOUT"],"sources":["../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/claimer.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/portfolio.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/watcher.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/swap-types.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/swap.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/permit2.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/liquidity.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/api-deployer.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/price.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/orders.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/wayfinder.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/hummingbot.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/herd-auth.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/herd.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/herd-hal.js","../../../node_modules/.pnpm/@clawnch+clawncher-sdk@0.3.4_@types+node@25.5.2_hardhat@2.28.6_typescript@6.0.2__typesc_a082d605d8b8771f03593b43bf11d8ac/node_modules/@clawnch/clawncher-sdk/dist/index.js"],"sourcesContent":["/**\n * ClawncherClaimer - On-chain fee and allocation claiming for Clawncher tokens\n *\n * v3: Claims from Clanker's approved infrastructure.\n * All claim functions are permissionless (anyone can trigger them),\n * but tokens always go to the designated recipient on-chain.\n *\n * Flow:\n *   1. collectRewards(token) - triggers LP locker to distribute fees to FeeLocker\n *   2. claimFees(feeOwner, token) - claims accumulated fees from FeeLocker\n *   3. claimVault(token) - claims vested vault allocation\n *   4. claimAll(token, feeOwner) - collects rewards + claims fees (WETH and token)\n *\n * Note: claimVestedDevBuy() is not available in v3 (Clanker does not support it).\n */\nimport { base, baseSepolia } from 'viem/chains';\nimport { ClawnchFeeLockerABI, ClawnchLpLockerABI, ClawnchVaultABI, } from './abis.js';\nimport { getAddresses } from './addresses.js';\nimport { ClawnchErrorCode, ClawnchDeployError } from './errors.js';\n/**\n * ClawncherClaimer - Claim fees and allocations from Clawncher contracts\n *\n * @example\n * ```typescript\n * import { ClawncherClaimer } from '@clawnch/clawncher-sdk';\n * import { createWalletClient, createPublicClient, http } from 'viem';\n * import { privateKeyToAccount } from 'viem/accounts';\n * import { base } from 'viem/chains';\n *\n * const account = privateKeyToAccount('0x...');\n * const wallet = createWalletClient({ account, chain: base, transport: http() });\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n *\n * const claimer = new ClawncherClaimer({\n *   wallet,\n *   publicClient,\n *   network: 'mainnet',\n * });\n *\n * // Collect LP rewards and claim all fees for a token\n * const result = await claimer.claimAll(tokenAddress, feeOwnerAddress);\n * ```\n */\nexport class ClawncherClaimer {\n    wallet;\n    publicClient;\n    network;\n    constructor(config) {\n        this.wallet = config.wallet;\n        this.publicClient = config.publicClient;\n        this.network = config.network;\n    }\n    /**\n     * Get contract addresses for configured network\n     */\n    getAddresses() {\n        return getAddresses(this.network);\n    }\n    /**\n     * Get the chain for the configured network\n     */\n    getChain() {\n        return this.network === 'mainnet' ? base : baseSepolia;\n    }\n    /**\n     * Helper to write a contract and return a ClaimTxResult\n     */\n    async writeContract(params) {\n        const txHash = await this.wallet.writeContract({\n            address: params.address,\n            abi: params.abi,\n            functionName: params.functionName,\n            args: params.args,\n            chain: this.getChain(),\n        });\n        return {\n            txHash,\n            wait: async () => {\n                const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n                return { success: receipt.status === 'success' };\n            },\n        };\n    }\n    // =========================================================================\n    // Individual Claim Methods\n    // =========================================================================\n    /**\n     * Collect LP rewards for a token\n     *\n     * This triggers the LP locker to collect trading fees from the Uniswap V4 pool\n     * and distribute them to the FeeLocker contract. Must be called before claimFees.\n     *\n     * Permissionless - anyone can call this.\n     */\n    async collectRewards(token) {\n        const addresses = this.getAddresses();\n        return this.writeContract({\n            address: addresses.clawnch.locker,\n            abi: ClawnchLpLockerABI,\n            functionName: 'collectRewards',\n            args: [token],\n        });\n    }\n    /**\n     * Claim accumulated fees from the FeeLocker\n     *\n     * Claims fees for a specific feeOwner + token pair.\n     * Tokens are sent to the feeOwner's designated recipient.\n     *\n     * Permissionless - anyone can call this.\n     *\n     * @param feeOwner - The fee recipient address (as configured in token rewards)\n     * @param token - The token address to claim fees for (WETH or the launched token)\n     */\n    async claimFees(feeOwner, token) {\n        const addresses = this.getAddresses();\n        return this.writeContract({\n            address: addresses.clawnch.feeLocker,\n            abi: ClawnchFeeLockerABI,\n            functionName: 'claim',\n            args: [feeOwner, token],\n        });\n    }\n    /**\n     * Claim vested vault allocation for a token\n     *\n     * Claims the available portion of the vault allocation (based on lockup/vesting schedule).\n     * Tokens are sent to the vault admin.\n     *\n     * Permissionless - anyone can call this.\n     */\n    async claimVault(token) {\n        const addresses = this.getAddresses();\n        return this.writeContract({\n            address: addresses.clawnch.vault,\n            abi: ClawnchVaultABI,\n            functionName: 'claim',\n            args: [token],\n        });\n    }\n    /**\n     * Claim vested dev buy allocation for a token\n     *\n     * @throws Error - Not available in v3 (Clanker does not support vested dev buy)\n     * @deprecated Use packages/sdk-direct for vested dev buy support\n     */\n    async claimVestedDevBuy(_token) {\n        throw new ClawnchDeployError(ClawnchErrorCode.FEATURE_NOT_AVAILABLE, 'Vested dev buy is not available in v3. Clanker does not support this extension.');\n    }\n    // =========================================================================\n    // Combined Claims\n    // =========================================================================\n    /**\n     * Collect rewards and claim all fees for a token\n     *\n     * Steps:\n     *   1. collectRewards(token) - distributes LP fees to FeeLocker\n     *   2. claimFees(feeOwner, WETH) - claims WETH fees (if available)\n     *   3. claimFees(feeOwner, token) - claims token fees (if available)\n     *\n     * @param token - The Clawncher token address\n     * @param feeOwner - The fee owner to claim for\n     */\n    async claimAll(token, feeOwner) {\n        const addresses = this.getAddresses();\n        // Step 1: Collect rewards from LP locker -> FeeLocker\n        const collectResult = await this.collectRewards(token);\n        await collectResult.wait();\n        // Step 2: Claim WETH fees (protocol always pays in WETH)\n        let claimWeth = null;\n        try {\n            const wethAvailable = await this.publicClient.readContract({\n                address: addresses.clawnch.feeLocker,\n                abi: ClawnchFeeLockerABI,\n                functionName: 'availableFees',\n                args: [feeOwner, addresses.infrastructure.weth],\n            });\n            if (wethAvailable > 0n) {\n                claimWeth = await this.claimFees(feeOwner, addresses.infrastructure.weth);\n                await claimWeth.wait();\n            }\n        }\n        catch (err) {\n            // WETH fees may not be available for this feeOwner.\n            // The caller can inspect claimFeesWeth === null to detect this.\n            console.warn(`[clawnch] claimAll WETH step failed for ${token}:`, err instanceof Error ? err.message : err);\n        }\n        // Step 3: Claim token fees (if fee preference is Clawnch)\n        let claimToken = null;\n        try {\n            const tokenAvailable = await this.publicClient.readContract({\n                address: addresses.clawnch.feeLocker,\n                abi: ClawnchFeeLockerABI,\n                functionName: 'availableFees',\n                args: [feeOwner, token],\n            });\n            if (tokenAvailable > 0n) {\n                claimToken = await this.claimFees(feeOwner, token);\n                await claimToken.wait();\n            }\n        }\n        catch (err) {\n            // Token fees may not be available for this feeOwner/token pair.\n            console.warn(`[clawnch] claimAll token step failed for ${token}:`, err instanceof Error ? err.message : err);\n        }\n        return {\n            collectRewards: collectResult,\n            claimFeesWeth: claimWeth,\n            claimFeesToken: claimToken,\n        };\n    }\n    // =========================================================================\n    // Batch Claiming\n    // =========================================================================\n    /**\n     * Claim fees for multiple tokens in sequence.\n     *\n     * For each token: collects LP rewards, then claims WETH and token fees.\n     * Continues to the next token even if one fails.\n     *\n     * @param tokens - Array of token addresses to claim for\n     * @param feeOwner - The fee owner to claim for\n     * @param options - Optional progress callback\n     *\n     * @example\n     * ```typescript\n     * const result = await claimer.claimBatch(\n     *   ['0xToken1...', '0xToken2...'],\n     *   feeOwnerAddress,\n     *   {\n     *     onProgress: (token, step) => {\n     *       console.log(`${token}: ${step}`);\n     *     },\n     *   },\n     * );\n     * console.log(`Claimed ${result.successCount}/${result.results.length} tokens`);\n     * ```\n     */\n    async claimBatch(tokens, feeOwner, options) {\n        if (tokens.length === 0) {\n            return { results: [], successCount: 0, failureCount: 0 };\n        }\n        const results = [];\n        const addresses = this.getAddresses();\n        for (const token of tokens) {\n            const tokenResult = {\n                token,\n                success: false,\n                collectRewards: null,\n                claimFeesWeth: null,\n                claimFeesToken: null,\n            };\n            try {\n                // Step 1: Collect rewards\n                options?.onProgress?.(token, 'collecting rewards');\n                const collectResult = await this.collectRewards(token);\n                await collectResult.wait();\n                tokenResult.collectRewards = collectResult;\n                // Step 2: Claim WETH fees\n                options?.onProgress?.(token, 'claiming WETH fees');\n                try {\n                    const wethAvailable = await this.publicClient.readContract({\n                        address: addresses.clawnch.feeLocker,\n                        abi: ClawnchFeeLockerABI,\n                        functionName: 'availableFees',\n                        args: [feeOwner, addresses.infrastructure.weth],\n                    });\n                    if (wethAvailable > 0n) {\n                        const claimWeth = await this.claimFees(feeOwner, addresses.infrastructure.weth);\n                        await claimWeth.wait();\n                        tokenResult.claimFeesWeth = claimWeth;\n                    }\n                }\n                catch (err) {\n                    console.warn(`[clawnch] batchClaim WETH step failed for ${token}:`, err instanceof Error ? err.message : err);\n                }\n                // Step 3: Claim token fees\n                options?.onProgress?.(token, 'claiming token fees');\n                try {\n                    const tokenAvailable = await this.publicClient.readContract({\n                        address: addresses.clawnch.feeLocker,\n                        abi: ClawnchFeeLockerABI,\n                        functionName: 'availableFees',\n                        args: [feeOwner, token],\n                    });\n                    if (tokenAvailable > 0n) {\n                        const claimToken = await this.claimFees(feeOwner, token);\n                        await claimToken.wait();\n                        tokenResult.claimFeesToken = claimToken;\n                    }\n                }\n                catch (err) {\n                    console.warn(`[clawnch] batchClaim token step failed for ${token}:`, err instanceof Error ? err.message : err);\n                }\n                tokenResult.success = true;\n                options?.onProgress?.(token, 'done');\n            }\n            catch (err) {\n                tokenResult.error = err instanceof Error\n                    ? new ClawnchDeployError(ClawnchErrorCode.CLAIM_FAILED, `Claim failed for ${token}: ${err.message}`, err)\n                    : new ClawnchDeployError(ClawnchErrorCode.CLAIM_FAILED, `Claim failed for ${token}: ${String(err)}`);\n                options?.onProgress?.(token, 'failed');\n            }\n            results.push(tokenResult);\n        }\n        return {\n            results,\n            successCount: results.filter(r => r.success).length,\n            failureCount: results.filter(r => !r.success).length,\n        };\n    }\n}\n//# sourceMappingURL=claimer.js.map","/**\n * ClawnchPortfolio - Portfolio tracking for Clawncher token deployers\n *\n * Aggregates token holdings, fee balances, and vault allocations\n * for a wallet across all their deployed/participated tokens.\n *\n * Since Clanker's FeeLocker doesn't have efficient enumeration,\n * this class uses two approaches:\n * 1. Accept a known token list (fast, no event scanning)\n * 2. Scan factory TokenCreated events for a wallet (comprehensive but slower)\n */\nimport { formatEther, } from 'viem';\nimport { ClawnchFactoryABI, ClawnchFeeLockerABI, ClawnchLpLockerABI, ERC20ABI, } from './abis.js';\nimport { getAddresses } from './addresses.js';\n/**\n * ClawnchPortfolio - Track tokens and fees for a wallet\n *\n * @example\n * ```typescript\n * import { ClawnchPortfolio } from '@clawnch/clawncher-sdk';\n * import { createPublicClient, http } from 'viem';\n * import { base } from 'viem/chains';\n *\n * const publicClient = createPublicClient({\n *   chain: base,\n *   transport: http(),\n * });\n *\n * const portfolio = new ClawnchPortfolio({\n *   publicClient,\n *   network: 'mainnet',\n * });\n *\n * // Get portfolio for known tokens\n * const tokens = await portfolio.getTokensForWallet(\n *   walletAddress,\n *   [token1, token2, token3],\n * );\n *\n * // Get total claimable\n * const claimable = await portfolio.getTotalClaimable(\n *   walletAddress,\n *   [token1, token2],\n * );\n * console.log(`Total WETH: ${claimable.formattedWeth}`);\n * ```\n */\nexport class ClawnchPortfolio {\n    publicClient;\n    network;\n    constructor(config) {\n        this.publicClient = config.publicClient;\n        this.network = config.network;\n    }\n    /**\n     * Get contract addresses for configured network\n     */\n    getAddresses() {\n        return getAddresses(this.network);\n    }\n    /**\n     * Get all tokens where wallet is a reward recipient.\n     *\n     * Checks each provided token to see if the wallet is listed as a\n     * reward recipient in the LP locker, and fetches fee balances.\n     *\n     * @param wallet - The wallet address to check\n     * @param tokens - Known token addresses to check against\n     */\n    async getTokensForWallet(wallet, tokens) {\n        const addresses = this.getAddresses();\n        const results = [];\n        for (const token of tokens) {\n            try {\n                // Get reward info from LP locker\n                const rewards = await this.publicClient.readContract({\n                    address: addresses.clawnch.locker,\n                    abi: ClawnchLpLockerABI,\n                    functionName: 'tokenRewards',\n                    args: [token],\n                });\n                // Find this wallet in the reward recipients\n                const recipientIndex = rewards.rewardRecipients.findIndex((r) => r.toLowerCase() === wallet.toLowerCase());\n                if (recipientIndex === -1)\n                    continue;\n                // Get token info and fee balances in parallel\n                const [name, symbol, claimableWeth, claimableToken] = await Promise.all([\n                    this.publicClient.readContract({\n                        address: token,\n                        abi: ERC20ABI,\n                        functionName: 'name',\n                    }).catch(() => 'Unknown'),\n                    this.publicClient.readContract({\n                        address: token,\n                        abi: ERC20ABI,\n                        functionName: 'symbol',\n                    }).catch(() => '???'),\n                    this.publicClient.readContract({\n                        address: addresses.clawnch.feeLocker,\n                        abi: ClawnchFeeLockerABI,\n                        functionName: 'availableFees',\n                        args: [wallet, addresses.infrastructure.weth],\n                    }).catch(() => 0n),\n                    this.publicClient.readContract({\n                        address: addresses.clawnch.feeLocker,\n                        abi: ClawnchFeeLockerABI,\n                        functionName: 'availableFees',\n                        args: [wallet, token],\n                    }).catch(() => 0n),\n                ]);\n                results.push({\n                    address: token,\n                    name: name,\n                    symbol: symbol,\n                    bps: rewards.rewardBps[recipientIndex],\n                    claimableWeth,\n                    claimableToken,\n                    formattedWeth: formatEther(claimableWeth),\n                    formattedToken: formatEther(claimableToken),\n                });\n            }\n            catch {\n                // Skip tokens that fail (may not be Clawncher tokens)\n            }\n        }\n        return results;\n    }\n    /**\n     * Get total claimable fees across all specified tokens for a wallet.\n     *\n     * @param wallet - The wallet address\n     * @param tokens - Token addresses to aggregate\n     */\n    async getTotalClaimable(wallet, tokens) {\n        const addresses = this.getAddresses();\n        let totalWeth = 0n;\n        const tokenAmounts = [];\n        // Check WETH fees (these are per-feeOwner, not per-token, but we check anyway)\n        try {\n            totalWeth = await this.publicClient.readContract({\n                address: addresses.clawnch.feeLocker,\n                abi: ClawnchFeeLockerABI,\n                functionName: 'availableFees',\n                args: [wallet, addresses.infrastructure.weth],\n            });\n        }\n        catch {\n            // No WETH fees\n        }\n        // Check each token's fees\n        for (const token of tokens) {\n            try {\n                const [symbol, amount] = await Promise.all([\n                    this.publicClient.readContract({\n                        address: token,\n                        abi: ERC20ABI,\n                        functionName: 'symbol',\n                    }).catch(() => '???'),\n                    this.publicClient.readContract({\n                        address: addresses.clawnch.feeLocker,\n                        abi: ClawnchFeeLockerABI,\n                        functionName: 'availableFees',\n                        args: [wallet, token],\n                    }).catch(() => 0n),\n                ]);\n                if (amount > 0n) {\n                    tokenAmounts.push({\n                        address: token,\n                        symbol,\n                        amount,\n                        formatted: formatEther(amount),\n                    });\n                }\n            }\n            catch {\n                // Skip tokens that fail\n            }\n        }\n        return {\n            weth: totalWeth,\n            formattedWeth: formatEther(totalWeth),\n            tokens: tokenAmounts,\n        };\n    }\n    /**\n     * Discover tokens deployed by a wallet by scanning factory events.\n     *\n     * Scans TokenCreated events where tokenAdmin matches the wallet.\n     * This is slower than providing a known list but finds all tokens.\n     *\n     * @param wallet - The deployer wallet address\n     * @param fromBlock - Block to start scanning from (default: last 100k blocks)\n     */\n    async discoverTokens(wallet, fromBlock) {\n        const addresses = this.getAddresses();\n        const startBlock = fromBlock ?? await this.publicClient.getBlockNumber()\n            .then(n => n > 100000n ? n - 100000n : 0n);\n        try {\n            const logs = await this.publicClient.getContractEvents({\n                address: addresses.clawnch.factory,\n                abi: ClawnchFactoryABI,\n                eventName: 'TokenCreated',\n                args: {\n                    tokenAdmin: wallet,\n                },\n                fromBlock: startBlock,\n            });\n            return logs.map(log => {\n                const args = log.args;\n                return args.tokenAddress;\n            }).filter((addr) => !!addr);\n        }\n        catch {\n            return [];\n        }\n    }\n}\n//# sourceMappingURL=portfolio.js.map","/**\n * ClawnchWatcher - Live event watching for Clawncher tokens\n *\n * Watches for new token deployments, swaps, and transfers in real-time\n * using viem's event subscription (WebSocket recommended) or historical\n * log fetching (HTTP).\n *\n * Uses `publicClient.watchContractEvent()` which works with both\n * polling (HTTP) and subscription (WebSocket) transports.\n */\nimport { formatEther, parseAbiItem, } from 'viem';\nimport { ClawnchFactoryABI } from './abis.js';\nimport { getAddresses } from './addresses.js';\n/**\n * ClawnchWatcher - Watch live events from Clawncher contracts\n *\n * @example\n * ```typescript\n * import { ClawnchWatcher } from '@clawnch/clawncher-sdk';\n * import { createPublicClient, webSocket } from 'viem';\n * import { base } from 'viem/chains';\n *\n * // WebSocket recommended for live watching\n * const publicClient = createPublicClient({\n *   chain: base,\n *   transport: webSocket('wss://base-mainnet.g.alchemy.com/v2/YOUR_KEY'),\n * });\n *\n * const watcher = new ClawnchWatcher({\n *   publicClient,\n *   network: 'mainnet',\n * });\n *\n * // Watch for new token deployments\n * const unwatch = watcher.watchDeployments((event) => {\n *   console.log(`New token: ${event.tokenSymbol} at ${event.tokenAddress}`);\n * });\n *\n * // Stop watching later\n * unwatch();\n * ```\n */\nexport class ClawnchWatcher {\n    publicClient;\n    network;\n    constructor(config) {\n        this.publicClient = config.publicClient;\n        this.network = config.network;\n    }\n    /**\n     * Get contract addresses for configured network\n     */\n    getAddresses() {\n        return getAddresses(this.network);\n    }\n    /**\n     * Watch for new token deployments from the factory.\n     *\n     * Subscribes to TokenCreated events on the factory contract.\n     * Returns an unsubscribe function to stop watching.\n     *\n     * @param callback - Called for each new token deployment\n     * @param options - Optional filter by token admin\n     * @returns Unsubscribe function\n     */\n    watchDeployments(callback, options) {\n        const addresses = this.getAddresses();\n        const unwatch = this.publicClient.watchContractEvent({\n            address: addresses.clawnch.factory,\n            abi: ClawnchFactoryABI,\n            eventName: 'TokenCreated',\n            args: options?.tokenAdmin ? { tokenAdmin: options.tokenAdmin } : undefined,\n            onLogs: (logs) => {\n                for (const log of logs) {\n                    const args = log.args;\n                    if (!args.tokenAddress)\n                        continue;\n                    callback({\n                        tokenAddress: args.tokenAddress,\n                        tokenAdmin: args.tokenAdmin ?? '0x0000000000000000000000000000000000000000',\n                        tokenName: args.tokenName ?? '',\n                        tokenSymbol: args.tokenSymbol ?? '',\n                        tokenImage: args.tokenImage ?? '',\n                        deployer: args.msgSender ?? '0x0000000000000000000000000000000000000000',\n                        poolHook: args.poolHook ?? '0x0000000000000000000000000000000000000000',\n                        locker: args.locker ?? '0x0000000000000000000000000000000000000000',\n                        poolId: args.poolId ?? '0x0000000000000000000000000000000000000000000000000000000000000000',\n                        blockNumber: log.blockNumber ?? 0n,\n                        txHash: log.transactionHash ?? '0x0000000000000000000000000000000000000000000000000000000000000000',\n                    });\n                }\n            },\n        });\n        return unwatch;\n    }\n    /**\n     * Get historical token deployments (past events).\n     *\n     * Fetches TokenCreated events from the factory within a block range.\n     * Useful for building initial state before starting live watching.\n     *\n     * @param options - Block range and optional filter\n     */\n    async getHistoricalDeployments(options) {\n        const addresses = this.getAddresses();\n        const fromBlock = options?.fromBlock ?? await this.publicClient.getBlockNumber()\n            .then(n => n > 10000n ? n - 10000n : 0n);\n        const logs = await this.publicClient.getContractEvents({\n            address: addresses.clawnch.factory,\n            abi: ClawnchFactoryABI,\n            eventName: 'TokenCreated',\n            args: options?.tokenAdmin ? { tokenAdmin: options.tokenAdmin } : undefined,\n            fromBlock,\n            toBlock: options?.toBlock,\n        });\n        return logs.map(log => {\n            const args = log.args;\n            return {\n                tokenAddress: args.tokenAddress ?? '0x0000000000000000000000000000000000000000',\n                tokenAdmin: args.tokenAdmin ?? '0x0000000000000000000000000000000000000000',\n                tokenName: args.tokenName ?? '',\n                tokenSymbol: args.tokenSymbol ?? '',\n                tokenImage: args.tokenImage ?? '',\n                deployer: args.msgSender ?? '0x0000000000000000000000000000000000000000',\n                poolHook: args.poolHook ?? '0x0000000000000000000000000000000000000000',\n                locker: args.locker ?? '0x0000000000000000000000000000000000000000',\n                poolId: args.poolId ?? '0x0000000000000000000000000000000000000000000000000000000000000000',\n                blockNumber: log.blockNumber ?? 0n,\n                txHash: log.transactionHash ?? '0x0000000000000000000000000000000000000000000000000000000000000000',\n            };\n        });\n    }\n    // =========================================================================\n    // ERC-20 Transfer Events\n    // =========================================================================\n    /**\n     * Get recent ERC-20 Transfer events for a token.\n     *\n     * Useful for detecting whale movements, new holders, and distribution changes.\n     * Default block range: last 2,000 blocks (~1.1 hours on Base at 2s blocks).\n     */\n    async getRecentTransfers(token, options) {\n        const limit = options?.limit ?? 50;\n        const currentBlock = await this.publicClient.getBlockNumber();\n        const fromBlock = options?.fromBlock ?? (currentBlock > 2000n ? currentBlock - 2000n : 0n);\n        const transferEvent = parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)');\n        const logs = await this.publicClient.getLogs({\n            address: token,\n            event: transferEvent,\n            fromBlock,\n            toBlock: options?.toBlock ?? currentBlock,\n        });\n        // Sort newest first, limit\n        const sorted = logs.reverse().slice(0, limit);\n        return sorted.map((log) => ({\n            token,\n            from: log.args.from ?? '0x0000000000000000000000000000000000000000',\n            to: log.args.to ?? '0x0000000000000000000000000000000000000000',\n            amount: log.args.value ?? 0n,\n            amountFormatted: formatEther(log.args.value ?? 0n),\n            blockNumber: log.blockNumber ?? 0n,\n            txHash: log.transactionHash ?? '0x0000000000000000000000000000000000000000000000000000000000000000',\n        }));\n    }\n    // =========================================================================\n    // V4 Pool Swap Events\n    // =========================================================================\n    /**\n     * Get recent swap events from the Uniswap V4 PoolManager for a given poolId.\n     *\n     * The PoolManager emits `Swap(bytes32 indexed id, address indexed sender,\n     * int128 amount0, int128 amount1, uint160 sqrtPriceX96, uint128 liquidity,\n     * int24 tick, uint24 fee)`.\n     *\n     * Default range: last 2,000 blocks.\n     */\n    async getRecentSwaps(poolId, options) {\n        const addresses = this.getAddresses();\n        const limit = options?.limit ?? 50;\n        const currentBlock = await this.publicClient.getBlockNumber();\n        const fromBlock = options?.fromBlock ?? (currentBlock > 2000n ? currentBlock - 2000n : 0n);\n        const swapEvent = parseAbiItem('event Swap(bytes32 indexed id, address indexed sender, int128 amount0, int128 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick, uint24 fee)');\n        const logs = await this.publicClient.getLogs({\n            address: addresses.infrastructure.poolManager,\n            event: swapEvent,\n            args: { id: poolId },\n            fromBlock,\n            toBlock: options?.toBlock ?? currentBlock,\n        });\n        const sorted = logs.reverse().slice(0, limit);\n        return sorted.map((log) => {\n            const args = log.args;\n            return {\n                poolId,\n                sender: args.sender ?? '0x0000000000000000000000000000000000000000',\n                amount0: args.amount0 ?? 0n,\n                amount1: args.amount1 ?? 0n,\n                sqrtPriceX96: args.sqrtPriceX96 ?? 0n,\n                liquidity: args.liquidity ?? 0n,\n                tick: Number(args.tick ?? 0),\n                fee: Number(args.fee ?? 0),\n                blockNumber: log.blockNumber ?? 0n,\n                txHash: log.transactionHash ?? '0x0000000000000000000000000000000000000000000000000000000000000000',\n            };\n        });\n    }\n    // =========================================================================\n    // Combined Activity\n    // =========================================================================\n    /**\n     * Get a combined activity summary for a Clawncher token.\n     *\n     * Fetches both ERC-20 transfers and V4 pool swaps, computes summary stats\n     * including unique addresses, largest transfer, and total volume.\n     *\n     * Requires the poolId (get it from `ClawnchReader.getTokenRewards(token).poolKey`\n     * and compute the hash, or pass it directly).\n     *\n     * @param token - Token contract address\n     * @param poolId - V4 pool ID (bytes32)\n     * @param options - Block range and limits\n     */\n    async getTokenActivity(token, poolId, options) {\n        const currentBlock = await this.publicClient.getBlockNumber();\n        const fromBlock = options?.fromBlock ?? (currentBlock > 2000n ? currentBlock - 2000n : 0n);\n        const toBlock = options?.toBlock ?? currentBlock;\n        const [transfers, swaps] = await Promise.all([\n            this.getRecentTransfers(token, {\n                fromBlock,\n                toBlock,\n                limit: options?.transferLimit ?? 50,\n            }),\n            this.getRecentSwaps(poolId, {\n                fromBlock,\n                toBlock,\n                limit: options?.swapLimit ?? 50,\n            }),\n        ]);\n        // Compute stats\n        const addressSet = new Set();\n        let largestTransfer = 0n;\n        let totalVolume0 = 0n;\n        let totalVolume1 = 0n;\n        for (const t of transfers) {\n            addressSet.add(t.from.toLowerCase());\n            addressSet.add(t.to.toLowerCase());\n            const abs = t.amount < 0n ? -t.amount : t.amount;\n            if (abs > largestTransfer)\n                largestTransfer = abs;\n        }\n        for (const s of swaps) {\n            addressSet.add(s.sender.toLowerCase());\n            const abs0 = s.amount0 < 0n ? -s.amount0 : s.amount0;\n            const abs1 = s.amount1 < 0n ? -s.amount1 : s.amount1;\n            totalVolume0 += abs0;\n            totalVolume1 += abs1;\n        }\n        // Remove zero address from unique count\n        addressSet.delete('0x0000000000000000000000000000000000000000');\n        return {\n            token,\n            transfers,\n            swaps,\n            fromBlock,\n            toBlock,\n            stats: {\n                transferCount: transfers.length,\n                swapCount: swaps.length,\n                uniqueAddresses: addressSet.size,\n                largestTransfer,\n                totalVolume0,\n                totalVolume1,\n            },\n        };\n    }\n}\n//# sourceMappingURL=watcher.js.map","/**\n * Token Swap Types (0x Swap API v2)\n *\n * Types for the ClawnchSwapper class which wraps the 0x Swap API\n * for server-side / agent token swaps on Base.\n */\n// ============================================================================\n// Constants\n// ============================================================================\n/** 0x representation of native ETH (not an actual contract) */\nexport const NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';\n/** WETH on Base mainnet */\nexport const BASE_WETH = '0x4200000000000000000000000000000000000006';\n/** WETH on Base Sepolia */\nexport const BASE_SEPOLIA_WETH = '0x4200000000000000000000000000000000000006';\n/** 0x API base URL */\nexport const ZEROX_API_BASE = 'https://api.0x.org';\n/** Base mainnet chain ID */\nexport const BASE_CHAIN_ID = 8453;\n/** Base Sepolia chain ID */\nexport const BASE_SEPOLIA_CHAIN_ID = 84532;\n//# sourceMappingURL=swap-types.js.map","/**\n * ClawnchSwapper - Token swaps via Clawnch API (0x aggregation)\n *\n * Server-side / agent swap execution on Base using 0x aggregation\n * routed through the Clawnch API. No API key needed — the Clawnch\n * server handles 0x authentication and integrator fees.\n *\n * Uses the AllowanceHolder path for simple approve-and-swap flow.\n *\n * @example\n * ```typescript\n * import { ClawnchSwapper, NATIVE_TOKEN_ADDRESS } from '@clawnch/clawncher-sdk';\n * import { createWalletClient, createPublicClient, http, parseEther } from 'viem';\n * import { privateKeyToAccount } from 'viem/accounts';\n * import { base } from 'viem/chains';\n *\n * const account = privateKeyToAccount('0x...');\n * const wallet = createWalletClient({ account, chain: base, transport: http() });\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n *\n * const swapper = new ClawnchSwapper({ wallet, publicClient });\n *\n * // Swap 0.01 ETH for a token\n * const result = await swapper.swap({\n *   sellToken: NATIVE_TOKEN_ADDRESS,\n *   buyToken: '0x...',  // token address\n *   sellAmount: parseEther('0.01'),\n * });\n * console.log('Received:', result.buyAmount);\n * ```\n */\nimport { erc20Abi, maxUint256, formatUnits, } from 'viem';\nimport { base, baseSepolia } from 'viem/chains';\nimport { ClawnchErrorCode, ClawnchDeployError, withRetry } from './errors.js';\nimport { NATIVE_TOKEN_ADDRESS, BASE_CHAIN_ID, BASE_SEPOLIA_CHAIN_ID, } from './swap-types.js';\nexport { NATIVE_TOKEN_ADDRESS, ZEROX_API_BASE, BASE_CHAIN_ID, BASE_SEPOLIA_CHAIN_ID, BASE_WETH, BASE_SEPOLIA_WETH, } from './swap-types.js';\n// ============================================================================\n// Helpers\n// ============================================================================\nfunction isNativeToken(address) {\n    return address.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();\n}\nfunction buildQueryString(params) {\n    const entries = Object.entries(params).filter((entry) => entry[1] !== undefined);\n    return new URLSearchParams(entries).toString();\n}\n// ============================================================================\n// ClawnchSwapper\n// ============================================================================\n/** Default Clawnch API base URL */\nconst DEFAULT_API_BASE = 'https://clawn.ch';\nexport class ClawnchSwapper {\n    wallet;\n    publicClient;\n    network;\n    apiBaseUrl;\n    chainId;\n    constructor(config) {\n        if (!config.wallet) {\n            throw new ClawnchDeployError(ClawnchErrorCode.WALLET_NOT_CONFIGURED, 'Wallet client is required for ClawnchSwapper');\n        }\n        this.wallet = config.wallet;\n        this.publicClient = config.publicClient;\n        this.network = config.network ?? 'mainnet';\n        this.apiBaseUrl = (config.apiBaseUrl ?? DEFAULT_API_BASE).replace(/\\/$/, '');\n        this.chainId = this.network === 'mainnet' ? BASE_CHAIN_ID : BASE_SEPOLIA_CHAIN_ID;\n    }\n    /**\n     * Get the taker address (wallet account)\n     */\n    getTakerAddress() {\n        return this.wallet.account.address;\n    }\n    /**\n     * Get the chain object for the configured network\n     */\n    getChain() {\n        return this.network === 'mainnet' ? base : baseSepolia;\n    }\n    // ==========================================================================\n    // 0x API calls\n    // ==========================================================================\n    /**\n     * Make a request to the Clawnch swap API proxy\n     *\n     * The Clawnch server proxies 0x Swap API requests, adding our API key\n     * and integrator fee configuration server-side. Users never need a 0x key.\n     *\n     * Paths are relative to the API base, e.g. '/price?...' becomes\n     * 'https://clawn.ch/api/swap/price?...'\n     */\n    async apiRequest(path) {\n        return withRetry(async () => {\n            const url = `${this.apiBaseUrl}/api/swap${path}`;\n            const response = await fetch(url, {\n                method: 'GET',\n                headers: {\n                    'Accept': 'application/json',\n                },\n            });\n            if (!response.ok) {\n                let errorMsg;\n                try {\n                    const body = await response.json();\n                    errorMsg = body.error || body.reason || JSON.stringify(body);\n                }\n                catch {\n                    errorMsg = `HTTP ${response.status}: ${response.statusText}`;\n                }\n                throw new ClawnchDeployError(ClawnchErrorCode.RPC_ERROR, `Swap API error: ${errorMsg}`);\n            }\n            return response.json();\n        });\n    }\n    /**\n     * Build query params from SwapParams\n     */\n    buildSwapQuery(params, includeTaker) {\n        const taker = params.taker ?? this.getTakerAddress();\n        const query = {\n            chainId: this.chainId.toString(),\n            sellToken: params.sellToken,\n            buyToken: params.buyToken,\n            sellAmount: params.sellAmount.toString(),\n            slippageBps: (params.slippageBps ?? 100).toString(),\n        };\n        if (includeTaker) {\n            query.taker = taker;\n        }\n        if (params.swapFeeRecipient) {\n            query.swapFeeRecipient = params.swapFeeRecipient;\n        }\n        if (params.swapFeeBps !== undefined) {\n            query.swapFeeBps = params.swapFeeBps.toString();\n        }\n        if (params.swapFeeToken) {\n            query.swapFeeToken = params.swapFeeToken;\n        }\n        if (params.excludedSources) {\n            query.excludedSources = params.excludedSources;\n        }\n        return buildQueryString(query);\n    }\n    /**\n     * Parse the raw 0x API price/quote response into our typed result\n     */\n    parsePriceResponse(raw) {\n        return {\n            buyAmount: BigInt(raw.buyAmount),\n            sellAmount: BigInt(raw.sellAmount),\n            minBuyAmount: BigInt(raw.minBuyAmount),\n            gas: BigInt(raw.gas || '0'),\n            gasPrice: BigInt(raw.gasPrice || '0'),\n            totalNetworkFee: BigInt(raw.totalNetworkFee || '0'),\n            allowanceTarget: raw.allowanceTarget,\n            liquidityAvailable: raw.liquidityAvailable ?? true,\n            route: raw.route ?? { fills: [], tokens: [] },\n            fees: raw.fees ?? { integratorFee: null, zeroExFee: null, gasFee: null },\n            issues: raw.issues ?? { simulationIncomplete: false, invalidSourcesPassed: [] },\n            tokenMetadata: raw.tokenMetadata ?? {\n                buyToken: { buyTaxBps: '0', sellTaxBps: '0' },\n                sellToken: { buyTaxBps: '0', sellTaxBps: '0' },\n            },\n            blockNumber: raw.blockNumber ?? '0',\n            zid: raw.zid ?? '',\n        };\n    }\n    /**\n     * Parse a quote response (includes transaction data)\n     */\n    parseQuoteResponse(raw) {\n        const base = this.parsePriceResponse(raw);\n        const tx = raw.transaction;\n        return {\n            ...base,\n            transaction: {\n                to: tx.to,\n                data: tx.data,\n                gas: BigInt(tx.gas || '0'),\n                gasPrice: BigInt(tx.gasPrice || '0'),\n                value: BigInt(tx.value || '0'),\n            },\n        };\n    }\n    // ==========================================================================\n    // Public API\n    // ==========================================================================\n    /**\n     * Get an indicative price for a swap (no commitment, no taker required)\n     *\n     * Use this for price discovery / display before the user commits.\n     * Does NOT reserve liquidity with market makers.\n     */\n    async getPrice(params) {\n        const query = this.buildSwapQuery(params, false);\n        const raw = await this.apiRequest(`/price?${query}`);\n        return this.parsePriceResponse(raw);\n    }\n    /**\n     * Get a firm quote for a swap (market makers commit assets)\n     *\n     * Requires a taker address. Returns transaction data ready to submit.\n     * Only call this when ready to execute — market makers reserve liquidity.\n     */\n    async getQuote(params) {\n        const query = this.buildSwapQuery(params, true);\n        const raw = await this.apiRequest(`/quote?${query}`);\n        return this.parseQuoteResponse(raw);\n    }\n    /**\n     * Check current ERC20 allowance for a given spender\n     */\n    async getAllowance(token, owner, spender) {\n        if (isNativeToken(token))\n            return maxUint256; // native ETH needs no approval\n        const allowance = await this.publicClient.readContract({\n            address: token,\n            abi: erc20Abi,\n            functionName: 'allowance',\n            args: [owner, spender],\n        });\n        return allowance;\n    }\n    /**\n     * Approve an ERC20 token for a spender (e.g. AllowanceHolder)\n     *\n     * @param token - ERC20 token address\n     * @param spender - Contract to approve (usually the allowanceTarget from quote)\n     * @param amount - Amount to approve (default: max uint256)\n     * @returns Transaction hash of the approval\n     */\n    async approveToken(token, spender, amount = maxUint256) {\n        if (isNativeToken(token)) {\n            throw new ClawnchDeployError(ClawnchErrorCode.INVALID_ADDRESS, 'Cannot approve native ETH — no approval needed');\n        }\n        const txHash = await this.wallet.writeContract({\n            address: token,\n            abi: erc20Abi,\n            functionName: 'approve',\n            args: [spender, amount],\n            chain: this.getChain(),\n        });\n        // Wait for approval to be mined\n        await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        return txHash;\n    }\n    /**\n     * Execute a full swap: quote -> approve if needed -> send transaction\n     *\n     * This is the primary method for agents. It handles the entire flow:\n     * 1. Gets a firm quote from 0x\n     * 2. Checks and sets token allowance if needed (ERC20 only)\n     * 3. Sends the swap transaction\n     * 4. Waits for confirmation\n     *\n     * @returns SwapResult with transaction details and amounts\n     */\n    async swap(params) {\n        const taker = params.taker ?? this.getTakerAddress();\n        // 1. Get firm quote\n        const quote = await this.getQuote({ ...params, taker });\n        if (!quote.liquidityAvailable) {\n            throw new ClawnchDeployError(ClawnchErrorCode.DEPLOY_FAILED, 'Insufficient liquidity available for this swap');\n        }\n        // 2. Approve token if selling ERC20 (not needed for native ETH)\n        if (!isNativeToken(params.sellToken)) {\n            const spender = quote.allowanceTarget;\n            const currentAllowance = await this.getAllowance(params.sellToken, taker, spender);\n            if (currentAllowance < params.sellAmount) {\n                await this.approveToken(params.sellToken, spender);\n            }\n        }\n        // 3. Send swap transaction\n        const tx = quote.transaction;\n        const txHash = await this.wallet.sendTransaction({\n            account: this.wallet.account,\n            chain: this.getChain(),\n            to: tx.to,\n            data: tx.data,\n            gas: tx.gas > 0n ? tx.gas : undefined,\n            gasPrice: tx.gasPrice > 0n ? tx.gasPrice : undefined,\n            value: tx.value,\n        });\n        // 4. Wait for confirmation\n        const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        if (receipt.status === 'reverted') {\n            throw new ClawnchDeployError(ClawnchErrorCode.TX_REVERTED, `Swap transaction reverted: ${txHash}`);\n        }\n        return {\n            txHash,\n            buyAmount: quote.buyAmount,\n            sellAmount: quote.sellAmount,\n            receipt,\n            gasUsed: receipt.gasUsed,\n            effectiveGasPrice: receipt.effectiveGasPrice,\n        };\n    }\n    /**\n     * Get token balance for an address\n     */\n    async getBalance(token, owner) {\n        const address = owner ?? this.getTakerAddress();\n        if (isNativeToken(token)) {\n            return this.publicClient.getBalance({ address });\n        }\n        return this.publicClient.readContract({\n            address: token,\n            abi: erc20Abi,\n            functionName: 'balanceOf',\n            args: [address],\n        });\n    }\n    /**\n     * Get token decimals\n     */\n    async getDecimals(token) {\n        if (isNativeToken(token))\n            return 18;\n        const decimals = await this.publicClient.readContract({\n            address: token,\n            abi: erc20Abi,\n            functionName: 'decimals',\n        });\n        return decimals;\n    }\n    /**\n     * Get token symbol\n     */\n    async getSymbol(token) {\n        if (isNativeToken(token))\n            return 'ETH';\n        const symbol = await this.publicClient.readContract({\n            address: token,\n            abi: erc20Abi,\n            functionName: 'symbol',\n        });\n        return symbol;\n    }\n    /**\n     * Format a token amount to human-readable string\n     */\n    async formatAmount(token, amount) {\n        const decimals = await this.getDecimals(token);\n        return formatUnits(amount, decimals);\n    }\n}\n//# sourceMappingURL=swap.js.map","/**\n * Permit2 — EIP-712 signature-based token approvals for Uniswap V4.\n *\n * Permit2 replaces per-contract ERC20 approvals with a two-step model:\n *   1. Owner approves Permit2 once (ERC20.approve(Permit2, MAX))\n *   2. For each swap/LP action, owner signs an EIP-712 permit granting\n *      the router/PositionManager a time-limited, amount-limited allowance\n *\n * Two transfer modes:\n *\n * **AllowanceTransfer** — used by PositionManager for LP operations\n *   - On-chain nonce tracking (uint48, auto-incremented per token+spender)\n *   - Supports amount limits and expiration timestamps\n *   - sign PermitSingle/PermitBatch → call permit() → router calls transferFrom()\n *\n * **SignatureTransfer** — used by UniversalRouter for swaps\n *   - Off-chain nonce (uint256, bitmap-based, single-use)\n *   - No on-chain state change for the permit itself\n *   - sign PermitTransferFrom → router calls permitTransferFrom() in one tx\n *   - Supports \"witness\" data for swap parameters\n *\n * @see https://docs.uniswap.org/contracts/permit2/overview\n * @see https://github.com/Uniswap/permit2\n */\nimport { erc20Abi, maxUint256, maxUint160, } from 'viem';\nimport { Permit2ABI } from './uniswap-abis.js';\nimport { ClawnchErrorCode, ClawnchDeployError } from './errors.js';\n// ============================================================================\n// Constants\n// ============================================================================\n/** Permit2 is deployed at the same address on all chains */\nexport const PERMIT2_ADDRESS = '0x000000000022D473030F116dDEE9F6B43aC78BA3';\n/** 30 days in seconds — default permit expiration */\nconst DEFAULT_PERMIT_EXPIRATION = 30 * 24 * 60 * 60;\n/** 30 minutes — default signature deadline */\nconst DEFAULT_SIG_DEADLINE = 30 * 60;\nconst ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';\n// ============================================================================\n// EIP-712 Domain & Types\n// ============================================================================\n/** Permit2 EIP-712 domain (same for all chains — uses chainId at signing time) */\nfunction getPermit2Domain(chainId) {\n    return {\n        name: 'Permit2',\n        chainId,\n        verifyingContract: PERMIT2_ADDRESS,\n    };\n}\n// ── AllowanceTransfer EIP-712 types ─────────────────────────────────────\nconst PERMIT_DETAILS_TYPE = {\n    PermitDetails: [\n        { name: 'token', type: 'address' },\n        { name: 'amount', type: 'uint160' },\n        { name: 'expiration', type: 'uint48' },\n        { name: 'nonce', type: 'uint48' },\n    ],\n};\nconst PERMIT_SINGLE_TYPES = {\n    PermitSingle: [\n        { name: 'details', type: 'PermitDetails' },\n        { name: 'spender', type: 'address' },\n        { name: 'sigDeadline', type: 'uint256' },\n    ],\n    ...PERMIT_DETAILS_TYPE,\n};\nconst PERMIT_BATCH_TYPES = {\n    PermitBatch: [\n        { name: 'details', type: 'PermitDetails[]' },\n        { name: 'spender', type: 'address' },\n        { name: 'sigDeadline', type: 'uint256' },\n    ],\n    ...PERMIT_DETAILS_TYPE,\n};\n// ── SignatureTransfer EIP-712 types ─────────────────────────────────────\nconst TOKEN_PERMISSIONS_TYPE = {\n    TokenPermissions: [\n        { name: 'token', type: 'address' },\n        { name: 'amount', type: 'uint256' },\n    ],\n};\nconst PERMIT_TRANSFER_FROM_TYPES = {\n    PermitTransferFrom: [\n        { name: 'permitted', type: 'TokenPermissions' },\n        { name: 'spender', type: 'address' },\n        { name: 'nonce', type: 'uint256' },\n        { name: 'deadline', type: 'uint256' },\n    ],\n    ...TOKEN_PERMISSIONS_TYPE,\n};\nconst PERMIT_BATCH_TRANSFER_FROM_TYPES = {\n    PermitBatchTransferFrom: [\n        { name: 'permitted', type: 'TokenPermissions[]' },\n        { name: 'spender', type: 'address' },\n        { name: 'nonce', type: 'uint256' },\n        { name: 'deadline', type: 'uint256' },\n    ],\n    ...TOKEN_PERMISSIONS_TYPE,\n};\n// ============================================================================\n// Permit2Client\n// ============================================================================\nexport class Permit2Client {\n    wallet;\n    publicClient;\n    chainId;\n    constructor(config) {\n        if (!config.wallet) {\n            throw new ClawnchDeployError(ClawnchErrorCode.WALLET_NOT_CONFIGURED, 'Wallet client is required for Permit2Client');\n        }\n        this.wallet = config.wallet;\n        this.publicClient = config.publicClient;\n        this.chainId = config.chainId ?? 8453;\n    }\n    /** Owner address */\n    get owner() {\n        return this.wallet.account.address;\n    }\n    // ==========================================================================\n    // Step 0: Ensure ERC20 → Permit2 approval\n    // ==========================================================================\n    /**\n     * Ensure a token has approved the Permit2 contract for max spending.\n     *\n     * This is a one-time operation per token. After this, all future\n     * permits are gas-free (off-chain signatures).\n     *\n     * @returns Transaction hash if approval was needed, null if already approved\n     */\n    async ensureTokenApproval(token) {\n        if (token === ZERO_ADDRESS)\n            return null; // native ETH\n        const currentAllowance = await this.publicClient.readContract({\n            address: token,\n            abi: erc20Abi,\n            functionName: 'allowance',\n            args: [this.owner, PERMIT2_ADDRESS],\n        });\n        // If already approved for > half of max, skip\n        if (currentAllowance > maxUint256 / 2n)\n            return null;\n        const txHash = await this.wallet.writeContract({\n            account: this.wallet.account,\n            address: token,\n            abi: erc20Abi,\n            functionName: 'approve',\n            args: [PERMIT2_ADDRESS, maxUint256],\n            chain: null,\n        });\n        await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        return txHash;\n    }\n    /**\n     * Batch-approve multiple tokens for Permit2.\n     * Only sends transactions for tokens that need approval.\n     *\n     * @returns Map of token → txHash (only tokens that needed approval)\n     */\n    async ensureTokenApprovals(tokens) {\n        const results = new Map();\n        // Check all allowances in parallel\n        const allowances = await Promise.all(tokens.filter(t => t !== ZERO_ADDRESS).map(async (token) => {\n            const allowance = await this.publicClient.readContract({\n                address: token,\n                abi: erc20Abi,\n                functionName: 'allowance',\n                args: [this.owner, PERMIT2_ADDRESS],\n            });\n            return { token, allowance };\n        }));\n        // Approve tokens that need it (sequentially to avoid nonce issues)\n        for (const { token, allowance } of allowances) {\n            if (allowance <= maxUint256 / 2n) {\n                const txHash = await this.wallet.writeContract({\n                    account: this.wallet.account,\n                    address: token,\n                    abi: erc20Abi,\n                    functionName: 'approve',\n                    args: [PERMIT2_ADDRESS, maxUint256],\n                    chain: null,\n                });\n                await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n                results.set(token, txHash);\n            }\n        }\n        return results;\n    }\n    // ==========================================================================\n    // AllowanceTransfer: Read state\n    // ==========================================================================\n    /**\n     * Read the current Permit2 allowance for a token/spender pair.\n     */\n    async getAllowance(token, spender) {\n        const result = await this.publicClient.readContract({\n            address: PERMIT2_ADDRESS,\n            abi: Permit2ABI,\n            functionName: 'allowance',\n            args: [this.owner, token, spender],\n        });\n        return {\n            amount: result[0],\n            expiration: Number(result[1]),\n            nonce: Number(result[2]),\n        };\n    }\n    /**\n     * Check if a Permit2 allowance is sufficient and not expired.\n     */\n    async isAllowanceSufficient(token, spender, requiredAmount) {\n        const allowance = await this.getAllowance(token, spender);\n        const now = Math.floor(Date.now() / 1000);\n        return allowance.amount >= requiredAmount && allowance.expiration > now;\n    }\n    // ==========================================================================\n    // AllowanceTransfer: Sign PermitSingle\n    // ==========================================================================\n    /**\n     * Sign a PermitSingle for a single token → spender allowance.\n     *\n     * This is an off-chain operation (no gas). The returned signature\n     * can be submitted by the spender to claim the allowance.\n     *\n     * Used by: PositionManager (LP operations), UniversalRouter (some flows)\n     */\n    async signPermitSingle(params) {\n        const { nonce } = await this.getAllowance(params.token, params.spender);\n        const amount = params.amount ?? maxUint160;\n        const expiration = Math.floor(Date.now() / 1000) + (params.expirationSeconds ?? DEFAULT_PERMIT_EXPIRATION);\n        const sigDeadline = BigInt(Math.floor(Date.now() / 1000) + (params.sigDeadlineSeconds ?? DEFAULT_SIG_DEADLINE));\n        const permit = {\n            details: {\n                token: params.token,\n                amount,\n                expiration,\n                nonce,\n            },\n            spender: params.spender,\n            sigDeadline,\n        };\n        const signature = await this.wallet.signTypedData({\n            account: this.wallet.account,\n            domain: getPermit2Domain(this.chainId),\n            types: PERMIT_SINGLE_TYPES,\n            primaryType: 'PermitSingle',\n            message: {\n                details: {\n                    token: permit.details.token,\n                    amount: permit.details.amount,\n                    expiration: permit.details.expiration,\n                    nonce: permit.details.nonce,\n                },\n                spender: permit.spender,\n                sigDeadline: permit.sigDeadline,\n            },\n        });\n        return { permit, signature, owner: this.owner };\n    }\n    // ==========================================================================\n    // AllowanceTransfer: Sign PermitBatch\n    // ==========================================================================\n    /**\n     * Sign a PermitBatch for multiple tokens → single spender.\n     *\n     * Used by PositionManager when minting LP with two tokens.\n     */\n    async signPermitBatch(params) {\n        const sigDeadline = BigInt(Math.floor(Date.now() / 1000) + (params.sigDeadlineSeconds ?? DEFAULT_SIG_DEADLINE));\n        // Fetch nonces for all tokens in parallel\n        const detailsPromises = params.tokens.map(async (t) => {\n            const { nonce } = await this.getAllowance(t.token, params.spender);\n            const amount = t.amount ?? maxUint160;\n            const expiration = Math.floor(Date.now() / 1000) + (t.expirationSeconds ?? DEFAULT_PERMIT_EXPIRATION);\n            return { token: t.token, amount, expiration, nonce };\n        });\n        const details = await Promise.all(detailsPromises);\n        const permit = {\n            details,\n            spender: params.spender,\n            sigDeadline,\n        };\n        const signature = await this.wallet.signTypedData({\n            account: this.wallet.account,\n            domain: getPermit2Domain(this.chainId),\n            types: PERMIT_BATCH_TYPES,\n            primaryType: 'PermitBatch',\n            message: {\n                details: permit.details.map(d => ({\n                    token: d.token,\n                    amount: d.amount,\n                    expiration: d.expiration,\n                    nonce: d.nonce,\n                })),\n                spender: permit.spender,\n                sigDeadline: permit.sigDeadline,\n            },\n        });\n        return { permit, signature, owner: this.owner };\n    }\n    // ==========================================================================\n    // AllowanceTransfer: Submit permit on-chain\n    // ==========================================================================\n    /**\n     * Submit a signed PermitSingle to the Permit2 contract.\n     *\n     * After this, the spender can call transferFrom() on Permit2.\n     * In practice, this is often bundled in the same tx as the router call\n     * via multicall, so you may not need to call this separately.\n     */\n    async submitPermitSingle(signed) {\n        const txHash = await this.wallet.writeContract({\n            account: this.wallet.account,\n            address: PERMIT2_ADDRESS,\n            abi: Permit2ABI,\n            functionName: 'permit',\n            args: [\n                signed.owner,\n                {\n                    details: {\n                        token: signed.permit.details.token,\n                        amount: signed.permit.details.amount,\n                        expiration: signed.permit.details.expiration,\n                        nonce: signed.permit.details.nonce,\n                    },\n                    spender: signed.permit.spender,\n                    sigDeadline: signed.permit.sigDeadline,\n                },\n                signed.signature,\n            ],\n            chain: null,\n        });\n        await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        return txHash;\n    }\n    // ==========================================================================\n    // AllowanceTransfer: Direct approve (no signature, on-chain)\n    // ==========================================================================\n    /**\n     * Directly approve a spender on Permit2 (no signature, costs gas).\n     *\n     * Simpler but requires an on-chain tx. For agent wallets that control\n     * their own private key, this is often easier than signing a permit.\n     */\n    async directApprove(token, spender, amount = maxUint160, expirationSeconds = DEFAULT_PERMIT_EXPIRATION) {\n        const expiration = Math.floor(Date.now() / 1000) + expirationSeconds;\n        const txHash = await this.wallet.writeContract({\n            account: this.wallet.account,\n            address: PERMIT2_ADDRESS,\n            abi: Permit2ABI,\n            functionName: 'approve',\n            args: [token, spender, amount, expiration],\n            chain: null,\n        });\n        await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        return txHash;\n    }\n    /**\n     * Direct-approve multiple tokens for a spender in sequence.\n     */\n    async directApproveBatch(tokens, spender, amount = maxUint160, expirationSeconds = DEFAULT_PERMIT_EXPIRATION) {\n        const hashes = [];\n        for (const token of tokens) {\n            const sufficient = await this.isAllowanceSufficient(token, spender, amount);\n            if (!sufficient) {\n                const hash = await this.directApprove(token, spender, amount, expirationSeconds);\n                hashes.push(hash);\n            }\n        }\n        return hashes;\n    }\n    // ==========================================================================\n    // SignatureTransfer: Sign PermitTransferFrom\n    // ==========================================================================\n    /**\n     * Sign a PermitTransferFrom for the UniversalRouter.\n     *\n     * This creates a single-use, nonce-specific permit. The router\n     * calls `permitTransferFrom()` which atomically verifies the sig\n     * and transfers the tokens.\n     *\n     * @param params.nonce - Must be an unused nonce. Use `findUnusedNonce()` to find one.\n     */\n    async signPermitTransferFrom(params) {\n        const deadline = BigInt(Math.floor(Date.now() / 1000) + (params.deadlineSeconds ?? DEFAULT_SIG_DEADLINE));\n        const permit = {\n            permitted: { token: params.token, amount: params.amount },\n            nonce: params.nonce,\n            deadline,\n        };\n        const signature = await this.wallet.signTypedData({\n            account: this.wallet.account,\n            domain: getPermit2Domain(this.chainId),\n            types: PERMIT_TRANSFER_FROM_TYPES,\n            primaryType: 'PermitTransferFrom',\n            message: {\n                permitted: {\n                    token: permit.permitted.token,\n                    amount: permit.permitted.amount,\n                },\n                spender: params.spender,\n                nonce: permit.nonce,\n                deadline: permit.deadline,\n            },\n        });\n        return { permit, signature, owner: this.owner };\n    }\n    // ==========================================================================\n    // SignatureTransfer: Nonce management\n    // ==========================================================================\n    /**\n     * Check if a specific nonce has been used (SignatureTransfer).\n     *\n     * Permit2 uses a bitmap: nonce N is stored in word N/256, bit N%256.\n     */\n    async isNonceUsed(nonce) {\n        const word = nonce / 256n;\n        const bit = nonce % 256n;\n        const bitmap = await this.publicClient.readContract({\n            address: PERMIT2_ADDRESS,\n            abi: Permit2ABI,\n            functionName: 'nonceBitmap',\n            args: [this.owner, word],\n        });\n        return (bitmap & (1n << bit)) !== 0n;\n    }\n    /**\n     * Find an unused nonce for SignatureTransfer.\n     *\n     * Scans from `startNonce` forward until an unused one is found.\n     * Uses bitmap reads for efficiency (checks 256 nonces per read).\n     */\n    async findUnusedNonce(startNonce = 0n) {\n        const word = startNonce / 256n;\n        const bitmap = await this.publicClient.readContract({\n            address: PERMIT2_ADDRESS,\n            abi: Permit2ABI,\n            functionName: 'nonceBitmap',\n            args: [this.owner, word],\n        });\n        // Find first unused bit in this word\n        const startBit = startNonce % 256n;\n        for (let bit = startBit; bit < 256n; bit++) {\n            if ((bitmap & (1n << bit)) === 0n) {\n                return word * 256n + bit;\n            }\n        }\n        // All bits in this word used — try next word\n        return this.findUnusedNonce((word + 1n) * 256n);\n    }\n    // ==========================================================================\n    // Lockdown: Emergency revocation\n    // ==========================================================================\n    /**\n     * Revoke all Permit2 allowances for specific token/spender pairs.\n     *\n     * Sets amount=0 and expiration=0 for each pair. This is the\n     * emergency kill switch if you need to revoke access immediately.\n     */\n    async lockdown(pairs) {\n        const txHash = await this.wallet.writeContract({\n            account: this.wallet.account,\n            address: PERMIT2_ADDRESS,\n            abi: Permit2ABI,\n            functionName: 'lockdown',\n            args: [pairs.map(p => ({ token: p.token, spender: p.spender }))],\n            chain: null,\n        });\n        await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        return txHash;\n    }\n    // ==========================================================================\n    // Convenience: Full permit flow for a swap\n    // ==========================================================================\n    /**\n     * Complete AllowanceTransfer flow for a single token:\n     *   1. Ensure ERC20 → Permit2 approval\n     *   2. Check if Permit2 allowance is sufficient for the spender\n     *   3. If not, sign a PermitSingle and submit it\n     *\n     * Returns the current nonce after the flow completes.\n     */\n    async ensurePermit2Allowance(token, spender, amount) {\n        // Step 1: ERC20 → Permit2\n        const approvalTxHash = await this.ensureTokenApproval(token);\n        // Step 2: Check Permit2 → Spender\n        const sufficient = await this.isAllowanceSufficient(token, spender, amount);\n        if (sufficient) {\n            return { approvalTxHash, permitTxHash: null };\n        }\n        // Step 3: Direct approve on Permit2 (simpler for agent wallets)\n        const permitTxHash = await this.directApprove(token, spender, maxUint160);\n        return { approvalTxHash, permitTxHash };\n    }\n    /**\n     * Complete flow for two tokens (LP operations):\n     *   1. Ensure ERC20 → Permit2 for both\n     *   2. Direct-approve both on Permit2 for the spender\n     */\n    async ensurePermit2AllowancePair(token0, token1, spender, amount0, amount1) {\n        // ERC20 approvals in parallel\n        const [token0ApprovalTx, token1ApprovalTx] = await Promise.all([\n            this.ensureTokenApproval(token0),\n            this.ensureTokenApproval(token1),\n        ]);\n        // Permit2 allowances (sequential to avoid nonce issues)\n        const [suf0, suf1] = await Promise.all([\n            this.isAllowanceSufficient(token0, spender, amount0),\n            this.isAllowanceSufficient(token1, spender, amount1),\n        ]);\n        let permit0Tx = null;\n        let permit1Tx = null;\n        if (!suf0) {\n            permit0Tx = await this.directApprove(token0, spender, maxUint160);\n        }\n        if (!suf1) {\n            permit1Tx = await this.directApprove(token1, spender, maxUint160);\n        }\n        return { token0ApprovalTx, token1ApprovalTx, permit0Tx, permit1Tx };\n    }\n}\n//# sourceMappingURL=permit2.js.map","/**\n * ClawnchLiquidity - Uniswap V3 & V4 Liquidity Management\n *\n * Manages liquidity positions on both Uniswap V3 and V4 pools on Base.\n * Supports minting, adding/removing liquidity, and fee collection.\n *\n * V4 uses the PositionManager with multicall + command encoding.\n * V3 uses the NonfungiblePositionManager directly.\n *\n * @example\n * ```typescript\n * import { ClawnchLiquidity } from '@clawnch/clawncher-sdk';\n * import { createWalletClient, createPublicClient, http } from 'viem';\n * import { privateKeyToAccount } from 'viem/accounts';\n * import { base } from 'viem/chains';\n *\n * const account = privateKeyToAccount('0x...');\n * const wallet = createWalletClient({ account, chain: base, transport: http() });\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n *\n * const liquidity = new ClawnchLiquidity({ wallet, publicClient });\n *\n * // Read a V3 position\n * const pos = await liquidity.v3GetPosition(123456n);\n * console.log(pos.liquidity, pos.unclaimedFees);\n * ```\n */\nimport { erc20Abi, maxUint256, maxUint128, encodeFunctionData, } from 'viem';\nimport { base, baseSepolia } from 'viem/chains';\nimport { ClawnchErrorCode, ClawnchDeployError } from './errors.js';\nimport { getUniswapV4Addresses, getUniswapV3Addresses, getCommonAddresses } from './uniswap-addresses.js';\nimport { StateViewABI, V4PositionManagerABI, V3NonfungiblePositionManagerABI } from './uniswap-abis.js';\nimport { Permit2Client } from './permit2.js';\n// ============================================================================\n// Constants\n// ============================================================================\nconst Q128 = 2n ** 128n;\nconst ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';\nconst DEFAULT_DEADLINE_SECONDS = 1200; // 20 minutes\nconst DEFAULT_SLIPPAGE_BPS = 50; // 0.5%\n// ============================================================================\n// Helpers\n// ============================================================================\nfunction getDeadline(secondsFromNow) {\n    return BigInt(Math.floor(Date.now() / 1000) + (secondsFromNow ?? DEFAULT_DEADLINE_SECONDS));\n}\nfunction applySlippage(amount, slippageBps) {\n    // Returns minimum acceptable amount after slippage\n    return amount - (amount * BigInt(slippageBps) / 10000n);\n}\n// ============================================================================\n// ClawnchLiquidity\n// ============================================================================\nexport class ClawnchLiquidity {\n    wallet;\n    publicClient;\n    network;\n    _permit2 = null;\n    constructor(config) {\n        if (!config.wallet) {\n            throw new ClawnchDeployError(ClawnchErrorCode.WALLET_NOT_CONFIGURED, 'Wallet client is required for ClawnchLiquidity');\n        }\n        if (!config.publicClient) {\n            throw new ClawnchDeployError(ClawnchErrorCode.PUBLIC_CLIENT_NOT_CONFIGURED, 'Public client is required for ClawnchLiquidity');\n        }\n        this.wallet = config.wallet;\n        this.publicClient = config.publicClient;\n        this.network = config.network ?? 'mainnet';\n    }\n    /** Lazy-initialized Permit2 client for V4 approval flows */\n    get permit2() {\n        if (!this._permit2) {\n            this._permit2 = new Permit2Client({\n                wallet: this.wallet,\n                publicClient: this.publicClient,\n                chainId: this.getChain().id,\n            });\n        }\n        return this._permit2;\n    }\n    getChain() {\n        return this.network === 'mainnet' ? base : baseSepolia;\n    }\n    getWalletAddress() {\n        return this.wallet.account.address;\n    }\n    // ==========================================================================\n    // Token Approval Helpers\n    // ==========================================================================\n    /**\n     * Approve an ERC20 token for a spender if current allowance is insufficient\n     */\n    async ensureApproval(token, spender, amount) {\n        if (token === ZERO_ADDRESS)\n            return; // native ETH\n        const currentAllowance = await this.publicClient.readContract({\n            address: token,\n            abi: erc20Abi,\n            functionName: 'allowance',\n            args: [this.getWalletAddress(), spender],\n        });\n        if (currentAllowance < amount) {\n            const txHash = await this.wallet.writeContract({\n                address: token,\n                abi: erc20Abi,\n                functionName: 'approve',\n                args: [spender, maxUint256],\n                chain: this.getChain(),\n            });\n            await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        }\n    }\n    // ==========================================================================\n    // V4: Pool State Reading\n    // ==========================================================================\n    /**\n     * Get V4 pool state via StateView\n     */\n    async v4GetPoolState(poolKey) {\n        const v4 = getUniswapV4Addresses(this.network);\n        // Compute poolId by hashing the pool key\n        // The SDK method Pool.getPoolId handles this, but we can also compute directly\n        const { keccak256, encodeAbiParameters } = await import('viem');\n        const poolId = keccak256(encodeAbiParameters([\n            { type: 'address' },\n            { type: 'address' },\n            { type: 'uint24' },\n            { type: 'int24' },\n            { type: 'address' },\n        ], [poolKey.currency0, poolKey.currency1, poolKey.fee, poolKey.tickSpacing, poolKey.hooks]));\n        const [slot0Result, liquidityResult] = await Promise.all([\n            this.publicClient.readContract({\n                address: v4.stateView,\n                abi: StateViewABI,\n                functionName: 'getSlot0',\n                args: [poolId],\n            }),\n            this.publicClient.readContract({\n                address: v4.stateView,\n                abi: StateViewABI,\n                functionName: 'getLiquidity',\n                args: [poolId],\n            }),\n        ]);\n        return {\n            sqrtPriceX96: slot0Result[0],\n            tick: Number(slot0Result[1]),\n            liquidity: liquidityResult,\n            poolId,\n        };\n    }\n    // ==========================================================================\n    // V4: Position Reading\n    // ==========================================================================\n    /**\n     * Get V4 position details from a token ID\n     */\n    async v4GetPosition(tokenId) {\n        const v4 = getUniswapV4Addresses(this.network);\n        // Get pool key and position info from PositionManager\n        const [poolKey, info] = await this.publicClient.readContract({\n            address: v4.positionManager,\n            abi: V4PositionManagerABI,\n            functionName: 'getPoolAndPositionInfo',\n            args: [tokenId],\n        });\n        // Compute poolId\n        const { keccak256, encodeAbiParameters } = await import('viem');\n        const poolId = keccak256(encodeAbiParameters([\n            { type: 'address' },\n            { type: 'address' },\n            { type: 'uint24' },\n            { type: 'int24' },\n            { type: 'address' },\n        ], [poolKey.currency0, poolKey.currency1, poolKey.fee, poolKey.tickSpacing, poolKey.hooks]));\n        // Get fee growth data from StateView to calculate unclaimed fees\n        const salt = `0x${tokenId.toString(16).padStart(64, '0')}`;\n        const [positionState, feeGrowthCurrent] = await Promise.all([\n            this.publicClient.readContract({\n                address: v4.stateView,\n                abi: StateViewABI,\n                functionName: 'getPositionInfo',\n                args: [poolId, v4.positionManager, info.tickLower, info.tickUpper, salt],\n            }),\n            this.publicClient.readContract({\n                address: v4.stateView,\n                abi: StateViewABI,\n                functionName: 'getFeeGrowthInside',\n                args: [poolId, info.tickLower, info.tickUpper],\n            }),\n        ]);\n        const liquidity = positionState[0];\n        const feeGrowthInside0Last = positionState[1];\n        const feeGrowthInside1Last = positionState[2];\n        const feeGrowthInside0Current = feeGrowthCurrent[0];\n        const feeGrowthInside1Current = feeGrowthCurrent[1];\n        // Calculate unclaimed fees\n        const delta0 = feeGrowthInside0Current >= feeGrowthInside0Last\n            ? feeGrowthInside0Current - feeGrowthInside0Last : 0n;\n        const delta1 = feeGrowthInside1Current >= feeGrowthInside1Last\n            ? feeGrowthInside1Current - feeGrowthInside1Last : 0n;\n        const token0Fees = liquidity > 0n ? (delta0 * liquidity) / Q128 : 0n;\n        const token1Fees = liquidity > 0n ? (delta1 * liquidity) / Q128 : 0n;\n        return {\n            tokenId,\n            version: 'v4',\n            token0: poolKey.currency0,\n            token1: poolKey.currency1,\n            fee: Number(poolKey.fee),\n            tickLower: Number(info.tickLower),\n            tickUpper: Number(info.tickUpper),\n            liquidity,\n            unclaimedFees: {\n                token0: token0Fees,\n                token1: token1Fees,\n            },\n        };\n    }\n    // ==========================================================================\n    // V4: Mint Position\n    // ==========================================================================\n    /**\n     * Mint a new V4 liquidity position using the @uniswap/v4-sdk.\n     *\n     * Creates a Position object from the desired amounts, computes the\n     * encoded calldata via V4PositionManager.addCallParameters(), and\n     * executes it through the PositionManager contract.\n     *\n     * Handles token approvals to the PositionManager before minting.\n     */\n    async v4MintPosition(params) {\n        const v4 = getUniswapV4Addresses(this.network);\n        const common = getCommonAddresses(this.network);\n        const recipient = params.recipient ?? this.getWalletAddress();\n        const hookAddress = params.hookAddress ?? ZERO_ADDRESS;\n        // Dynamically import the V4 SDK (heavy dependency, loaded lazily)\n        let v4Sdk;\n        let sdkCore;\n        try {\n            v4Sdk = await import('@uniswap/v4-sdk');\n            sdkCore = await import('@uniswap/sdk-core');\n        }\n        catch {\n            throw new ClawnchDeployError(ClawnchErrorCode.FEATURE_NOT_AVAILABLE, 'V4 minting requires @uniswap/v4-sdk and @uniswap/sdk-core. ' +\n                'Install them: npm install @uniswap/v4-sdk @uniswap/sdk-core');\n        }\n        // Build Currency objects for the SDK\n        const chainId = this.getChain().id;\n        const isToken0Native = params.token0.toLowerCase() === ZERO_ADDRESS.toLowerCase();\n        const isToken1Native = params.token1.toLowerCase() === ZERO_ADDRESS.toLowerCase();\n        const isToken0Weth = params.token0.toLowerCase() === common.weth.toLowerCase();\n        const isToken1Weth = params.token1.toLowerCase() === common.weth.toLowerCase();\n        // For the SDK, we need Token objects. WETH is treated as a Token, not native.\n        const currency0 = new sdkCore.Token(chainId, params.token0, 18);\n        const currency1 = new sdkCore.Token(chainId, params.token1, 18);\n        // We need to fetch token decimals for non-WETH tokens\n        const [decimals0, decimals1] = await Promise.all([\n            isToken0Native ? Promise.resolve(18) : this.getTokenDecimals(params.token0),\n            isToken1Native ? Promise.resolve(18) : this.getTokenDecimals(params.token1),\n        ]);\n        const token0 = new sdkCore.Token(chainId, params.token0, decimals0);\n        const token1 = new sdkCore.Token(chainId, params.token1, decimals1);\n        // Read current pool state to construct Pool object\n        const poolState = await this.v4GetPoolState({\n            currency0: params.token0,\n            currency1: params.token1,\n            fee: params.fee,\n            tickSpacing: params.tickSpacing,\n            hooks: hookAddress,\n        });\n        if (poolState.sqrtPriceX96 === 0n) {\n            throw new ClawnchDeployError(ClawnchErrorCode.DEPLOY_FAILED, 'Pool does not exist or has no liquidity. Initialize the pool first.');\n        }\n        // Construct the SDK Pool object\n        const pool = new v4Sdk.Pool(token0, token1, params.fee, params.tickSpacing, hookAddress, poolState.sqrtPriceX96.toString(), poolState.liquidity.toString(), poolState.tick);\n        // Construct Position from amounts\n        const position = v4Sdk.Position.fromAmounts({\n            pool,\n            tickLower: params.tickLower,\n            tickUpper: params.tickUpper,\n            amount0: params.amount0Desired.toString(),\n            amount1: params.amount1Desired.toString(),\n            useFullPrecision: true,\n        });\n        // Compute slippage-adjusted parameters\n        const slippageBps = params.slippageBps ?? DEFAULT_SLIPPAGE_BPS;\n        const slippageTolerance = new sdkCore.Percent(slippageBps, 10000);\n        const deadline = getDeadline(params.deadline);\n        // Build calldata using V4PositionManager\n        const useNative = params.useNativeEth && (isToken0Weth || isToken1Weth)\n            ? sdkCore.Ether.onChain(chainId)\n            : undefined;\n        const { calldata, value } = v4Sdk.V4PositionManager.addCallParameters(position, {\n            slippageTolerance,\n            deadline: deadline.toString(),\n            recipient,\n            useNative,\n        });\n        // Approve tokens via Permit2 for the V4 PositionManager.\n        // V4 uses Permit2-based approvals: ERC20→Permit2 (one-time), then\n        // Permit2→PositionManager (allowance grant).\n        const tokensToApprove = [];\n        if (!isToken0Native && !(params.useNativeEth && isToken0Weth)) {\n            tokensToApprove.push(params.token0);\n        }\n        if (!isToken1Native && !(params.useNativeEth && isToken1Weth)) {\n            tokensToApprove.push(params.token1);\n        }\n        if (tokensToApprove.length === 2) {\n            await this.permit2.ensurePermit2AllowancePair(tokensToApprove[0], tokensToApprove[1], v4.positionManager, params.amount0Desired, params.amount1Desired);\n        }\n        else if (tokensToApprove.length === 1) {\n            const amount = tokensToApprove[0].toLowerCase() === params.token0.toLowerCase()\n                ? params.amount0Desired\n                : params.amount1Desired;\n            await this.permit2.ensurePermit2Allowance(tokensToApprove[0], v4.positionManager, amount);\n        }\n        // Execute the multicall\n        const ethValue = BigInt(value);\n        const { txHash, receipt } = await this.v4ExecuteMulticall(calldata, ethValue);\n        // Parse mint event from receipt to get tokenId and amounts\n        // PositionManager emits Transfer(address,address,uint256) for the NFT mint\n        let tokenId = 0n;\n        let amount0 = params.amount0Desired;\n        let amount1 = params.amount1Desired;\n        let liquidityMinted = BigInt(position.liquidity.toString());\n        // Try to parse Transfer event (ERC721: topic[0]=Transfer, topic[1]=from, topic[2]=to, topic[3]=tokenId)\n        const transferTopic = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';\n        for (const log of receipt.logs) {\n            if (log.address.toLowerCase() === v4.positionManager.toLowerCase() &&\n                log.topics[0] === transferTopic &&\n                log.topics.length === 4) {\n                tokenId = BigInt(log.topics[3] || '0');\n                break;\n            }\n        }\n        return {\n            txHash,\n            tokenId,\n            amount0,\n            amount1,\n            liquidity: liquidityMinted,\n            receipt,\n        };\n    }\n    /**\n     * Helper: get ERC20 token decimals\n     */\n    async getTokenDecimals(token) {\n        try {\n            const decimals = await this.publicClient.readContract({\n                address: token,\n                abi: erc20Abi,\n                functionName: 'decimals',\n            });\n            return decimals;\n        }\n        catch {\n            return 18; // default assumption\n        }\n    }\n    /**\n     * Execute a V4 PositionManager multicall with pre-built calldata\n     *\n     * Use this with calldata generated by @uniswap/v4-sdk's\n     * V4PositionManager.addCallParameters(), removeCallParameters(), or\n     * collectCallParameters().\n     *\n     * @param calldata - Encoded calldata bytes from V4 SDK\n     * @param value - ETH value to send (for native ETH positions)\n     * @returns Transaction hash and receipt\n     */\n    async v4ExecuteMulticall(calldata, value = 0n) {\n        const v4 = getUniswapV4Addresses(this.network);\n        const txHash = await this.wallet.writeContract({\n            address: v4.positionManager,\n            abi: V4PositionManagerABI,\n            functionName: 'multicall',\n            args: [[calldata]],\n            value,\n            chain: this.getChain(),\n        });\n        const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        if (receipt.status === 'reverted') {\n            throw new ClawnchDeployError(ClawnchErrorCode.TX_REVERTED, `V4 multicall transaction reverted: ${txHash}`);\n        }\n        return { txHash, receipt };\n    }\n    // ==========================================================================\n    // V3: Position Reading\n    // ==========================================================================\n    /**\n     * Get V3 position details from a token ID\n     */\n    async v3GetPosition(tokenId) {\n        const v3 = getUniswapV3Addresses(this.network);\n        const result = await this.publicClient.readContract({\n            address: v3.nonfungiblePositionManager,\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'positions',\n            args: [tokenId],\n        });\n        // result: [nonce, operator, token0, token1, fee, tickLower, tickUpper,\n        //          liquidity, feeGrowthInside0LastX128, feeGrowthInside1LastX128,\n        //          tokensOwed0, tokensOwed1]\n        return {\n            tokenId,\n            version: 'v3',\n            token0: result[2],\n            token1: result[3],\n            fee: Number(result[4]),\n            tickLower: Number(result[5]),\n            tickUpper: Number(result[6]),\n            liquidity: result[7],\n            unclaimedFees: {\n                token0: result[10],\n                token1: result[11],\n            },\n        };\n    }\n    /**\n     * List all V3 positions for a wallet\n     */\n    async v3GetPositionsForWallet(wallet) {\n        const v3 = getUniswapV3Addresses(this.network);\n        const owner = wallet ?? this.getWalletAddress();\n        const balance = await this.publicClient.readContract({\n            address: v3.nonfungiblePositionManager,\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'balanceOf',\n            args: [owner],\n        });\n        const count = Number(balance);\n        if (count === 0)\n            return [];\n        // Fetch all token IDs\n        const tokenIdPromises = Array.from({ length: count }, (_, i) => this.publicClient.readContract({\n            address: v3.nonfungiblePositionManager,\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'tokenOfOwnerByIndex',\n            args: [owner, BigInt(i)],\n        }));\n        const tokenIds = await Promise.all(tokenIdPromises);\n        // Fetch position details for each\n        const positions = await Promise.all(tokenIds.map(id => this.v3GetPosition(id)));\n        return positions;\n    }\n    // ==========================================================================\n    // V3: Mint Position\n    // ==========================================================================\n    /**\n     * Mint a new V3 liquidity position\n     */\n    async v3MintPosition(params) {\n        const v3 = getUniswapV3Addresses(this.network);\n        const recipient = params.recipient ?? this.getWalletAddress();\n        const deadline = getDeadline(params.deadline);\n        const amount0Min = params.amount0Min ?? 0n;\n        const amount1Min = params.amount1Min ?? 0n;\n        // Ensure token approvals\n        await Promise.all([\n            this.ensureApproval(params.token0, v3.nonfungiblePositionManager, params.amount0Desired),\n            this.ensureApproval(params.token1, v3.nonfungiblePositionManager, params.amount1Desired),\n        ]);\n        const txHash = await this.wallet.writeContract({\n            address: v3.nonfungiblePositionManager,\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'mint',\n            args: [{\n                    token0: params.token0,\n                    token1: params.token1,\n                    fee: params.fee,\n                    tickLower: params.tickLower,\n                    tickUpper: params.tickUpper,\n                    amount0Desired: params.amount0Desired,\n                    amount1Desired: params.amount1Desired,\n                    amount0Min,\n                    amount1Min,\n                    recipient,\n                    deadline,\n                }],\n            chain: this.getChain(),\n        });\n        const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        if (receipt.status === 'reverted') {\n            throw new ClawnchDeployError(ClawnchErrorCode.TX_REVERTED, `V3 mint transaction reverted: ${txHash}`);\n        }\n        // Parse the mint event to get tokenId, liquidity, amounts\n        // The NonfungiblePositionManager emits IncreaseLiquidity(tokenId, liquidity, amount0, amount1)\n        // and Transfer(from, to, tokenId)\n        let tokenId = 0n;\n        let liquidityMinted = 0n;\n        let amount0 = 0n;\n        let amount1 = 0n;\n        for (const log of receipt.logs) {\n            // IncreaseLiquidity event topic\n            if (log.topics[0] === '0x3067048beee31b25b2f1681f88dac838c8bba36af25bfb2b7cf7473a5847e35f') {\n                tokenId = BigInt(log.topics[1] || '0');\n                // Decode data: liquidity (uint128), amount0 (uint256), amount1 (uint256)\n                if (log.data && log.data.length >= 194) {\n                    liquidityMinted = BigInt('0x' + log.data.slice(2, 66));\n                    amount0 = BigInt('0x' + log.data.slice(66, 130));\n                    amount1 = BigInt('0x' + log.data.slice(130, 194));\n                }\n            }\n        }\n        return {\n            txHash,\n            tokenId,\n            amount0,\n            amount1,\n            liquidity: liquidityMinted,\n            receipt,\n        };\n    }\n    // ==========================================================================\n    // V3: Add Liquidity\n    // ==========================================================================\n    /**\n     * Add liquidity to an existing V3 position\n     */\n    async v3AddLiquidity(tokenId, params) {\n        const v3 = getUniswapV3Addresses(this.network);\n        const deadline = getDeadline(params.deadline);\n        const amount0Min = params.amount0Min ?? 0n;\n        const amount1Min = params.amount1Min ?? 0n;\n        // Get position to know tokens\n        const position = await this.v3GetPosition(tokenId);\n        // Ensure approvals\n        await Promise.all([\n            this.ensureApproval(position.token0, v3.nonfungiblePositionManager, params.amount0Desired),\n            this.ensureApproval(position.token1, v3.nonfungiblePositionManager, params.amount1Desired),\n        ]);\n        const txHash = await this.wallet.writeContract({\n            address: v3.nonfungiblePositionManager,\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'increaseLiquidity',\n            args: [{\n                    tokenId,\n                    amount0Desired: params.amount0Desired,\n                    amount1Desired: params.amount1Desired,\n                    amount0Min,\n                    amount1Min,\n                    deadline,\n                }],\n            chain: this.getChain(),\n        });\n        const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        if (receipt.status === 'reverted') {\n            throw new ClawnchDeployError(ClawnchErrorCode.TX_REVERTED, `V3 increaseLiquidity transaction reverted: ${txHash}`);\n        }\n        // Parse amounts from IncreaseLiquidity event\n        let amount0 = 0n;\n        let amount1 = 0n;\n        for (const log of receipt.logs) {\n            if (log.topics[0] === '0x3067048beee31b25b2f1681f88dac838c8bba36af25bfb2b7cf7473a5847e35f'\n                && BigInt(log.topics[1] || '0') === tokenId) {\n                if (log.data && log.data.length >= 194) {\n                    amount0 = BigInt('0x' + log.data.slice(66, 130));\n                    amount1 = BigInt('0x' + log.data.slice(130, 194));\n                }\n            }\n        }\n        return { txHash, amount0, amount1, receipt };\n    }\n    // ==========================================================================\n    // V3: Remove Liquidity\n    // ==========================================================================\n    /**\n     * Remove liquidity from a V3 position\n     *\n     * This decreases liquidity and then collects the withdrawn tokens.\n     * If removing 100% and burnToken is true, also burns the NFT.\n     */\n    async v3RemoveLiquidity(tokenId, params) {\n        const v3 = getUniswapV3Addresses(this.network);\n        const deadline = getDeadline(params.deadline);\n        const amount0Min = params.amount0Min ?? 0n;\n        const amount1Min = params.amount1Min ?? 0n;\n        // Get current position\n        const position = await this.v3GetPosition(tokenId);\n        if (position.liquidity === 0n) {\n            throw new ClawnchDeployError(ClawnchErrorCode.CLAIM_FAILED, 'Position has no liquidity to remove');\n        }\n        // Calculate liquidity to remove\n        const pct = Math.min(Math.max(params.percentageToRemove, 0), 1);\n        const liquidityToRemove = BigInt(Math.floor(Number(position.liquidity) * pct));\n        if (liquidityToRemove === 0n) {\n            throw new ClawnchDeployError(ClawnchErrorCode.INVALID_BPS, 'Calculated liquidity to remove is zero');\n        }\n        // Build multicall: decreaseLiquidity + collect (+ optionally burn)\n        const calls = [];\n        // 1. Decrease liquidity\n        calls.push(encodeFunctionData({\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'decreaseLiquidity',\n            args: [{\n                    tokenId,\n                    liquidity: liquidityToRemove,\n                    amount0Min,\n                    amount1Min,\n                    deadline,\n                }],\n        }));\n        // 2. Collect all tokens (includes withdrawn liquidity + fees)\n        calls.push(encodeFunctionData({\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'collect',\n            args: [{\n                    tokenId,\n                    recipient: this.getWalletAddress(),\n                    amount0Max: maxUint128,\n                    amount1Max: maxUint128,\n                }],\n        }));\n        // 3. Optionally burn the NFT (only if 100% removed)\n        if (params.burnToken && pct === 1) {\n            calls.push(encodeFunctionData({\n                abi: V3NonfungiblePositionManagerABI,\n                functionName: 'burn',\n                args: [tokenId],\n            }));\n        }\n        // Execute multicall\n        const txHash = await this.wallet.writeContract({\n            address: v3.nonfungiblePositionManager,\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'multicall',\n            args: [calls],\n            chain: this.getChain(),\n        });\n        const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        if (receipt.status === 'reverted') {\n            throw new ClawnchDeployError(ClawnchErrorCode.TX_REVERTED, `V3 removeLiquidity transaction reverted: ${txHash}`);\n        }\n        // Parse Collect event for actual amounts received\n        let amount0 = 0n;\n        let amount1 = 0n;\n        // Collect event: topic0 = Collect(uint256 indexed tokenId, address recipient, uint256 amount0, uint256 amount1)\n        const collectTopic = '0x40d0efd1a53d60ecbf40971b9daf7dc90178c3aadc7aab1765632738fa8b8f01';\n        for (const log of receipt.logs) {\n            if (log.topics[0] === collectTopic && BigInt(log.topics[1] || '0') === tokenId) {\n                if (log.data && log.data.length >= 130) {\n                    // Skip recipient (first 32 bytes of data), then amount0 + amount1\n                    amount0 = BigInt('0x' + log.data.slice(66, 130));\n                    amount1 = BigInt('0x' + log.data.slice(130, 194));\n                }\n            }\n        }\n        return { txHash, amount0, amount1, receipt };\n    }\n    // ==========================================================================\n    // V3: Collect Fees\n    // ==========================================================================\n    /**\n     * Collect unclaimed fees from a V3 position\n     *\n     * This calls collect() with max amounts to sweep all available fees.\n     */\n    async v3CollectFees(tokenId, params = {}) {\n        const v3 = getUniswapV3Addresses(this.network);\n        const recipient = params.recipient ?? this.getWalletAddress();\n        const txHash = await this.wallet.writeContract({\n            address: v3.nonfungiblePositionManager,\n            abi: V3NonfungiblePositionManagerABI,\n            functionName: 'collect',\n            args: [{\n                    tokenId,\n                    recipient,\n                    amount0Max: maxUint128,\n                    amount1Max: maxUint128,\n                }],\n            chain: this.getChain(),\n        });\n        const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        if (receipt.status === 'reverted') {\n            throw new ClawnchDeployError(ClawnchErrorCode.TX_REVERTED, `V3 collect transaction reverted: ${txHash}`);\n        }\n        // Parse Collect event\n        let amount0 = 0n;\n        let amount1 = 0n;\n        const collectTopic = '0x40d0efd1a53d60ecbf40971b9daf7dc90178c3aadc7aab1765632738fa8b8f01';\n        for (const log of receipt.logs) {\n            if (log.topics[0] === collectTopic && BigInt(log.topics[1] || '0') === tokenId) {\n                if (log.data && log.data.length >= 130) {\n                    amount0 = BigInt('0x' + log.data.slice(66, 130));\n                    amount1 = BigInt('0x' + log.data.slice(130, 194));\n                }\n            }\n        }\n        return { txHash, amount0, amount1, receipt };\n    }\n    // ==========================================================================\n    // Convenience: Detect pool version for a token\n    // ==========================================================================\n    /**\n     * Get all V3 positions for a wallet, optionally filtered by a specific token\n     */\n    async getPositionsForToken(tokenAddress, wallet) {\n        const allPositions = await this.v3GetPositionsForWallet(wallet);\n        const tokenLower = tokenAddress.toLowerCase();\n        return allPositions.filter(p => p.token0.toLowerCase() === tokenLower || p.token1.toLowerCase() === tokenLower);\n    }\n}\n//# sourceMappingURL=liquidity.js.map","/**\n * ClawnchApiDeployer — Verified agent token deployment via Clawnch API\n *\n * Deploys tokens through the Clawnch API using the Clawnch deployer wallet.\n * Tokens deployed this way receive a verified badge on the Clawnch launchpad.\n *\n * Free deploys are rate-limited to 1 per hour per agent. To bypass the\n * rate limit, set `bypassRateLimit: true` — this burns 10,000 $CLAWNCH\n * per deploy.\n *\n * Flow for each deploy:\n *   1. Request captcha challenge from API\n *   2. Solve challenge: read on-chain storage, sign message, compute proof\n *   3. Submit solution + deploy params → server deploys token\n *      (burns $CLAWNCH only if bypassing rate limit)\n *\n * Requires prior agent registration. $CLAWNCH approval only needed for\n * rate limit bypass.\n *\n * @example\n * ```typescript\n * // One-time registration\n * const { apiKey } = await ClawnchApiDeployer.register({\n *   wallet,\n *   publicClient,\n * }, {\n *   name: 'MyAgent',\n *   wallet: account.address,\n *   description: 'An AI agent that launches tokens',\n * });\n *\n * // Create deployer with API key\n * const deployer = new ClawnchApiDeployer({\n *   apiKey,\n *   wallet,\n *   publicClient,\n * });\n *\n * // One-time $CLAWNCH approval\n * await deployer.approveClawnch();\n *\n * // Deploy a token\n * const result = await deployer.deploy({\n *   name: 'My Token',\n *   symbol: 'MYTKN',\n * });\n * console.log('Token deployed:', result.tokenAddress);\n * ```\n */\nimport { keccak256, encodePacked, getAddress, maxUint256, parseAbi, } from 'viem';\nimport { ClawnchErrorCode, ClawnchDeployError, withRetry } from './errors.js';\n/** Default Clawnch API base URL */\nconst DEFAULT_API_BASE = 'https://clawn.ch';\n/** $CLAWNCH token address on Base mainnet */\nconst CLAWNCH_TOKEN_ADDRESS = '0xa1F72459dfA10BAD200Ac160eCd78C6b77a747be';\n/** Minimal ERC20 ABI for approve + allowance */\nconst ERC20_ABI = parseAbi([\n    'function approve(address spender, uint256 amount) returns (bool)',\n    'function allowance(address owner, address spender) view returns (uint256)',\n    'function balanceOf(address account) view returns (uint256)',\n]);\nexport class ClawnchApiDeployer {\n    apiKey;\n    wallet;\n    publicClient;\n    apiBaseUrl;\n    constructor(config) {\n        if (!config.apiKey) {\n            throw new ClawnchDeployError(ClawnchErrorCode.WALLET_NOT_CONFIGURED, 'API key is required. Register an agent first with ClawnchApiDeployer.register()');\n        }\n        if (!config.wallet) {\n            throw new ClawnchDeployError(ClawnchErrorCode.WALLET_NOT_CONFIGURED, 'Wallet client is required for signing captcha challenges');\n        }\n        if (!config.publicClient) {\n            throw new ClawnchDeployError(ClawnchErrorCode.PUBLIC_CLIENT_NOT_CONFIGURED, 'Public client is required for reading on-chain challenge data');\n        }\n        this.apiKey = config.apiKey;\n        this.wallet = config.wallet;\n        this.publicClient = config.publicClient;\n        this.apiBaseUrl = (config.apiBaseUrl ?? DEFAULT_API_BASE).replace(/\\/$/, '');\n    }\n    // ==========================================================================\n    // Static: Agent Registration\n    // ==========================================================================\n    /**\n     * Register a new agent with the Clawnch API.\n     *\n     * Two-step process:\n     *   1. POST /api/agents/register — submits agent info, receives challenge\n     *   2. POST /api/agents/verify — submits wallet signature, receives API key\n     *\n     * @returns VerifyResponse containing the API key\n     */\n    static async register(config, request) {\n        const baseUrl = (config.apiBaseUrl ?? DEFAULT_API_BASE).replace(/\\/$/, '');\n        // Step 1: Register — get challenge\n        const registerRes = await fetch(`${baseUrl}/api/agents/register`, {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify(request),\n        });\n        if (!registerRes.ok) {\n            const err = await registerRes.json().catch(() => ({ error: 'Registration failed' }));\n            throw new ClawnchDeployError(ClawnchErrorCode.DEPLOY_FAILED, `Agent registration failed: ${err.error}`);\n        }\n        const registerData = await registerRes.json();\n        // Step 2: Sign the challenge message with wallet\n        const signature = await config.wallet.signMessage({\n            message: registerData.message,\n        });\n        // Step 3: Verify — submit signature, receive API key\n        const verifyBody = {\n            registrationId: registerData.registrationId,\n            signature,\n        };\n        const verifyRes = await fetch(`${baseUrl}/api/agents/verify`, {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify(verifyBody),\n        });\n        if (!verifyRes.ok) {\n            const err = await verifyRes.json().catch(() => ({ error: 'Verification failed' }));\n            throw new ClawnchDeployError(ClawnchErrorCode.DEPLOY_FAILED, `Agent verification failed: ${err.error}`);\n        }\n        return verifyRes.json();\n    }\n    // ==========================================================================\n    // Agent Status\n    // ==========================================================================\n    /**\n     * Get the current agent status (verification, balance, launch count)\n     */\n    async getStatus() {\n        return this.apiRequest('GET', '/api/agents/me');\n    }\n    // ==========================================================================\n    // $CLAWNCH Token Approval\n    // ==========================================================================\n    /**\n     * Approve the Clawnch deployer to spend $CLAWNCH from the agent's wallet.\n     *\n     * This is a one-time operation. The approval is set to max uint256 so\n     * the agent doesn't need to re-approve before each launch.\n     *\n     * @param spender - The Clawnch deployer address (fetched from API if not provided)\n     * @returns ApprovalResult with transaction hash\n     */\n    async approveClawnch(spender) {\n        // Get the deployer address from the API if not provided\n        let deployerAddress = spender;\n        if (!deployerAddress) {\n            const status = await this.getStatus();\n            // The API should return the deployer address, but fallback to a fetch\n            const configRes = await this.apiRequest('GET', '/api/agents/config');\n            deployerAddress = configRes.deployerAddress;\n        }\n        const txHash = await this.wallet.writeContract({\n            address: CLAWNCH_TOKEN_ADDRESS,\n            abi: ERC20_ABI,\n            functionName: 'approve',\n            args: [deployerAddress, maxUint256],\n            chain: this.wallet.chain,\n        });\n        const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n        if (receipt.status === 'reverted') {\n            throw new ClawnchDeployError(ClawnchErrorCode.TX_REVERTED, 'Approval transaction reverted');\n        }\n        return {\n            txHash,\n            spender: deployerAddress,\n            amount: maxUint256.toString(),\n        };\n    }\n    /**\n     * Check the current $CLAWNCH allowance for the Clawnch deployer\n     */\n    async getClawnchAllowance(spender) {\n        const owner = this.wallet.account.address;\n        return this.publicClient.readContract({\n            address: CLAWNCH_TOKEN_ADDRESS,\n            abi: ERC20_ABI,\n            functionName: 'allowance',\n            args: [owner, spender],\n        });\n    }\n    /**\n     * Check the agent's $CLAWNCH balance\n     */\n    async getClawnchBalance() {\n        const owner = this.wallet.account.address;\n        return this.publicClient.readContract({\n            address: CLAWNCH_TOKEN_ADDRESS,\n            abi: ERC20_ABI,\n            functionName: 'balanceOf',\n            args: [owner],\n        });\n    }\n    // ==========================================================================\n    // Verified Deploy\n    // ==========================================================================\n    /**\n     * Deploy a token via the Clawnch API (verified launch).\n     *\n     * Internally handles the full flow:\n     *   1. Request captcha challenge\n     *   2. Solve: read storage slot, sign message, compute keccak proof\n     *   3. Submit solution + deploy params\n     *   4. Server deploys from Clawnch wallet (burns $CLAWNCH only if bypassing rate limit)\n     *\n     * Free deploys are rate-limited to 1 per hour per agent.\n     * Set `bypassRateLimit: true` to skip the cooldown by burning 10,000 $CLAWNCH.\n     *\n     * @param request - Token deployment parameters\n     * @returns ApiDeployResponse with txHash and tokenAddress\n     */\n    async deploy(request) {\n        // Step 1: Request captcha challenge\n        const challenge = await this.apiRequest('POST', '/api/deploy', { tokenParams: request, bypassRateLimit: request.bypassRateLimit ?? false });\n        // Step 2: Solve the captcha\n        const solution = await this.solveCaptcha(challenge);\n        // Step 3: Submit solution → server burns $CLAWNCH and deploys\n        const result = await this.apiRequest('POST', '/api/deploy/confirm', {\n            challengeId: challenge.challengeId,\n            solution,\n            tokenParams: request,\n        });\n        return result;\n    }\n    // ==========================================================================\n    // Captcha Solving (Internal)\n    // ==========================================================================\n    /**\n     * Solve a cryptographic captcha challenge.\n     *\n     * Steps:\n     *   1. Read the on-chain storage slot specified in the challenge\n     *   2. Hash the challenge message with keccak256\n     *   3. Sign the hash with the agent's wallet (ECDSA)\n     *   4. Compute proof: keccak256(signature + nonce + storageValue)\n     *\n     * All must complete within the 5-second deadline.\n     */\n    async solveCaptcha(challenge) {\n        // Check deadline hasn't passed\n        const deadline = new Date(challenge.deadline);\n        if (Date.now() > deadline.getTime()) {\n            throw new ClawnchDeployError(ClawnchErrorCode.TIMEOUT, 'Captcha challenge has expired');\n        }\n        // Step 1: Read on-chain storage slot\n        const storageValue = await this.publicClient.getStorageAt({\n            address: getAddress(challenge.contractAddress),\n            slot: challenge.storageSlot,\n        });\n        if (!storageValue) {\n            throw new ClawnchDeployError(ClawnchErrorCode.RPC_ERROR, 'Failed to read on-chain storage slot for captcha');\n        }\n        // Step 2: Sign the challenge message\n        const signature = await this.wallet.signMessage({\n            message: challenge.message,\n        });\n        // Step 3: Compute proof = keccak256(signature + nonce + storageValue)\n        const proof = keccak256(encodePacked(['bytes', 'string', 'bytes32'], [signature, challenge.nonce, storageValue]));\n        // Check deadline again after computation\n        if (Date.now() > deadline.getTime()) {\n            throw new ClawnchDeployError(ClawnchErrorCode.TIMEOUT, 'Captcha solution exceeded the 5-second deadline');\n        }\n        return {\n            challengeId: challenge.challengeId,\n            signature: signature,\n            storageValue,\n            proof,\n        };\n    }\n    // ==========================================================================\n    // HTTP Client\n    // ==========================================================================\n    /**\n     * Make an authenticated API request to the Clawnch server\n     */\n    async apiRequest(method, path, body) {\n        return withRetry(async () => {\n            const url = `${this.apiBaseUrl}${path}`;\n            const headers = {\n                'Accept': 'application/json',\n                'Authorization': `Bearer ${this.apiKey}`,\n            };\n            const options = { method, headers };\n            if (body && method === 'POST') {\n                headers['Content-Type'] = 'application/json';\n                options.body = JSON.stringify(body);\n            }\n            const response = await fetch(url, {\n                ...options,\n                signal: AbortSignal.timeout(30000),\n            });\n            if (!response.ok) {\n                let errorMsg;\n                let errorCode;\n                try {\n                    const errBody = await response.json();\n                    errorMsg = errBody.error || `HTTP ${response.status}`;\n                    errorCode = errBody.code;\n                }\n                catch {\n                    errorMsg = `HTTP ${response.status}: ${response.statusText}`;\n                }\n                // Map known HTTP codes to SDK error codes\n                const sdkCode = response.status === 401 || response.status === 403\n                    ? ClawnchErrorCode.WALLET_NOT_CONFIGURED\n                    : response.status === 402\n                        ? ClawnchErrorCode.INSUFFICIENT_FUNDS\n                        : response.status === 408 || response.status === 504\n                            ? ClawnchErrorCode.TIMEOUT\n                            : ClawnchErrorCode.DEPLOY_FAILED;\n                throw new ClawnchDeployError(sdkCode, `API error: ${errorMsg}`);\n            }\n            return response.json();\n        });\n    }\n}\n//# sourceMappingURL=api-deployer.js.map","/**\n * ClawnchPrice — On-chain price reading for Clawncher tokens.\n *\n * Reads sqrtPriceX96 from the Uniswap V4 pool via StateView and converts\n * to human-readable prices. Supports ETH-denominated and USD-denominated\n * pricing (USD via CoinGecko ETH price).\n *\n * Price math:\n *   sqrtPriceX96 = sqrt(token1/token0) * 2^96\n *   price(token1/token0) = (sqrtPriceX96 / 2^96)^2\n *\n * For a Clawnch token paired with WETH:\n *   - If WETH is currency0 and token is currency1: price = token/WETH → invert for WETH/token\n *   - If token is currency0 and WETH is currency1: price = WETH/token → that's what we want\n *\n * @example\n * ```typescript\n * const price = new ClawnchPrice({ publicClient, network: 'mainnet' });\n *\n * const info = await price.getTokenPrice('0xYourToken...');\n * console.log(`Price: ${info.priceInEth} ETH per token`);\n * console.log(`Price: $${info.priceInUsd} per token`);\n * console.log(`Market cap: $${info.marketCapUsd}`);\n * ```\n */\nimport { ClawnchReader } from './reader.js';\nimport { getUniswapV4Addresses, getCommonAddresses } from './uniswap-addresses.js';\nimport { StateViewABI } from './uniswap-abis.js';\n// ============================================================================\n// Constants\n// ============================================================================\nconst Q96 = 2n ** 96n;\nconst Q192 = Q96 * Q96;\n/** CoinGecko free API — no key needed, 30 req/min */\nconst COINGECKO_ETH_URL = 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd';\n/** Cache ETH/USD for 60 seconds */\nconst ETH_USD_CACHE_MS = 60_000;\n// ============================================================================\n// ClawnchPrice\n// ============================================================================\nexport class ClawnchPrice {\n    publicClient;\n    network;\n    reader;\n    /** Cached ETH/USD price */\n    ethUsdCache = null;\n    constructor(config) {\n        this.publicClient = config.publicClient;\n        this.network = config.network ?? 'mainnet';\n        this.reader = new ClawnchReader({\n            publicClient: config.publicClient,\n            network: this.network,\n        });\n    }\n    /**\n     * Get full price info for a Clawncher token.\n     *\n     * Reads the V4 pool state on-chain, computes price from sqrtPriceX96,\n     * and optionally enriches with USD pricing from CoinGecko.\n     * Supports both WETH-paired and USDC-paired pools.\n     */\n    async getTokenPrice(token) {\n        const common = getCommonAddresses(this.network);\n        const weth = common.weth.toLowerCase();\n        const usdc = common.usdc.toLowerCase();\n        // Get pool key from LP locker rewards (tells us currency0, currency1, etc.)\n        const rewards = await this.reader.getTokenRewards(token);\n        if (!rewards) {\n            throw new Error(`No pool found for token ${token}. Is it a Clawncher token?`);\n        }\n        const { currency0, currency1, fee, tickSpacing, hooks } = rewards.poolKey;\n        // Determine what the token is paired with and which side it's on\n        const c0Lower = currency0.toLowerCase();\n        const c1Lower = currency1.toLowerCase();\n        let pairedWith;\n        let pairedSide;\n        let pairedDecimals;\n        if (c0Lower === usdc || c1Lower === usdc) {\n            pairedWith = 'USDC';\n            pairedSide = c0Lower === usdc ? 0 : 1;\n            pairedDecimals = 6; // USDC = 6 decimals\n        }\n        else {\n            pairedWith = 'WETH';\n            pairedSide = c0Lower === weth ? 0 : 1;\n            pairedDecimals = 18; // WETH = 18 decimals\n        }\n        // Get pool state from StateView\n        const v4 = getUniswapV4Addresses(this.network);\n        const { keccak256, encodeAbiParameters } = await import('viem');\n        const poolId = keccak256(encodeAbiParameters([\n            { type: 'address' },\n            { type: 'address' },\n            { type: 'uint24' },\n            { type: 'int24' },\n            { type: 'address' },\n        ], [currency0, currency1, fee, tickSpacing, hooks]));\n        const [slot0Result, liquidityResult] = await Promise.all([\n            this.publicClient.readContract({\n                address: v4.stateView,\n                abi: StateViewABI,\n                functionName: 'getSlot0',\n                args: [poolId],\n            }),\n            this.publicClient.readContract({\n                address: v4.stateView,\n                abi: StateViewABI,\n                functionName: 'getLiquidity',\n                args: [poolId],\n            }),\n        ]);\n        const sqrtPriceX96 = slot0Result[0];\n        const tick = Number(slot0Result[1]);\n        const liquidity = liquidityResult;\n        // Compute price\n        const priceRatio = this.sqrtPriceX96ToPrice(sqrtPriceX96);\n        // Get token info for decimals + total supply\n        const tokenInfo = await this.reader.getTokenInfo(token);\n        const tokenDecimals = tokenInfo.decimals;\n        // Compute price in paired token units\n        // priceRatio is currency1/currency0 in raw units\n        let priceInPaired;\n        if (pairedSide === 0) {\n            // Paired token is currency0, our token is currency1\n            // priceRatio = token_raw / paired_raw\n            // priceInPaired (paired per token) = 1 / (priceRatio * 10^(pairedDecimals - tokenDecimals))\n            const decimalAdjust = 10 ** (pairedDecimals - tokenDecimals);\n            priceInPaired = 1 / (priceRatio * decimalAdjust);\n        }\n        else {\n            // Our token is currency0, paired token is currency1\n            // priceRatio = paired_raw / token_raw\n            // priceInPaired (paired per token) = priceRatio * 10^(tokenDecimals - pairedDecimals)\n            const decimalAdjust = 10 ** (tokenDecimals - pairedDecimals);\n            priceInPaired = priceRatio * decimalAdjust;\n        }\n        // Total supply in human-readable\n        const totalSupplyFormatted = Number(tokenInfo.totalSupply) / (10 ** tokenDecimals);\n        let priceInEth;\n        let priceInUsd;\n        let ethUsdRate;\n        let marketCapEth;\n        let marketCapUsd;\n        if (pairedWith === 'USDC') {\n            // USDC pair: price is directly in USD (1 USDC ~ $1)\n            priceInUsd = priceInPaired;\n            marketCapUsd = priceInPaired * totalSupplyFormatted;\n            // Optionally compute ETH price (for backwards compat)\n            ethUsdRate = await this.getEthUsdPrice();\n            priceInEth = ethUsdRate !== null ? priceInPaired / ethUsdRate : null;\n            marketCapEth = priceInEth !== null ? priceInEth * totalSupplyFormatted : null;\n        }\n        else {\n            // WETH pair: price is in ETH, need CoinGecko for USD\n            priceInEth = priceInPaired;\n            marketCapEth = priceInPaired * totalSupplyFormatted;\n            ethUsdRate = await this.getEthUsdPrice();\n            priceInUsd = ethUsdRate !== null ? priceInEth * ethUsdRate : null;\n            marketCapUsd = ethUsdRate !== null ? marketCapEth * ethUsdRate : null;\n        }\n        return {\n            token,\n            priceInEth,\n            priceInUsd,\n            ethUsdRate,\n            marketCapEth,\n            marketCapUsd,\n            totalSupply: tokenInfo.totalSupply,\n            totalSupplyFormatted,\n            liquidity,\n            tick,\n            pairedSide,\n            pairedWith,\n            timestamp: Date.now(),\n        };\n    }\n    /**\n     * Quick price check — just ETH and USD price, no market cap.\n     */\n    async getQuickPrice(token) {\n        const info = await this.getTokenPrice(token);\n        return {\n            priceInEth: info.priceInEth,\n            priceInUsd: info.priceInUsd,\n            pairedWith: info.pairedWith,\n        };\n    }\n    /**\n     * Get the current ETH/USD price from CoinGecko (cached for 60s).\n     * Returns null on failure — never throws.\n     */\n    async getEthUsdPrice() {\n        // Check cache\n        if (this.ethUsdCache && Date.now() - this.ethUsdCache.fetchedAt < ETH_USD_CACHE_MS) {\n            return this.ethUsdCache.rate;\n        }\n        try {\n            const controller = new AbortController();\n            const timeout = setTimeout(() => controller.abort(), 5000);\n            const res = await fetch(COINGECKO_ETH_URL, {\n                signal: controller.signal,\n                headers: { Accept: 'application/json' },\n            });\n            clearTimeout(timeout);\n            if (!res.ok)\n                return this.ethUsdCache?.rate ?? null;\n            const data = (await res.json());\n            const rate = data.ethereum?.usd ?? null;\n            if (rate !== null) {\n                this.ethUsdCache = { rate, fetchedAt: Date.now() };\n            }\n            return rate;\n        }\n        catch {\n            // Return stale cache if available, else null\n            return this.ethUsdCache?.rate ?? null;\n        }\n    }\n    // --------------------------------------------------------------------------\n    // Internal math\n    // --------------------------------------------------------------------------\n    /**\n     * Convert sqrtPriceX96 to a floating-point price ratio (currency1/currency0).\n     *\n     * For precision with very large/small numbers, we use a hybrid approach:\n     * compute with bigint where possible, then convert to float at the end.\n     */\n    sqrtPriceX96ToPrice(sqrtPriceX96) {\n        if (sqrtPriceX96 === 0n)\n            return 0;\n        // price = (sqrtPriceX96)^2 / 2^192\n        // To avoid overflow in JS Number, we'll split the computation:\n        // Convert sqrtPriceX96 to float, divide by 2^96, then square\n        const sqrtPrice = Number(sqrtPriceX96) / Number(Q96);\n        return sqrtPrice * sqrtPrice;\n    }\n}\n//# sourceMappingURL=price.js.map","/**\n * ClawnchOrders — Conditional order engine for autonomous token management.\n *\n * Supports:\n *   - Limit orders (buy/sell at a specific ETH price)\n *   - Stop-loss orders (sell if price drops below threshold)\n *   - Take-profit orders (sell if price rises above threshold)\n *   - DCA orders (recurring buys at fixed intervals)\n *   - Trailing stop orders (sell when price drops N% from its peak)\n *   - TWAP orders (split a large trade into N equal chunks over a time window)\n *   - Order chaining (automatically create follow-up orders when one executes)\n *\n * Risk management:\n *   - Per-trade risk caps (max % of portfolio per order)\n *   - Max drawdown circuit breaker (halt all orders if drawdown exceeds limit)\n *   - Cooldown periods (prevent rapid-fire execution after failures)\n *\n * Orders are pure data — they don't execute themselves. The agent's heartbeat\n * checks pending orders against current prices and triggers execution.\n *\n * Storage is pluggable: pass a read/write interface for persistence.\n * The Clawtomaton agent uses its StateStore; standalone users can use fs.\n *\n * @example\n * ```typescript\n * const orders = new ClawnchOrders(storage);\n *\n * // Trailing stop: sell 100% if price drops 15% from peak\n * orders.create({\n *   type: 'trailing_stop',\n *   token: '0x...',\n *   triggerPriceEth: 0,  // not used — trailingPct is the trigger\n *   action: { side: 'sell', amountPct: 100 },\n *   trailing: { pct: 15 },\n * });\n *\n * // TWAP: buy 0.1 ETH worth of tokens, split into 10 chunks over 2 hours\n * orders.create({\n *   type: 'twap',\n *   token: '0x...',\n *   triggerPriceEth: 0,\n *   action: { side: 'buy', amountRaw: '0.1' },\n *   twap: { totalChunks: 10, windowMs: 2 * 60 * 60 * 1000 },\n * });\n *\n * // Chained: buy + auto-set stop-loss after fill\n * orders.create({\n *   type: 'limit_buy',\n *   token: '0x...',\n *   triggerPriceEth: 0.000005,\n *   action: { side: 'buy', amountRaw: '0.01' },\n *   chain: [{\n *     type: 'stop_loss',\n *     triggerPriceEth: 0.000004,\n *     action: { side: 'sell', amountPct: 100 },\n *   }],\n * });\n * ```\n */\n// ============================================================================\n// Default risk config\n// ============================================================================\nconst DEFAULT_RISK_CONFIG = {\n    maxPositionPct: 25,\n    maxDrawdownPct: 30,\n    failureCooldownMs: 5 * 60 * 1000, // 5 minutes\n    maxExecutionsPerHour: 20,\n    circuitBreakerTripped: false,\n    circuitBreakerTrippedAt: 0,\n    peakPortfolioEth: 0,\n    recentExecutions: [],\n    lastFailureAt: 0,\n};\n// ============================================================================\n// ClawnchOrders\n// ============================================================================\nexport class ClawnchOrders {\n    storage;\n    riskStorage;\n    constructor(storage, riskStorage) {\n        this.storage = storage;\n        this.riskStorage = riskStorage ?? null;\n    }\n    // --------------------------------------------------------------------------\n    // Order CRUD\n    // --------------------------------------------------------------------------\n    /**\n     * Create a new order.\n     *\n     * @returns The created order\n     */\n    create(params) {\n        const orders = this.storage.getOrders();\n        const id = `ord_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n        // Build trailing stop config\n        let trailingConfig;\n        if (params.type === 'trailing_stop' && params.trailing) {\n            const initialPrice = params.currentPrice ?? params.triggerPriceEth;\n            trailingConfig = {\n                pct: params.trailing.pct,\n                highWaterMark: initialPrice,\n                currentTriggerPrice: initialPrice * (1 - params.trailing.pct / 100),\n                floorPriceEth: params.trailing.floorPriceEth,\n            };\n        }\n        // Build TWAP config\n        let twapConfig;\n        if (params.type === 'twap' && params.twap) {\n            const totalAmount = parseFloat(params.action.amountRaw ?? '0');\n            const chunks = params.twap.totalChunks;\n            twapConfig = {\n                totalChunks: chunks,\n                chunksCompleted: 0,\n                windowMs: params.twap.windowMs,\n                chunkIntervalMs: Math.floor(params.twap.windowMs / chunks),\n                lastChunkAt: 0,\n                amountPerChunk: (totalAmount / chunks).toFixed(8),\n                maxPriceEth: params.twap.maxPriceEth,\n                minPriceEth: params.twap.minPriceEth,\n                startedAt: Date.now(),\n            };\n        }\n        const order = {\n            id,\n            type: params.type,\n            status: 'pending',\n            token: params.token,\n            condition: {\n                token: params.token,\n                triggerPriceEth: params.triggerPriceEth,\n            },\n            action: params.action,\n            dca: params.dca\n                ? { ...params.dca, buysCompleted: 0, lastBuyAt: 0 }\n                : undefined,\n            trailing: trailingConfig,\n            twap: twapConfig,\n            chain: params.chain,\n            createdAt: Date.now(),\n            lastCheckedAt: Date.now(),\n            executedAt: null,\n            expiresAt: params.expiresAt ?? null,\n            description: params.description ?? this.describeOrder(params.type, params.triggerPriceEth, params.action, params.trailing, params.twap),\n            tag: params.tag,\n            createdAtPrice: params.currentPrice,\n        };\n        orders.push(order);\n        this.storage.saveOrders(orders);\n        return order;\n    }\n    /**\n     * List all orders, optionally filtered by status.\n     */\n    list(status) {\n        const orders = this.storage.getOrders();\n        if (!status)\n            return orders;\n        return orders.filter(o => o.status === status);\n    }\n    /**\n     * List orders by tag.\n     */\n    listByTag(tag) {\n        return this.storage.getOrders().filter(o => o.tag === tag);\n    }\n    /**\n     * Cancel an order by ID.\n     */\n    cancel(orderId) {\n        const orders = this.storage.getOrders();\n        const order = orders.find(o => o.id === orderId);\n        if (!order || (order.status !== 'pending' && order.status !== 'paused'))\n            return false;\n        order.status = 'cancelled';\n        this.storage.saveOrders(orders);\n        return true;\n    }\n    /**\n     * Cancel all orders with a given tag.\n     */\n    cancelByTag(tag) {\n        const orders = this.storage.getOrders();\n        let count = 0;\n        for (const order of orders) {\n            if (order.tag === tag && (order.status === 'pending' || order.status === 'paused')) {\n                order.status = 'cancelled';\n                count++;\n            }\n        }\n        if (count > 0)\n            this.storage.saveOrders(orders);\n        return count;\n    }\n    /**\n     * Pause an order (prevents triggering until resumed).\n     */\n    pause(orderId) {\n        const orders = this.storage.getOrders();\n        const order = orders.find(o => o.id === orderId);\n        if (!order || order.status !== 'pending')\n            return false;\n        order.status = 'paused';\n        this.storage.saveOrders(orders);\n        return true;\n    }\n    /**\n     * Resume a paused order.\n     */\n    resume(orderId) {\n        const orders = this.storage.getOrders();\n        const order = orders.find(o => o.id === orderId);\n        if (!order || order.status !== 'paused')\n            return false;\n        order.status = 'pending';\n        this.storage.saveOrders(orders);\n        return true;\n    }\n    // --------------------------------------------------------------------------\n    // Trigger checking\n    // --------------------------------------------------------------------------\n    /**\n     * Check all pending orders against the current price.\n     * Returns orders that should be executed NOW.\n     *\n     * Does NOT execute them — the caller (agent) does the actual swap.\n     *\n     * Side effects:\n     *   - Updates trailing stop high-water marks\n     *   - Expires orders past their expiry\n     *   - Marks triggered orders as 'triggered'\n     *   - Pauses TWAP chunks when price is outside bounds\n     */\n    checkTriggers(currentPriceEth) {\n        const orders = this.storage.getOrders();\n        const now = Date.now();\n        const triggered = [];\n        // Risk check: if circuit breaker is tripped, return empty\n        if (this.isCircuitBreakerTripped()) {\n            this.storage.saveOrders(orders); // still save any expiry updates\n            return [];\n        }\n        // Risk check: rate limit\n        if (this.isRateLimited()) {\n            this.storage.saveOrders(orders);\n            return [];\n        }\n        // Risk check: cooldown after failure\n        if (this.isInCooldown()) {\n            this.storage.saveOrders(orders);\n            return [];\n        }\n        for (const order of orders) {\n            if (order.status !== 'pending')\n                continue;\n            // Check expiry\n            if (order.expiresAt !== null && now > order.expiresAt) {\n                order.status = 'expired';\n                continue;\n            }\n            order.lastCheckedAt = now;\n            switch (order.type) {\n                case 'limit_buy':\n                    // Buy when price drops to or below trigger\n                    if (currentPriceEth <= order.condition.triggerPriceEth) {\n                        order.status = 'triggered';\n                        triggered.push(order);\n                    }\n                    break;\n                case 'limit_sell':\n                case 'take_profit':\n                    // Sell when price rises to or above trigger\n                    if (currentPriceEth >= order.condition.triggerPriceEth) {\n                        order.status = 'triggered';\n                        triggered.push(order);\n                    }\n                    break;\n                case 'stop_loss':\n                    // Sell when price drops to or below trigger\n                    if (currentPriceEth <= order.condition.triggerPriceEth) {\n                        order.status = 'triggered';\n                        triggered.push(order);\n                    }\n                    break;\n                case 'dca':\n                    // Execute if enough time has passed since last buy\n                    if (order.dca) {\n                        const timeSinceLastBuy = now - order.dca.lastBuyAt;\n                        if (timeSinceLastBuy >= order.dca.intervalMs) {\n                            // Check if max buys reached\n                            if (order.dca.maxBuys !== null && order.dca.buysCompleted >= order.dca.maxBuys) {\n                                order.status = 'executed'; // All buys done\n                            }\n                            else {\n                                order.status = 'triggered';\n                                triggered.push(order);\n                            }\n                        }\n                    }\n                    break;\n                case 'trailing_stop':\n                    if (order.trailing) {\n                        // Update high-water mark if price has risen\n                        if (currentPriceEth > order.trailing.highWaterMark) {\n                            order.trailing.highWaterMark = currentPriceEth;\n                            order.trailing.currentTriggerPrice = currentPriceEth * (1 - order.trailing.pct / 100);\n                            // Enforce floor\n                            if (order.trailing.floorPriceEth != null && order.trailing.currentTriggerPrice < order.trailing.floorPriceEth) {\n                                order.trailing.currentTriggerPrice = order.trailing.floorPriceEth;\n                            }\n                        }\n                        // Check if price has dropped below the trailing trigger\n                        if (currentPriceEth <= order.trailing.currentTriggerPrice) {\n                            order.status = 'triggered';\n                            triggered.push(order);\n                        }\n                    }\n                    break;\n                case 'twap':\n                    if (order.twap) {\n                        // Check if TWAP window has expired\n                        const windowEnd = order.twap.startedAt + order.twap.windowMs;\n                        if (now > windowEnd && order.twap.chunksCompleted < order.twap.totalChunks) {\n                            // Window expired but chunks remain — still trigger remaining chunks\n                            // (agent can decide whether to execute or cancel)\n                        }\n                        // Check if all chunks done\n                        if (order.twap.chunksCompleted >= order.twap.totalChunks) {\n                            order.status = 'executed';\n                            break;\n                        }\n                        // Check time since last chunk\n                        const timeSinceLastChunk = now - order.twap.lastChunkAt;\n                        if (timeSinceLastChunk < order.twap.chunkIntervalMs)\n                            break;\n                        // Check price bounds\n                        if (order.action.side === 'buy') {\n                            // For buys: skip if price too high\n                            if (order.twap.maxPriceEth != null && currentPriceEth > order.twap.maxPriceEth)\n                                break;\n                        }\n                        else {\n                            // For sells: skip if price too low\n                            if (order.twap.minPriceEth != null && currentPriceEth < order.twap.minPriceEth)\n                                break;\n                        }\n                        order.status = 'triggered';\n                        triggered.push(order);\n                    }\n                    break;\n            }\n        }\n        this.storage.saveOrders(orders);\n        return triggered;\n    }\n    // --------------------------------------------------------------------------\n    // Execution lifecycle\n    // --------------------------------------------------------------------------\n    /**\n     * Mark an order as executed after the agent performs the swap.\n     * For recurring orders (DCA, TWAP), resets to pending if more iterations remain.\n     * Handles order chaining — creates follow-up orders automatically.\n     *\n     * @returns Array of newly created chained orders (empty if none)\n     */\n    markExecuted(orderId, result) {\n        const orders = this.storage.getOrders();\n        const order = orders.find(o => o.id === orderId);\n        if (!order)\n            return [];\n        const chainedOrders = [];\n        if (order.type === 'dca' && order.dca) {\n            // DCA orders go back to pending after each buy\n            order.dca.buysCompleted++;\n            order.dca.lastBuyAt = Date.now();\n            order.executionResult = result;\n            if (order.dca.maxBuys !== null && order.dca.buysCompleted >= order.dca.maxBuys) {\n                order.status = 'executed'; // All buys done\n            }\n            else {\n                order.status = 'pending'; // More buys to do\n            }\n        }\n        else if (order.type === 'twap' && order.twap) {\n            // TWAP: increment chunk counter\n            order.twap.chunksCompleted++;\n            order.twap.lastChunkAt = Date.now();\n            order.executionResult = result;\n            if (order.twap.chunksCompleted >= order.twap.totalChunks) {\n                order.status = 'executed'; // All chunks done\n            }\n            else {\n                order.status = 'pending'; // More chunks to do\n            }\n        }\n        else {\n            order.status = 'executed';\n            order.executedAt = Date.now();\n            order.executionResult = result;\n        }\n        // Record execution for rate limiting\n        this.recordExecution();\n        // Handle order chaining — create follow-up orders\n        if (order.chain && order.chain.length > 0 && order.status === 'executed') {\n            for (const chainDef of order.chain) {\n                const chainedOrder = this.create({\n                    type: chainDef.type,\n                    token: order.token,\n                    triggerPriceEth: chainDef.triggerPriceEth,\n                    action: chainDef.action,\n                    trailing: chainDef.trailing,\n                    expiresAt: chainDef.expiresAfterMs != null ? Date.now() + chainDef.expiresAfterMs : undefined,\n                    description: chainDef.description ?? `[chained from ${order.id}] ${this.describeOrder(chainDef.type, chainDef.triggerPriceEth, chainDef.action, chainDef.trailing)}`,\n                    tag: order.tag, // inherit parent tag\n                });\n                chainedOrders.push(chainedOrder);\n            }\n        }\n        this.storage.saveOrders(orders);\n        return chainedOrders;\n    }\n    /**\n     * Mark a triggered order back as pending (e.g., if execution failed).\n     */\n    markPending(orderId) {\n        const orders = this.storage.getOrders();\n        const order = orders.find(o => o.id === orderId);\n        if (!order || order.status !== 'triggered')\n            return;\n        order.status = 'pending';\n        this.storage.saveOrders(orders);\n    }\n    /**\n     * Record a failed execution (for cooldown tracking).\n     */\n    recordFailure() {\n        const risk = this.getRiskConfig();\n        risk.lastFailureAt = Date.now();\n        this.saveRiskConfig(risk);\n    }\n    /**\n     * Remove all completed/cancelled/expired orders.\n     */\n    cleanup() {\n        const orders = this.storage.getOrders();\n        const before = orders.length;\n        const active = orders.filter(o => o.status === 'pending' || o.status === 'triggered' || o.status === 'paused');\n        this.storage.saveOrders(active);\n        return before - active.length;\n    }\n    // --------------------------------------------------------------------------\n    // Risk management\n    // --------------------------------------------------------------------------\n    /**\n     * Get the current risk configuration.\n     */\n    getRiskConfig() {\n        if (this.riskStorage) {\n            return this.riskStorage.getRiskConfig() ?? { ...DEFAULT_RISK_CONFIG };\n        }\n        return { ...DEFAULT_RISK_CONFIG };\n    }\n    /**\n     * Update risk configuration.\n     */\n    updateRiskConfig(updates) {\n        const config = this.getRiskConfig();\n        Object.assign(config, updates);\n        this.saveRiskConfig(config);\n        return config;\n    }\n    /**\n     * Update peak portfolio value for drawdown tracking.\n     * Call this with the current portfolio ETH value on each heartbeat.\n     */\n    updatePortfolioValue(currentValueEth) {\n        const risk = this.getRiskConfig();\n        // Update peak\n        if (currentValueEth > risk.peakPortfolioEth) {\n            risk.peakPortfolioEth = currentValueEth;\n        }\n        // Calculate drawdown\n        const drawdownPct = risk.peakPortfolioEth > 0\n            ? ((risk.peakPortfolioEth - currentValueEth) / risk.peakPortfolioEth) * 100\n            : 0;\n        // Check circuit breaker\n        if (drawdownPct >= risk.maxDrawdownPct && !risk.circuitBreakerTripped) {\n            risk.circuitBreakerTripped = true;\n            risk.circuitBreakerTrippedAt = Date.now();\n        }\n        this.saveRiskConfig(risk);\n        return { drawdownPct, circuitBreakerTripped: risk.circuitBreakerTripped };\n    }\n    /**\n     * Reset the circuit breaker (manual override by agent/user).\n     */\n    resetCircuitBreaker() {\n        const risk = this.getRiskConfig();\n        risk.circuitBreakerTripped = false;\n        risk.circuitBreakerTrippedAt = 0;\n        // Reset peak to current (prevents immediate re-trip)\n        // Caller should provide current portfolio value if they want a new baseline\n        this.saveRiskConfig(risk);\n    }\n    /**\n     * Check if a proposed order would exceed position size limits.\n     * @param amountEth - The ETH value of the proposed order\n     * @param portfolioEth - Current total portfolio value in ETH\n     * @returns true if the order is within limits\n     */\n    checkPositionSize(amountEth, portfolioEth) {\n        const risk = this.getRiskConfig();\n        const maxAllowedEth = portfolioEth * (risk.maxPositionPct / 100);\n        if (amountEth > maxAllowedEth) {\n            return {\n                allowed: false,\n                reason: `Order size ${amountEth.toFixed(6)} ETH exceeds max position size ${maxAllowedEth.toFixed(6)} ETH (${risk.maxPositionPct}% of portfolio)`,\n                maxAllowedEth,\n            };\n        }\n        return { allowed: true, maxAllowedEth };\n    }\n    /**\n     * Get a risk summary for display in agent prompt.\n     */\n    getRiskSummary() {\n        const risk = this.getRiskConfig();\n        const lines = [];\n        if (risk.circuitBreakerTripped) {\n            lines.push(`CIRCUIT BREAKER TRIPPED at ${new Date(risk.circuitBreakerTrippedAt).toISOString()}`);\n            lines.push(`All orders halted. Use manage_orders action=reset_circuit_breaker to resume.`);\n        }\n        const drawdownPct = risk.peakPortfolioEth > 0\n            ? `${((risk.peakPortfolioEth - risk.peakPortfolioEth) / risk.peakPortfolioEth * 100).toFixed(1)}%`\n            : 'N/A';\n        lines.push(`Peak portfolio: ${risk.peakPortfolioEth.toFixed(6)} ETH`);\n        lines.push(`Max position: ${risk.maxPositionPct}% | Max drawdown: ${risk.maxDrawdownPct}%`);\n        lines.push(`Rate limit: ${risk.recentExecutions.length}/${risk.maxExecutionsPerHour} executions/hr`);\n        if (risk.lastFailureAt > 0) {\n            const cooldownRemaining = Math.max(0, risk.failureCooldownMs - (Date.now() - risk.lastFailureAt));\n            if (cooldownRemaining > 0) {\n                lines.push(`Cooldown: ${Math.ceil(cooldownRemaining / 1000)}s remaining after last failure`);\n            }\n        }\n        return lines.join('\\n');\n    }\n    // --------------------------------------------------------------------------\n    // Internal risk helpers\n    // --------------------------------------------------------------------------\n    isCircuitBreakerTripped() {\n        const risk = this.getRiskConfig();\n        return risk.circuitBreakerTripped;\n    }\n    isRateLimited() {\n        const risk = this.getRiskConfig();\n        const oneHourAgo = Date.now() - 60 * 60 * 1000;\n        const recentCount = risk.recentExecutions.filter(t => t > oneHourAgo).length;\n        return recentCount >= risk.maxExecutionsPerHour;\n    }\n    isInCooldown() {\n        const risk = this.getRiskConfig();\n        if (risk.lastFailureAt === 0)\n            return false;\n        return Date.now() - risk.lastFailureAt < risk.failureCooldownMs;\n    }\n    recordExecution() {\n        if (!this.riskStorage)\n            return;\n        const risk = this.getRiskConfig();\n        risk.recentExecutions.push(Date.now());\n        // Keep only last hour\n        const oneHourAgo = Date.now() - 60 * 60 * 1000;\n        risk.recentExecutions = risk.recentExecutions.filter(t => t > oneHourAgo);\n        this.saveRiskConfig(risk);\n    }\n    saveRiskConfig(config) {\n        if (this.riskStorage) {\n            this.riskStorage.saveRiskConfig(config);\n        }\n    }\n    // --------------------------------------------------------------------------\n    // Helpers\n    // --------------------------------------------------------------------------\n    describeOrder(type, triggerPrice, action, trailing, twap) {\n        const amt = action.amountPct ? `${action.amountPct}% of holdings` : action.amountRaw ?? '?';\n        switch (type) {\n            case 'limit_buy':\n                return `Buy ${amt} when price ≤ ${triggerPrice} ETH`;\n            case 'limit_sell':\n                return `Sell ${amt} when price ≥ ${triggerPrice} ETH`;\n            case 'stop_loss':\n                return `Stop-loss: sell ${amt} when price ≤ ${triggerPrice} ETH`;\n            case 'take_profit':\n                return `Take-profit: sell ${amt} when price ≥ ${triggerPrice} ETH`;\n            case 'dca':\n                return `DCA: buy ${amt} at intervals`;\n            case 'trailing_stop': {\n                const pct = trailing?.pct ?? '?';\n                const floor = trailing?.floorPriceEth != null ? ` (floor: ${trailing.floorPriceEth} ETH)` : '';\n                return `Trailing stop: sell ${amt} if price drops ${pct}% from peak${floor}`;\n            }\n            case 'twap': {\n                const chunks = twap?.totalChunks ?? '?';\n                const windowHrs = twap ? (twap.windowMs / (60 * 60 * 1000)).toFixed(1) : '?';\n                return `TWAP: ${action.side} ${amt} in ${chunks} chunks over ${windowHrs}h`;\n            }\n            default:\n                return `${type}: ${action.side} ${amt} at ${triggerPrice} ETH`;\n        }\n    }\n}\n//# sourceMappingURL=orders.js.map","/**\n * WayfinderClient - Cross-chain DeFi via Wayfinder Paths\n *\n * Two-tier integration:\n * - Tier 1 (REST): Swap quotes, token resolution, balances, pool data.\n *   Always available — calls the Wayfinder API directly.\n * - Tier 2 (CLI bridge): Execute swaps, run strategies, Hyperliquid trading.\n *   Requires Python 3.12+ and the wayfinder-paths pip package installed locally.\n *   Shells out to the `wayfinder` CLI for operations that need local tx signing.\n *\n * @example\n * ```typescript\n * import { WayfinderClient } from '@clawnch/clawncher-sdk';\n *\n * const wf = new WayfinderClient({\n *   apiKey: 'wk_...',\n * });\n *\n * // Tier 1: Get a cross-chain swap quote (no Python needed)\n * const quote = await wf.quoteSwap({\n *   fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC on Ethereum\n *   toToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',   // USDC on Base\n *   fromChain: 1,\n *   toChain: 8453,\n *   fromWallet: '0x...',\n *   amount: '5000000', // 5 USDC in raw units (6 decimals)\n * });\n * console.log('Best route:', quote.bestQuote?.provider);\n *\n * // Tier 1: Get multi-chain balances\n * const balances = await wf.getBalances('0x...');\n * console.log('Total value:', balances.totalValueUsd);\n *\n * // Tier 2: Execute a swap (requires Python + wayfinder-paths)\n * const status = await wf.checkPython();\n * if (status.wayfinderInstalled) {\n *   const result = await wf.executeSwap({\n *     kind: 'swap',\n *     walletLabel: 'main',\n *     amount: '5',\n *     fromToken: 'usd-coin',\n *     toToken: 'ethereum',\n *   });\n *   console.log('Tx:', result.result?.effects);\n * }\n * ```\n */\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nconst execFileAsync = promisify(execFile);\n// ============================================================================\n// Constants\n// ============================================================================\nconst DEFAULT_API_URL = 'https://strategies.wayfinder.ai/api/v1';\nconst DEFAULT_TIMEOUT = 30_000;\nconst CLI_TIMEOUT = 120_000; // strategies can take a while\n// ============================================================================\n// Error class\n// ============================================================================\nexport class WayfinderError extends Error {\n    code;\n    details;\n    constructor(message, code, details) {\n        super(message);\n        this.code = code;\n        this.details = details;\n        this.name = 'WayfinderError';\n    }\n}\n// ============================================================================\n// WayfinderClient\n// ============================================================================\nexport class WayfinderClient {\n    apiKey;\n    apiUrl;\n    timeout;\n    pythonPathOverride;\n    pythonStatusCache = null;\n    constructor(config) {\n        if (!config.apiKey) {\n            throw new WayfinderError('Wayfinder API key is required', 'MISSING_API_KEY');\n        }\n        this.apiKey = config.apiKey;\n        this.apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, '');\n        this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n        this.pythonPathOverride = config.pythonPath;\n    }\n    // ==========================================================================\n    // Python detection\n    // ==========================================================================\n    /**\n     * Check whether Python 3 and wayfinder-paths are available.\n     * Results are cached after the first call.\n     */\n    async checkPython() {\n        if (this.pythonStatusCache)\n            return this.pythonStatusCache;\n        const status = {\n            available: false,\n            wayfinderInstalled: false,\n        };\n        // Find python3 binary\n        const pythonCmd = this.pythonPathOverride ?? 'python3';\n        try {\n            const { stdout: whichOut } = await execFileAsync('which', [pythonCmd], {\n                timeout: 5_000,\n            });\n            status.pythonPath = whichOut.trim();\n        }\n        catch {\n            // python3 not on PATH\n            this.pythonStatusCache = status;\n            return status;\n        }\n        // Get python version\n        try {\n            const { stdout: versionOut } = await execFileAsync(pythonCmd, ['--version'], { timeout: 5_000 });\n            const match = versionOut.trim().match(/Python\\s+(\\S+)/);\n            if (match) {\n                status.version = match[1];\n                status.available = true;\n            }\n        }\n        catch {\n            this.pythonStatusCache = status;\n            return status;\n        }\n        // Check wayfinder-paths installation\n        try {\n            const { stdout: wfOut } = await execFileAsync(pythonCmd, ['-c', 'import wayfinder_paths; print(wayfinder_paths.__version__)'], { timeout: 10_000 });\n            const version = wfOut.trim();\n            if (version) {\n                status.wayfinderInstalled = true;\n                status.wayfinderVersion = version;\n            }\n        }\n        catch {\n            // wayfinder-paths not installed\n        }\n        // Check wayfinder CLI binary\n        try {\n            const { stdout: cliOut } = await execFileAsync('which', ['wayfinder'], {\n                timeout: 5_000,\n            });\n            status.wayfinderCliPath = cliOut.trim();\n        }\n        catch {\n            // wayfinder CLI not on PATH\n        }\n        this.pythonStatusCache = status;\n        return status;\n    }\n    /**\n     * Clear the cached Python status (e.g. after installing wayfinder-paths).\n     */\n    clearPythonCache() {\n        this.pythonStatusCache = null;\n    }\n    // ==========================================================================\n    // Tier 1: REST API (always available)\n    // ==========================================================================\n    /**\n     * Resolve a token by name, symbol, address, or CoinGecko ID.\n     *\n     * @param query - Token identifier (e.g. \"USDC\", \"0xA0b8...\", \"usd-coin\")\n     * @param chainId - Optional chain ID filter\n     * @param marketData - Include market data (price, market cap)\n     */\n    async resolveToken(query, chainId, marketData = true) {\n        const params = {\n            query,\n            market_data: marketData.toString(),\n        };\n        if (chainId !== undefined)\n            params.chain_id = chainId.toString();\n        const raw = await this.restRequest('/blockchain/tokens/detail/', params);\n        return this.parseTokenDetail(raw);\n    }\n    /**\n     * Fuzzy search for tokens across chains.\n     *\n     * @param query - Search term\n     * @param chain - Chain code (e.g. \"base\", \"ethereum\")\n     */\n    async searchTokens(query, chain) {\n        const raw = await this.restRequest('/blockchain/tokens/fuzzy/', { query, chain }, 'text');\n        // Wayfinder fuzzy search returns XML — parse it\n        return this.parseFuzzySearchResults(raw, chain);\n    }\n    /**\n     * Get the gas token for a chain.\n     *\n     * @param chain - Chain code (e.g. \"base\", \"ethereum\")\n     */\n    async getGasToken(chain) {\n        const raw = await this.restRequest('/blockchain/tokens/gas/', { query: chain });\n        return this.parseTokenDetail(raw);\n    }\n    /**\n     * Get a cross-chain swap quote via the BRAP aggregator.\n     * Compares routes from multiple providers (LiFi, Squid, etc.)\n     * and returns the best option.\n     *\n     * @param params - Quote parameters (tokens, chains, amount in WEI)\n     */\n    async quoteSwap(params) {\n        const queryParams = {\n            from_token: params.fromToken,\n            to_token: params.toToken,\n            from_chain: params.fromChain.toString(),\n            to_chain: params.toChain.toString(),\n            from_wallet: params.fromWallet,\n            from_amount: params.amount,\n        };\n        if (params.slippage !== undefined) {\n            queryParams.slippage = params.slippage.toString();\n        }\n        const raw = await this.restRequest('/blockchain/braps/quote/', queryParams);\n        return this.parseBRAPQuoteResponse(raw);\n    }\n    /**\n     * Get enriched multi-chain wallet balances.\n     *\n     * @param walletAddress - Ethereum wallet address\n     * @param excludeSpam - Exclude spam tokens (default: true)\n     */\n    async getBalances(walletAddress, excludeSpam = true) {\n        const raw = await this.restRequest('/blockchain/balances/enriched/', {\n            address: walletAddress,\n            exclude_spam_tokens: excludeSpam.toString(),\n        });\n        return this.parseBalancesResponse(walletAddress, raw);\n    }\n    /**\n     * Get wallet transaction activity.\n     *\n     * @param walletAddress - Ethereum wallet address\n     * @param limit - Max results (default: 20)\n     * @param offset - Pagination offset\n     */\n    async getWalletActivity(walletAddress, limit = 20, offset = 0) {\n        const raw = await this.restRequest('/blockchain/balances/activity/', {\n            address: walletAddress,\n            limit: limit.toString(),\n            offset: offset.toString(),\n        });\n        return {\n            address: walletAddress,\n            activities: Array.isArray(raw.activities) ? raw.activities : [],\n            total: typeof raw.total === 'number' ? raw.total : 0,\n        };\n    }\n    /**\n     * Get DeFi pool data (Moonwell, Aave, Morpho, etc.)\n     *\n     * @param chainId - Optional chain ID filter\n     * @param protocol - Optional protocol filter (e.g. \"moonwell\", \"aave\")\n     */\n    async getPools(chainId, protocol) {\n        const params = {};\n        if (chainId !== undefined)\n            params.chain_id = chainId.toString();\n        if (protocol)\n            params.project = protocol;\n        const raw = await this.restRequest('/blockchain/pools/', params);\n        return Array.isArray(raw) ? raw : [];\n    }\n    /**\n     * Get Hyperliquid funding rate history.\n     *\n     * @param coin - Coin symbol (e.g. \"BTC\", \"ETH\")\n     * @param startMs - Start timestamp in milliseconds\n     * @param endMs - End timestamp in milliseconds\n     */\n    async getHyperliquidFunding(coin, startMs, endMs) {\n        const params = { coin };\n        if (startMs !== undefined)\n            params.start_ms = startMs.toString();\n        if (endMs !== undefined)\n            params.end_ms = endMs.toString();\n        return this.restRequest('/blockchain/hyperliquid/funding/', params);\n    }\n    /**\n     * Get Hyperliquid OHLCV candle data.\n     *\n     * @param coin - Coin symbol\n     * @param interval - Candle interval (e.g. \"1h\", \"4h\", \"1d\")\n     * @param startMs - Start timestamp in milliseconds\n     * @param endMs - End timestamp in milliseconds\n     */\n    async getHyperliquidCandles(coin, interval, startMs, endMs) {\n        const params = { coin, interval };\n        if (startMs !== undefined)\n            params.start_ms = startMs.toString();\n        if (endMs !== undefined)\n            params.end_ms = endMs.toString();\n        return this.restRequest('/blockchain/hyperliquid/candles/', params);\n    }\n    /**\n     * Get HyperLend stable market data.\n     */\n    async getHyperLendMarkets() {\n        return this.restRequest('/blockchain/hyperlend/stable_markets_headroom/');\n    }\n    // ==========================================================================\n    // Tier 2: CLI bridge (requires Python + wayfinder-paths)\n    // ==========================================================================\n    /**\n     * Execute a swap, send, or Hyperliquid deposit via the Wayfinder CLI.\n     * Signs transactions locally using wallets from wayfinder config.json.\n     *\n     * Requires Python 3.12+ and wayfinder-paths installed.\n     */\n    async executeSwap(params) {\n        const args = ['execute', '--kind', params.kind, '--wallet-label', params.walletLabel, '--amount', params.amount];\n        if (params.fromToken)\n            args.push('--from-token', params.fromToken);\n        if (params.toToken)\n            args.push('--to-token', params.toToken);\n        if (params.recipient)\n            args.push('--recipient', params.recipient);\n        if (params.token)\n            args.push('--token', params.token);\n        if (params.slippageBps !== undefined)\n            args.push('--slippage-bps', params.slippageBps.toString());\n        if (params.deadlineSeconds !== undefined)\n            args.push('--deadline-seconds', params.deadlineSeconds.toString());\n        if (params.chainId !== undefined)\n            args.push('--chain-id', params.chainId.toString());\n        const output = await this.cliExec(args);\n        try {\n            return JSON.parse(output);\n        }\n        catch {\n            return { ok: false, error: output };\n        }\n    }\n    /**\n     * Run a Wayfinder strategy action (status, deposit, update, exit, etc.)\n     *\n     * Requires Python 3.12+ and wayfinder-paths installed.\n     */\n    async runStrategy(params) {\n        const args = ['run_strategy', '--strategy', params.strategy, '--action', params.action];\n        if (params.mainTokenAmount !== undefined)\n            args.push('--main-token-amount', params.mainTokenAmount.toString());\n        if (params.gasTokenAmount !== undefined)\n            args.push('--gas-token-amount', params.gasTokenAmount.toString());\n        if (params.walletLabel)\n            args.push('--wallet-label', params.walletLabel);\n        if (params.dryRun)\n            args.push('--gorlami');\n        if (params.config)\n            args.push('--config', params.config);\n        const output = await this.cliExec(args, CLI_TIMEOUT);\n        try {\n            const parsed = JSON.parse(output);\n            return {\n                success: true,\n                action: params.action,\n                output: parsed,\n            };\n        }\n        catch {\n            // Strategy output may not be JSON — return as string\n            return {\n                success: true,\n                action: params.action,\n                output: output,\n            };\n        }\n    }\n    /**\n     * List available Wayfinder strategies.\n     *\n     * Requires Python 3.12+ and wayfinder-paths installed.\n     */\n    async listStrategies() {\n        const output = await this.cliExec(['resource', 'wayfinder://strategies']);\n        try {\n            const parsed = JSON.parse(output);\n            return Array.isArray(parsed) ? parsed : [];\n        }\n        catch {\n            // Parse text output\n            return this.parseStrategyList(output);\n        }\n    }\n    /**\n     * Get the status of a specific strategy.\n     *\n     * Requires Python 3.12+ and wayfinder-paths installed.\n     */\n    async getStrategyStatus(name) {\n        const result = await this.runStrategy({ strategy: name, action: 'status' });\n        return result.output;\n    }\n    // ==========================================================================\n    // Private: REST helper\n    // ==========================================================================\n    async restRequest(path, params, responseType = 'json') {\n        let url = `${this.apiUrl}${path}`;\n        if (params && Object.keys(params).length > 0) {\n            const qs = new URLSearchParams(params).toString();\n            url += `?${qs}`;\n        }\n        const controller = new AbortController();\n        const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n        try {\n            const response = await fetch(url, {\n                method: 'GET',\n                headers: {\n                    'X-API-KEY': this.apiKey,\n                    'Accept': responseType === 'json' ? 'application/json' : 'text/plain',\n                },\n                signal: controller.signal,\n            });\n            clearTimeout(timeoutId);\n            if (!response.ok) {\n                let errorMsg;\n                try {\n                    const body = await response.json();\n                    errorMsg = body.detail || body.error || JSON.stringify(body);\n                }\n                catch {\n                    errorMsg = `HTTP ${response.status}: ${response.statusText}`;\n                }\n                throw new WayfinderError(`Wayfinder API error: ${errorMsg}`, 'API_ERROR', { status: response.status, path });\n            }\n            if (responseType === 'text') {\n                return (await response.text());\n            }\n            return (await response.json());\n        }\n        catch (err) {\n            clearTimeout(timeoutId);\n            if (err instanceof WayfinderError)\n                throw err;\n            if (err instanceof Error && err.name === 'AbortError') {\n                throw new WayfinderError('Wayfinder API request timeout', 'TIMEOUT', { path });\n            }\n            throw new WayfinderError(err instanceof Error ? err.message : 'Unknown error', 'NETWORK_ERROR', { path });\n        }\n    }\n    // ==========================================================================\n    // Private: CLI bridge helper\n    // ==========================================================================\n    async cliExec(args, timeout = 60_000) {\n        const status = await this.checkPython();\n        if (!status.available) {\n            throw new WayfinderError('Python 3 is not installed. Install it with: brew install python@3.12 (macOS) or apt install python3 (Linux)', 'PYTHON_NOT_FOUND');\n        }\n        if (!status.wayfinderInstalled) {\n            throw new WayfinderError('wayfinder-paths is not installed. Install it with: pip3 install wayfinder-paths', 'WAYFINDER_NOT_INSTALLED');\n        }\n        const cliPath = status.wayfinderCliPath ?? 'wayfinder';\n        try {\n            const { stdout, stderr } = await execFileAsync(cliPath, args, {\n                timeout,\n                maxBuffer: 10 * 1024 * 1024, // 10MB\n                env: {\n                    ...process.env,\n                    // Ensure the Wayfinder API key is available\n                    WAYFINDER_API_KEY: this.apiKey,\n                },\n            });\n            if (stderr && !stdout) {\n                throw new WayfinderError(`Wayfinder CLI error: ${stderr.trim()}`, 'CLI_ERROR', { args });\n            }\n            return stdout.trim();\n        }\n        catch (err) {\n            if (err instanceof WayfinderError)\n                throw err;\n            const error = err;\n            if (error.killed) {\n                throw new WayfinderError(`Wayfinder CLI timed out after ${timeout / 1000}s`, 'CLI_TIMEOUT', { args });\n            }\n            throw new WayfinderError(`Wayfinder CLI failed: ${error.stderr?.trim() || error.message}`, 'CLI_ERROR', { args, exitCode: error.code });\n        }\n    }\n    // ==========================================================================\n    // Private: Response parsers\n    // ==========================================================================\n    parseTokenDetail(raw) {\n        return {\n            name: raw.name ?? '',\n            symbol: raw.symbol ?? '',\n            address: raw.address ?? raw.contract_address ?? '',\n            chainId: raw.chain_id ?? raw.chainId ?? 0,\n            decimals: raw.decimals ?? 18,\n            coingeckoId: raw.coingecko_id,\n            logoUrl: raw.logo_url ?? raw.image,\n            priceUsd: raw.current_price ?? raw.price_usd,\n            priceChange24h: raw.price_change_percentage_24h,\n            marketCapUsd: raw.market_cap,\n        };\n    }\n    parseFuzzySearchResults(xmlOrText, chain) {\n        // Wayfinder fuzzy search can return XML like:\n        // <token id=\"usd-coin\" name=\"USD Coin\" symbol=\"USDC\" address=\"0x...\" />\n        const results = [];\n        const tokenRegex = /<token\\s+([^>]+)\\/>/g;\n        let match;\n        while ((match = tokenRegex.exec(xmlOrText)) !== null) {\n            const attrs = match[1];\n            const getAttr = (name) => {\n                const m = new RegExp(`${name}=\"([^\"]*)\"`).exec(attrs);\n                return m ? m[1] : '';\n            };\n            results.push({\n                tokenId: getAttr('id'),\n                name: getAttr('name'),\n                symbol: getAttr('symbol'),\n                address: getAttr('address'),\n                chain,\n                chainId: parseInt(getAttr('chain_id')) || 0,\n            });\n        }\n        // Also try JSON fallback\n        if (results.length === 0) {\n            try {\n                const parsed = JSON.parse(xmlOrText);\n                if (Array.isArray(parsed)) {\n                    return parsed.map((t) => ({\n                        tokenId: t.id ?? '',\n                        name: t.name ?? '',\n                        symbol: t.symbol ?? '',\n                        address: t.address ?? '',\n                        chain,\n                        chainId: t.chain_id ?? 0,\n                    }));\n                }\n            }\n            catch {\n                // not JSON, not XML — return empty\n            }\n        }\n        return results;\n    }\n    parseBRAPQuoteResponse(raw) {\n        // Wayfinder BRAP response can have two shapes:\n        // 1. { quotes: [...], best_quote: {...} }\n        // 2. { quotes: { all_quotes: [...], best_quote: {...}, quote_count: N } }\n        let allQuotes = [];\n        let bestQuote = null;\n        let quoteCount = 0;\n        if (Array.isArray(raw.quotes)) {\n            allQuotes = raw.quotes;\n            bestQuote = raw.best_quote;\n            quoteCount = allQuotes.length;\n        }\n        else if (raw.quotes && typeof raw.quotes === 'object') {\n            const quotesObj = raw.quotes;\n            allQuotes = Array.isArray(quotesObj.all_quotes) ? quotesObj.all_quotes : [];\n            bestQuote = quotesObj.best_quote ?? null;\n            quoteCount = quotesObj.quote_count ?? allQuotes.length;\n        }\n        const parseEntry = (q) => {\n            if (!q || typeof q !== 'object')\n                return null;\n            const entry = q;\n            const feeEst = (entry.fee_estimate ?? {});\n            return {\n                provider: entry.provider ?? 'unknown',\n                outputAmount: String(entry.output_amount ?? '0'),\n                inputAmount: String(entry.input_amount ?? '0'),\n                gasEstimate: entry.gas_estimate ?? null,\n                error: entry.error ?? null,\n                inputAmountUsd: entry.input_amount_usd ?? 0,\n                outputAmountUsd: entry.output_amount_usd ?? 0,\n                feeEstimate: {\n                    feeTotalUsd: feeEst.fee_total_usd ?? 0,\n                    feeBreakdown: Array.isArray(feeEst.fee_breakdown) ? feeEst.fee_breakdown : [],\n                },\n                calldata: entry.calldata ?? null,\n                wrapTransaction: entry.wrap_transaction ?? null,\n                unwrapTransaction: entry.unwrap_transaction ?? null,\n                nativeInput: entry.native_input ?? false,\n                nativeOutput: entry.native_output ?? false,\n            };\n        };\n        const parsedQuotes = allQuotes\n            .map(parseEntry)\n            .filter((q) => q !== null);\n        return {\n            quotes: parsedQuotes,\n            bestQuote: bestQuote ? parseEntry(bestQuote) : (parsedQuotes[0] ?? null),\n            quoteCount,\n        };\n    }\n    parseBalancesResponse(address, raw) {\n        // enriched balances returns a list of tokens with chain info\n        const tokens = Array.isArray(raw.tokens) ? raw.tokens : [];\n        let totalValueUsd = 0;\n        const parsed = tokens.map((t) => {\n            const balUsd = t.balance_usd ?? t.balanceUsd ?? 0;\n            totalValueUsd += balUsd;\n            return {\n                name: t.name ?? '',\n                symbol: t.symbol ?? '',\n                address: t.address ?? t.contract_address ?? '',\n                chainId: t.chain_id ?? t.chainId ?? 0,\n                chainName: t.chain_name ?? t.chainName ?? '',\n                balance: String(t.balance ?? '0'),\n                balanceFormatted: t.balance_formatted ?? t.balanceFormatted ?? '0',\n                balanceUsd: balUsd,\n                decimals: t.decimals ?? 18,\n                logoUrl: t.logo_url,\n                isSpam: t.is_spam ?? t.isSpam,\n            };\n        });\n        return {\n            address,\n            totalValueUsd: raw.total_value_usd ?? totalValueUsd,\n            tokens: parsed,\n        };\n    }\n    parseStrategyList(output) {\n        // Best-effort parse of text output from wayfinder resource\n        const strategies = [];\n        const lines = output.split('\\n').filter((l) => l.trim());\n        for (const line of lines) {\n            const name = line.trim().replace(/^[-*]\\s*/, '');\n            if (name) {\n                strategies.push({\n                    name,\n                    description: '',\n                    chains: [],\n                    riskLevel: 'unknown',\n                    adapters: [],\n                });\n            }\n        }\n        return strategies;\n    }\n}\n//# sourceMappingURL=wayfinder.js.map","/**\n * HummingbotClient — Professional market making via Hummingbot API.\n *\n * Connects to the Hummingbot API server for automated trading, portfolio management,\n * and market making across 40+ exchange connectors (CEX + DEX).\n *\n * The client communicates with the Hummingbot API server (REST), which manages\n * bot instances, executors, and exchange connections. The API server itself\n * manages the Docker containers and EMQX message broker.\n *\n * @example\n * ```typescript\n * import { HummingbotClient } from '@clawnch/clawncher-sdk';\n *\n * const hb = new HummingbotClient({\n *   apiUrl: 'http://localhost:8000',\n *   username: 'admin',\n *   password: 'admin',\n * });\n *\n * // Check connection\n * const health = await hb.checkHealth();\n *\n * // Get portfolio\n * const portfolio = await hb.getPortfolioOverview();\n *\n * // Place an order\n * await hb.placeOrder({\n *   connectorName: 'binance',\n *   tradingPair: 'ETH-USDT',\n *   tradeType: 'BUY',\n *   amount: '0.1',\n *   orderType: 'MARKET',\n * });\n *\n * // Create a grid executor\n * await hb.createExecutor({\n *   executorType: 'grid_executor',\n *   connectorName: 'binance',\n *   tradingPair: 'ETH-USDT',\n *   side: 1,\n *   startPrice: 3000,\n *   endPrice: 3500,\n *   limitPrice: 2800,\n *   totalAmountQuote: 1000,\n *   levels: 10,\n * });\n *\n * // Get market data\n * const candles = await hb.getCandles('binance', 'ETH-USDT', '1h', 7);\n *\n * // Deploy a bot\n * await hb.deployBot({\n *   botName: 'my-mm-bot',\n *   controllersConfig: ['pmm_config_1'],\n * });\n * ```\n *\n * @see https://github.com/hummingbot/hummingbot\n * @see https://github.com/hummingbot/mcp\n */\n// ============================================================================\n// Constants\n// ============================================================================\nconst DEFAULT_API_URL = 'http://localhost:8000';\nconst DEFAULT_USERNAME = 'admin';\nconst DEFAULT_PASSWORD = 'admin';\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_RETRY_DELAY = 2_000;\n/** Docker container name prefix for legacy Hummingbot instances */\nconst HB_CONTAINER_PREFIX = 'clawnch-hb';\n/** Regex for valid Docker container names */\nconst SAFE_NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/;\n/** Regex for valid Ethereum addresses */\nconst ETH_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\n// ============================================================================\n// Error class\n// ============================================================================\nexport class HummingbotError extends Error {\n    code;\n    status;\n    details;\n    constructor(message, code, status, details) {\n        super(message);\n        this.code = code;\n        this.status = status;\n        this.details = details;\n        this.name = 'HummingbotError';\n    }\n}\n// ============================================================================\n// Strategy templates for Clawnch tokens\n// ============================================================================\nconst STRATEGY_TEMPLATES = {\n    // Clawnch-specific templates\n    clawnch_initial_liquidity: {\n        template: 'clawnch_initial_liquidity',\n        description: 'Post-launch liquidity provision for new Clawnch tokens. Tight spreads with inventory skew to accumulate trading fees while maintaining two-sided liquidity.',\n        executorType: 'grid_executor',\n        defaultConfig: {\n            levels: 15,\n            keepPosition: true,\n            // Spreads tighten as price stabilizes\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'startPrice', 'endPrice', 'limitPrice', 'totalAmountQuote'],\n    },\n    clawnch_post_launch_mm: {\n        template: 'clawnch_post_launch_mm',\n        description: 'Market making after initial price discovery. Wider spreads, lower risk. Uses position executor with stop-loss to protect against dumps.',\n        executorType: 'position_executor',\n        defaultConfig: {\n            stopLoss: 0.15,\n            takeProfit: 0.30,\n            orderType: 2, // LIMIT\n            timeLimit: 3600,\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'side', 'amount', 'entryPrice'],\n    },\n    clawnch_fee_optimization: {\n        template: 'clawnch_fee_optimization',\n        description: 'Maximize fee revenue by providing tight liquidity in the most-traded price range. Grid strategy centered on current price with narrow range.',\n        executorType: 'grid_executor',\n        defaultConfig: {\n            levels: 20,\n            keepPosition: false,\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'startPrice', 'endPrice', 'limitPrice', 'totalAmountQuote'],\n    },\n    clawnch_accumulation: {\n        template: 'clawnch_accumulation',\n        description: 'Gradually accumulate a Clawnch token over time with DCA, reducing timing risk. Buys are spread across price levels with increasing size at lower prices.',\n        executorType: 'dca_executor',\n        defaultConfig: {\n            side: 1, // BUY\n            stopLoss: 0.25,\n            takeProfit: 0.50,\n            timeBetweenOrders: 300,\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'amountsQuote'],\n    },\n    // Generic strategy templates\n    pure_market_making: {\n        template: 'pure_market_making',\n        description: 'Simple market making with configurable bid/ask spreads and order sizes. Good for providing liquidity on any pair.',\n        executorType: 'grid_executor',\n        defaultConfig: {\n            levels: 5,\n            keepPosition: true,\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'startPrice', 'endPrice', 'limitPrice', 'totalAmountQuote'],\n    },\n    avellaneda_market_making: {\n        template: 'avellaneda_market_making',\n        description: 'Dense grid inspired by Avellaneda-Stoikov MM principles. Many levels with inventory retention for active two-sided liquidity provision.',\n        executorType: 'grid_executor',\n        defaultConfig: {\n            levels: 10,\n            keepPosition: true,\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'startPrice', 'endPrice', 'limitPrice', 'totalAmountQuote'],\n    },\n    grid_trading: {\n        template: 'grid_trading',\n        description: 'Grid trading with defined price levels. Profits from price oscillation in a range. Configurable grid size and order amounts.',\n        executorType: 'grid_executor',\n        defaultConfig: {\n            levels: 10,\n            keepPosition: false,\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'side', 'startPrice', 'endPrice', 'limitPrice', 'totalAmountQuote'],\n    },\n    dca_buying: {\n        template: 'dca_buying',\n        description: 'Dollar-cost averaging strategy. Buys at regular intervals regardless of price. Reduces timing risk for long-term accumulation.',\n        executorType: 'dca_executor',\n        defaultConfig: {\n            side: 1, // BUY\n            timeBetweenOrders: 600,\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'amountsQuote'],\n    },\n    twap_execution: {\n        template: 'twap_execution',\n        description: 'Time-weighted average price execution. Splits a large order into smaller chunks over time to minimize market impact.',\n        executorType: 'order_executor',\n        defaultConfig: {\n            executionStrategy: 'LIMIT_CHASER',\n        },\n        requiredOverrides: ['connectorName', 'tradingPair', 'side', 'amount'],\n    },\n};\n// ============================================================================\n// HummingbotClient\n// ============================================================================\nexport class HummingbotClient {\n    apiUrl;\n    username;\n    password;\n    timeout;\n    maxRetries;\n    retryDelay;\n    /** Base64-encoded Basic Auth credentials, computed once at construction */\n    basicAuth;\n    constructor(config = {}) {\n        this.apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\\/$/, '');\n        this.username = config.username ?? DEFAULT_USERNAME;\n        this.password = config.password ?? DEFAULT_PASSWORD;\n        this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n        this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n        this.retryDelay = config.retryDelay ?? DEFAULT_RETRY_DELAY;\n        this.basicAuth = btoa(`${this.username}:${this.password}`);\n    }\n    // ==========================================================================\n    // Connection / Health\n    // ==========================================================================\n    /**\n     * Check if the Hummingbot API server is healthy and reachable.\n     * Uses the unauthenticated root endpoint `GET /`.\n     */\n    async checkHealth() {\n        try {\n            const response = await this.fetchWithTimeout(`${this.apiUrl}/`, {\n                method: 'GET',\n            });\n            if (response.ok) {\n                const data = await response.json();\n                return { healthy: true, apiUrl: this.apiUrl, version: data.version };\n            }\n            return { healthy: false, apiUrl: this.apiUrl };\n        }\n        catch (err) {\n            return {\n                healthy: false,\n                apiUrl: this.apiUrl,\n                error: err instanceof Error ? err.message : String(err),\n            };\n        }\n    }\n    /**\n     * Check all prerequisites: Docker, Hummingbot image, MCP server, API server.\n     */\n    async checkPrerequisites() {\n        const result = {\n            docker: false,\n            image: false,\n            mcp: false,\n            api: false,\n        };\n        // Check Docker\n        try {\n            await this.shellExec('docker info --format \"{{.ID}}\"');\n            result.docker = true;\n        }\n        catch { /* Docker not available */ }\n        // Check Hummingbot image\n        if (result.docker) {\n            try {\n                const images = await this.shellExec('docker images hummingbot/hummingbot --format \"{{.Tag}}\"');\n                result.image = images.length > 0;\n            }\n            catch { /* Image not found */ }\n        }\n        // Check API server health (unauthenticated root endpoint)\n        try {\n            const response = await this.fetchWithTimeout(`${this.apiUrl}/`, {\n                method: 'GET',\n            });\n            result.mcp = response.ok;\n        }\n        catch { /* API not running */ }\n        // Check API server\n        const health = await this.checkHealth();\n        result.api = health.healthy;\n        return result;\n    }\n    /**\n     * Verify credentials against the API server.\n     * Since the API uses HTTP Basic Auth on every request, this just makes\n     * an authenticated GET to confirm the credentials work.\n     */\n    async verifyCredentials() {\n        try {\n            // Use any authenticated endpoint — /accounts/ is lightweight\n            const response = await this.fetchWithTimeout(`${this.apiUrl}/accounts/`, {\n                method: 'GET',\n                headers: {\n                    'Authorization': `Basic ${this.basicAuth}`,\n                },\n            });\n            if (response.status === 401) {\n                return { valid: false, error: 'Invalid username or password' };\n            }\n            return { valid: response.ok };\n        }\n        catch (err) {\n            return {\n                valid: false,\n                error: `Cannot reach Hummingbot API at ${this.apiUrl}: ${err instanceof Error ? err.message : String(err)}`,\n            };\n        }\n    }\n    // ==========================================================================\n    // Connector / Account Setup\n    // ==========================================================================\n    /**\n     * Add connector credentials to an account.\n     * POST /accounts/{account_name}/add-connector\n     */\n    async addConnector(accountName, connectorName, credentials) {\n        return this.apiRequest('POST', `/accounts/${encodeURIComponent(accountName)}/add-connector`, { connector_name: connectorName, ...credentials });\n    }\n    /**\n     * List available exchange connectors.\n     * GET /connectors/\n     */\n    async listConnectors() {\n        return this.apiRequest('GET', '/connectors/');\n    }\n    /**\n     * Get the config fields required for a connector.\n     * GET /connectors/{connector_name}/config-map\n     */\n    async getConnectorConfigMap(connectorName) {\n        return this.apiRequest('GET', `/connectors/${encodeURIComponent(connectorName)}/config-map`);\n    }\n    /**\n     * Get trading rules for a connector (min order size, tick size, etc.).\n     * GET /connectors/{connector_name}/trading-rules\n     */\n    async getTradingRules(connectorName, tradingPairs) {\n        const qs = tradingPairs ? `?trading_pairs=${tradingPairs.join(',')}` : '';\n        return this.apiRequest('GET', `/connectors/${encodeURIComponent(connectorName)}/trading-rules${qs}`);\n    }\n    /**\n     * Get supported order types for a connector.\n     * GET /connectors/{connector_name}/order-types\n     */\n    async getOrderTypes(connectorName) {\n        return this.apiRequest('GET', `/connectors/${encodeURIComponent(connectorName)}/order-types`);\n    }\n    // ==========================================================================\n    // Portfolio\n    // ==========================================================================\n    /**\n     * Get portfolio overview (balances, positions, orders).\n     * POST /portfolio\n     */\n    async getPortfolioOverview(request = {}) {\n        return this.apiRequest('POST', '/portfolio', {\n            account_names: request.accountNames,\n            connector_names: request.connectorNames,\n            include_balances: request.includeBalances ?? true,\n            include_perp_positions: request.includePerpPositions ?? true,\n            include_lp_positions: request.includeLPPositions ?? true,\n            include_active_orders: request.includeActiveOrders ?? true,\n            as_distribution: request.asDistribution ?? false,\n            refresh: request.refresh ?? false,\n        });\n    }\n    /**\n     * Get portfolio history over time.\n     * POST /portfolio/history\n     */\n    async getPortfolioHistory(params = {}) {\n        return this.apiRequest('POST', '/portfolio/history', {\n            account_names: params.accountNames,\n            connector_names: params.connectorNames,\n            start_time: params.startTime,\n            end_time: params.endTime,\n            interval: params.interval ?? '1h',\n            limit: params.limit ?? 100,\n            cursor: params.cursor,\n        });\n    }\n    /**\n     * Get token distribution with percentages.\n     * POST /portfolio/distribution\n     */\n    async getPortfolioDistribution(params = {}) {\n        return this.apiRequest('POST', '/portfolio/distribution', {\n            account_names: params.accountNames,\n            connector_names: params.connectorNames,\n        });\n    }\n    /**\n     * Get portfolio distribution by account.\n     * GET /portfolio/accounts-distribution\n     */\n    async getAccountsDistribution() {\n        return this.apiRequest('GET', '/portfolio/accounts-distribution');\n    }\n    // ==========================================================================\n    // Trading\n    // ==========================================================================\n    /**\n     * Place a buy or sell order on an exchange.\n     * POST /trading/{account_name}/{connector_name}/place-order\n     */\n    async placeOrder(request) {\n        const accountName = request.accountName ?? 'master_account';\n        const result = await this.apiRequest('POST', `/trading/${encodeURIComponent(accountName)}/${encodeURIComponent(request.connectorName)}/place-order`, {\n            trading_pair: request.tradingPair,\n            trade_type: request.tradeType,\n            amount: request.amount,\n            order_type: request.orderType ?? 'MARKET',\n            price: request.price,\n            position_action: request.positionAction ?? 'OPEN',\n        });\n        return {\n            success: !result.error,\n            orderId: result.order_id,\n            result: result.result ?? JSON.stringify(result),\n        };\n    }\n    /**\n     * Cancel a specific order.\n     * POST /trading/{account_name}/{connector_name}/orders/{client_order_id}/cancel\n     */\n    async cancelOrder(accountName, connectorName, clientOrderId) {\n        return this.apiRequest('POST', `/trading/${encodeURIComponent(accountName)}/${encodeURIComponent(connectorName)}/orders/${encodeURIComponent(clientOrderId)}/cancel`);\n    }\n    /**\n     * Get active in-flight orders.\n     * POST /trading/orders/active\n     */\n    async getActiveOrders(params = {}) {\n        return this.apiRequest('POST', '/trading/orders/active', {\n            account_names: params.accountNames,\n            connector_names: params.connectorNames,\n            trading_pairs: params.tradingPairs,\n            limit: params.limit ?? 50,\n            cursor: params.cursor,\n        });\n    }\n    /**\n     * Search trade history.\n     * POST /trading/trades\n     */\n    async searchTrades(params = {}) {\n        return this.apiRequest('POST', '/trading/trades', {\n            account_names: params.accountNames,\n            connector_names: params.connectorNames,\n            trading_pairs: params.tradingPairs,\n            trade_types: params.tradeTypes,\n            start_time: params.startTime,\n            end_time: params.endTime,\n            limit: params.limit ?? 50,\n            cursor: params.cursor,\n        });\n    }\n    /**\n     * Get funding payment history.\n     * POST /trading/funding-payments\n     */\n    async getFundingPayments(params = {}) {\n        return this.apiRequest('POST', '/trading/funding-payments', {\n            account_names: params.accountNames,\n            connector_names: params.connectorNames,\n            trading_pair: params.tradingPair,\n            limit: params.limit ?? 50,\n            cursor: params.cursor,\n        });\n    }\n    /**\n     * Set position mode and/or leverage for an account.\n     * POST /trading/{account_name}/{connector_name}/position-mode-and-leverage\n     */\n    async setPositionModeAndLeverage(request) {\n        const accountName = request.accountName ?? 'master_account';\n        return this.apiRequest('POST', `/trading/${encodeURIComponent(accountName)}/${encodeURIComponent(request.connectorName)}/position-mode-and-leverage`, {\n            trading_pair: request.tradingPair,\n            position_mode: request.positionMode,\n            leverage: request.leverage,\n        });\n    }\n    // ==========================================================================\n    // Executors\n    // ==========================================================================\n    /**\n     * Create a new executor.\n     * POST /executors/\n     */\n    async createExecutor(config) {\n        return this.apiRequest('POST', '/executors/', this.toSnakeCase(config));\n    }\n    /**\n     * Get detailed executor info by ID.\n     * GET /executors/{executor_id}\n     */\n    async getExecutorById(executorId) {\n        return this.apiRequest('GET', `/executors/${encodeURIComponent(executorId)}`);\n    }\n    /**\n     * Stop a running executor.\n     * POST /executors/{executor_id}/stop\n     */\n    async stopExecutor(executorId, keepPosition = false) {\n        return this.apiRequest('POST', `/executors/${encodeURIComponent(executorId)}/stop`, { keep_position: keepPosition });\n    }\n    /**\n     * Search/list executors with optional filters.\n     * POST /executors/search\n     */\n    async searchExecutors(filters = {}) {\n        return this.apiRequest('POST', '/executors/search', {\n            executor_id: filters.executorId,\n            executor_types: filters.executorTypes,\n            connector_names: filters.connectorNames,\n            trading_pairs: filters.tradingPairs,\n            status: filters.status,\n            limit: filters.limit ?? 50,\n            cursor: filters.cursor,\n        });\n    }\n    /**\n     * List available executor types with descriptions.\n     * GET /executors/types/available\n     */\n    async getExecutorTypes() {\n        return this.apiRequest('GET', '/executors/types/available');\n    }\n    /**\n     * Get config schema for a specific executor type.\n     * GET /executors/types/{executor_type}/config\n     */\n    async getExecutorTypeConfig(executorType) {\n        return this.apiRequest('GET', `/executors/types/${encodeURIComponent(executorType)}/config`);\n    }\n    /**\n     * Get aggregate executor statistics.\n     * GET /executors/summary\n     */\n    async getExecutorsSummary() {\n        return this.apiRequest('GET', '/executors/summary');\n    }\n    /**\n     * Get positions summary across all executors.\n     * POST /executors/positions-summary\n     */\n    async getPositionsSummary(connectorName, tradingPair) {\n        return this.apiRequest('POST', '/executors/positions-summary', {\n            connector_name: connectorName,\n            trading_pair: tradingPair,\n        });\n    }\n    /**\n     * Get logs for a running executor.\n     * GET /executors/{executor_id}/logs\n     */\n    async getExecutorLogs(executorId, logLevel) {\n        const qs = logLevel ? `?log_level=${logLevel}` : '';\n        return this.apiRequest('GET', `/executors/${encodeURIComponent(executorId)}/logs${qs}`);\n    }\n    /**\n     * Clear a position (force-close and remove tracking).\n     * POST /executors/clear-position\n     */\n    async clearPosition(connectorName, tradingPair) {\n        return this.apiRequest('POST', '/executors/clear-position', {\n            connector_name: connectorName,\n            trading_pair: tradingPair,\n        });\n    }\n    // ==========================================================================\n    // Market Data\n    // ==========================================================================\n    /**\n     * Get latest prices for trading pairs.\n     * POST /market-data/prices\n     */\n    async getPrices(connectorName, tradingPairs) {\n        return this.apiRequest('POST', '/market-data/prices', {\n            connector_name: connectorName,\n            trading_pairs: tradingPairs,\n        });\n    }\n    /**\n     * Get OHLCV candle data.\n     * POST /market-data/candles\n     */\n    async getCandles(connectorName, tradingPair, interval = '1h', days = 30) {\n        return this.apiRequest('POST', '/market-data/candles', {\n            connector_name: connectorName,\n            trading_pair: tradingPair,\n            interval,\n            days,\n        });\n    }\n    /**\n     * Get perpetual funding rate.\n     * POST /market-data/funding-rate\n     */\n    async getFundingRate(connectorName, tradingPair) {\n        return this.apiRequest('POST', '/market-data/funding-rate', {\n            connector_name: connectorName,\n            trading_pair: tradingPair,\n        });\n    }\n    /**\n     * Get order book data.\n     * POST /market-data/order-book\n     */\n    async getOrderBook(connectorName, tradingPair, queryType = 'snapshot', queryValue, isBuy = true) {\n        return this.apiRequest('POST', '/market-data/order-book', {\n            connector_name: connectorName,\n            trading_pair: tradingPair,\n            query_type: queryType,\n            query_value: queryValue,\n            is_buy: isBuy,\n        });\n    }\n    /**\n     * Initialize order book tracking for a trading pair.\n     * POST /market-data/trading-pair/add\n     */\n    async addTradingPair(connectorName, tradingPair, accountName) {\n        return this.apiRequest('POST', '/market-data/trading-pair/add', {\n            connector_name: connectorName,\n            trading_pair: tradingPair,\n            account_name: accountName,\n            timeout: 30.0,\n        });\n    }\n    /**\n     * Remove a trading pair from order book tracking.\n     * POST /market-data/trading-pair/remove\n     */\n    async removeTradingPair(connectorName, tradingPair, accountName) {\n        return this.apiRequest('POST', '/market-data/trading-pair/remove', {\n            connector_name: connectorName,\n            trading_pair: tradingPair,\n            account_name: accountName,\n        });\n    }\n    /**\n     * Get VWAP (Volume Weighted Average Price) for a given volume.\n     * POST /market-data/order-book/vwap-for-volume\n     */\n    async getVWAP(connectorName, tradingPair, isBuy, volume) {\n        return this.apiRequest('POST', '/market-data/order-book/vwap-for-volume', {\n            connector_name: connectorName,\n            trading_pair: tradingPair,\n            is_buy: isBuy,\n            volume,\n        });\n    }\n    /**\n     * Get historical candle data between specific timestamps.\n     * POST /market-data/historical-candles\n     */\n    async getHistoricalCandles(params) {\n        return this.apiRequest('POST', '/market-data/historical-candles', {\n            connector_name: params.connectorName,\n            trading_pair: params.tradingPair,\n            interval: params.interval,\n            start_time: params.startTime,\n            end_time: params.endTime,\n        });\n    }\n    // ==========================================================================\n    // Controllers\n    // ==========================================================================\n    /**\n     * List all controllers.\n     * GET /controllers/\n     */\n    async listControllers(controllerType) {\n        const qs = controllerType ? `?controller_type=${encodeURIComponent(controllerType)}` : '';\n        return this.apiRequest('GET', `/controllers/${qs}`);\n    }\n    /**\n     * Get a controller by name.\n     * GET /controllers/{controller_name}\n     */\n    async getController(controllerName) {\n        return this.apiRequest('GET', `/controllers/${encodeURIComponent(controllerName)}`);\n    }\n    /**\n     * Create or update a controller.\n     * POST /controllers/{controller_name}\n     */\n    async upsertController(controllerName, params) {\n        return this.apiRequest('POST', `/controllers/${encodeURIComponent(controllerName)}`, {\n            controller_type: params.controllerType,\n            controller_code: params.controllerCode,\n        });\n    }\n    /**\n     * Delete a controller.\n     * DELETE /controllers/{controller_name}\n     */\n    async deleteController(controllerName) {\n        return this.apiRequest('DELETE', `/controllers/${encodeURIComponent(controllerName)}`);\n    }\n    /**\n     * List controller configs.\n     * GET /controllers/configs/\n     */\n    async listControllerConfigs() {\n        return this.apiRequest('GET', '/controllers/configs/');\n    }\n    /**\n     * Get a controller config.\n     * GET /controllers/configs/{config_name}\n     */\n    async getControllerConfig(configName) {\n        return this.apiRequest('GET', `/controllers/configs/${encodeURIComponent(configName)}`);\n    }\n    /**\n     * Create or update a controller config.\n     * POST /controllers/configs/{config_name}\n     */\n    async upsertControllerConfig(configName, configData) {\n        return this.apiRequest('POST', `/controllers/configs/${encodeURIComponent(configName)}`, configData);\n    }\n    /**\n     * Delete a controller config.\n     * DELETE /controllers/configs/{config_name}\n     */\n    async deleteControllerConfig(configName) {\n        return this.apiRequest('DELETE', `/controllers/configs/${encodeURIComponent(configName)}`);\n    }\n    // ==========================================================================\n    // Bot Orchestration\n    // ==========================================================================\n    /**\n     * Deploy a new bot with controller configs.\n     * POST /bot-orchestration/deploy-v2-controllers\n     */\n    async deployBot(request) {\n        return this.apiRequest('POST', '/bot-orchestration/deploy-v2-controllers', {\n            bot_name: request.botName,\n            controllers_config: request.controllersConfig,\n            account_name: request.accountName ?? 'master_account',\n            max_global_drawdown_quote: request.maxGlobalDrawdownQuote,\n            max_controller_drawdown_quote: request.maxControllerDrawdownQuote,\n            image: request.image ?? 'hummingbot/hummingbot:latest',\n        });\n    }\n    /**\n     * Get status of all active bots.\n     * GET /bot-orchestration/active-bots\n     */\n    async getBotsStatus() {\n        return this.apiRequest('GET', '/bot-orchestration/active-bots');\n    }\n    /**\n     * Get logs for a specific bot.\n     * GET /bot-orchestration/{bot_name}/logs\n     */\n    async getBotLogs(request) {\n        const qs = new URLSearchParams();\n        if (request.logType)\n            qs.set('log_type', request.logType);\n        if (request.limit)\n            qs.set('limit', request.limit.toString());\n        if (request.searchTerm)\n            qs.set('search_term', request.searchTerm);\n        const query = qs.toString();\n        return this.apiRequest('GET', `/bot-orchestration/${encodeURIComponent(request.botName)}/logs${query ? '?' + query : ''}`);\n    }\n    /**\n     * Stop a bot.\n     * POST /bot-orchestration/{bot_name}/stop\n     */\n    async stopBot(botName) {\n        return this.apiRequest('POST', `/bot-orchestration/${encodeURIComponent(botName)}/stop`);\n    }\n    /**\n     * Stop specific controllers in a bot.\n     * POST /bot-orchestration/{bot_name}/stop-controllers\n     */\n    async stopControllers(botName, controllerNames) {\n        return this.apiRequest('POST', `/bot-orchestration/${encodeURIComponent(botName)}/stop-controllers`, { controller_names: controllerNames });\n    }\n    /**\n     * Start/resume specific controllers in a bot.\n     * POST /bot-orchestration/{bot_name}/start-controllers\n     */\n    async startControllers(botName, controllerNames) {\n        return this.apiRequest('POST', `/bot-orchestration/${encodeURIComponent(botName)}/start-controllers`, { controller_names: controllerNames });\n    }\n    /**\n     * Get bot trading history.\n     * GET /bot-orchestration/{bot_name}/history\n     */\n    async getBotHistory(botName, days = 0, verbose = false) {\n        return this.apiRequest('GET', `/bot-orchestration/${encodeURIComponent(botName)}/history?days=${days}&verbose=${verbose}`);\n    }\n    /**\n     * Get bot runs with filters.\n     * GET /bot-orchestration/bot-runs\n     */\n    async getBotRuns(params = {}) {\n        const query = new URLSearchParams();\n        if (params.botName)\n            query.set('bot_name', params.botName);\n        if (params.accountName)\n            query.set('account_name', params.accountName);\n        if (params.strategyType)\n            query.set('strategy_type', params.strategyType);\n        if (params.runStatus)\n            query.set('run_status', params.runStatus);\n        if (params.limit)\n            query.set('limit', params.limit.toString());\n        if (params.offset)\n            query.set('offset', params.offset.toString());\n        const qs = query.toString();\n        return this.apiRequest('GET', `/bot-orchestration/bot-runs${qs ? '?' + qs : ''}`);\n    }\n    /**\n     * Stop, archive, and remove a bot.\n     * POST /bot-orchestration/stop-and-archive-bot/{bot_name}\n     */\n    async archiveBot(botName, skipOrderCancellation = true) {\n        return this.apiRequest('POST', `/bot-orchestration/stop-and-archive-bot/${encodeURIComponent(botName)}?skip_order_cancellation=${skipOrderCancellation}`);\n    }\n    // ==========================================================================\n    // Gateway (DEX swaps, CLMM)\n    // ==========================================================================\n    /**\n     * Get Gateway status.\n     * GET /gateway/status\n     */\n    async getGatewayStatus() {\n        return this.apiRequest('GET', '/gateway/status');\n    }\n    /**\n     * Start Gateway container.\n     * POST /gateway/start\n     */\n    async startGateway(config) {\n        return this.apiRequest('POST', '/gateway/start', config ? {\n            passphrase: config.passphrase,\n            image: config.image,\n            port: config.port ?? 15888,\n            environment: config.environment,\n        } : undefined);\n    }\n    /**\n     * Stop Gateway container.\n     * POST /gateway/stop\n     */\n    async stopGateway() {\n        return this.apiRequest('POST', '/gateway/stop');\n    }\n    /**\n     * Get Gateway logs.\n     * GET /gateway/logs\n     */\n    async getGatewayLogs(tail = 100) {\n        return this.apiRequest('GET', `/gateway/logs?tail=${tail}`);\n    }\n    /**\n     * List Gateway chains.\n     * GET /gateway/chains\n     */\n    async listGatewayChains() {\n        return this.apiRequest('GET', '/gateway/chains');\n    }\n    /**\n     * List Gateway networks for a chain.\n     * GET /gateway/networks\n     */\n    async listGatewayNetworks(chain) {\n        const qs = chain ? `?chain=${encodeURIComponent(chain)}` : '';\n        return this.apiRequest('GET', `/gateway/networks${qs}`);\n    }\n    /**\n     * List Gateway connectors.\n     * GET /gateway/connectors\n     */\n    async listGatewayConnectors() {\n        return this.apiRequest('GET', '/gateway/connectors');\n    }\n    /**\n     * List Gateway tokens.\n     * GET /gateway/tokens\n     */\n    async listGatewayTokens(chain, network, search) {\n        const qs = new URLSearchParams();\n        if (chain)\n            qs.set('chain', chain);\n        if (network)\n            qs.set('network', network);\n        if (search)\n            qs.set('search', search);\n        const query = qs.toString();\n        return this.apiRequest('GET', `/gateway/tokens${query ? '?' + query : ''}`);\n    }\n    /**\n     * Add a Gateway token.\n     * POST /gateway/tokens/add\n     */\n    async addGatewayToken(params) {\n        return this.apiRequest('POST', '/gateway/tokens/add', {\n            chain: params.chain,\n            network: params.network,\n            token_address: params.tokenAddress,\n            token_symbol: params.tokenSymbol,\n            token_decimals: params.tokenDecimals,\n            token_name: params.tokenName,\n        });\n    }\n    /**\n     * List Gateway wallets.\n     * GET /gateway/wallets\n     */\n    async listGatewayWallets(chain) {\n        const qs = chain ? `?chain=${encodeURIComponent(chain)}` : '';\n        return this.apiRequest('GET', `/gateway/wallets${qs}`);\n    }\n    /**\n     * Add a Gateway wallet.\n     * POST /gateway/wallets/add\n     */\n    async addGatewayWallet(chain, privateKey) {\n        return this.apiRequest('POST', '/gateway/wallets/add', {\n            chain,\n            private_key: privateKey,\n        });\n    }\n    /**\n     * Get AMM price/quote.\n     * POST /gateway/amm/price\n     */\n    async getGatewayAmmPrice(params) {\n        return this.apiRequest('POST', '/gateway/amm/price', {\n            connector: params.connector,\n            chain: params.chain,\n            network: params.network,\n            trading_pair: params.tradingPair,\n            side: params.side,\n            amount: params.amount,\n        });\n    }\n    /**\n     * Execute an AMM trade.\n     * POST /gateway/amm/trade\n     */\n    async executeGatewayAmmTrade(params) {\n        return this.apiRequest('POST', '/gateway/amm/trade', {\n            connector: params.connector,\n            chain: params.chain,\n            network: params.network,\n            trading_pair: params.tradingPair,\n            side: params.side,\n            amount: params.amount,\n            slippage_pct: params.slippagePct ?? '1.0',\n            wallet_address: params.walletAddress,\n        });\n    }\n    /**\n     * List CLMM pools.\n     * POST /gateway/clmm/pools\n     */\n    async listCLMMPools(params) {\n        return this.apiRequest('POST', '/gateway/clmm/pools', {\n            connector: params.connector,\n            chain: params.chain,\n            network: params.network,\n            page: params.page ?? 0,\n            limit: params.limit ?? 50,\n            search_term: params.searchTerm,\n            sort_key: params.sortKey ?? 'volume',\n            order_by: params.orderBy ?? 'desc',\n        });\n    }\n    /**\n     * Get CLMM pool info.\n     * POST /gateway/clmm/pool-info\n     */\n    async getCLMMPoolInfo(params) {\n        return this.apiRequest('POST', '/gateway/clmm/pool-info', {\n            connector: params.connector,\n            chain: params.chain,\n            network: params.network,\n            pool_address: params.poolAddress,\n        });\n    }\n    /**\n     * Get CLMM positions.\n     * POST /gateway/clmm/positions\n     */\n    async getCLMMPositions(params) {\n        return this.apiRequest('POST', '/gateway/clmm/positions', {\n            connector: params.connector,\n            chain: params.chain,\n            network: params.network,\n            wallet_address: params.walletAddress,\n            pool_address: params.poolAddress,\n        });\n    }\n    /**\n     * Add CLMM liquidity.\n     * POST /gateway/clmm/add-liquidity\n     */\n    async addCLMMLiquidity(params) {\n        return this.apiRequest('POST', '/gateway/clmm/add-liquidity', {\n            connector: params.connector,\n            chain: params.chain,\n            network: params.network,\n            pool_address: params.poolAddress,\n            wallet_address: params.walletAddress,\n            lower_price: params.lowerPrice,\n            upper_price: params.upperPrice,\n            base_token_amount: params.baseTokenAmount,\n            quote_token_amount: params.quoteTokenAmount,\n            slippage_pct: params.slippagePct ?? '1.0',\n        });\n    }\n    /**\n     * Remove CLMM liquidity.\n     * POST /gateway/clmm/remove-liquidity\n     */\n    async removeCLMMLiquidity(params) {\n        return this.apiRequest('POST', '/gateway/clmm/remove-liquidity', {\n            connector: params.connector,\n            chain: params.chain,\n            network: params.network,\n            position_address: params.positionAddress,\n            wallet_address: params.walletAddress,\n            slippage_pct: params.slippagePct ?? '1.0',\n        });\n    }\n    // ==========================================================================\n    // History\n    // ==========================================================================\n    /**\n     * Search historical orders.\n     * POST /trading/orders/history\n     */\n    async searchHistory(request) {\n        return this.apiRequest('POST', '/trading/orders/history', {\n            account_names: request.accountNames,\n            connector_names: request.connectorNames,\n            trading_pairs: request.tradingPairs,\n            status: request.status,\n            start_time: request.startTime,\n            end_time: request.endTime,\n            limit: request.limit ?? 50,\n            offset: request.offset ?? 0,\n        });\n    }\n    // ==========================================================================\n    // Backtesting\n    // ==========================================================================\n    /**\n     * Run a backtesting simulation against historical data.\n     * POST /backtesting/run-backtesting\n     */\n    async runBacktest(params) {\n        return this.apiRequest('POST', '/backtesting/run-backtesting', {\n            config: params.config,\n            start_time: params.startTime,\n            end_time: params.endTime,\n            backtesting_resolution: params.resolution ?? '1m',\n            trade_cost: params.tradeCost ?? 0.0006,\n        });\n    }\n    // ==========================================================================\n    // Archived Bot Analytics\n    // ==========================================================================\n    /**\n     * List archived bot database files.\n     * GET /archived-bots/\n     */\n    async listArchivedBots() {\n        return this.apiRequest('GET', '/archived-bots/');\n    }\n    /**\n     * Get archived bot performance metrics.\n     * GET /archived-bots/{db_path}/performance\n     */\n    async getArchivedBotPerformance(dbPath) {\n        return this.apiRequest('GET', `/archived-bots/${encodeURIComponent(dbPath)}/performance`);\n    }\n    /**\n     * Get archived bot summary.\n     * GET /archived-bots/{db_path}/summary\n     */\n    async getArchivedBotSummary(dbPath) {\n        return this.apiRequest('GET', `/archived-bots/${encodeURIComponent(dbPath)}/summary`);\n    }\n    /**\n     * Get archived bot trades.\n     * GET /archived-bots/{db_path}/trades\n     */\n    async getArchivedBotTrades(dbPath, limit = 100, offset = 0) {\n        return this.apiRequest('GET', `/archived-bots/${encodeURIComponent(dbPath)}/trades?limit=${limit}&offset=${offset}`);\n    }\n    /**\n     * Get archived bot orders.\n     * GET /archived-bots/{db_path}/orders\n     */\n    async getArchivedBotOrders(dbPath, limit = 100, offset = 0, status) {\n        let url = `/archived-bots/${encodeURIComponent(dbPath)}/orders?limit=${limit}&offset=${offset}`;\n        if (status)\n            url += `&status=${encodeURIComponent(status)}`;\n        return this.apiRequest('GET', url);\n    }\n    // ==========================================================================\n    // Script Management\n    // ==========================================================================\n    /**\n     * List all available scripts.\n     * GET /scripts/\n     */\n    async listScripts() {\n        return this.apiRequest('GET', '/scripts/');\n    }\n    /**\n     * Get script source code.\n     * GET /scripts/{script_name}\n     */\n    async getScript(scriptName) {\n        return this.apiRequest('GET', `/scripts/${encodeURIComponent(scriptName)}`);\n    }\n    /**\n     * Create or update a script.\n     * POST /scripts/{script_name}\n     */\n    async upsertScript(scriptName, content) {\n        return this.apiRequest('POST', `/scripts/${encodeURIComponent(scriptName)}`, { content });\n    }\n    /**\n     * Delete a script.\n     * DELETE /scripts/{script_name}\n     */\n    async deleteScript(scriptName) {\n        return this.apiRequest('DELETE', `/scripts/${encodeURIComponent(scriptName)}`);\n    }\n    /**\n     * List all script configs.\n     * GET /scripts/configs/\n     */\n    async listScriptConfigs() {\n        return this.apiRequest('GET', '/scripts/configs/');\n    }\n    /**\n     * Get a script config.\n     * GET /scripts/configs/{config_name}\n     */\n    async getScriptConfig(configName) {\n        return this.apiRequest('GET', `/scripts/configs/${encodeURIComponent(configName)}`);\n    }\n    /**\n     * Create or update a script config.\n     * POST /scripts/configs/{config_name}\n     */\n    async upsertScriptConfig(configName, config) {\n        return this.apiRequest('POST', `/scripts/configs/${encodeURIComponent(configName)}`, config);\n    }\n    /**\n     * Delete a script config.\n     * DELETE /scripts/configs/{config_name}\n     */\n    async deleteScriptConfig(configName) {\n        return this.apiRequest('DELETE', `/scripts/configs/${encodeURIComponent(configName)}`);\n    }\n    /**\n     * Get script config template with defaults and types.\n     * GET /scripts/{script_name}/config/template\n     */\n    async getScriptConfigTemplate(scriptName) {\n        return this.apiRequest('GET', `/scripts/${encodeURIComponent(scriptName)}/config/template`);\n    }\n    // ==========================================================================\n    // Rate Oracle\n    // ==========================================================================\n    /**\n     * List available rate oracle sources.\n     * GET /rate-oracle/sources\n     */\n    async getRateOracleSources() {\n        return this.apiRequest('GET', '/rate-oracle/sources');\n    }\n    /**\n     * Get current rate oracle config.\n     * GET /rate-oracle/config\n     */\n    async getRateOracleConfig() {\n        return this.apiRequest('GET', '/rate-oracle/config');\n    }\n    /**\n     * Get rate for a single trading pair (e.g. BTC-USDT).\n     * GET /rate-oracle/rate/{trading_pair}\n     */\n    async getRate(tradingPair) {\n        return this.apiRequest('GET', `/rate-oracle/rate/${encodeURIComponent(tradingPair)}`);\n    }\n    /**\n     * Get rates for multiple trading pairs.\n     * POST /rate-oracle/rates\n     */\n    async getRates(tradingPairs) {\n        return this.apiRequest('POST', '/rate-oracle/rates', {\n            trading_pairs: tradingPairs,\n        });\n    }\n    // ==========================================================================\n    // Account Management\n    // ==========================================================================\n    /**\n     * List all account names.\n     * GET /accounts/\n     */\n    async listAccounts() {\n        return this.apiRequest('GET', '/accounts/');\n    }\n    /**\n     * Get connector credentials for an account.\n     * GET /accounts/{account_name}/credentials\n     */\n    async getAccountCredentials(accountName) {\n        return this.apiRequest('GET', `/accounts/${encodeURIComponent(accountName)}/credentials`);\n    }\n    /**\n     * Create a new account.\n     * POST /accounts/add-account\n     */\n    async createAccount(accountName) {\n        return this.apiRequest('POST', `/accounts/add-account?account_name=${encodeURIComponent(accountName)}`);\n    }\n    /**\n     * Delete an account.\n     * POST /accounts/delete-account\n     */\n    async deleteAccount(accountName) {\n        return this.apiRequest('POST', `/accounts/delete-account?account_name=${encodeURIComponent(accountName)}`);\n    }\n    // ==========================================================================\n    // Docker Management\n    // ==========================================================================\n    /**\n     * List Docker images.\n     * GET /docker/images\n     */\n    async listDockerImages() {\n        return this.apiRequest('GET', '/docker/images');\n    }\n    /**\n     * List Docker containers.\n     * GET /docker/active-containers\n     */\n    async listDockerContainers() {\n        return this.apiRequest('GET', '/docker/active-containers');\n    }\n    /**\n     * Pull a Docker image.\n     * POST /docker/pull-image\n     */\n    async pullDockerImage(imageName) {\n        return this.apiRequest('POST', '/docker/pull-image', { image_name: imageName });\n    }\n    // ==========================================================================\n    // Strategy Templates\n    // ==========================================================================\n    /**\n     * Get all available strategy templates.\n     */\n    getStrategyTemplates() {\n        return Object.values(STRATEGY_TEMPLATES);\n    }\n    /**\n     * Get a specific strategy template.\n     */\n    getStrategyTemplate(name) {\n        return STRATEGY_TEMPLATES[name] ?? null;\n    }\n    /**\n     * Get Clawnch-specific strategy templates.\n     */\n    getClawnchTemplates() {\n        return Object.values(STRATEGY_TEMPLATES).filter(t => t.template.startsWith('clawnch_'));\n    }\n    /**\n     * Build an executor config from a template with overrides.\n     */\n    buildFromTemplate(template, overrides) {\n        const tmpl = STRATEGY_TEMPLATES[template];\n        if (!tmpl) {\n            throw new HummingbotError(`Unknown strategy template: ${template}. Available: ${Object.keys(STRATEGY_TEMPLATES).join(', ')}`, 'INVALID_TEMPLATE');\n        }\n        // Validate required overrides are present\n        const missing = tmpl.requiredOverrides.filter(k => !(k in overrides));\n        if (missing.length > 0) {\n            throw new HummingbotError(`Missing required parameters for ${template}: ${missing.join(', ')}`, 'MISSING_PARAMS', undefined, { required: tmpl.requiredOverrides, provided: Object.keys(overrides) });\n        }\n        return {\n            executorType: tmpl.executorType,\n            connectorName: overrides.connectorName,\n            tradingPair: overrides.tradingPair,\n            ...tmpl.defaultConfig,\n            ...overrides,\n        };\n    }\n    // ==========================================================================\n    // Docker management (backward compat with legacy approach)\n    // ==========================================================================\n    /**\n     * List running Hummingbot Docker instances managed by Clawtomaton.\n     */\n    async listDockerInstances() {\n        try {\n            const output = await this.shellExec(`docker ps -a --filter \"name=${HB_CONTAINER_PREFIX}\" --format \"{{.Names}}|{{.Status}}|{{.CreatedAt}}\"`);\n            if (!output)\n                return [];\n            return output.split('\\n').filter(Boolean).map(line => {\n                const [name, status, created] = line.split('|');\n                return { name, status, created };\n            });\n        }\n        catch {\n            return [];\n        }\n    }\n    /**\n     * Get logs from a Docker instance.\n     */\n    async getDockerLogs(instanceName, tail = 50) {\n        const name = this.sanitizeName(instanceName);\n        return this.shellExec(`docker logs --tail ${tail} \"${name}\"`);\n    }\n    /**\n     * Stop and remove a Docker instance.\n     */\n    async stopDockerInstance(instanceName) {\n        const name = this.sanitizeName(instanceName);\n        await this.shellExec(`docker stop \"${name}\"`);\n        await this.shellExec(`docker rm \"${name}\"`);\n    }\n    // ==========================================================================\n    // Private: API request helpers\n    // ==========================================================================\n    /**\n     * Make an authenticated API request to the Hummingbot REST API.\n     *\n     * Uses HTTP Basic Auth on every request (no JWT, no login endpoint).\n     * Retries only on 5xx or network errors; client errors (4xx) fail immediately.\n     *\n     * @param method - HTTP method (GET, POST, PUT, DELETE)\n     * @param endpoint - API path (e.g. '/accounts/')\n     * @param body - Request body for POST/PUT (ignored for GET/DELETE)\n     */\n    async apiRequest(method, endpoint, body) {\n        let lastError = null;\n        for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n            try {\n                const headers = {\n                    'Authorization': `Basic ${this.basicAuth}`,\n                };\n                const init = { method, headers };\n                // Only attach body for methods that support it\n                if (body !== undefined && (method === 'POST' || method === 'PUT')) {\n                    headers['Content-Type'] = 'application/json';\n                    init.body = JSON.stringify(typeof body === 'object' && body !== null && !Array.isArray(body)\n                        ? this.stripUndefined(body)\n                        : body);\n                }\n                const response = await this.fetchWithTimeout(`${this.apiUrl}${endpoint}`, init);\n                if (!response.ok) {\n                    const responseBody = await response.text();\n                    const error = new HummingbotError(`Hummingbot API ${method} ${endpoint}: ${response.status} ${responseBody}`, 'API_ERROR', response.status, { endpoint, method, body: responseBody });\n                    // Only retry on 5xx (server errors); 4xx are not retryable\n                    if (response.status >= 500) {\n                        lastError = error;\n                        if (attempt < this.maxRetries - 1) {\n                            await new Promise(resolve => setTimeout(resolve, this.retryDelay));\n                        }\n                        continue;\n                    }\n                    // 4xx — fail immediately\n                    throw error;\n                }\n                // Parse response\n                const text = await response.text();\n                if (!text)\n                    return undefined;\n                try {\n                    return JSON.parse(text);\n                }\n                catch {\n                    // Non-JSON response — return raw text\n                    return text;\n                }\n            }\n            catch (err) {\n                if (err instanceof HummingbotError) {\n                    // Already a structured error — if it's a 4xx we already threw above.\n                    // If we reach here it was a 5xx that fell through; lastError is set.\n                    if (err.status && err.status < 500)\n                        throw err;\n                    lastError = err;\n                }\n                else {\n                    // Network error — retryable\n                    lastError = err instanceof Error ? err : new Error(String(err));\n                }\n                if (attempt < this.maxRetries - 1) {\n                    await new Promise(resolve => setTimeout(resolve, this.retryDelay));\n                }\n            }\n        }\n        throw lastError ?? new HummingbotError('Max retries exceeded', 'MAX_RETRIES');\n    }\n    async fetchWithTimeout(url, init) {\n        const controller = new AbortController();\n        const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n        try {\n            const response = await fetch(url, {\n                ...init,\n                signal: controller.signal,\n            });\n            clearTimeout(timeoutId);\n            return response;\n        }\n        catch (err) {\n            clearTimeout(timeoutId);\n            if (err instanceof Error && err.name === 'AbortError') {\n                throw new HummingbotError(`Request to ${url} timed out after ${this.timeout}ms`, 'TIMEOUT');\n            }\n            throw err;\n        }\n    }\n    // ==========================================================================\n    // Private: Shell helpers (for Docker operations)\n    // ==========================================================================\n    async shellExec(command) {\n        const { execSync } = await import('child_process');\n        try {\n            return execSync(command, { encoding: 'utf8', timeout: 30_000 }).trim();\n        }\n        catch (err) {\n            throw new HummingbotError(`Shell command failed: ${command}\\n${err.stderr ?? err.message}`, 'SHELL_ERROR');\n        }\n    }\n    sanitizeName(name) {\n        if (!SAFE_NAME_RE.test(name) || name.length > 128) {\n            throw new HummingbotError(`Invalid name \"${name}\": must be 1-128 chars, alphanumeric/dash/underscore/dot`, 'INVALID_NAME');\n        }\n        return name;\n    }\n    // ==========================================================================\n    // Private: Utility helpers\n    // ==========================================================================\n    /** Remove undefined values from an object (deep) */\n    stripUndefined(obj) {\n        const result = {};\n        for (const [key, value] of Object.entries(obj)) {\n            if (value === undefined)\n                continue;\n            if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n                result[key] = this.stripUndefined(value);\n            }\n            else {\n                result[key] = value;\n            }\n        }\n        return result;\n    }\n    /** Convert camelCase keys to snake_case (deep) */\n    toSnakeCase(obj) {\n        const result = {};\n        for (const [key, value] of Object.entries(obj)) {\n            const snakeKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);\n            if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n                result[snakeKey] = this.toSnakeCase(value);\n            }\n            else {\n                result[snakeKey] = value;\n            }\n        }\n        return result;\n    }\n}\n//# sourceMappingURL=hummingbot.js.map","/**\n * Herd MCP Authentication\n *\n * Manages OAuth credentials for the Herd MCP server.\n * Supports three modes:\n *   1. Environment variable (HERD_ACCESS_TOKEN)\n *   2. Stored token file (~/.clawncher/herd-auth.json)\n *   3. Interactive OAuth PKCE flow (opens browser)\n *\n * The MCP SDK's StreamableHTTPClientTransport handles OAuth natively.\n * This module manages credential persistence and retrieval so that\n * tokens obtained in one session (e.g. CLI `clawncher herd auth`)\n * can be reused by the SDK, MCP server, and Clawtomaton agents.\n */\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\n// =========================================================================\n// Constants\n// =========================================================================\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.clawncher');\nconst DEFAULT_TOKEN_FILE = 'herd-auth.json';\nconst ENV_VAR = 'HERD_ACCESS_TOKEN';\nexport const HERD_MCP_URL = 'https://mcp.herd.eco/v1';\n// =========================================================================\n// HerdAuth\n// =========================================================================\nexport class HerdAuth {\n    tokenStore = null;\n    tokenPath;\n    constructor(config = {}) {\n        this.tokenPath = config.tokenPath || join(DEFAULT_CONFIG_DIR, DEFAULT_TOKEN_FILE);\n        // Direct token takes highest priority\n        if (config.accessToken) {\n            this.tokenStore = {\n                accessToken: config.accessToken,\n                tokenType: 'Bearer',\n                storedAt: new Date().toISOString(),\n            };\n        }\n    }\n    // -----------------------------------------------------------------------\n    // Token Resolution (env > stored file > null)\n    // -----------------------------------------------------------------------\n    /**\n     * Get the current access token, resolving from env var or stored file.\n     * Returns null if no token is available (user needs to authenticate).\n     */\n    getAccessToken() {\n        // 1. Already loaded in memory\n        if (this.tokenStore) {\n            if (this.isExpired())\n                return null;\n            return this.tokenStore.accessToken;\n        }\n        // 2. Environment variable\n        const envToken = process.env[ENV_VAR];\n        if (envToken) {\n            this.tokenStore = {\n                accessToken: envToken,\n                tokenType: 'Bearer',\n                storedAt: new Date().toISOString(),\n            };\n            return envToken;\n        }\n        // 3. Stored file\n        const stored = this.loadFromFile();\n        if (stored) {\n            this.tokenStore = stored;\n            if (this.isExpired())\n                return null;\n            return stored.accessToken;\n        }\n        return null;\n    }\n    /**\n     * Check if authentication is available (token exists and not expired).\n     */\n    isAuthenticated() {\n        return this.getAccessToken() !== null;\n    }\n    /**\n     * Get the Authorization header value.\n     * Throws if not authenticated.\n     */\n    getAuthHeader() {\n        const token = this.getAccessToken();\n        if (!token) {\n            throw new Error('Herd authentication required. Run `clawncher herd auth` or set HERD_ACCESS_TOKEN.');\n        }\n        return `Bearer ${token}`;\n    }\n    // -----------------------------------------------------------------------\n    // Token Storage\n    // -----------------------------------------------------------------------\n    /**\n     * Store a token obtained from OAuth flow or other source.\n     */\n    saveToken(token) {\n        this.tokenStore = {\n            ...token,\n            storedAt: new Date().toISOString(),\n        };\n        this.writeToFile(this.tokenStore);\n    }\n    /**\n     * Clear stored credentials.\n     */\n    clearToken() {\n        this.tokenStore = null;\n        try {\n            const { unlinkSync } = require('node:fs');\n            if (existsSync(this.tokenPath)) {\n                unlinkSync(this.tokenPath);\n            }\n        }\n        catch {\n            // Ignore file deletion errors\n        }\n    }\n    // -----------------------------------------------------------------------\n    // Static Factories\n    // -----------------------------------------------------------------------\n    /**\n     * Create HerdAuth from environment variable.\n     * Returns null if env var is not set.\n     */\n    static fromEnv() {\n        const token = process.env[ENV_VAR];\n        if (!token)\n            return null;\n        return new HerdAuth({ accessToken: token });\n    }\n    /**\n     * Create HerdAuth from stored token file.\n     * Returns null if no stored token exists.\n     */\n    static fromStoredToken(tokenPath) {\n        const auth = new HerdAuth({ tokenPath });\n        if (auth.getAccessToken())\n            return auth;\n        return null;\n    }\n    /**\n     * Create HerdAuth with automatic resolution:\n     * env var > stored file > null\n     */\n    static resolve(config = {}) {\n        return new HerdAuth(config);\n    }\n    // -----------------------------------------------------------------------\n    // Internal\n    // -----------------------------------------------------------------------\n    isExpired() {\n        if (!this.tokenStore?.expiresAt)\n            return false;\n        return new Date(this.tokenStore.expiresAt) <= new Date();\n    }\n    loadFromFile() {\n        try {\n            if (!existsSync(this.tokenPath))\n                return null;\n            const raw = readFileSync(this.tokenPath, 'utf-8');\n            const parsed = JSON.parse(raw);\n            if (!parsed.accessToken)\n                return null;\n            return parsed;\n        }\n        catch {\n            return null;\n        }\n    }\n    writeToFile(store) {\n        try {\n            const dir = dirname(this.tokenPath);\n            if (!existsSync(dir)) {\n                mkdirSync(dir, { recursive: true, mode: 0o700 });\n            }\n            writeFileSync(this.tokenPath, JSON.stringify(store, null, 2), {\n                mode: 0o600,\n            });\n        }\n        catch {\n            // Non-fatal — token is still in memory\n        }\n    }\n}\n//# sourceMappingURL=herd-auth.js.map","/**\n * HerdIntelligence — On-chain intelligence via Herd MCP\n *\n * Composes Herd's block explorer data with Clawncher's domain-specific\n * on-chain reading to produce rich, actionable intelligence that neither\n * system can provide alone.\n *\n * Architecture:\n *   - Uses the MCP SDK's HTTP client to call Herd's MCP server\n *   - Combines Herd responses with ClawnchReader / ClawnchPrice data\n *   - Caches responses with configurable TTLs\n *   - Degrades gracefully when Herd is unavailable\n *\n * @example\n * ```typescript\n * const herd = new HerdIntelligence({\n *   accessToken: 'your-herd-token',\n *   publicClient,\n *   network: 'mainnet',\n * });\n *\n * // Investigate any contract — enriched with Clawncher data if applicable\n * const profile = await herd.investigateContract('0x...');\n *\n * // Audit a token for safety before interacting\n * const audit = await herd.auditTokenSafety('0x...');\n *\n * // Validate a swap route against historical on-chain data\n * const validation = await herd.validateSwapRoute('0xTokenIn', '0xTokenOut', '1.0');\n * ```\n */\nimport { formatUnits } from 'viem';\nimport { ClawnchReader } from './reader.js';\nimport { ClawnchPrice } from './price.js';\nimport { getAddresses } from './addresses.js';\nimport { HerdAuth, HERD_MCP_URL } from './herd-auth.js';\nimport { ClawnchErrorCode, ClawnchDeployError, withRetry } from './errors.js';\nclass MemoryCache {\n    store = new Map();\n    get(key) {\n        const entry = this.store.get(key);\n        if (!entry)\n            return null;\n        if (Date.now() - entry.cachedAt > entry.ttlMs) {\n            this.store.delete(key);\n            return null;\n        }\n        return entry.data;\n    }\n    set(key, data, ttlSeconds) {\n        this.store.set(key, {\n            data,\n            cachedAt: Date.now(),\n            ttlMs: ttlSeconds * 1000,\n        });\n    }\n    clear() {\n        this.store.clear();\n    }\n}\n// =========================================================================\n// Herd MCP Client (thin wrapper over HTTP)\n// =========================================================================\n/**\n * Calls Herd MCP tools via HTTP transport.\n *\n * The MCP protocol uses JSON-RPC over HTTP. We call `tools/call` with\n * the tool name and arguments, and receive structured results back.\n */\nclass HerdMcpClient {\n    baseUrl;\n    auth;\n    timeout;\n    sessionId = null;\n    constructor(mcpUrl, auth, timeout) {\n        this.baseUrl = mcpUrl;\n        this.auth = auth;\n        this.timeout = timeout;\n    }\n    /**\n     * Call a Herd MCP tool and return the parsed text content.\n     */\n    async callTool(toolName, args) {\n        const token = this.auth.getAccessToken();\n        if (!token) {\n            throw new ClawnchDeployError(ClawnchErrorCode.FEATURE_NOT_AVAILABLE, 'Herd authentication required. Run `clawncher herd auth` or set HERD_ACCESS_TOKEN.');\n        }\n        const controller = new AbortController();\n        const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n        try {\n            const headers = {\n                'Content-Type': 'application/json',\n                Authorization: `Bearer ${token}`,\n            };\n            if (this.sessionId) {\n                headers['mcp-session-id'] = this.sessionId;\n            }\n            const response = await fetch(this.baseUrl, {\n                method: 'POST',\n                headers,\n                body: JSON.stringify({\n                    jsonrpc: '2.0',\n                    id: Date.now(),\n                    method: 'tools/call',\n                    params: {\n                        name: toolName,\n                        arguments: args,\n                    },\n                }),\n                signal: controller.signal,\n            });\n            clearTimeout(timeoutId);\n            // Capture session ID from response headers\n            const sid = response.headers.get('mcp-session-id');\n            if (sid)\n                this.sessionId = sid;\n            if (!response.ok) {\n                throw new ClawnchDeployError(ClawnchErrorCode.RPC_ERROR, `Herd MCP returned HTTP ${response.status}: ${response.statusText}`);\n            }\n            const rpcResult = (await response.json());\n            if (rpcResult.error) {\n                throw new ClawnchDeployError(ClawnchErrorCode.RPC_ERROR, `Herd MCP error: ${rpcResult.error.message}`);\n            }\n            const content = rpcResult.result?.content;\n            if (!content || content.length === 0) {\n                return null;\n            }\n            if (rpcResult.result?.isError) {\n                throw new ClawnchDeployError(ClawnchErrorCode.RPC_ERROR, `Herd tool error: ${content[0]?.text || 'Unknown error'}`);\n            }\n            // Parse text content — Herd returns JSON-stringified data in text blocks\n            const textContent = content\n                .filter((c) => c.type === 'text')\n                .map((c) => c.text)\n                .join('\\n');\n            try {\n                return JSON.parse(textContent);\n            }\n            catch {\n                // Some tools return plain text, not JSON\n                return textContent;\n            }\n        }\n        catch (err) {\n            clearTimeout(timeoutId);\n            if (err instanceof ClawnchDeployError)\n                throw err;\n            if (err instanceof Error && err.name === 'AbortError') {\n                throw new ClawnchDeployError(ClawnchErrorCode.TIMEOUT, 'Herd MCP request timed out');\n            }\n            throw new ClawnchDeployError(ClawnchErrorCode.RPC_ERROR, `Herd MCP connection error: ${err instanceof Error ? err.message : 'Unknown'}`, err instanceof Error ? err : undefined);\n        }\n    }\n    /**\n     * Check if the MCP server is reachable.\n     */\n    async isAvailable() {\n        try {\n            const token = this.auth.getAccessToken();\n            if (!token)\n                return false;\n            const controller = new AbortController();\n            const timeoutId = setTimeout(() => controller.abort(), 5000);\n            const response = await fetch(this.baseUrl, {\n                method: 'POST',\n                headers: {\n                    'Content-Type': 'application/json',\n                    Authorization: `Bearer ${token}`,\n                },\n                body: JSON.stringify({\n                    jsonrpc: '2.0',\n                    id: 1,\n                    method: 'initialize',\n                    params: {\n                        protocolVersion: '2025-03-26',\n                        capabilities: {},\n                        clientInfo: { name: 'clawncher-sdk', version: '0.3.2' },\n                    },\n                }),\n                signal: controller.signal,\n            });\n            clearTimeout(timeoutId);\n            return response.ok;\n        }\n        catch {\n            return false;\n        }\n    }\n}\n// =========================================================================\n// Known Clawncher Contract Set\n// =========================================================================\nfunction buildKnownAddressSet(addresses) {\n    const set = new Set();\n    for (const addr of Object.values(addresses.clawnch)) {\n        if (addr !== '0x0000000000000000000000000000000000000000') {\n            set.add(addr.toLowerCase());\n        }\n    }\n    for (const addr of Object.values(addresses.infrastructure)) {\n        set.add(addr.toLowerCase());\n    }\n    return set;\n}\n// =========================================================================\n// Security Pattern Matching\n// =========================================================================\nconst SECURITY_PATTERNS = [\n    { pattern: 'selfdestruct', severity: 'critical', category: 'destruction', description: 'Contract can be destroyed, removing all code and state' },\n    { pattern: 'delegatecall', severity: 'high', category: 'delegation', description: 'Uses delegatecall which can execute arbitrary code in contract context' },\n    { pattern: 'blacklist|blocklist|deny', severity: 'high', category: 'access-control', description: 'Has blacklist/blocklist capability — can block specific addresses' },\n    { pattern: 'pause|unpause|paused', severity: 'medium', category: 'pausability', description: 'Contract can be paused, potentially freezing funds or operations' },\n    { pattern: 'mint|_mint', severity: 'medium', category: 'supply', description: 'Has mint function — supply may not be fixed' },\n    { pattern: 'onlyOwner|onlyAdmin|onlyRole', severity: 'low', category: 'access-control', description: 'Has privileged functions restricted to owner/admin/role' },\n    { pattern: 'setFee|updateFee|changeFee', severity: 'medium', category: 'fee-control', description: 'Fees can be changed by admin after deployment' },\n    { pattern: 'upgradeTo|upgradeToAndCall', severity: 'high', category: 'upgradeability', description: 'Contract is upgradeable — implementation can be changed' },\n];\n// =========================================================================\n// HerdIntelligence\n// =========================================================================\nexport class HerdIntelligence {\n    mcp;\n    reader = null;\n    price = null;\n    publicClient;\n    network;\n    blockchain;\n    addresses;\n    knownAddresses;\n    cache;\n    cacheTtl;\n    constructor(config = {}) {\n        const auth = new HerdAuth({ accessToken: config.accessToken });\n        this.mcp = new HerdMcpClient(config.mcpUrl || HERD_MCP_URL, auth, config.timeout || 30000);\n        this.publicClient = config.publicClient || null;\n        this.network = config.network || 'mainnet';\n        this.blockchain = config.blockchain || 'base';\n        this.addresses = getAddresses(this.network);\n        this.knownAddresses = buildKnownAddressSet(this.addresses);\n        this.cache = new MemoryCache();\n        this.cacheTtl = {\n            contractMetadata: 3600,\n            transactionData: 86400000,\n            walletOverview: 300,\n            tokenActivity: 120,\n            bookmarks: 300,\n            ...config.cacheTtl,\n        };\n        // Initialize Clawncher-side readers if we have a publicClient\n        if (this.publicClient) {\n            this.reader = new ClawnchReader({\n                publicClient: this.publicClient,\n                network: this.network,\n            });\n            this.price = new ClawnchPrice({\n                publicClient: this.publicClient,\n                network: this.network,\n            });\n        }\n    }\n    // -----------------------------------------------------------------------\n    // Availability\n    // -----------------------------------------------------------------------\n    /**\n     * Check if the Herd MCP server is reachable and authenticated.\n     */\n    async isAvailable() {\n        return this.mcp.isAvailable();\n    }\n    // -----------------------------------------------------------------------\n    // Contract Investigation\n    // -----------------------------------------------------------------------\n    /**\n     * Investigate any contract on Base/Ethereum.\n     *\n     * Returns a rich profile combining Herd's metadata (ABI, proxy info,\n     * token data, protocol labels) with Clawncher-specific data when the\n     * contract is one of ours (vault status, MEV config, fees, etc.).\n     *\n     * Also runs security pattern analysis on the source code.\n     */\n    async investigateContract(address, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        const cacheKey = `contract:${address}:${blockchain}`;\n        const cached = this.cache.get(cacheKey);\n        if (cached)\n            return cached;\n        const addr = address;\n        // Fetch from Herd + our reader in parallel\n        const [herdMeta, clawncherData, securityFlags] = await Promise.all([\n            this.callToolSafe('contractMetadataTool', {\n                contractAddress: address,\n                blockchain,\n            }),\n            this.getClawncherOverlay(addr),\n            options.skipCodeAnalysis\n                ? []\n                : this.analyzeContractSecurity(address, blockchain),\n        ]);\n        const profile = this.buildContractProfile(addr, blockchain, herdMeta, clawncherData, securityFlags);\n        this.cache.set(cacheKey, profile, this.cacheTtl.contractMetadata);\n        return profile;\n    }\n    // -----------------------------------------------------------------------\n    // Transaction Investigation\n    // -----------------------------------------------------------------------\n    /**\n     * Investigate any transaction.\n     *\n     * Decodes traces, logs, and balance changes via Herd, then annotates\n     * with Clawncher-specific context (e.g. \"this was a fee claim\",\n     * \"this was a V4 swap with 0.35 ETH output\").\n     */\n    async investigateTransaction(txHash, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        const cacheKey = `tx:${txHash}:${blockchain}`;\n        const cached = this.cache.get(cacheKey);\n        if (cached)\n            return cached;\n        const herdTx = await this.callToolSafe('queryTransactionTool', {\n            txHash,\n            returnAllData: true,\n            blockchain,\n        });\n        const profile = this.buildTransactionProfile(txHash, blockchain, herdTx);\n        // Tx data is immutable — cache indefinitely\n        this.cache.set(cacheKey, profile, this.cacheTtl.transactionData);\n        return profile;\n    }\n    // -----------------------------------------------------------------------\n    // Wallet Investigation\n    // -----------------------------------------------------------------------\n    /**\n     * Investigate any wallet.\n     *\n     * Detects wallet type (EOA, 4337, 7702, multisig), shows holdings,\n     * and overlays Clawncher token positions and fee data if the wallet\n     * holds any of our tokens.\n     */\n    async investigateWallet(address, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        const cacheKey = `wallet:${address}:${blockchain}`;\n        const cached = this.cache.get(cacheKey);\n        if (cached)\n            return cached;\n        const addr = address;\n        // Fetch Herd overview + optional activity in parallel\n        const [herdOverview, herdActivity] = await Promise.all([\n            this.callToolSafe('getWalletOverviewTool', {\n                walletAddress: address,\n                blockchain,\n            }),\n            options.includeActivity !== false\n                ? this.callToolSafe('getTransactionActivityTool', {\n                    fromAddress: address,\n                    blockchain,\n                })\n                : null,\n        ]);\n        const clawncherOverlay = await this.getClawncherWalletOverlay(addr);\n        const profile = this.buildWalletProfile(addr, blockchain, herdOverview, herdActivity, clawncherOverlay);\n        this.cache.set(cacheKey, profile, this.cacheTtl.walletOverview);\n        return profile;\n    }\n    // -----------------------------------------------------------------------\n    // Contract Relationships\n    // -----------------------------------------------------------------------\n    /**\n     * Map relationships for a contract — who calls it, what it calls,\n     * what it deployed. Highlights Clawncher contracts in the graph.\n     */\n    async getContractRelationships(address, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        const [latestTxs, deployed] = await Promise.all([\n            this.callToolSafe('getLatestTransactionsTool', {\n                contractAddress: address,\n                type: 'function',\n                signature: '0x00000000', // Herd uses this as \"any function\"\n                blockchain,\n            }),\n            this.callToolSafe('getDeployedContractsTool', {\n                deployerAddress: address,\n                blockchain,\n            }),\n        ]);\n        return this.buildRelationships(address, blockchain, latestTxs, deployed);\n    }\n    // -----------------------------------------------------------------------\n    // Token Flow Tracking\n    // -----------------------------------------------------------------------\n    /**\n     * Track token transfer history for a holder.\n     * Annotates transfers with known contract labels.\n     */\n    async trackTokenFlow(holder, token, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        const herdActivity = await this.callToolSafe('getTokenActivityTool', {\n            holderAddress: holder,\n            tokenAddress: token,\n            blockchain,\n            page: options.page || 1,\n        });\n        return this.buildTokenFlowReport(holder, token, blockchain, herdActivity);\n    }\n    // -----------------------------------------------------------------------\n    // Version Diff\n    // -----------------------------------------------------------------------\n    /**\n     * Compare implementation versions of an upgradeable contract.\n     */\n    async compareVersions(address, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        // First get contract metadata to identify it as a proxy\n        const meta = await this.callToolSafe('contractMetadataTool', {\n            contractAddress: address,\n            blockchain,\n        });\n        const diff = await this.callToolSafe('diffContractVersions', {\n            compareAllVersions: options.allVersions || false,\n        });\n        return this.buildVersionDiff(address, blockchain, meta, diff);\n    }\n    // -----------------------------------------------------------------------\n    // Code Search\n    // -----------------------------------------------------------------------\n    /**\n     * Search contract source code using natural language or regex.\n     */\n    async searchCode(addresses, query, options = {}) {\n        const result = await this.callToolSafe('regexCodeAnalysisTool', {\n            query,\n            contractAddresses: addresses,\n            includeProxies: options.includeProxies || false,\n            returnAllCode: options.returnAllCode || false,\n        });\n        return typeof result === 'string' ? result : JSON.stringify(result, null, 2);\n    }\n    // -----------------------------------------------------------------------\n    // Composed Validation: Token Safety Audit\n    // -----------------------------------------------------------------------\n    /**\n     * Comprehensive security audit of any ERC-20 token.\n     *\n     * Combines contract metadata, code analysis for dangerous patterns,\n     * proxy/upgrade detection, and owner privilege scanning into a single\n     * risk report with a 0-100 score.\n     */\n    async auditTokenSafety(tokenAddress, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        // Get full contract profile (includes code analysis)\n        const profile = await this.investigateContract(tokenAddress, { blockchain });\n        // Check for version changes if it's a proxy\n        let isUpgradeable = profile.proxy !== null;\n        let upgradeFindings = [];\n        if (isUpgradeable) {\n            try {\n                const diff = await this.compareVersions(tokenAddress, { blockchain });\n                if (diff.changes.length > 0) {\n                    upgradeFindings.push({\n                        severity: 'medium',\n                        category: 'upgradeability',\n                        description: `Contract was upgraded. ${diff.changes.length} changes detected between versions.`,\n                        location: null,\n                    });\n                }\n            }\n            catch {\n                // Version diff not available — still flag upgradeability\n            }\n        }\n        const allFindings = [...profile.securityFlags, ...upgradeFindings];\n        const hasOwnerControls = allFindings.some((f) => f.category === 'access-control' && f.severity !== 'info');\n        const hasMintFunction = allFindings.some((f) => f.category === 'supply');\n        const hasPauseOrBlacklist = allFindings.some((f) => f.category === 'pausability' || (f.category === 'access-control' && f.severity === 'high'));\n        // Calculate risk score\n        let riskScore = 0;\n        for (const finding of allFindings) {\n            switch (finding.severity) {\n                case 'critical':\n                    riskScore += 30;\n                    break;\n                case 'high':\n                    riskScore += 20;\n                    break;\n                case 'medium':\n                    riskScore += 10;\n                    break;\n                case 'low':\n                    riskScore += 3;\n                    break;\n                case 'info':\n                    riskScore += 0;\n                    break;\n            }\n        }\n        // Bonus risk factors\n        if (!profile.verified)\n            riskScore += 25;\n        if (isUpgradeable)\n            riskScore += 10;\n        riskScore = Math.min(100, riskScore);\n        const riskLevel = riskScore >= 70 ? 'critical'\n            : riskScore >= 50 ? 'high'\n                : riskScore >= 30 ? 'medium'\n                    : riskScore >= 10 ? 'low'\n                        : 'safe';\n        const checksPerformed = [\n            'Contract verification status',\n            'Source code pattern analysis',\n            'Proxy/upgrade detection',\n            'Owner privilege scan',\n            'Mint function check',\n            'Pause/blacklist check',\n        ];\n        if (isUpgradeable)\n            checksPerformed.push('Implementation version diff');\n        return {\n            riskScore,\n            riskLevel,\n            contract: profile,\n            findings: allFindings,\n            checksPerformed,\n            isUpgradeable,\n            hasOwnerControls,\n            hasMintFunction,\n            hasPauseOrBlacklist,\n            auditedAt: new Date().toISOString(),\n        };\n    }\n    // -----------------------------------------------------------------------\n    // Composed Validation: Swap Route\n    // -----------------------------------------------------------------------\n    /**\n     * Validate a swap route by comparing our on-chain quote against\n     * historical execution data from Herd.\n     *\n     * Answers: \"Is our quote reasonable? What did recent swaps actually get?\"\n     */\n    async validateSwapRoute(tokenIn, tokenOut, amountIn, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        // Find recent swap txs via Herd\n        const recentSwaps = await this.callToolSafe('getLatestTransactionsTool', {\n            contractAddress: tokenIn,\n            type: 'event',\n            // Transfer event signature\n            signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',\n            blockchain,\n        });\n        // Try to get our own quote\n        let ourQuote = null;\n        if (this.publicClient) {\n            try {\n                const { UniswapQuoter } = await import('./uniswap-quoter.js');\n                const quoter = new UniswapQuoter({\n                    publicClient: this.publicClient,\n                    network: this.network,\n                });\n                // Use quoteClawnchToken for Clawncher tokens\n                const amountRaw = BigInt(Math.floor(parseFloat(amountIn) * 1e18));\n                const quote = await quoter.quoteClawnchToken(tokenIn, amountRaw, 'sell');\n                if (quote) {\n                    ourQuote = {\n                        amountOut: quote.quotedAmount.toString(),\n                        priceImpact: String(quote.priceImpact ?? '0'),\n                    };\n                }\n            }\n            catch {\n                // Quote unavailable — that's fine, validation still works with historical data\n            }\n        }\n        const historicalSwaps = this.extractHistoricalSwaps(recentSwaps);\n        // Compare\n        const analysis = this.analyzeSwapValidation(ourQuote, historicalSwaps, amountIn);\n        return {\n            tokenIn: tokenIn,\n            tokenOut: tokenOut,\n            amountIn,\n            blockchain,\n            ourQuote,\n            historicalSwaps,\n            analysis,\n        };\n    }\n    // -----------------------------------------------------------------------\n    // Composed Validation: Fee Claim\n    // -----------------------------------------------------------------------\n    /**\n     * Validate fee claim expectations against historical on-chain data.\n     *\n     * Looks up recent claimFees txs on our FeeLocker, decodes actual gas\n     * costs and outcomes, and compares with our ClawnchReader estimate.\n     */\n    async validateFeeClaim(tokenAddress, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        const feeLockerAddr = this.addresses.clawnch.feeLocker;\n        // Look up recent interactions with our FeeLocker\n        const recentTxs = await this.callToolSafe('getTransactionActivityTool', {\n            fromAddress: feeLockerAddr,\n            blockchain,\n        });\n        // Get our estimate (requires a wallet address to check fees for)\n        // The caller can provide a wallet via options; otherwise we skip our estimate\n        let ourEstimate = null;\n        // Our reader's getAvailableFees requires both wallet+token.\n        // At this layer we don't know the wallet — callers with a wallet\n        // should use ClawnchReader.getAvailableFees directly and pass results here.\n        // The Herd historical data is the primary value of this method.\n        const historicalClaims = this.extractHistoricalClaims(recentTxs);\n        const analysis = this.analyzeFeeClaimValidation(ourEstimate, historicalClaims);\n        return {\n            tokenAddress: tokenAddress,\n            blockchain,\n            ourEstimate,\n            historicalClaims,\n            analysis,\n        };\n    }\n    // -----------------------------------------------------------------------\n    // Composed: Counterparty Profile\n    // -----------------------------------------------------------------------\n    /**\n     * Profile a counterparty wallet before interacting.\n     *\n     * Combines wallet overview, transaction history, deployed contracts,\n     * and derives a trust assessment.\n     */\n    async profileCounterparty(address, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        // Get full wallet profile + deployments in parallel\n        const [wallet, deployedRaw] = await Promise.all([\n            this.investigateWallet(address, { blockchain, includeActivity: true }),\n            this.callToolSafe('getDeployedContractsTool', {\n                deployerAddress: address,\n                blockchain,\n            }),\n        ]);\n        const deployedContracts = this.extractDeployedContracts(deployedRaw);\n        // Calculate wallet age\n        const walletAge = wallet.activity.firstTransaction\n            ? this.calculateAge(wallet.activity.firstTransaction)\n            : null;\n        // Risk assessment\n        const riskAssessment = this.assessCounterpartyRisk(wallet, walletAge, deployedContracts);\n        return {\n            wallet,\n            walletAge,\n            deployedContracts,\n            riskAssessment,\n        };\n    }\n    // -----------------------------------------------------------------------\n    // Deploy Target Validation\n    // -----------------------------------------------------------------------\n    /**\n     * Validate a factory contract before deploying through it.\n     * Checks metadata, recent successful deploys, and source code.\n     */\n    async validateDeployTarget(factoryAddress, options = {}) {\n        const blockchain = options.blockchain || this.blockchain;\n        const addr = factoryAddress || this.addresses.clawnch.factory;\n        const [factory, recentTxs] = await Promise.all([\n            this.investigateContract(addr, { blockchain }),\n            this.callToolSafe('getLatestTransactionsTool', {\n                contractAddress: addr,\n                type: 'function',\n                signature: '0x00000000',\n                blockchain,\n            }),\n        ]);\n        const warnings = [];\n        if (!factory.verified) {\n            warnings.push('Factory contract source code is not verified');\n        }\n        if (factory.proxy) {\n            warnings.push('Factory is a proxy contract — implementation could be changed');\n        }\n        if (factory.securityFlags.some((f) => f.severity === 'critical')) {\n            warnings.push('Critical security patterns detected in factory code');\n        }\n        const recentDeploys = Array.isArray(recentTxs) ? recentTxs.length : 0;\n        return {\n            factory,\n            recentDeploys,\n            warnings,\n            safe: warnings.length === 0,\n        };\n    }\n    // -----------------------------------------------------------------------\n    // Bookmarks\n    // -----------------------------------------------------------------------\n    /**\n     * Get all bookmarks for the authenticated user.\n     */\n    async getBookmarks() {\n        const cacheKey = 'bookmarks:all';\n        const cached = this.cache.get(cacheKey);\n        if (cached)\n            return cached;\n        const result = await this.callToolSafe('getBookmarksTool', {});\n        const bookmarks = this.parseBookmarks(result);\n        this.cache.set(cacheKey, bookmarks, this.cacheTtl.bookmarks);\n        return bookmarks;\n    }\n    /**\n     * Add or update a bookmark.\n     */\n    async bookmark(objectType, objectId, label, blockchain) {\n        await this.mcp.callTool('updateBookmarksTool', {\n            operation: 'add',\n            objectType,\n            objectId,\n            ...(blockchain && { blockchain }),\n            ...(label && { userLabel: label }),\n        });\n        // Invalidate cache\n        this.cache.set('bookmarks:all', null, 0);\n    }\n    /**\n     * Remove a bookmark.\n     */\n    async removeBookmark(objectType, objectId, blockchain) {\n        await this.mcp.callTool('updateBookmarksTool', {\n            operation: 'remove',\n            objectType,\n            objectId,\n            ...(blockchain && { blockchain }),\n        });\n        this.cache.set('bookmarks:all', null, 0);\n    }\n    /**\n     * Clear the in-memory cache.\n     */\n    clearCache() {\n        this.cache.clear();\n    }\n    // =======================================================================\n    // Private: MCP Call Helpers\n    // =======================================================================\n    /**\n     * Call a Herd tool with retry and graceful error handling.\n     * Returns null instead of throwing on non-critical failures.\n     * Logs warnings on transient failures so callers can distinguish\n     * \"no data\" from \"Herd unreachable\".\n     */\n    async callToolSafe(toolName, args) {\n        try {\n            return await withRetry(() => this.mcp.callTool(toolName, args), 1, // 1 retry = 2 total attempts\n            2000);\n        }\n        catch (err) {\n            // For auth/feature errors, rethrow — caller should handle\n            if (err instanceof ClawnchDeployError &&\n                err.code === ClawnchErrorCode.FEATURE_NOT_AVAILABLE) {\n                throw err;\n            }\n            // For network/timeout errors, log and return null — caller degrades gracefully\n            const msg = err instanceof Error ? err.message : String(err);\n            console.warn(`[herd] ${toolName} failed after retries: ${msg}`);\n            return null;\n        }\n    }\n    // =======================================================================\n    // Private: Profile Builders\n    // =======================================================================\n    buildContractProfile(address, blockchain, herdMeta, clawncherOverlay, securityFlags) {\n        const meta = (herdMeta || {});\n        const functions = [];\n        const events = [];\n        // Parse Herd's ABI data\n        if (meta.abi && Array.isArray(meta.abi)) {\n            for (const item of meta.abi) {\n                if (item.type === 'function') {\n                    functions.push({\n                        name: item.name || 'unknown',\n                        type: item.stateMutability === 'view' || item.stateMutability === 'pure' ? 'read' : 'write',\n                        description: item.description || null,\n                        selector: item.selector || '',\n                        inputs: (item.inputs || []).map((i) => ({ name: i.name, type: i.type })),\n                        outputs: (item.outputs || []).map((o) => ({ name: o.name, type: o.type })),\n                    });\n                }\n                else if (item.type === 'event') {\n                    events.push({\n                        name: item.name || 'unknown',\n                        description: item.description || null,\n                        signature: item.signature || '',\n                        inputs: (item.inputs || []).map((i) => ({\n                            name: i.name,\n                            type: i.type,\n                            indexed: i.indexed,\n                        })),\n                    });\n                }\n            }\n        }\n        // Parse functions/events from Herd's summary format if ABI not available\n        if (functions.length === 0 && meta.functions) {\n            const fns = Array.isArray(meta.functions) ? meta.functions : [];\n            for (const fn of fns) {\n                functions.push({\n                    name: fn.name || fn.functionName || 'unknown',\n                    type: fn.type === 'read' || fn.stateMutability === 'view' ? 'read' : 'write',\n                    description: fn.description || fn.summary || null,\n                    selector: fn.selector || fn.signature || '',\n                    inputs: fn.inputs || [],\n                    outputs: fn.outputs || [],\n                });\n            }\n        }\n        // Proxy info\n        let proxy = null;\n        if (meta.proxy || meta.proxyType || meta.implementation) {\n            proxy = {\n                proxyType: meta.proxyType || meta.proxy?.type || 'Unknown',\n                currentImplementation: (meta.implementation || meta.proxy?.currentImplementation || '0x0'),\n                previousImplementations: (meta.previousImplementations || meta.proxy?.history || []).map((impl) => ({\n                    address: (impl.address || impl),\n                    upgradedAtBlock: impl.block || impl.upgradedAtBlock || undefined,\n                })),\n            };\n        }\n        // Token data\n        let token = null;\n        if (meta.token || meta.tokenData || meta.symbol) {\n            const td = meta.token || meta.tokenData || meta;\n            token = {\n                symbol: td.symbol || meta.symbol || '',\n                decimals: td.decimals || meta.decimals || 18,\n                priceUsd: td.priceUsd || td.price || null,\n                volume24h: td.volume24h || td.volume || null,\n                marketCap: td.marketCap || null,\n                holders: td.holders || null,\n            };\n        }\n        return {\n            address,\n            blockchain,\n            name: meta.name || meta.contractName || null,\n            verified: meta.verified ?? meta.isVerified ?? true,\n            compiler: meta.compiler || meta.compilerVersion || null,\n            protocol: meta.protocol || meta.label || null,\n            functions,\n            events,\n            proxy,\n            token,\n            clawncher: clawncherOverlay,\n            securityFlags,\n            _raw: herdMeta,\n        };\n    }\n    buildTransactionProfile(txHash, blockchain, herdTx) {\n        const tx = (herdTx || {});\n        // Parse balance changes\n        const balanceChanges = (tx.balanceChanges || tx.transfers || []).map((bc) => ({\n            token: bc.token || bc.symbol || 'Unknown',\n            tokenAddress: (bc.tokenAddress || bc.address || '0x0'),\n            from: (bc.from || '0x0'),\n            to: (bc.to || '0x0'),\n            amount: String(bc.amount || bc.value || '0'),\n            usdValue: bc.usdValue ? String(bc.usdValue) : null,\n        }));\n        // Parse traces\n        const traces = this.parseTraces(tx.traces || tx.trace || []);\n        // Parse events\n        const events = (tx.events || tx.logs || []).map((e) => ({\n            contract: (e.contract || e.address || '0x0'),\n            contractName: e.contractName || e.name || null,\n            eventName: e.eventName || e.event || 'Unknown',\n            args: e.args || e.data || {},\n        }));\n        // Gas info\n        const gas = {\n            gasUsed: tx.gasUsed || tx.gas?.used || 0,\n            gasPrice: tx.gasPrice || tx.gas?.price || '0',\n            costEth: tx.gasCostEth || tx.gas?.costEth || '0',\n            costUsd: tx.gasCostUsd || tx.gas?.costUsd || null,\n        };\n        // Clawncher annotation\n        const annotation = this.annotateTransaction(tx, balanceChanges);\n        return {\n            hash: txHash,\n            blockchain,\n            blockNumber: tx.blockNumber || tx.block || 0,\n            timestamp: tx.timestamp || new Date().toISOString(),\n            success: tx.status !== false && tx.status !== 'failed' && tx.status !== 0,\n            revertReason: tx.revertReason || tx.error || null,\n            functionCalled: tx.functionName || tx.function || tx.method || null,\n            decodedArgs: tx.decodedArgs || tx.args || tx.input || null,\n            balanceChanges,\n            traces,\n            events,\n            gas,\n            clawncher: annotation,\n            _raw: herdTx,\n        };\n    }\n    buildWalletProfile(address, blockchain, herdOverview, herdActivity, clawncherOverlay) {\n        const overview = (herdOverview || {});\n        const activity = (herdActivity || {});\n        // Parse wallet type\n        const typeStr = (overview.walletType || overview.type || 'eoa').toLowerCase();\n        const walletType = typeStr.includes('4337')\n            ? 'erc4337'\n            : typeStr.includes('7702')\n                ? 'erc7702'\n                : typeStr.includes('multisig') || typeStr.includes('safe')\n                    ? 'multisig'\n                    : typeStr.includes('contract')\n                        ? 'contract'\n                        : 'eoa';\n        // Parse holdings\n        const holdings = (overview.balances || overview.holdings || overview.tokens || []).map((h) => ({\n            token: h.symbol || h.token || 'Unknown',\n            tokenAddress: (h.tokenAddress || h.address || '0x0'),\n            balance: String(h.balance || h.amount || '0'),\n            usdValue: h.usdValue || h.value || null,\n        }));\n        // Total value\n        const totalValueUsd = overview.totalValue || overview.totalPortfolioValue || null;\n        // Multisig info\n        let multisig = null;\n        if (walletType === 'multisig' && (overview.multisig || overview.signers)) {\n            const ms = overview.multisig || overview;\n            multisig = {\n                threshold: ms.threshold || 0,\n                signers: (ms.signers || []).map((s) => (typeof s === 'string' ? s : s.address)),\n                pendingTransactions: ms.pendingTransactions || ms.pending || 0,\n            };\n        }\n        // Activity summary\n        const walletActivity = {\n            transactionCount: overview.transactionCount || overview.txCount || activity.total || 0,\n            contractsDeployed: overview.contractsDeployed || 0,\n            firstTransaction: overview.firstTransaction || overview.firstTx || null,\n            topContracts: (overview.topContracts || activity.topContracts || []).map((c) => ({\n                address: (c.address || '0x0'),\n                name: c.name || c.contractName || null,\n                callCount: c.callCount || c.count || 0,\n            })),\n        };\n        return {\n            address,\n            blockchain,\n            walletType,\n            holdings,\n            totalValueUsd,\n            activity: walletActivity,\n            multisig,\n            clawncher: clawncherOverlay,\n            _raw: herdOverview,\n        };\n    }\n    buildRelationships(address, blockchain, latestTxs, deployed) {\n        const txs = (latestTxs || []);\n        const deps = (deployed || []);\n        // Extract unique contracts from transactions\n        const callerMap = new Map();\n        const calleeMap = new Map();\n        if (Array.isArray(txs)) {\n            for (const tx of txs) {\n                const from = (tx.from || tx.sender || '').toLowerCase();\n                const to = (tx.to || tx.recipient || '').toLowerCase();\n                const fn = tx.functionName || tx.function || 'unknown';\n                if (from && from !== address.toLowerCase()) {\n                    const existing = callerMap.get(from);\n                    if (existing) {\n                        existing.callCount++;\n                        if (!existing.functions.includes(fn))\n                            existing.functions.push(fn);\n                    }\n                    else {\n                        callerMap.set(from, {\n                            address: from,\n                            name: tx.fromName || tx.senderName || null,\n                            protocol: tx.fromProtocol || null,\n                            functions: [fn],\n                            callCount: 1,\n                            isClawncher: this.knownAddresses.has(from),\n                        });\n                    }\n                }\n                if (to && to !== address.toLowerCase()) {\n                    const existing = calleeMap.get(to);\n                    if (existing) {\n                        existing.callCount++;\n                        if (!existing.functions.includes(fn))\n                            existing.functions.push(fn);\n                    }\n                    else {\n                        calleeMap.set(to, {\n                            address: to,\n                            name: tx.toName || tx.recipientName || null,\n                            protocol: tx.toProtocol || null,\n                            functions: [fn],\n                            callCount: 1,\n                            isClawncher: this.knownAddresses.has(to),\n                        });\n                    }\n                }\n            }\n        }\n        // Extract deployed contracts\n        const deployedContracts = (Array.isArray(deps) ? deps : []).map((d) => ({\n            address: (d.address || d.contractAddress || '0x0'),\n            name: d.name || d.contractName || null,\n            protocol: d.protocol || null,\n            functions: [],\n            callCount: 0,\n            isClawncher: this.knownAddresses.has((d.address || d.contractAddress || '').toLowerCase()),\n        }));\n        // Identify which related addresses are Clawncher contracts\n        const clawncherContracts = [\n            ...Array.from(callerMap.values()),\n            ...Array.from(calleeMap.values()),\n            ...deployedContracts,\n        ]\n            .filter((c) => c.isClawncher)\n            .map((c) => c.address);\n        return {\n            contract: address,\n            contractName: null,\n            blockchain,\n            callers: Array.from(callerMap.values()),\n            callees: Array.from(calleeMap.values()),\n            deployed: deployedContracts,\n            clawncherContracts: Array.from(new Set(clawncherContracts)),\n        };\n    }\n    buildTokenFlowReport(holder, token, blockchain, herdActivity) {\n        const activity = (herdActivity || {});\n        const transfers = (activity.transfers || activity.history || []).map((t) => ({\n            txHash: t.txHash || t.transactionHash || '',\n            timestamp: t.timestamp || t.date || '',\n            direction: (t.direction || (t.from?.toLowerCase() === holder.toLowerCase() ? 'out' : 'in')),\n            amount: String(t.amount || t.value || '0'),\n            counterparty: (t.direction === 'in' || t.from?.toLowerCase() === holder.toLowerCase()\n                ? t.to || t.counterparty\n                : t.from || t.counterparty),\n            counterpartyName: t.counterpartyName || t.toName || t.fromName || null,\n            usdValue: t.usdValue ? String(t.usdValue) : null,\n        }));\n        // Annotate transfers with known contract labels\n        const annotations = [];\n        transfers.forEach((transfer, index) => {\n            const counterpartyLower = transfer.counterparty?.toLowerCase();\n            if (!counterpartyLower)\n                return;\n            if (counterpartyLower === this.addresses.clawnch.feeLocker.toLowerCase()) {\n                annotations.push({ transferIndices: [index], label: 'FeeLocker claim' });\n            }\n            else if (counterpartyLower === this.addresses.clawnch.vault.toLowerCase()) {\n                annotations.push({ transferIndices: [index], label: 'Vault claim' });\n            }\n            else if (counterpartyLower === this.addresses.clawnch.locker.toLowerCase()) {\n                annotations.push({ transferIndices: [index], label: 'LP Locker interaction' });\n            }\n            else if (counterpartyLower === this.addresses.infrastructure.poolManager.toLowerCase()) {\n                annotations.push({ transferIndices: [index], label: 'Uniswap V4 swap' });\n            }\n            else if (counterpartyLower === this.addresses.infrastructure.positionManager.toLowerCase()) {\n                annotations.push({ transferIndices: [index], label: 'Uniswap V4 liquidity' });\n            }\n        });\n        return {\n            holder,\n            token,\n            tokenSymbol: activity.tokenSymbol || activity.symbol || 'Unknown',\n            blockchain,\n            currentBalance: String(activity.balance || activity.currentBalance || '0'),\n            transfers,\n            annotations,\n        };\n    }\n    buildVersionDiff(address, blockchain, meta, diff) {\n        const metaObj = (meta || {});\n        const diffObj = (diff || {});\n        const changes = (diffObj.changes || []).map((c) => ({\n            type: c.type || 'modified',\n            name: c.name || c.functionName || 'unknown',\n            description: c.description || c.summary || '',\n        }));\n        return {\n            contract: address,\n            blockchain,\n            previousVersion: (diffObj.previousVersion || diffObj.oldImplementation || metaObj.proxy?.previousImplementation || '0x0'),\n            currentVersion: (diffObj.currentVersion || diffObj.newImplementation || metaObj.implementation || '0x0'),\n            changes,\n            rawDiff: diffObj.rawDiff || diffObj.diff || null,\n        };\n    }\n    // =======================================================================\n    // Private: Clawncher Data Overlay\n    // =======================================================================\n    async getClawncherOverlay(address) {\n        if (!this.reader)\n            return null;\n        try {\n            const details = await this.reader.getTokenDetails(address);\n            if (!details)\n                return null;\n            return {\n                feesWeth: '0', // Reader doesn't directly return fees — portfolio does\n                feesToken: '0',\n                vaultStatus: details.vault\n                    ? details.vault.isFullyVested\n                        ? 'unlocked'\n                        : details.vault.isUnlocked\n                            ? 'vesting'\n                            : 'locked'\n                    : 'none',\n                vaultPercentVested: details.vault ? details.vault.percentVested : null,\n                mevProtection: details.mev !== null,\n                mevMaxBps: details.mev ? details.mev.startingFee : null,\n                launchedAt: null, // Not available from reader — from API\n                agent: null,\n            };\n        }\n        catch {\n            return null;\n        }\n    }\n    async getClawncherWalletOverlay(address) {\n        if (!this.publicClient)\n            return null;\n        try {\n            // Check if the wallet has a $CLAWNCH token balance as a quick signal\n            // Full portfolio scan requires a known token list, which we don't have here.\n            // Callers with specific tokens can use ClawnchPortfolio.getTokensForWallet() directly.\n            const clawnchTokenAddr = '0xa1F72459dfA10BAD200Ac160eCd78C6b77a747be';\n            const balance = await this.publicClient.readContract({\n                address: clawnchTokenAddr,\n                abi: [{\n                        type: 'function',\n                        name: 'balanceOf',\n                        inputs: [{ name: 'account', type: 'address' }],\n                        outputs: [{ name: '', type: 'uint256' }],\n                        stateMutability: 'view',\n                    }],\n                functionName: 'balanceOf',\n                args: [address],\n            });\n            const hasClawnch = balance > BigInt(0);\n            return {\n                tokenPositions: hasClawnch\n                    ? [{\n                            tokenAddress: clawnchTokenAddr,\n                            symbol: 'CLAWNCH',\n                            balance: formatUnits(balance, 18),\n                            claimableFees: null,\n                        }]\n                    : [],\n                isRegisteredAgent: false, // Would need API call to check\n            };\n        }\n        catch {\n            return null;\n        }\n    }\n    // =======================================================================\n    // Private: Security Analysis\n    // =======================================================================\n    async analyzeContractSecurity(address, blockchain) {\n        const flags = [];\n        for (const pattern of SECURITY_PATTERNS) {\n            try {\n                const result = await this.callToolSafe('regexCodeAnalysisTool', {\n                    query: pattern.pattern,\n                    contractAddresses: [address],\n                    includeProxies: false,\n                    returnAllCode: false,\n                });\n                // If we got results back, the pattern was found\n                if (result && typeof result === 'string' && result.trim().length > 0) {\n                    // Check if it's a \"0 matches\" response\n                    if (result.includes('0 match') || result.includes('no match')) {\n                        continue;\n                    }\n                    flags.push({\n                        severity: pattern.severity,\n                        category: pattern.category,\n                        description: pattern.description,\n                        location: null, // Could parse line numbers from result\n                    });\n                }\n                else if (result && typeof result === 'object') {\n                    const r = result;\n                    if (r.matches && r.matches.length > 0) {\n                        flags.push({\n                            severity: pattern.severity,\n                            category: pattern.category,\n                            description: pattern.description,\n                            location: r.matches[0]?.location || null,\n                        });\n                    }\n                }\n            }\n            catch {\n                // Pattern search failed — skip\n            }\n        }\n        return flags;\n    }\n    // =======================================================================\n    // Private: Transaction Helpers\n    // =======================================================================\n    parseTraces(raw) {\n        if (!Array.isArray(raw))\n            return [];\n        return raw.map((t) => ({\n            depth: t.depth || 0,\n            from: (t.from || '0x0'),\n            to: (t.to || '0x0'),\n            functionName: t.functionName || t.function || null,\n            summary: t.summary || null,\n            value: String(t.value || '0'),\n            gasUsed: t.gasUsed || 0,\n            children: this.parseTraces(t.children || t.calls || []),\n        }));\n    }\n    annotateTransaction(tx, balanceChanges) {\n        const toAddr = (tx.to || '').toLowerCase();\n        const funcName = (tx.functionName || tx.function || '').toLowerCase();\n        // Check if any address in the tx touches our contracts\n        const touchesClawncher = this.knownAddresses.has(toAddr) ||\n            balanceChanges.some((bc) => this.knownAddresses.has(bc.from.toLowerCase()) ||\n                this.knownAddresses.has(bc.to.toLowerCase()));\n        if (!touchesClawncher)\n            return null;\n        // Determine operation type\n        let operationType = 'other';\n        let description = 'Interacts with Clawncher infrastructure';\n        let tokenAddress = null;\n        if (toAddr === this.addresses.clawnch.factory.toLowerCase()) {\n            if (funcName.includes('deploy') || funcName.includes('create')) {\n                operationType = 'token_deploy';\n                description = 'Token deployment via Clawncher factory';\n            }\n        }\n        else if (toAddr === this.addresses.clawnch.feeLocker.toLowerCase()) {\n            operationType = 'fee_claim';\n            description = 'Fee claim from FeeLocker';\n        }\n        else if (toAddr === this.addresses.clawnch.vault.toLowerCase()) {\n            operationType = 'vault_claim';\n            description = 'Vault token claim';\n        }\n        else if (toAddr === this.addresses.infrastructure.poolManager.toLowerCase() ||\n            funcName.includes('swap')) {\n            operationType = 'swap';\n            description = 'Token swap via Uniswap V4';\n        }\n        else if (toAddr === this.addresses.infrastructure.positionManager.toLowerCase()) {\n            if (funcName.includes('mint') || funcName.includes('increase')) {\n                operationType = 'liquidity_add';\n                description = 'Liquidity added to Uniswap V4';\n            }\n            else if (funcName.includes('decrease') || funcName.includes('burn')) {\n                operationType = 'liquidity_remove';\n                description = 'Liquidity removed from Uniswap V4';\n            }\n        }\n        else if (toAddr === this.addresses.infrastructure.permit2.toLowerCase()) {\n            operationType = 'permit2_approve';\n            description = 'Permit2 token approval';\n        }\n        return { operationType, description, tokenAddress };\n    }\n    // =======================================================================\n    // Private: Validation Helpers\n    // =======================================================================\n    extractHistoricalSwaps(raw) {\n        if (!raw || !Array.isArray(raw))\n            return [];\n        return raw.slice(0, 10).map((tx) => ({\n            txHash: tx.txHash || tx.hash || '',\n            timestamp: tx.timestamp || '',\n            amountIn: String(tx.amountIn || tx.amount || '0'),\n            amountOut: String(tx.amountOut || '0'),\n            effectiveRate: String(tx.effectiveRate || tx.rate || '0'),\n            gasUsed: tx.gasUsed || 0,\n        }));\n    }\n    analyzeSwapValidation(ourQuote, historicalSwaps, amountIn) {\n        const warnings = [];\n        if (historicalSwaps.length === 0) {\n            warnings.push('No historical swap data available for comparison');\n            return {\n                quoteReasonable: ourQuote !== null,\n                deviationPercent: null,\n                warnings,\n                recommendation: ourQuote ? 'caution' : 'abort',\n            };\n        }\n        // Calculate median historical rate\n        const rates = historicalSwaps\n            .map((s) => parseFloat(s.effectiveRate))\n            .filter((r) => r > 0);\n        if (rates.length === 0 || !ourQuote) {\n            return {\n                quoteReasonable: false,\n                deviationPercent: null,\n                warnings: [...warnings, 'Unable to compare rates'],\n                recommendation: 'caution',\n            };\n        }\n        rates.sort((a, b) => a - b);\n        const medianRate = rates[Math.floor(rates.length / 2)];\n        const ourRate = parseFloat(ourQuote.amountOut) / parseFloat(amountIn);\n        const deviation = ((ourRate - medianRate) / medianRate) * 100;\n        const deviationAbs = Math.abs(deviation);\n        if (deviationAbs > 10) {\n            warnings.push(`Quote deviates ${deviationAbs.toFixed(1)}% from recent median rate`);\n        }\n        const priceImpact = parseFloat(ourQuote.priceImpact);\n        if (priceImpact > 5) {\n            warnings.push(`High price impact: ${priceImpact.toFixed(2)}%`);\n        }\n        const quoteReasonable = deviationAbs <= 15 && priceImpact <= 10;\n        const recommendation = deviationAbs > 20 || priceImpact > 15\n            ? 'abort'\n            : deviationAbs > 10 || priceImpact > 5\n                ? 'caution'\n                : 'proceed';\n        return {\n            quoteReasonable,\n            deviationPercent: parseFloat(deviation.toFixed(2)),\n            warnings,\n            recommendation,\n        };\n    }\n    extractHistoricalClaims(raw) {\n        if (!raw || !Array.isArray(raw))\n            return [];\n        return raw\n            .filter((tx) => {\n            const fn = (tx.functionName || tx.function || '').toLowerCase();\n            return fn.includes('claim') || fn.includes('collect');\n        })\n            .slice(0, 10)\n            .map((tx) => ({\n            txHash: tx.txHash || tx.hash || '',\n            timestamp: tx.timestamp || '',\n            claimer: (tx.from || tx.sender || '0x0'),\n            wethReceived: String(tx.wethReceived || '0'),\n            tokenReceived: String(tx.tokenReceived || '0'),\n            gasCostEth: String(tx.gasCost || tx.gasCostEth || '0'),\n        }));\n    }\n    analyzeFeeClaimValidation(ourEstimate, historicalClaims) {\n        const warnings = [];\n        if (historicalClaims.length === 0) {\n            warnings.push('No historical claim data available for comparison');\n            return {\n                estimateReliable: ourEstimate !== null,\n                avgGasCostEth: null,\n                estimatedNetProfitEth: null,\n                warnings,\n            };\n        }\n        // Average gas cost\n        const gasCosts = historicalClaims\n            .map((c) => parseFloat(c.gasCostEth))\n            .filter((g) => g > 0);\n        const avgGas = gasCosts.length > 0\n            ? gasCosts.reduce((sum, g) => sum + g, 0) / gasCosts.length\n            : null;\n        // Net profit estimate\n        let estimatedNetProfitEth = null;\n        if (ourEstimate && avgGas !== null) {\n            const wethFees = parseFloat(ourEstimate.wethAvailable);\n            estimatedNetProfitEth = (wethFees - avgGas).toFixed(6);\n            if (wethFees - avgGas < 0) {\n                warnings.push('Fee claim would cost more in gas than it yields');\n            }\n        }\n        return {\n            estimateReliable: ourEstimate !== null,\n            avgGasCostEth: avgGas ? avgGas.toFixed(6) : null,\n            estimatedNetProfitEth,\n            warnings,\n        };\n    }\n    // =======================================================================\n    // Private: Counterparty Helpers\n    // =======================================================================\n    extractDeployedContracts(raw) {\n        if (!raw || !Array.isArray(raw))\n            return [];\n        return raw.map((d) => ({\n            address: (d.address || d.contractAddress || '0x0'),\n            name: d.name || d.contractName || null,\n            verified: d.verified ?? d.isVerified ?? false,\n        }));\n    }\n    assessCounterpartyRisk(wallet, walletAge, deployedContracts) {\n        const factors = [];\n        // Age-based assessment\n        let trustLevel = 'moderate';\n        if (walletAge) {\n            if (walletAge.includes('year')) {\n                trustLevel = 'established';\n                factors.push(`Wallet is ${walletAge} old`);\n            }\n            else if (walletAge.includes('month')) {\n                trustLevel = 'moderate';\n                factors.push(`Wallet is ${walletAge} old`);\n            }\n            else {\n                trustLevel = 'new';\n                factors.push(`Wallet is relatively new (${walletAge})`);\n            }\n        }\n        else {\n            trustLevel = 'new';\n            factors.push('Unable to determine wallet age');\n        }\n        // Transaction count\n        if (wallet.activity.transactionCount > 1000) {\n            factors.push(`High activity: ${wallet.activity.transactionCount} transactions`);\n        }\n        else if (wallet.activity.transactionCount < 10) {\n            trustLevel = wallet.activity.transactionCount < 3 ? 'suspicious' : 'new';\n            factors.push(`Low activity: only ${wallet.activity.transactionCount} transactions`);\n        }\n        // Wallet type\n        if (wallet.walletType === 'multisig') {\n            factors.push('Uses a multisig wallet (higher security)');\n            if (trustLevel !== 'established')\n                trustLevel = 'moderate';\n        }\n        // Deployed contracts\n        if (deployedContracts.length > 0) {\n            const verifiedCount = deployedContracts.filter((c) => c.verified).length;\n            factors.push(`Deployed ${deployedContracts.length} contracts (${verifiedCount} verified)`);\n        }\n        // Portfolio value\n        if (wallet.totalValueUsd !== null && wallet.totalValueUsd > 100000) {\n            factors.push(`Significant portfolio value: $${wallet.totalValueUsd.toLocaleString()}`);\n        }\n        return { trustLevel, factors };\n    }\n    calculateAge(firstTransactionDate) {\n        const first = new Date(firstTransactionDate);\n        const now = new Date();\n        const diffMs = now.getTime() - first.getTime();\n        const days = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n        if (days >= 365) {\n            const years = Math.floor(days / 365);\n            const months = Math.floor((days % 365) / 30);\n            return months > 0 ? `${years} year${years > 1 ? 's' : ''}, ${months} month${months > 1 ? 's' : ''}` : `${years} year${years > 1 ? 's' : ''}`;\n        }\n        else if (days >= 30) {\n            const months = Math.floor(days / 30);\n            return `${months} month${months > 1 ? 's' : ''}`;\n        }\n        else {\n            return `${days} day${days !== 1 ? 's' : ''}`;\n        }\n    }\n    // =======================================================================\n    // Private: Bookmark Helpers\n    // =======================================================================\n    parseBookmarks(raw) {\n        if (!raw || typeof raw !== 'object')\n            return [];\n        const data = raw;\n        const bookmarks = [];\n        // Herd groups bookmarks by type\n        for (const type of ['contract', 'wallet', 'transaction']) {\n            const items = data[type + 's'] || data[type] || [];\n            if (Array.isArray(items)) {\n                for (const item of items) {\n                    bookmarks.push({\n                        objectType: type,\n                        objectId: item.address || item.hash || item.id || '',\n                        blockchain: item.blockchain || null,\n                        label: item.label || item.name || null,\n                    });\n                }\n            }\n        }\n        return bookmarks;\n    }\n}\n//# sourceMappingURL=herd.js.map","/**\n * HAL Expression Builder — Programmatic construction of Herd Action Language expressions.\n *\n * HAL (Herd Action Language) is a JSON DSL for composing blockchain transactions\n * and data reads. Instead of requiring users to hand-write the nested JSON,\n * this module provides a TypeScript builder API.\n *\n * Use cases:\n *   - Pre-simulate any transaction before sending\n *   - Generate reusable adapters for common Clawncher operations\n *   - Validate parameter types at compile time\n *\n * @example\n * ```typescript\n * const hal = new HalBuilder();\n *\n * // Build an ERC-20 transfer adapter\n * const expr = hal.buildTransferAdapter({\n *   token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n *   blockchain: 'base',\n *   decimals: 6,\n * });\n *\n * // Simulate it via Herd\n * const result = await herd.simulateAction(expr, {\n *   to: '0xRecipient...',\n *   amount: '100',\n * });\n * ```\n */\n// =========================================================================\n// Function Signatures (4-byte selectors)\n// =========================================================================\nconst SELECTORS = {\n    transfer: '0xa9059cbb', // transfer(address,uint256)\n    approve: '0x095ea7b3', // approve(address,uint256)\n    balanceOf: '0x70a08231', // balanceOf(address)\n    allowance: '0xdd62ed3e', // allowance(address,address)\n    totalSupply: '0x18160ddd', // totalSupply()\n};\n// =========================================================================\n// HAL Expression Helpers (build individual nodes)\n// =========================================================================\n/**\n * Create a [\"do\", ...] block — the top-level wrapper.\n */\nfunction doBlock(...exprs) {\n    return ['do', ...exprs];\n}\n/**\n * Create an [\"import\", module, [functions]] node.\n */\nfunction importStdlib(module, functions) {\n    return ['import', module, functions];\n}\n/**\n * Create a [\"define\", { name, parameters, body, meta? }] node.\n */\nfunction define(name, parameters, body, meta) {\n    const def = { name, parameters, body };\n    if (meta)\n        def.meta = meta;\n    return ['define', def];\n}\n/**\n * Create an [\"export\", ...] wrapper.\n */\nfunction exportExpr(expr) {\n    return ['export', expr];\n}\n/**\n * Create a [\"coerce\", { type, value }] node.\n */\nfunction coerce(type, value) {\n    return ['coerce', { type, value }];\n}\n/**\n * Create an [\"encode-calldata\", { ... }] node.\n */\nfunction encodeCalldata(params) {\n    return [\n        'encode-calldata',\n        {\n            blockchain: params.blockchain,\n            contractAddress: params.contractAddress,\n            functionSignature: params.functionSignature,\n            args: params.args,\n            inputAbi: ['quote', params.inputAbi],\n            functionName: params.functionName,\n        },\n    ];\n}\n/**\n * Create a [\"decimals\", { value, decimals }] node.\n */\nfunction decimalsExpr(value, decimals) {\n    return ['decimals', { value, decimals }];\n}\n/**\n * Create a [\"write-function\", <data>] node for use in batch steps.\n */\nfunction writeFunction(data) {\n    return ['write-function', data];\n}\n/**\n * Create a [\"read-function\", { calldata, outputAbi }] node.\n */\nfunction readFunction(calldata, outputAbi) {\n    return [\n        'read-function',\n        {\n            calldata,\n            outputAbi: ['quote', outputAbi],\n        },\n    ];\n}\n/**\n * Create a batch call data return value (for write adapters).\n */\nfunction batchCallData(payable, payableAmount, encodedCalldata) {\n    return [\n        'coerce',\n        {\n            type: {\n                payable: 'bool',\n                payableAmount: 'uint256',\n                encodedCalldata: {\n                    blockchain: 'string',\n                    contractAddress: 'address',\n                    functionSignature: 'bytes4',\n                    calldata: 'bytes',\n                },\n            },\n            value: {\n                payable,\n                payableAmount,\n                encodedCalldata,\n            },\n        },\n    ];\n}\nexport class HalBuilder {\n    /**\n     * Build a HAL adapter expression for an ERC-20 transfer.\n     *\n     * Parameters exposed to the user: `to` (address), `amount` (human-readable).\n     * The adapter handles decimal conversion and calldata encoding.\n     */\n    buildTransferAdapter(options) {\n        const decimals = options.decimals ?? 18;\n        return doBlock(importStdlib('herd', ['encode-calldata', 'decimals']), exportExpr(define('transfer', [\n            { name: 'to', type: 'address', meta: { description: 'Recipient address' } },\n            { name: 'amount', type: 'uint256', meta: { description: 'Amount (human-readable)', decimals } },\n        ], batchCallData(false, '0', encodeCalldata({\n            blockchain: options.blockchain,\n            contractAddress: options.token,\n            functionSignature: SELECTORS.transfer,\n            args: {\n                recipient: 'to',\n                value: coerce('uint256', decimalsExpr('amount', decimals)),\n            },\n            inputAbi: [\n                { name: 'recipient', type: 'address' },\n                { name: 'value', type: 'uint256' },\n            ],\n            functionName: 'transfer',\n        })), {\n            description: `Transfer ${options.tokenName || 'tokens'}`,\n            originContract: {\n                address: options.token,\n                blockchain: options.blockchain,\n                contractName: options.tokenName || 'ERC20',\n                functionName: 'transfer',\n            },\n        })));\n    }\n    /**\n     * Build a HAL action for a swap using 0x API.\n     *\n     * This generates an action with an optional approval step (conditional\n     * on whether the wallet has already approved the spender).\n     */\n    buildSwapAction(options) {\n        const includeApproval = options.includeApproval !== false;\n        const swapCall = [\n            'swap',\n            {\n                blockchain: options.blockchain,\n                sellTokenAddress: options.sellToken,\n                sellTokenAmount: 'amount',\n                buyTokenAddress: options.buyToken,\n                walletAddress: ['user-wallet'],\n                divideDecimals: false,\n            },\n        ];\n        const swapStep = writeFunction([\n            'getPath',\n            {\n                object: swapCall,\n                path: ['quote', ['swapSteps', 'swap']],\n            },\n        ]);\n        const steps = [];\n        if (includeApproval) {\n            // Conditional approval: only add if approvalRequired is true\n            steps.push([\n                'if',\n                [\n                    'getPath',\n                    {\n                        object: swapCall,\n                        path: ['quote', ['swapSteps', 'approval', 'approvalRequired']],\n                    },\n                ],\n                writeFunction([\n                    'getPath',\n                    {\n                        object: swapCall,\n                        path: ['quote', ['swapSteps', 'approval']],\n                    },\n                ]),\n                null,\n            ]);\n        }\n        steps.push(swapStep);\n        return doBlock(importStdlib('herd', ['swap', 'write-function', 'user-wallet']), importStdlib('object', ['getPath']), exportExpr(define('main', [\n            { name: 'amount', type: 'uint256', meta: { description: 'Sell amount (human-readable)' } },\n        ], [\n            define('batch0', [], steps, { isBatch: true, batchLabel: 'Swap Tokens' }),\n        ])));\n    }\n    /**\n     * Build a HAL read adapter for checking an ERC-20 balance.\n     */\n    buildBalanceReader(options) {\n        return doBlock(importStdlib('herd', ['encode-calldata', 'read-function']), exportExpr(define('checkBalance', [\n            { name: 'account', type: 'address', meta: { description: 'Wallet to check' } },\n        ], coerce({ balance: 'uint256' }, readFunction(encodeCalldata({\n            blockchain: options.blockchain,\n            contractAddress: options.token,\n            functionSignature: SELECTORS.balanceOf,\n            args: { account: 'account' },\n            inputAbi: [{ name: 'account', type: 'address' }],\n            functionName: 'balanceOf',\n        }), [{ name: 'balance', type: 'uint256' }])), {\n            description: 'Check ERC-20 token balance',\n            originContract: {\n                address: options.token,\n                blockchain: options.blockchain,\n                contractName: 'ERC20',\n                functionName: 'balanceOf',\n            },\n        })));\n    }\n    /**\n     * Build a HAL read adapter for checking allowance.\n     */\n    buildAllowanceReader(options) {\n        return doBlock(importStdlib('herd', ['encode-calldata', 'read-function']), exportExpr(define('checkAllowance', [\n            { name: 'owner', type: 'address' },\n            { name: 'spender', type: 'address' },\n        ], coerce({ remaining: 'uint256' }, readFunction(encodeCalldata({\n            blockchain: options.blockchain,\n            contractAddress: options.token,\n            functionSignature: SELECTORS.allowance,\n            args: { owner: 'owner', spender: 'spender' },\n            inputAbi: [\n                { name: 'owner', type: 'address' },\n                { name: 'spender', type: 'address' },\n            ],\n            functionName: 'allowance',\n        }), [{ name: 'remaining', type: 'uint256' }])), {\n            description: 'Check ERC-20 token allowance',\n            originContract: {\n                address: options.token,\n                blockchain: options.blockchain,\n                contractName: 'ERC20',\n                functionName: 'allowance',\n            },\n        })));\n    }\n    /**\n     * Build a HAL approve adapter.\n     */\n    buildApproveAdapter(options) {\n        const decimals = options.decimals ?? 18;\n        return doBlock(importStdlib('herd', ['encode-calldata', 'decimals']), exportExpr(define('approve', [\n            { name: 'spender', type: 'address', meta: { description: 'Spender address' } },\n            { name: 'amount', type: 'uint256', meta: { description: 'Approval amount', decimals } },\n        ], batchCallData(false, '0', encodeCalldata({\n            blockchain: options.blockchain,\n            contractAddress: options.token,\n            functionSignature: SELECTORS.approve,\n            args: {\n                spender: 'spender',\n                value: coerce('uint256', decimalsExpr('amount', decimals)),\n            },\n            inputAbi: [\n                { name: 'spender', type: 'address' },\n                { name: 'value', type: 'uint256' },\n            ],\n            functionName: 'approve',\n        })), {\n            description: `Approve ${options.tokenName || 'token'} spending`,\n            originContract: {\n                address: options.token,\n                blockchain: options.blockchain,\n                contractName: options.tokenName || 'ERC20',\n                functionName: 'approve',\n            },\n        })));\n    }\n}\n// =========================================================================\n// Simulation Result Parsing\n// =========================================================================\n/**\n * Parse a raw HAL simulation response into typed structure.\n */\nexport function parseSimulationResult(raw) {\n    const data = (raw || {});\n    const oplog = (data.entries || data.oplog || []).map((entry) => ({\n        operationId: entry.operationId || '',\n        functionName: entry.functionName || '',\n        status: entry.status || 'success',\n        timestamp: entry.timestamp || entry.timestampIso || '',\n        args: entry.args,\n        result: entry.result,\n    }));\n    return {\n        success: data.executionStatus === 'completed' || data.success === true,\n        finalResult: data.finalResult ?? data.result ?? null,\n        oplog,\n        error: data.error || null,\n    };\n}\n//# sourceMappingURL=herd-hal.js.map","/**\n * Clawncher SDK\n *\n * TypeScript SDK for deploying and managing tokens on Base with Uniswap V4 pools.\n *\n * ## Deploying Tokens (Verified Agent)\n *\n * @example\n * ```typescript\n * import { ClawnchApiDeployer } from '@clawnch/clawncher-sdk';\n *\n * const deployer = new ClawnchApiDeployer({\n *   apiKey: 'your-api-key',\n *   wallet,\n *   publicClient,\n * });\n *\n * const result = await deployer.deploy({\n *   name: 'My Token',\n *   symbol: 'MYTKN',\n * });\n * console.log('Token deployed:', result.tokenAddress);\n * ```\n *\n * ## API Client (Optional)\n *\n * @example\n * ```typescript\n * import { ClawnchClient } from '@clawnch/clawncher-sdk';\n *\n * const client = new ClawnchClient();\n *\n * // Get all tokens\n * const tokens = await client.getTokens();\n *\n * // Check available fees\n * const fees = await client.getAvailableFees('0x...');\n * ```\n */\nexport * from './types.js';\nexport * from './molten.js';\n// Structured error codes\nexport * from './errors.js';\nexport * from './addresses.js';\nexport * from './abis.js';\n// On-chain reading\nexport * from './reader.js';\n// Fee/vault claiming\nexport * from './claimer.js';\n// Bankr fee claiming (Doppler protocol)\nexport * from './bankr-fees.js';\n// Portfolio tracking\nexport * from './portfolio.js';\n// Live event watching\nexport * from './watcher.js';\n// Token swaps (0x API)\nexport * from './swap.js';\nexport * from './swap-types.js';\n// Uniswap V3/V4 liquidity management\nexport * from './liquidity.js';\nexport * from './liquidity-types.js';\nexport * from './uniswap-addresses.js';\nexport * from './uniswap-abis.js';\n// Multi-chain Uniswap registry (15+ chains)\nexport * from './uniswap-chains.js';\n// Uniswap Trading API (swap via Uniswap's hosted API)\nexport * from './uniswap-trading.js';\n// V4 Quoter (on-chain swap simulation + price impact)\nexport * from './uniswap-quoter.js';\n// Permit2 (EIP-712 signature-based token approvals)\nexport * from './permit2.js';\n// Verified agent launches (via Clawnch API)\nexport * from './api-deployer.js';\nexport * from './api-deployer-types.js';\n// On-chain price reading\nexport * from './price.js';\n// Conditional order engine\nexport * from './orders.js';\n// Trade-level portfolio tracking (cost basis, P&L, snapshots)\nexport * from './trader.js';\n// Market analytics (OHLCV candles, technical indicators)\nexport * from './analytics.js';\n// Wayfinder Paths integration (cross-chain DeFi)\nexport * from './wayfinder.js';\nexport * from './wayfinder-types.js';\n// WalletConnect signer (human-in-the-loop wallet approval)\nexport * from './walletconnect-signer.js';\n// Hummingbot market making (professional trading bots)\nexport * from './hummingbot.js';\nexport * from './hummingbot-types.js';\n// Herd on-chain intelligence (contract/tx/wallet investigation, token audits)\nexport * from './herd.js';\nexport * from './herd-types.js';\nexport * from './herd-auth.js';\nexport { HalBuilder, parseSimulationResult } from './herd-hal.js';\n// Simple validation helpers\nconst isValidAddress = (addr) => /^0x[a-fA-F0-9]{40}$/.test(addr);\nconst isValidUrl = (url) => {\n    try {\n        const parsed = new URL(url);\n        return parsed.protocol === 'https:' || parsed.protocol === 'http:';\n    }\n    catch {\n        return false;\n    }\n};\nexport class ClawnchClient {\n    baseUrl;\n    moltbookKey;\n    timeout;\n    constructor(options = {}) {\n        // Validate baseUrl if provided\n        const baseUrl = options.baseUrl || 'https://clawn.ch';\n        if (!isValidUrl(baseUrl)) {\n            throw new Error('Invalid baseUrl: must be a valid HTTP(S) URL');\n        }\n        this.baseUrl = baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n        this.moltbookKey = options.moltbookKey;\n        this.timeout = options.timeout || 30000;\n    }\n    /**\n     * Make an API request\n     */\n    async request(path, options = {}) {\n        const url = `${this.baseUrl}${path}`;\n        const headers = {\n            'Content-Type': 'application/json',\n            'Accept': 'application/json',\n            ...options.headers,\n        };\n        if (this.moltbookKey) {\n            headers['X-Moltbook-Key'] = this.moltbookKey;\n        }\n        const controller = new AbortController();\n        const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n        try {\n            const response = await fetch(url, {\n                ...options,\n                headers,\n                signal: controller.signal,\n            });\n            clearTimeout(timeoutId);\n            if (!response.ok) {\n                let errorData;\n                try {\n                    errorData = await response.json();\n                }\n                catch {\n                    errorData = { error: `HTTP ${response.status}: ${response.statusText}` };\n                }\n                throw new ClawnchError(errorData.error, response.status, errorData.errors);\n            }\n            return response.json();\n        }\n        catch (err) {\n            clearTimeout(timeoutId);\n            if (err instanceof ClawnchError) {\n                throw err;\n            }\n            if (err instanceof Error && err.name === 'AbortError') {\n                throw new ClawnchError('Request timeout', 408);\n            }\n            throw new ClawnchError(err instanceof Error ? err.message : 'Unknown error', 0);\n        }\n    }\n    // =========================================================================\n    // Token Operations (Read)\n    // =========================================================================\n    /**\n     * Get all tokens launched via Clawncher\n     */\n    async getTokens() {\n        const response = await this.request('/api/tokens');\n        return response.tokens;\n    }\n    /**\n     * Get a single token by symbol\n     */\n    async getTokenBySymbol(symbol) {\n        const response = await this.request(`/api/tokens?symbol=${encodeURIComponent(symbol)}`);\n        return response.tokens[0] || null;\n    }\n    /**\n     * Get launch history with optional filters\n     */\n    async getLaunches(filters = {}) {\n        const params = new URLSearchParams();\n        if (filters.limit)\n            params.set('limit', filters.limit.toString());\n        if (filters.offset)\n            params.set('offset', filters.offset.toString());\n        if (filters.agent)\n            params.set('agent', filters.agent);\n        if (filters.source)\n            params.set('source', filters.source);\n        if (filters.address)\n            params.set('address', filters.address);\n        const query = params.toString();\n        return this.request(`/api/launches${query ? `?${query}` : ''}`);\n    }\n    /**\n     * Get a single launch by contract address\n     */\n    async getLaunch(address) {\n        const response = await this.getLaunches({ address });\n        return response.launches[0] || null;\n    }\n    /**\n     * Get market statistics\n     */\n    async getStats() {\n        return this.request('/api/stats');\n    }\n    // =========================================================================\n    // Preview / Validation\n    // =========================================================================\n    /**\n     * Validate a launch post before publishing\n     *\n     * @param content - The full post content including !clawnch trigger\n     * @returns Validation result with parsed data, errors, and warnings\n     *\n     * @example\n     * ```typescript\n     * const result = await client.preview(`\n     * !clawnch\n     * name: My Token\n     * symbol: MYTKN\n     * wallet: 0x1234...\n     * description: A test token\n     * image: https://iili.io/example.jpg\n     * `);\n     *\n     * if (result.valid) {\n     *   console.log('Ready to post!', result.parsed);\n     * } else {\n     *   console.log('Errors:', result.errors);\n     * }\n     * ```\n     */\n    async preview(content) {\n        return this.request('/api/preview', {\n            method: 'POST',\n            body: JSON.stringify({ content }),\n        });\n    }\n    // =========================================================================\n    // Fee Operations\n    // =========================================================================\n    /**\n     * Check available fees for a wallet\n     *\n     * @param wallet - Ethereum wallet address\n     * @param tokens - Optional comma-separated list of token addresses to check\n     */\n    async getAvailableFees(wallet, tokens) {\n        const params = new URLSearchParams({ wallet });\n        if (tokens)\n            params.set('tokens', tokens);\n        return this.request(`/api/fees/available?${params.toString()}`);\n    }\n    /**\n     * Claim fees for a token\n     *\n     * Requires Moltbook API key (set in constructor) or the wallet must be\n     * the deployer of the token.\n     *\n     * @param tokenAddress - Token contract address\n     */\n    async claimFees(tokenAddress) {\n        const body = {\n            token_address: tokenAddress,\n        };\n        if (this.moltbookKey) {\n            body.moltbook_key = this.moltbookKey;\n        }\n        return this.request('/api/fees/claim', {\n            method: 'POST',\n            body: JSON.stringify(body),\n        });\n    }\n    // =========================================================================\n    // Analytics\n    // =========================================================================\n    /**\n     * Get detailed analytics for a token\n     */\n    async getTokenAnalytics(address) {\n        return this.request(`/api/analytics/token?address=${encodeURIComponent(address)}`);\n    }\n    /**\n     * Get analytics for an agent (all their tokens)\n     */\n    async getAgentAnalytics(name) {\n        return this.request(`/api/analytics/agent?name=${encodeURIComponent(name)}`);\n    }\n    /**\n     * Get the agent leaderboard\n     *\n     * @param sort - Sort metric: 'market_cap' | 'volume' | 'launches'\n     * @param limit - Number of results (default 20, max 100)\n     */\n    async getLeaderboard(sort = 'market_cap', limit = 20) {\n        return this.request(`/api/analytics/leaderboard?sort=${sort}&limit=${limit}`);\n    }\n    // =========================================================================\n    // Utilities\n    // =========================================================================\n    /**\n     * Upload an image for use as a token logo\n     *\n     * @param image - Base64-encoded image data OR URL to re-host\n     * @param name - Optional filename\n     * @returns Direct image URL (iili.io)\n     */\n    async uploadImage(image, name) {\n        const body = { image };\n        if (name)\n            body.name = name;\n        const response = await this.request('/api/upload', {\n            method: 'POST',\n            body: JSON.stringify(body),\n        });\n        return response.url;\n    }\n    /**\n     * Get the skill documentation\n     */\n    async getSkill() {\n        const response = await fetch(`${this.baseUrl}/skill.md`, {\n            method: 'GET',\n            headers: { 'Accept': 'text/markdown' }\n        });\n        if (!response.ok) {\n            throw new ClawnchError('Failed to fetch skill documentation', response.status);\n        }\n        return response.text();\n    }\n    /**\n     * Get the OpenAPI specification\n     */\n    async getOpenAPISpec() {\n        return this.request('/api/openapi');\n    }\n}\n/**\n * Custom error class for Clawnch API errors\n */\nexport class ClawnchError extends Error {\n    status;\n    errors;\n    constructor(message, status, errors) {\n        super(message);\n        this.status = status;\n        this.errors = errors;\n        this.name = 'ClawnchError';\n    }\n}\n// Default export for convenience\nexport default ClawnchClient;\n//# sourceMappingURL=index.js.map"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],"mappings":"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"}