@peridot-agent/agent-kit 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/shared/constants.ts","../../../src/adapters/vercel-ai/index.ts","../../../src/features/lending/read/list-markets.ts","../../../src/shared/api-client.ts","../../../src/features/lending/read/get-portfolio.ts","../../../src/shared/zod-utils.ts","../../../src/shared/cache.ts","../../../src/features/lending/read/get-leaderboard.ts","../../../src/features/lending/read/get-market-rates.ts","../../../src/features/lending/read/get-user-position.ts","../../../src/features/lending/read/simulate-borrow.ts","../../../src/features/lending/read/get-account-liquidity.ts","../../../src/shared/abis.ts","../../../src/features/lending/intents/hub/supply.ts","../../../src/features/lending/intents/hub/borrow.ts","../../../src/features/lending/intents/hub/repay.ts","../../../src/features/lending/intents/hub/withdraw.ts","../../../src/features/lending/intents/hub/enable-collateral.ts","../../../src/features/lending/intents/hub/disable-collateral.ts","../../../src/features/lending/intents/cross-chain/supply.ts","../../../src/features/lending/intents/cross-chain/borrow.ts","../../../src/features/lending/intents/cross-chain/repay.ts","../../../src/features/lending/intents/cross-chain/withdraw.ts","../../../src/features/lending/status/check-transaction.ts","../../../src/features/lending/read/get-liquidatable-positions.ts","../../../src/features/lending/intents/hub/liquidate.ts","../../../src/features/lending/tools.ts"],"sourcesContent":["import type { Address } from 'viem'\n\n// ---------------------------------------------------------------------------\n// API endpoints\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_API_BASE_URL = 'https://app.peridot.finance'\nexport const BICONOMY_API_URL = 'https://api.biconomy.io'\n\n// ---------------------------------------------------------------------------\n// Chain IDs\n// ---------------------------------------------------------------------------\n\n/** Hub chains host the pToken lending pools natively. */\nexport const HUB_CHAIN_IDS = [56, 97, 143, 10143, 1868, 50312] as const\nexport type HubChainId = (typeof HUB_CHAIN_IDS)[number]\n\nexport const BSC_MAINNET_CHAIN_ID = 56\nexport const BSC_TESTNET_CHAIN_ID = 97\nexport const MONAD_MAINNET_CHAIN_ID = 143\nexport const MONAD_TESTNET_CHAIN_ID = 10143\nexport const SOMNIA_MAINNET_CHAIN_ID = 1868\nexport const SOMNIA_TESTNET_CHAIN_ID = 50312\n\n/** Spoke chains — users bridge to the hub to interact with the protocol. */\nexport const ARBITRUM_CHAIN_ID = 42161\nexport const BASE_CHAIN_ID = 8453\nexport const ETHEREUM_CHAIN_ID = 1\nexport const POLYGON_CHAIN_ID = 137\nexport const OPTIMISM_CHAIN_ID = 10\nexport const AVALANCHE_CHAIN_ID = 43114\n\n/** Map of human-readable chain names for error messages. */\nexport const CHAIN_NAMES: Record<number, string> = {\n [BSC_MAINNET_CHAIN_ID]: 'BSC Mainnet',\n [BSC_TESTNET_CHAIN_ID]: 'BSC Testnet',\n [MONAD_MAINNET_CHAIN_ID]: 'Monad Mainnet',\n [MONAD_TESTNET_CHAIN_ID]: 'Monad Testnet',\n [SOMNIA_MAINNET_CHAIN_ID]: 'Somnia Mainnet',\n [SOMNIA_TESTNET_CHAIN_ID]: 'Somnia Testnet',\n [ARBITRUM_CHAIN_ID]: 'Arbitrum',\n [BASE_CHAIN_ID]: 'Base',\n [ETHEREUM_CHAIN_ID]: 'Ethereum',\n [POLYGON_CHAIN_ID]: 'Polygon',\n [OPTIMISM_CHAIN_ID]: 'Optimism',\n [AVALANCHE_CHAIN_ID]: 'Avalanche',\n}\n\nexport function isHubChain(chainId: number): boolean {\n return (HUB_CHAIN_IDS as readonly number[]).includes(chainId)\n}\n\n/** For spoke chains, returns the hub chain that hosts the markets. */\nexport function resolveHubChainId(chainId: number, network: 'mainnet' | 'testnet' = 'mainnet'): number {\n if (isHubChain(chainId)) return chainId\n return network === 'testnet' ? BSC_TESTNET_CHAIN_ID : BSC_MAINNET_CHAIN_ID\n}\n\n// ---------------------------------------------------------------------------\n// Contract addresses — Hub chains\n// ---------------------------------------------------------------------------\n\nexport const PERIDOT_CONTROLLER: Partial<Record<number, Address>> = {\n [BSC_MAINNET_CHAIN_ID]: '0x6fC0c15531CB5901ac72aB3CFCd9dF6E99552e14',\n // [MONAD_MAINNET_CHAIN_ID]: '0x...', // TODO: add when deployed\n // [SOMNIA_MAINNET_CHAIN_ID]: '0x...', // TODO: add when deployed\n}\n\n/** pToken market addresses per hub chain, keyed by asset symbol (uppercase). */\nexport const PERIDOT_MARKETS: Partial<Record<number, Partial<Record<string, Address>>>> = {\n [BSC_MAINNET_CHAIN_ID]: {\n WETH: '0x28E4F2Bb64ac79500ec3CAa074A3C30721B6bC84',\n USDC: '0x1A726369Bfc60198A0ce19C66726C8046c0eC17e',\n WBNB: '0xD9fDF5E2c7a2e7916E7f10Da276D95d4daC5a3c3',\n USDT: '0xc37f3869720B672addFE5F9E22a9459e0E851372',\n WBTC: '0xdCAbDc1F0B5e603b9191be044a912A8A2949e212',\n AUSD: '0x7A9940B77c0B6DFCcA2028b9F3CCa88E5DC36ebb',\n },\n // [MONAD_MAINNET_CHAIN_ID]: { ... }, // TODO: add when deployed\n // [SOMNIA_MAINNET_CHAIN_ID]: { ... }, // TODO: add when deployed\n}\n\n/** Underlying ERC-20 token addresses on BSC Mainnet. */\nexport const BSC_UNDERLYING_TOKENS: Partial<Record<string, Address>> = {\n WETH: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8',\n WBTC: '0x0555E30da8f98308EdB960aa94C0Db47230d2B9c',\n USDC: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n AUSD: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n WBNB: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',\n USDT: '0x55d398326f99059fF775485246999027B3197955',\n}\n\n/**\n * Underlying ERC-20 token addresses for all hub chains.\n * Add Monad/Somnia entries here when contracts are deployed.\n */\nexport const HUB_UNDERLYING_TOKENS: Partial<Record<number, Partial<Record<string, Address>>>> = {\n [BSC_MAINNET_CHAIN_ID]: BSC_UNDERLYING_TOKENS,\n // [MONAD_MAINNET_CHAIN_ID]: { USDC: '0x...', WETH: '0x...', ... }, // TODO\n // [SOMNIA_MAINNET_CHAIN_ID]: { USDC: '0x...', WETH: '0x...', ... }, // TODO\n}\n\n/** Token addresses on spoke chains, keyed by chainId then asset symbol. */\nexport const SPOKE_TOKENS: Partial<Record<number, Partial<Record<string, Address>>>> = {\n [ARBITRUM_CHAIN_ID]: {\n USDC: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n USDT: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',\n WETH: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',\n AUSD: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n WBTC: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',\n },\n [BASE_CHAIN_ID]: {\n USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n WETH: '0x4200000000000000000000000000000000000006',\n USDT: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2',\n WBTC: '0x0555E30da8f98308EdB960aa94C0Db47230d2B9c',\n },\n [ETHEREUM_CHAIN_ID]: {\n USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',\n WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',\n WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',\n },\n [POLYGON_CHAIN_ID]: {\n USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',\n WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',\n WBTC: '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6',\n },\n [OPTIMISM_CHAIN_ID]: {\n USDC: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607',\n USDT: '0x94b008aA00579c1307B0eF2c499aD98a8ce58e58',\n WETH: '0x4200000000000000000000000000000000000006',\n },\n [AVALANCHE_CHAIN_ID]: {\n USDC: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n USDT: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',\n WETH: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB',\n WBTC: '0x0555E30da8f98308EdB960aa94C0Db47230d2B9c',\n },\n}\n\n/** ERC-20 decimal places by asset symbol. */\nexport const ASSET_DECIMALS: Record<string, number> = {\n USDC: 6,\n USDT: 6,\n WBTC: 8,\n WETH: 18,\n WBNB: 18,\n AUSD: 18,\n}\n\n// ---------------------------------------------------------------------------\n// Address helpers\n// ---------------------------------------------------------------------------\n\nexport function getPTokenAddress(chainId: number, asset: string): Address {\n const markets = PERIDOT_MARKETS[chainId]\n if (!markets) {\n throw new Error(`No pToken markets configured for chain ${chainId} (${CHAIN_NAMES[chainId] ?? 'unknown'})`)\n }\n const address = markets[asset.toUpperCase()]\n if (!address) {\n const available = Object.keys(markets).join(', ')\n throw new Error(`No pToken market for ${asset.toUpperCase()} on chain ${chainId}. Available: ${available}`)\n }\n return address\n}\n\nexport function getUnderlyingTokenAddress(chainId: number, asset: string): Address {\n const symbol = asset.toUpperCase()\n const chainName = CHAIN_NAMES[chainId] ?? `chain ${chainId}`\n\n // Hub chains use HUB_UNDERLYING_TOKENS\n if (isHubChain(chainId)) {\n const hubTokens = HUB_UNDERLYING_TOKENS[chainId]\n if (!hubTokens) throw new Error(`No underlying token config for hub chain ${chainName} — contracts may not be deployed yet`)\n const address = hubTokens[symbol]\n if (!address) throw new Error(`No underlying token for ${symbol} on ${chainName}`)\n return address\n }\n\n // Spoke chains use SPOKE_TOKENS\n const spokeTokens = SPOKE_TOKENS[chainId]\n if (!spokeTokens) throw new Error(`No token config for chain ${chainName}`)\n const address = spokeTokens[symbol]\n if (!address) throw new Error(`No token address for ${symbol} on ${chainName}`)\n return address\n}\n\nexport function getControllerAddress(chainId: number): Address {\n const address = PERIDOT_CONTROLLER[chainId]\n if (!address) throw new Error(`No Peridot controller for chain ${chainId}`)\n return address\n}\n\nexport function getAssetDecimals(asset: string): number {\n const symbol = asset.toUpperCase()\n const decimals = ASSET_DECIMALS[symbol]\n if (decimals === undefined) {\n throw new Error(\n `Unknown asset \"${symbol}\": decimal precision not configured. ` +\n `Add it to ASSET_DECIMALS in constants.ts before use.`,\n )\n }\n return decimals\n}\n\n/** Default public RPC endpoints (no API key required). */\nexport const DEFAULT_RPC_URLS: Partial<Record<number, string>> = {\n [BSC_MAINNET_CHAIN_ID]: 'https://bsc-dataseed.binance.org',\n [BSC_TESTNET_CHAIN_ID]: 'https://data-seed-prebsc-1-s1.binance.org:8545',\n [MONAD_MAINNET_CHAIN_ID]: 'https://rpc.monad.xyz',\n [MONAD_TESTNET_CHAIN_ID]: 'https://testnet-rpc.monad.xyz',\n [SOMNIA_MAINNET_CHAIN_ID]: 'https://dream-rpc.somnia.network',\n [SOMNIA_TESTNET_CHAIN_ID]: 'https://testnet.rpc.somnia.network',\n [ARBITRUM_CHAIN_ID]: 'https://arb1.arbitrum.io/rpc',\n [BASE_CHAIN_ID]: 'https://mainnet.base.org',\n [ETHEREUM_CHAIN_ID]: 'https://eth.llamarpc.com',\n}\n","/**\n * Vercel AI SDK adapter for the Peridot Agent Kit.\n *\n * @example\n * ```typescript\n * import { generateText } from \"ai\"\n * import { openai } from \"@ai-sdk/openai\"\n * import { createVercelAITools } from \"@peridot-agent/agent-kit/vercel-ai\"\n *\n * const tools = createVercelAITools({ network: \"mainnet\" })\n *\n * const { text } = await generateText({\n * model: openai(\"gpt-4o\"),\n * tools,\n * prompt: \"What is my health factor? My address is 0x...\"\n * })\n * ```\n */\n\nimport { tool } from 'ai'\nimport type { z } from 'zod'\nimport { lendingTools } from '../../features/lending/tools'\nimport type { PeridotConfig, ToolDefinition } from '../../shared/types'\n\n// import { marginTools } from '../../features/margin/tools' // Phase 2\n\nfunction toolsForConfig(_config: PeridotConfig): ToolDefinition[] {\n return [\n ...lendingTools,\n // ...marginTools,\n ]\n}\n\n/**\n * Create Vercel AI SDK tools for all Peridot Agent Kit tools.\n * Returns a record of tool name → tool, ready to pass to `generateText` / `streamText`.\n */\n/**\n * Create Vercel AI SDK tools for all Peridot Agent Kit tools.\n * Returns a record of tool name → tool, ready to pass to `generateText` / `streamText`.\n */\nexport function createVercelAITools(\n config: PeridotConfig = {},\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Record<string, any> {\n const tools = toolsForConfig(config)\n\n return Object.fromEntries(\n tools.map((t) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const capturedTool = t as ToolDefinition<any, any>\n return [\n capturedTool.name,\n tool({\n description: capturedTool.description,\n parameters: capturedTool.inputSchema as z.ZodObject<z.ZodRawShape>,\n // eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unsafe-return\n execute: async (input: unknown) => capturedTool.execute(input, config) as unknown,\n }),\n ]\n }),\n )\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { MarketSummary, PeridotConfig } from '../../../shared/types'\n\nexport const listMarketsSchema = z.object({\n chainId: z\n .number()\n .optional()\n .describe(\n 'Filter by hub chain ID. 56=BSC, 143=Monad, 1868=Somnia. Omit to list all markets across all chains.',\n ),\n})\n\nexport type ListMarketsInput = z.infer<typeof listMarketsSchema>\n\nexport async function listMarkets(\n input: ListMarketsInput,\n config: PeridotConfig,\n): Promise<{ markets: MarketSummary[]; count: number }> {\n const client = new PeridotApiClient(config)\n const metrics = await client.getMarketMetrics()\n\n const markets: MarketSummary[] = Object.entries(metrics)\n .filter(([, m]) => input.chainId === undefined || m.chainId === input.chainId)\n .map(([key, m]) => {\n const [asset] = key.split(':')\n const dataAgeSeconds = m.updatedAt\n ? Math.round((Date.now() - new Date(m.updatedAt).getTime()) / 1000)\n : 0\n return {\n asset: asset ?? key,\n chainId: m.chainId,\n priceUsd: m.priceUsd,\n tvlUsd: m.tvlUsd,\n utilizationPct: m.utilizationPct,\n liquidityUsd: m.liquidityUsd,\n collateralFactorPct: m.collateral_factor_pct,\n updatedAt: m.updatedAt,\n dataAgeSeconds,\n }\n })\n .sort((a, b) => b.tvlUsd - a.tvlUsd)\n\n return { markets, count: markets.length }\n}\n","import { BICONOMY_API_URL, DEFAULT_API_BASE_URL } from './constants'\n\n/** Default timeout for Peridot platform API reads (ms). */\nconst PLATFORM_TIMEOUT_MS = 10_000\n/** Longer timeout for Biconomy compose — builds a full cross-chain route (ms). */\nconst BICONOMY_COMPOSE_TIMEOUT_MS = 30_000\n/** Delay before the single automatic retry (ms). */\nconst RETRY_DELAY_MS = 200\n\n/**\n * Fetches a URL with one automatic retry on network errors or 5xx responses.\n * 4xx responses are NOT retried — they indicate a client error.\n */\nasync function fetchWithRetry(url: string, init: RequestInit): Promise<Response> {\n const attempt = () => fetch(url, init)\n let res: Response\n try {\n res = await attempt()\n } catch (err) {\n // Network-level failure (timeout, DNS, etc.) — retry once\n await new Promise((r) => setTimeout(r, RETRY_DELAY_MS))\n return attempt()\n }\n if (res.status >= 500) {\n await new Promise((r) => setTimeout(r, RETRY_DELAY_MS))\n return attempt()\n }\n return res\n}\nimport type {\n BiconomyResponse,\n ComposeRequest,\n LiquidatablePositions,\n PeridotConfig,\n TransactionStatus,\n} from './types'\n\n// ---------------------------------------------------------------------------\n// Raw API response shapes (internal — not exported from package root)\n// ---------------------------------------------------------------------------\n\nexport interface RawMarketMetric {\n utilizationPct: number\n tvlUsd: number\n liquidityUnderlying: number\n liquidityUsd: number\n priceUsd: number\n collateral_factor_pct: number\n updatedAt: string\n chainId: number\n}\n\n/** Shape of one entry from `/api/apy` (from `apy_latest_mainnet` table). */\nexport interface RawMarketApy {\n supplyApy: number\n borrowApy: number\n peridotSupplyApy: number\n peridotBorrowApy: number\n boostSourceSupplyApy: number\n boostRewardsSupplyApy: number\n totalSupplyApy: number\n netBorrowApy: number\n timestamp: string\n}\n\n/**\n * Full response from `/api/apy`.\n * Keys are lowercase asset IDs (e.g. \"usdc\"), values are a map of chainId → APY data.\n */\nexport type RawApyResponse = Record<string, Record<number, RawMarketApy>>\n\n/** Shape of one leaderboard entry from `/api/leaderboard`. */\nexport interface RawTransaction {\n txHash: string\n chainId: number\n blockNumber: number\n actionType: string\n tokenSymbol: string | null\n amount: number\n usdValue: number\n pointsAwarded: number\n verifiedAt: string\n contractAddress: string\n}\n\nexport interface RawTransactionsResponse {\n transactions: RawTransaction[]\n total: number\n}\n\nexport interface RawLeaderboardEntry {\n rank: number\n address: string\n totalPoints: number\n supplyCount: number\n borrowCount: number\n repayCount: number\n redeemCount: number\n updatedAt: string\n}\n\nexport interface RawLeaderboardResponse {\n entries: RawLeaderboardEntry[]\n total: number\n}\n\nexport interface RawUserPortfolio {\n portfolio: {\n currentValue: number\n totalSupplied: number\n totalBorrowed: number\n netApy: number\n /** Note: simplified ratio (totalSupplied / totalBorrowed), not liquidation HF */\n healthFactor: number\n }\n assets: Array<{\n assetId: string\n supplied: number\n borrowed: number\n net: number\n percentage: number\n }>\n transactions: {\n totalCount: number\n supplyCount: number\n borrowCount: number\n repayCount: number\n redeemCount: number\n }\n earnings: {\n effectiveApy: number\n totalLifetimeEarnings: number\n }\n}\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\nexport class PeridotApiClient {\n private readonly baseUrl: string\n private readonly biconomyApiKey: string | undefined\n\n constructor(config: PeridotConfig) {\n this.baseUrl = config.apiBaseUrl ?? DEFAULT_API_BASE_URL\n this.biconomyApiKey = config.biconomyApiKey\n }\n\n /**\n * Fetches all market metrics. Returns a record keyed by `${ASSET}:${chainId}`.\n * Example key: `USDC:56`\n */\n async getMarketMetrics(): Promise<Record<string, RawMarketMetric>> {\n const res = await fetchWithRetry(`${this.baseUrl}/api/markets/metrics`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch market metrics: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: Record<string, RawMarketMetric>; error?: string }\n if (!json.ok) throw new Error(`Market metrics API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches the portfolio overview for a wallet address.\n * Uses the platform's portfolio-data endpoint which aggregates DB snapshots.\n */\n async getUserPortfolio(address: string): Promise<RawUserPortfolio> {\n if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {\n throw new Error(`Invalid address format: \"${address}\". Expected 0x followed by 40 hex characters.`)\n }\n const res = await fetchWithRetry(`${this.baseUrl}/api/user/portfolio-data?address=${address}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch portfolio: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: RawUserPortfolio; error?: string }\n if (!json.ok) throw new Error(`Portfolio API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches the latest APY snapshot for all markets (or a specific chain).\n * Calls `/api/apy` — backed by the `apy_latest_mainnet` DB table.\n *\n * Returns a record keyed by lowercase asset ID, then by chainId.\n * Example: `data[\"usdc\"][56].totalSupplyApy`\n */\n async getMarketApy(chainId?: number): Promise<RawApyResponse> {\n const url = chainId\n ? `${this.baseUrl}/api/apy?chainId=${chainId}`\n : `${this.baseUrl}/api/apy`\n const res = await fetchWithRetry(url, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch APY data: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: RawApyResponse; error?: string }\n if (!json.ok) throw new Error(`APY API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches the Peridot leaderboard (top users by points).\n * Optionally filters by chainId and limits the result set.\n */\n async getLeaderboard(options?: { limit?: number; chainId?: number }): Promise<RawLeaderboardResponse> {\n const params = new URLSearchParams()\n if (options?.limit !== undefined) params.set('limit', String(options.limit))\n if (options?.chainId !== undefined) params.set('chainId', String(options.chainId))\n const query = params.toString() ? `?${params.toString()}` : ''\n const res = await fetchWithRetry(`${this.baseUrl}/api/leaderboard${query}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch leaderboard: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: RawLeaderboardResponse; error?: string }\n if (!json.ok) throw new Error(`Leaderboard API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches accounts that are currently underwater (shortfall_usd > 0) and\n * eligible for liquidation. Data is sourced from the account health scanner.\n */\n async getLiquidatablePositions(options?: {\n chainId?: number\n minShortfall?: number\n limit?: number\n }): Promise<LiquidatablePositions> {\n const params = new URLSearchParams()\n if (options?.chainId !== undefined) params.set('chainId', String(options.chainId))\n if (options?.minShortfall !== undefined) params.set('minShortfall', String(options.minShortfall))\n if (options?.limit !== undefined) params.set('limit', String(options.limit))\n const query = params.toString() ? `?${params.toString()}` : ''\n const res = await fetchWithRetry(`${this.baseUrl}/api/liquidations/at-risk${query}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch liquidatable positions: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: LiquidatablePositions; error?: string }\n if (!json.ok) throw new Error(`Liquidations API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches verified transaction history for a wallet address.\n * Optionally filters by chainId and/or actionType.\n */\n async getUserTransactions(\n address: string,\n options?: { limit?: number; chainId?: number; actionType?: 'supply' | 'borrow' | 'repay' | 'redeem' },\n ): Promise<RawTransactionsResponse> {\n if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {\n throw new Error(`Invalid address format: \"${address}\". Expected 0x followed by 40 hex characters.`)\n }\n const params = new URLSearchParams({ address })\n if (options?.limit !== undefined) params.set('limit', String(options.limit))\n if (options?.chainId !== undefined) params.set('chainId', String(options.chainId))\n if (options?.actionType !== undefined) params.set('actionType', options.actionType)\n const res = await fetchWithRetry(`${this.baseUrl}/api/user/transactions?${params.toString()}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch transactions: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: RawTransactionsResponse; error?: string }\n if (!json.ok) throw new Error(`Transactions API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Calls Biconomy MEE /compose to build a cross-chain transaction payload.\n * Does NOT execute — the returned instructions must be signed by the user.\n */\n async biconomyCompose(request: ComposeRequest): Promise<BiconomyResponse> {\n if (!this.biconomyApiKey) {\n throw new Error('biconomyApiKey is required in PeridotConfig for cross-chain operations')\n }\n const res = await fetch(`${BICONOMY_API_URL}/v1/instructions/compose`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.biconomyApiKey,\n },\n body: JSON.stringify(request),\n signal: AbortSignal.timeout(BICONOMY_COMPOSE_TIMEOUT_MS),\n })\n if (!res.ok) {\n const error: unknown = await res.json().catch(() => ({}))\n throw new Error(`Biconomy compose error: ${JSON.stringify(error)}`)\n }\n return res.json() as Promise<BiconomyResponse>\n }\n\n /** Polls Biconomy for the status of a submitted super-transaction. */\n async biconomyGetStatus(superTxHash: string): Promise<TransactionStatus> {\n const res = await fetchWithRetry(`${BICONOMY_API_URL}/v1/explorer/transaction/${superTxHash}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (res.status === 404) return { superTxHash, status: 'not_found' }\n if (!res.ok) throw new Error(`Biconomy status error: ${res.status}`)\n const data = (await res.json()) as Record<string, unknown>\n return parseBiconomyStatus(superTxHash, data)\n }\n}\n\nfunction parseBiconomyStatus(superTxHash: string, data: Record<string, unknown>): TransactionStatus {\n const status = String(data['status'] ?? '').toLowerCase()\n const txHashes = (data['txHashes'] as string[] | undefined) ?? []\n\n if (status.includes('success') || status.includes('completed')) {\n return { superTxHash, status: 'success', chainTxHashes: txHashes }\n }\n if (status.includes('fail') || status.includes('error')) {\n return { superTxHash, status: 'failed', error: String(data['message'] ?? 'Unknown error') }\n }\n if (status.includes('process')) {\n return { superTxHash, status: 'processing', chainTxHashes: txHashes }\n }\n return { superTxHash, status: 'pending' }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { PeridotConfig, PortfolioOverview } from '../../../shared/types'\nimport { evmAddress } from '../../../shared/zod-utils'\nimport { Cache } from '../../../shared/cache'\n\n/**\n * Module-level cache: 30 s TTL matches the backend's Cache-Control header.\n * In-flight coalescing ensures that a burst of concurrent calls for the same\n * address (e.g. an agent calling the tool multiple times in one turn) results\n * in exactly one upstream request.\n *\n * Exported as `portfolioCache` so tests can call `.clear()` between runs.\n */\nexport const portfolioCache = new Cache<PortfolioOverview>(30_000)\n\nexport const getPortfolioSchema = z.object({\n address: evmAddress.describe('The wallet address (0x...) to look up'),\n})\n\nexport type GetPortfolioInput = z.infer<typeof getPortfolioSchema>\n\nexport async function getPortfolio(\n input: GetPortfolioInput,\n config: PeridotConfig,\n): Promise<PortfolioOverview> {\n // Normalise to lowercase so 0xABCD… and 0xabcd… share the same cache slot.\n const key = input.address.toLowerCase()\n\n return portfolioCache.getOrFetch(key, async () => {\n const client = new PeridotApiClient(config)\n const data = await client.getUserPortfolio(input.address)\n\n return {\n address: input.address,\n fetchedAt: new Date().toISOString(),\n portfolio: {\n currentValue: data.portfolio.currentValue,\n totalSupplied: data.portfolio.totalSupplied,\n totalBorrowed: data.portfolio.totalBorrowed,\n netApy: data.portfolio.netApy,\n healthFactor:\n data.portfolio.totalBorrowed > 0\n ? data.portfolio.totalSupplied / data.portfolio.totalBorrowed\n : null,\n },\n assets: data.assets,\n transactions: data.transactions,\n earnings: data.earnings,\n }\n })\n}\n","import { z } from 'zod'\n\n/**\n * Accepts any valid 0x-prefixed 40-hex-character Ethereum address.\n * Rejects bare hex strings, ENS names, and truncated addresses.\n */\nexport const evmAddress = z\n .string()\n .regex(/^0x[0-9a-fA-F]{40}$/, 'Must be a valid Ethereum address (0x followed by 40 hex chars)')\n\n/**\n * Accepts a positive decimal number expressed as a string.\n * Valid: \"100\", \"0.5\", \"1234.56789\"\n * Invalid: \"-1\", \"NaN\", \"Infinity\", \"1e18\", \"\"\n */\nexport const tokenAmount = z\n .string()\n .regex(/^\\d+(\\.\\d+)?$/, 'Amount must be a positive decimal number (e.g. \"100\" or \"0.5\")')\n","interface Entry<T> {\n data: T\n expiresAt: number\n inflight?: Promise<T>\n}\n\n/**\n * In-memory TTL cache with thundering herd protection.\n *\n * Concurrent callers for the same key share one in-flight promise rather than\n * each triggering a separate upstream request. On fetch error the entry is\n * removed so the next caller can retry (unlike a naïve promise-coalescing\n * cache that would permanently serve the rejection).\n */\nexport class Cache<T> {\n private store = new Map<string, Entry<T>>()\n\n constructor(private ttlMs: number) {}\n\n get(key: string): T | undefined {\n const entry = this.store.get(key)\n if (!entry) return undefined\n // Never evict an entry that has an active in-flight promise — getOrFetch\n // still needs to find it. We just don't return stale data for it.\n if (entry.inflight) return undefined\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key)\n return undefined\n }\n return entry.data\n }\n\n set(key: string, data: T): void {\n this.store.set(key, { data, expiresAt: Date.now() + this.ttlMs })\n }\n\n clear(): void {\n this.store.clear()\n }\n\n /**\n * Return the cached value if fresh, otherwise call `fetcher` once — even\n * when multiple callers arrive simultaneously while the fetch is in-flight.\n * If the fetch throws, the entry is deleted so subsequent callers retry.\n */\n async getOrFetch(key: string, fetcher: () => Promise<T>): Promise<T> {\n const cached = this.get(key)\n if (cached !== undefined) return cached\n\n const existing = this.store.get(key)\n if (existing?.inflight) return existing.inflight\n\n const promise = fetcher()\n .then((data) => {\n this.set(key, data)\n const entry = this.store.get(key)\n if (entry) delete entry.inflight\n return data\n })\n .catch((err: unknown) => {\n // Remove the entry so the next caller triggers a fresh attempt.\n this.store.delete(key)\n throw err\n })\n\n this.store.set(key, { data: undefined as unknown as T, expiresAt: 0, inflight: promise })\n return promise\n }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { LeaderboardEntry, PeridotConfig } from '../../../shared/types'\n\nexport const getLeaderboardSchema = z.object({\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Number of entries to return (1–100, default 50).'),\n chainId: z\n .number()\n .optional()\n .describe('Filter by hub chain ID. 56=BSC, 143=Monad, 1868=Somnia. Omit to show all chains.'),\n})\n\nexport type GetLeaderboardInput = z.infer<typeof getLeaderboardSchema>\n\nexport async function getLeaderboard(\n input: GetLeaderboardInput,\n config: PeridotConfig,\n): Promise<{ entries: LeaderboardEntry[]; total: number }> {\n const client = new PeridotApiClient(config)\n const opts: { limit?: number; chainId?: number } = {}\n if (input.limit !== undefined) opts.limit = input.limit\n if (input.chainId !== undefined) opts.chainId = input.chainId\n const data = await client.getLeaderboard(opts)\n return {\n entries: data.entries,\n total: data.total,\n }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport { BSC_MAINNET_CHAIN_ID } from '../../../shared/constants'\nimport type { MarketRates, PeridotConfig } from '../../../shared/types'\n\nexport const getMarketRatesSchema = z.object({\n asset: z.string().describe('Asset symbol, e.g. \"USDC\", \"WETH\", \"WBTC\", \"WBNB\", \"USDT\", \"AUSD\"'),\n chainId: z\n .number()\n .default(BSC_MAINNET_CHAIN_ID)\n .describe('Hub chain ID where the market lives. 56=BSC (default), 143=Monad, 1868=Somnia'),\n})\n\nexport type GetMarketRatesInput = z.infer<typeof getMarketRatesSchema>\n\nexport async function getMarketRates(\n input: GetMarketRatesInput,\n config: PeridotConfig,\n): Promise<MarketRates> {\n const client = new PeridotApiClient(config)\n const assetUpper = input.asset.toUpperCase()\n\n // Fetch market metrics and APY data in parallel\n const [metrics, apyData] = await Promise.all([\n client.getMarketMetrics(),\n client.getMarketApy(input.chainId),\n ])\n\n // Metrics are keyed as `${ASSET}:${chainId}` (uppercase asset)\n const key = `${assetUpper}:${input.chainId}`\n const metric = metrics[key]\n\n if (!metric) {\n const available = Object.keys(metrics)\n .filter((k) => k.endsWith(`:${input.chainId}`))\n .map((k) => k.split(':')[0])\n throw new Error(\n `No market data found for \"${assetUpper}\" on chain ${input.chainId}. ` +\n `Available assets on this chain: ${available.join(', ')}`,\n )\n }\n\n // APY data is keyed by lowercase asset ID, then by chainId\n const apy = apyData[assetUpper.toLowerCase()]?.[input.chainId]\n const apyDataAvailable = apy !== undefined\n\n const dataAgeSeconds = metric.updatedAt\n ? Math.round((Date.now() - new Date(metric.updatedAt).getTime()) / 1000)\n : 0\n\n const warnings: string[] = []\n if (!apyDataAvailable) {\n warnings.push(\n `APY data is not yet available for ${assetUpper} on chain ${input.chainId}. ` +\n `All yield figures (supplyApyPct, borrowApyPct, totalSupplyApyPct, etc.) are showing 0 as a placeholder — ` +\n `do NOT present them as real rates. The APY indexer may still be catching up.`,\n )\n }\n if (dataAgeSeconds > 300) {\n warnings.push(`Market data is ${Math.round(dataAgeSeconds / 60)} minutes old — figures may not reflect current conditions.`)\n }\n\n return {\n asset: assetUpper,\n chainId: input.chainId,\n supplyApyPct: apy?.supplyApy ?? 0,\n borrowApyPct: apy?.borrowApy ?? 0,\n peridotSupplyApyPct: apy?.peridotSupplyApy ?? 0,\n peridotBorrowApyPct: apy?.peridotBorrowApy ?? 0,\n boostSourceSupplyApyPct: apy?.boostSourceSupplyApy ?? 0,\n boostRewardsSupplyApyPct: apy?.boostRewardsSupplyApy ?? 0,\n totalSupplyApyPct: apy?.totalSupplyApy ?? 0,\n netBorrowApyPct: apy?.netBorrowApy ?? 0,\n tvlUsd: metric.tvlUsd,\n utilizationPct: metric.utilizationPct,\n liquidityUsd: metric.liquidityUsd,\n priceUsd: metric.priceUsd,\n collateralFactorPct: metric.collateral_factor_pct ?? 0,\n updatedAt: metric.updatedAt,\n dataAgeSeconds,\n apyDataAvailable,\n warning: warnings.length > 0 ? warnings.join(' ') : undefined,\n }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { PeridotConfig, UserPosition } from '../../../shared/types'\nimport { evmAddress } from '../../../shared/zod-utils'\n\nexport const getUserPositionSchema = z.object({\n address: evmAddress.describe('The wallet address (0x...) to look up'),\n})\n\nexport type GetUserPositionInput = z.infer<typeof getUserPositionSchema>\n\nexport async function getUserPosition(\n input: GetUserPositionInput,\n config: PeridotConfig,\n): Promise<UserPosition> {\n const client = new PeridotApiClient(config)\n const data = await client.getUserPortfolio(input.address)\n\n const { portfolio, assets, transactions } = data\n\n const healthFactor =\n portfolio.totalBorrowed > 0\n ? portfolio.totalSupplied / portfolio.totalBorrowed\n : null\n\n return {\n address: input.address,\n totalSuppliedUsd: portfolio.totalSupplied,\n totalBorrowedUsd: portfolio.totalBorrowed,\n netWorthUsd: portfolio.currentValue,\n netApyPct: portfolio.netApy,\n healthFactor,\n assets: assets.map((a) => ({\n assetId: a.assetId,\n suppliedUsd: a.supplied,\n borrowedUsd: a.borrowed,\n netUsd: a.net,\n })),\n transactions: {\n supplyCount: transactions.supplyCount,\n borrowCount: transactions.borrowCount,\n repayCount: transactions.repayCount,\n redeemCount: transactions.redeemCount,\n },\n fetchedAt: new Date().toISOString(),\n }\n}\n","import Decimal from 'decimal.js'\nimport { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport { BSC_MAINNET_CHAIN_ID, isHubChain } from '../../../shared/constants'\nimport type { PeridotConfig, SimulateBorrowResult } from '../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../shared/zod-utils'\n\nexport const simulateBorrowSchema = z.object({\n address: evmAddress.describe('The wallet address planning to borrow'),\n asset: z.string().describe('The asset to borrow, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable borrow amount, e.g. \"500\" for 500 USDC'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type SimulateBorrowInput = z.infer<typeof simulateBorrowSchema>\n\n/** Risk thresholds for the simplified health factor. */\nconst RISK_THRESHOLDS = {\n safe: 2.0,\n moderate: 1.5,\n high: 1.2,\n critical: 1.0,\n} as const\n\nfunction classifyRisk(hf: number): SimulateBorrowResult['riskLevel'] {\n if (hf >= RISK_THRESHOLDS.safe) return 'safe'\n if (hf >= RISK_THRESHOLDS.moderate) return 'moderate'\n if (hf >= RISK_THRESHOLDS.high) return 'high'\n if (hf >= RISK_THRESHOLDS.critical) return 'critical'\n return 'liquidatable'\n}\n\nexport async function simulateBorrow(\n input: SimulateBorrowInput,\n config: PeridotConfig,\n): Promise<SimulateBorrowResult> {\n const client = new PeridotApiClient(config)\n\n // Fetch position and market price in parallel\n const [portfolioData, metricsData] = await Promise.all([\n client.getUserPortfolio(input.address),\n client.getMarketMetrics(),\n ])\n\n const assetUpper = input.asset.toUpperCase()\n const metricKey = `${assetUpper}:${input.chainId}`\n const metric = metricsData[metricKey]\n\n if (!metric) {\n throw new Error(`No market data for ${assetUpper} on chain ${input.chainId}`)\n }\n\n const borrowAmountRaw = parseFloat(input.amount)\n if (isNaN(borrowAmountRaw) || borrowAmountRaw <= 0) {\n throw new Error(`Invalid borrow amount: \"${input.amount}\"`)\n }\n\n const borrowAmount = new Decimal(input.amount)\n const borrowAmountUsd = borrowAmount.mul(metric.priceUsd).toNumber()\n const { totalSupplied, totalBorrowed } = portfolioData.portfolio\n\n const currentHF =\n totalBorrowed > 0\n ? new Decimal(totalSupplied).div(totalBorrowed).toNumber()\n : null\n const projectedBorrowedUsd = new Decimal(totalBorrowed).add(borrowAmountUsd)\n\n if (totalSupplied === 0) {\n return {\n currentHealthFactor: null,\n projectedHealthFactor: null,\n borrowAmountUsd,\n isSafe: false,\n riskLevel: 'liquidatable',\n maxSafeBorrowUsd: 0,\n warning:\n 'Portfolio shows no supplied collateral (data is sourced from indexed DB snapshots and may ' +\n 'not reflect activity from the last few minutes). If you recently supplied assets, wait for ' +\n 'the next snapshot update. Otherwise, supply assets and enable them as collateral before borrowing.',\n }\n }\n\n const projectedHF = new Decimal(totalSupplied).div(projectedBorrowedUsd).toNumber()\n\n // Max safe borrow keeps projected HF at the \"safe\" threshold (2.0)\n const maxSafeBorrowUsd = Decimal.max(\n 0,\n new Decimal(totalSupplied).div(RISK_THRESHOLDS.safe).sub(totalBorrowed),\n ).toNumber()\n\n const riskLevel = classifyRisk(projectedHF)\n const isSafe = projectedHF >= RISK_THRESHOLDS.high\n\n const warnings: string[] = []\n if (riskLevel === 'liquidatable') {\n warnings.push('This borrow would immediately make you eligible for liquidation.')\n } else if (riskLevel === 'critical') {\n warnings.push('Health factor would drop critically low. Any price movement risks liquidation.')\n } else if (riskLevel === 'high') {\n warnings.push('Health factor would be dangerously low. Consider borrowing less.')\n }\n\n return {\n currentHealthFactor: currentHF,\n projectedHealthFactor: projectedHF,\n borrowAmountUsd,\n isSafe,\n riskLevel,\n maxSafeBorrowUsd,\n warning: warnings[0],\n }\n}\n","import Decimal from 'decimal.js'\nimport { z } from 'zod'\nimport { createPublicClient, http } from 'viem'\nimport { COMPTROLLER_ABI } from '../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n DEFAULT_RPC_URLS,\n getControllerAddress,\n isHubChain,\n} from '../../../shared/constants'\nimport type { AccountLiquidity, PeridotConfig } from '../../../shared/types'\nimport { evmAddress } from '../../../shared/zod-utils'\n\nexport const getAccountLiquiditySchema = z.object({\n address: evmAddress.describe('The wallet address to check'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID to query (must be a hub chain). Defaults to BSC (56).'),\n})\n\nexport type GetAccountLiquidityInput = z.infer<typeof getAccountLiquiditySchema>\n\n/**\n * Reads account liquidity directly from the Peridottroller contract.\n * Returns the precise USD liquidity (excess borrowing power) and shortfall.\n *\n * This is the authoritative source for liquidation risk — more accurate than\n * the portfolio-data API which uses a simplified health factor.\n *\n * Requires an RPC URL for the hub chain (uses public fallback if not configured).\n */\nexport async function getAccountLiquidity(\n input: GetAccountLiquidityInput,\n config: PeridotConfig,\n): Promise<AccountLiquidity> {\n const rpcUrl =\n config.rpcUrls?.[input.chainId] ?? DEFAULT_RPC_URLS[input.chainId]\n\n if (!rpcUrl) {\n throw new Error(\n `No RPC URL available for chain ${input.chainId}. ` +\n `Provide one via config.rpcUrls[${input.chainId}].`,\n )\n }\n\n const controllerAddress = getControllerAddress(input.chainId)\n\n const client = createPublicClient({ transport: http(rpcUrl) })\n\n const [error, liquidity, shortfall] = await client.readContract({\n address: controllerAddress,\n abi: COMPTROLLER_ABI,\n functionName: 'getAccountLiquidity',\n args: [input.address as `0x${string}`],\n })\n\n if (error !== 0n) {\n throw new Error(`Comptroller getAccountLiquidity returned error code ${error.toString()}`)\n }\n\n // Values are in USD with 18 decimal mantissa — use Decimal to avoid float precision loss\n const liquidityUsd = new Decimal(liquidity.toString()).div('1e18').toNumber()\n const shortfallUsd = new Decimal(shortfall.toString()).div('1e18').toNumber()\n\n return {\n address: input.address,\n chainId: input.chainId,\n liquidityUsd,\n shortfallUsd,\n isHealthy: shortfallUsd === 0,\n }\n}\n","import { parseAbi } from 'viem'\n\n/**\n * Minimal ABI for pToken (Compound V2-style cToken) markets.\n * Only includes functions used by the agent-kit.\n */\nexport const PTOKEN_ABI = parseAbi([\n 'function mint(uint256 mintAmount) returns (uint256)',\n 'function redeem(uint256 redeemTokens) returns (uint256)',\n 'function redeemUnderlying(uint256 redeemAmount) returns (uint256)',\n 'function borrow(uint256 borrowAmount) returns (uint256)',\n 'function repayBorrow(uint256 repayAmount) returns (uint256)',\n 'function repayBorrowBehalf(address borrower, uint256 repayAmount) returns (uint256)',\n 'function liquidateBorrow(address borrower, uint256 repayAmount, address pTokenCollateral) returns (uint256)',\n 'function balanceOf(address owner) view returns (uint256)',\n 'function borrowBalanceStored(address account) view returns (uint256)',\n 'function supplyRatePerBlock() view returns (uint256)',\n 'function borrowRatePerBlock() view returns (uint256)',\n 'function exchangeRateStored() view returns (uint256)',\n 'function underlying() view returns (address)',\n])\n\n/**\n * Minimal ABI for the Peridottroller (Compound V2-style Comptroller).\n */\nexport const COMPTROLLER_ABI = parseAbi([\n 'function enterMarkets(address[] calldata pTokens) returns (uint256[] memory)',\n 'function exitMarket(address pTokenAddress) returns (uint256)',\n 'function getAccountLiquidity(address account) view returns (uint256 errorCode, uint256 liquidity, uint256 shortfall)',\n 'function getAllMarkets() view returns (address[] memory)',\n 'function markets(address pToken) view returns (bool isListed, uint256 collateralFactorMantissa, bool isComped)',\n 'function checkMembership(address account, address pToken) view returns (bool)',\n])\n\n/**\n * Standard ERC-20 ABI subset used for approvals and balance checks.\n */\nexport const 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 owner) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n])\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits } from 'viem'\nimport { ERC20_ABI, PTOKEN_ABI, COMPTROLLER_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getControllerAddress,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const hubSupplySchema = z.object({\n userAddress: evmAddress.describe('The wallet address supplying assets'),\n asset: z.string().describe('Asset to supply, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable amount to supply, e.g. \"100\" for 100 USDC'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia). Use build_cross_chain_supply_intent for spoke chains.' })\n .describe('Hub chain ID. Must be a chain with native Peridot markets. Defaults to BSC (56).'),\n enableAsCollateral: z\n .boolean()\n .default(true)\n .describe('Whether to enable the supplied asset as collateral. Defaults to true.'),\n})\n\nexport type HubSupplyInput = z.input<typeof hubSupplySchema>\n\n/**\n * Builds the transaction calls to supply an asset to a Peridot hub-chain market.\n *\n * Call sequence:\n * 1. approve(pToken, amount) — allow pToken to spend your underlying\n * 2. mint(amount) — supply underlying, receive pTokens\n * 3. enterMarkets([pToken]) — (optional) enable as collateral\n */\nexport function buildHubSupplyIntent(\n input: HubSupplyInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const chainId = input.chainId ?? BSC_MAINNET_CHAIN_ID\n const enableAsCollateral = input.enableAsCollateral ?? true\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const pToken = getPTokenAddress(chainId, assetUpper)\n const underlying = getUnderlyingTokenAddress(chainId, assetUpper)\n const controller = getControllerAddress(chainId)\n\n const calls: HubTransactionIntent['calls'] = [\n {\n to: underlying,\n data: encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [pToken, amount],\n }),\n value: 0n,\n description: `Approve p${assetUpper} contract to spend ${input.amount} ${assetUpper}`,\n },\n {\n to: pToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'mint',\n args: [amount],\n }),\n value: 0n,\n description: `Supply ${input.amount} ${assetUpper} to Peridot and receive p${assetUpper} tokens`,\n },\n ]\n\n if (enableAsCollateral) {\n calls.push({\n to: controller,\n data: encodeFunctionData({\n abi: COMPTROLLER_ABI,\n functionName: 'enterMarkets',\n args: [[pToken]],\n }),\n value: 0n,\n description: `Enable ${assetUpper} position as collateral for borrowing`,\n })\n }\n\n const collateralNote = enableAsCollateral ? ' and enable as collateral' : ''\n return {\n type: 'hub',\n chainId,\n calls,\n summary: `Supply ${input.amount} ${assetUpper} to Peridot on chain ${input.chainId}${collateralNote}`,\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits } from 'viem'\nimport { PTOKEN_ABI, COMPTROLLER_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getControllerAddress,\n getPTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const hubBorrowSchema = z.object({\n userAddress: evmAddress.describe('The wallet address that will borrow'),\n borrowAsset: z.string().describe('Asset to borrow, e.g. \"USDC\", \"WETH\"'),\n borrowAmount: tokenAmount.describe('Human-readable amount to borrow, e.g. \"500\" for 500 USDC'),\n collateralAssets: z\n .array(z.string())\n .min(1)\n .describe(\n 'Assets already supplied that will act as collateral, e.g. [\"WETH\"]. ' +\n 'These will have enterMarkets called to ensure they are active collateral.',\n ),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia). Use build_cross_chain_borrow_intent for spoke chains.' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubBorrowInput = z.infer<typeof hubBorrowSchema>\n\n/**\n * Builds the transaction calls to borrow from a Peridot hub-chain market.\n *\n * Call sequence:\n * 1. enterMarkets(collateralPTokens) — ensure collateral is active\n * 2. borrow(amount) — borrow from the market\n *\n * Prerequisites:\n * - Collateral must already be supplied (use build_hub_supply_intent first)\n * - Borrow amount must not exceed borrowing capacity (use simulate_borrow first)\n */\nexport function buildHubBorrowIntent(\n input: HubBorrowInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const borrowAssetUpper = input.borrowAsset.toUpperCase()\n const decimals = getAssetDecimals(borrowAssetUpper)\n const amount = parseUnits(input.borrowAmount, decimals)\n\n const borrowPToken = getPTokenAddress(input.chainId, borrowAssetUpper)\n const controller = getControllerAddress(input.chainId)\n const collateralPTokens = input.collateralAssets.map((a) =>\n getPTokenAddress(input.chainId, a.toUpperCase()),\n )\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: controller,\n data: encodeFunctionData({\n abi: COMPTROLLER_ABI,\n functionName: 'enterMarkets',\n args: [collateralPTokens],\n }),\n value: 0n,\n description: `Enable ${input.collateralAssets.join(', ')} as active collateral`,\n },\n {\n to: borrowPToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'borrow',\n args: [amount],\n }),\n value: 0n,\n description: `Borrow ${input.borrowAmount} ${borrowAssetUpper} from Peridot`,\n },\n ],\n summary: `Borrow ${input.borrowAmount} ${borrowAssetUpper} using ${input.collateralAssets.join(', ')} as collateral`,\n warning:\n 'Ensure your health factor stays above 1.2 after borrowing. Use simulate_borrow to verify.',\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits, maxUint256 } from 'viem'\nimport { ERC20_ABI, PTOKEN_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress } from '../../../../shared/zod-utils'\n\nexport const hubRepaySchema = z.object({\n userAddress: evmAddress.describe('The wallet address repaying the debt'),\n asset: z.string().describe('Asset to repay, e.g. \"USDC\", \"WETH\"'),\n amount: z\n .string()\n .refine((v) => v.toLowerCase() === 'max' || /^\\d+(\\.\\d+)?$/.test(v), {\n message: 'Amount must be a positive decimal number (e.g. \"500\") or \"max\" to repay all.',\n })\n .describe(\n 'Human-readable amount to repay, e.g. \"500\" for 500 USDC. ' +\n 'Use \"max\" to repay the full outstanding balance (sets uint256 max).',\n ),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubRepayInput = z.infer<typeof hubRepaySchema>\n\n/**\n * Builds the transaction calls to repay a borrow on a Peridot hub-chain market.\n *\n * Call sequence:\n * 1. approve(pToken, amount) — allow pToken to pull repayment tokens\n * 2. repayBorrow(amount) — repay outstanding debt\n *\n * Use amount = \"max\" to repay the full debt (passes uint256 max to the contract,\n * which the pToken interprets as \"repay all\").\n */\nexport function buildHubRepayIntent(\n input: HubRepayInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const isMax = input.amount.toLowerCase() === 'max'\n const amount = isMax ? maxUint256 : parseUnits(input.amount, decimals)\n\n const pToken = getPTokenAddress(input.chainId, assetUpper)\n const underlying = getUnderlyingTokenAddress(input.chainId, assetUpper)\n\n const displayAmount = isMax ? 'full balance' : `${input.amount} ${assetUpper}`\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: underlying,\n data: encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [pToken, amount],\n }),\n value: 0n,\n description: `Approve p${assetUpper} to pull repayment tokens`,\n },\n {\n to: pToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'repayBorrow',\n args: [amount],\n }),\n value: 0n,\n description: `Repay ${displayAmount} of ${assetUpper} debt`,\n },\n ],\n summary: `Repay ${displayAmount} of ${assetUpper} on Peridot (chain ${input.chainId})`,\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits } from 'viem'\nimport { PTOKEN_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const hubWithdrawSchema = z.object({\n userAddress: evmAddress.describe('The wallet address withdrawing'),\n asset: z.string().describe('Asset to withdraw, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable underlying amount to withdraw, e.g. \"100\" for 100 USDC'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubWithdrawInput = z.infer<typeof hubWithdrawSchema>\n\n/**\n * Builds the transaction call to withdraw (redeem) a supplied asset.\n * Uses redeemUnderlying so the user specifies the exact underlying amount to receive.\n *\n * Will revert on-chain if the withdrawal would cause the user's health factor\n * to drop below the liquidation threshold (i.e., they still have open borrows).\n */\nexport function buildHubWithdrawIntent(\n input: HubWithdrawInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const pToken = getPTokenAddress(input.chainId, assetUpper)\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: pToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'redeemUnderlying',\n args: [amount],\n }),\n value: 0n,\n description: `Withdraw ${input.amount} ${assetUpper} from Peridot`,\n },\n ],\n summary: `Withdraw ${input.amount} ${assetUpper} from Peridot (chain ${input.chainId})`,\n warning:\n 'This will revert if withdrawing would make your outstanding borrows undercollateralized.',\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData } from 'viem'\nimport { COMPTROLLER_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getControllerAddress,\n getPTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress } from '../../../../shared/zod-utils'\n\nexport const hubEnableCollateralSchema = z.object({\n userAddress: evmAddress.describe('The wallet address enabling collateral'),\n assets: z\n .array(z.string())\n .min(1)\n .describe('Assets to enable as collateral, e.g. [\"WETH\", \"USDC\"]'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubEnableCollateralInput = z.infer<typeof hubEnableCollateralSchema>\n\n/**\n * Builds the enterMarkets call to enable one or more supplied assets as collateral.\n * Must be called after supplying assets if they were not enabled during supply.\n * Enabling collateral is required before borrowing against that asset.\n */\nexport function buildHubEnableCollateralIntent(\n input: HubEnableCollateralInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const controller = getControllerAddress(input.chainId)\n const pTokens = input.assets.map((a) => getPTokenAddress(input.chainId, a.toUpperCase()))\n const assetsDisplay = input.assets.map((a) => a.toUpperCase()).join(', ')\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: controller,\n data: encodeFunctionData({\n abi: COMPTROLLER_ABI,\n functionName: 'enterMarkets',\n args: [pTokens],\n }),\n value: 0n,\n description: `Enable ${assetsDisplay} as collateral on Peridot`,\n },\n ],\n summary: `Enable ${assetsDisplay} as collateral on chain ${input.chainId}`,\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData } from 'viem'\nimport { COMPTROLLER_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getControllerAddress,\n getPTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress } from '../../../../shared/zod-utils'\n\nexport const hubDisableCollateralSchema = z.object({\n userAddress: evmAddress.describe('The wallet address disabling collateral'),\n asset: z.string().describe('Asset to disable as collateral, e.g. \"USDC\"'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubDisableCollateralInput = z.infer<typeof hubDisableCollateralSchema>\n\n/**\n * Builds the exitMarket call to disable a supplied asset as collateral.\n *\n * Will revert on-chain if disabling this collateral would make existing borrows\n * undercollateralized. Repay borrows or add more collateral first.\n */\nexport function buildHubDisableCollateralIntent(\n input: HubDisableCollateralInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const assetUpper = input.asset.toUpperCase()\n const controller = getControllerAddress(input.chainId)\n const pToken = getPTokenAddress(input.chainId, assetUpper)\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: controller,\n data: encodeFunctionData({\n abi: COMPTROLLER_ABI,\n functionName: 'exitMarket',\n args: [pToken],\n }),\n value: 0n,\n description: `Disable ${assetUpper} as collateral on Peridot`,\n },\n ],\n summary: `Disable ${assetUpper} as collateral on chain ${input.chainId}`,\n warning:\n 'This will revert if you have outstanding borrows that rely on this collateral.',\n }\n}\n","import { z } from 'zod'\nimport { parseUnits } from 'viem'\nimport { PeridotApiClient } from '../../../../shared/api-client'\nimport {\n ARBITRUM_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n resolveHubChainId,\n} from '../../../../shared/constants'\nimport type {\n CrossChainIntent,\n PeridotConfig,\n RuntimeErc20Balance,\n ComposeFlow,\n} from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const crossChainSupplySchema = z.object({\n userAddress: evmAddress.describe('The wallet address on the source chain'),\n sourceChainId: z\n .number()\n .int()\n .default(ARBITRUM_CHAIN_ID)\n .refine((id) => !isHubChain(id), { message: 'sourceChainId must be a spoke chain (e.g. 42161=Arbitrum, 8453=Base). Use build_hub_supply_intent for hub chains (56, 143, 1868).' })\n .describe(\n 'The spoke chain the user is on, e.g. 42161=Arbitrum, 8453=Base, 1=Ethereum. ' +\n 'This is where the user holds the tokens they want to supply.',\n ),\n asset: z.string().describe('Asset to supply, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable amount to supply, e.g. \"100\" for 100 USDC'),\n enableAsCollateral: z\n .boolean()\n .default(true)\n .describe('Whether to enable the supplied asset as collateral. Defaults to true.'),\n slippage: z\n .number()\n .default(0.01)\n .describe('Bridge slippage tolerance as a decimal (0.01 = 1%). Defaults to 1%.'),\n})\n\nexport type CrossChainSupplyInput = z.input<typeof crossChainSupplySchema>\n\n/**\n * Builds a cross-chain supply intent using Biconomy MEE.\n *\n * Biconomy orchestrates all steps atomically from a single user signature:\n * 1. Bridge asset from source chain → BSC (via Axelar/Squid internally)\n * 2. Approve p{Asset} to spend underlying on BSC\n * 3. mint(amount) — supply to Peridot, receive pTokens\n * 4. enterMarkets([]) — (optional) enable as collateral\n * 5. transfer pTokens — return pTokens to user's EOA on BSC\n *\n * Returns a CrossChainIntent — the user's dApp must pass biconomyInstructions\n * to POST /api/biconomy/execute (or directly to Biconomy's execute endpoint).\n */\nexport async function buildCrossChainSupplyIntent(\n input: CrossChainSupplyInput,\n config: PeridotConfig,\n): Promise<CrossChainIntent> {\n const client = new PeridotApiClient(config)\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const sourceChainId = input.sourceChainId ?? ARBITRUM_CHAIN_ID\n const enableAsCollateral = input.enableAsCollateral ?? true\n const hubChainId = resolveHubChainId(sourceChainId, config.network ?? 'mainnet')\n const sourceToken = getUnderlyingTokenAddress(sourceChainId, assetUpper)\n const hubUnderlying = getUnderlyingTokenAddress(hubChainId, assetUpper)\n const pToken = getPTokenAddress(hubChainId, assetUpper)\n\n const runtimeBalance: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: hubUnderlying,\n }\n\n const composeFlows: ComposeFlow[] = [\n // Step 1: Bridge from spoke → hub\n {\n type: '/instructions/intent-simple' as const,\n data: {\n srcToken: sourceToken,\n dstToken: hubUnderlying,\n srcChainId: sourceChainId,\n dstChainId: hubChainId,\n amount: amount.toString(),\n slippage: input.slippage ?? 0.01,\n },\n batch: false,\n },\n // Step 2: Approve pToken to spend underlying\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function approve(address,uint256)',\n args: [pToken, runtimeBalance],\n to: hubUnderlying,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n // Step 3: Mint pTokens\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function mint(uint256)',\n args: [runtimeBalance],\n to: pToken,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n ]\n\n // Step 4: Enable as collateral\n if (enableAsCollateral) {\n const { getControllerAddress } = await import('../../../../shared/constants')\n const controller = getControllerAddress(hubChainId)\n composeFlows.push({\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function enterMarkets(address[] memory)',\n args: [[pToken]],\n to: controller,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n })\n }\n\n // Step 5: Return pTokens to user's EOA\n const pTokenRuntime: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: pToken,\n constraints: { gte: '1' },\n }\n composeFlows.push({\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function transfer(address,uint256)',\n args: [input.userAddress, pTokenRuntime],\n to: pToken,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n })\n\n const biconomyResponse = await client.biconomyCompose({\n ownerAddress: input.userAddress as `0x${string}`,\n mode: 'eoa',\n composeFlows,\n })\n\n const collateralNote = enableAsCollateral ? ' and enable as collateral' : ''\n const userSteps = [\n `Bridge ${input.amount} ${assetUpper} from chain ${sourceChainId} → hub (chain ${hubChainId})`,\n `Approve Peridot p${assetUpper} market to spend ${assetUpper}`,\n `Supply ${input.amount} ${assetUpper} to Peridot, receiving p${assetUpper}`,\n ...(enableAsCollateral ? [`Enable ${assetUpper} as collateral`] : []),\n `Return p${assetUpper} tokens to your wallet`,\n ]\n\n return {\n type: 'cross-chain',\n sourceChainId,\n destinationChainId: hubChainId,\n summary: `Cross-chain supply ${input.amount} ${assetUpper} from chain ${sourceChainId} to Peridot${collateralNote}`,\n userSteps,\n biconomyInstructions: biconomyResponse,\n estimatedGas: biconomyResponse.estimatedGas ?? 'unknown',\n }\n}\n","import { z } from 'zod'\nimport { parseUnits } from 'viem'\nimport { PeridotApiClient } from '../../../../shared/api-client'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getControllerAddress,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type {\n CrossChainIntent,\n PeridotConfig,\n RuntimeErc20Balance,\n ComposeFlow,\n} from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const crossChainBorrowSchema = z.object({\n userAddress: evmAddress.describe('The wallet address borrowing'),\n collateralAssets: z\n .array(z.string())\n .min(1)\n .describe('Assets already supplied as collateral, e.g. [\"WETH\"]'),\n borrowAsset: z.string().describe('Asset to borrow, e.g. \"USDC\"'),\n borrowAmount: tokenAmount.describe('Human-readable amount, e.g. \"500\" for 500 USDC'),\n targetChainId: z\n .number()\n .int()\n .optional()\n .refine((id) => id === undefined || !isHubChain(id), {\n message:\n 'targetChainId must be a spoke chain (e.g. 42161=Arbitrum, 8453=Base) or omitted to keep funds on the hub.',\n })\n .describe(\n 'Spoke chain to receive borrowed funds, e.g. 42161=Arbitrum. ' +\n 'If omitted, borrowed funds remain on the hub chain (BSC).',\n ),\n slippage: z.number().default(0.01).describe('Bridge slippage tolerance. Defaults to 1%.'),\n})\n\nexport type CrossChainBorrowInput = z.input<typeof crossChainBorrowSchema>\n\n/**\n * Borrows from Peridot hub and optionally bridges the proceeds to a spoke chain.\n *\n * Call sequence (via Biconomy MEE):\n * 1. enterMarkets(collateralPTokens) — ensure collateral is active\n * 2. borrow(amount) — borrow from pToken market on hub\n * 3a. Bridge borrowed tokens → target chain (if targetChainId provided), OR\n * 3b. Transfer borrowed tokens to user's EOA on hub chain\n */\nexport async function buildCrossChainBorrowIntent(\n input: CrossChainBorrowInput,\n config: PeridotConfig,\n): Promise<CrossChainIntent> {\n const client = new PeridotApiClient(config)\n const borrowAssetUpper = input.borrowAsset.toUpperCase()\n const decimals = getAssetDecimals(borrowAssetUpper)\n const amount = parseUnits(input.borrowAmount, decimals)\n\n // Hub chain is always BSC for mainnet\n const actualHubChainId = BSC_MAINNET_CHAIN_ID\n\n const borrowPToken = getPTokenAddress(actualHubChainId, borrowAssetUpper)\n const controller = getControllerAddress(actualHubChainId)\n const hubUnderlying = getUnderlyingTokenAddress(actualHubChainId, borrowAssetUpper)\n const collateralPTokens = input.collateralAssets.map((a) =>\n getPTokenAddress(actualHubChainId, a.toUpperCase()),\n )\n\n const composeFlows: ComposeFlow[] = [\n // Step 1: Enable collateral\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function enterMarkets(address[] memory)',\n args: [collateralPTokens],\n to: controller,\n chainId: actualHubChainId,\n value: '0',\n },\n batch: true,\n },\n // Step 2: Borrow\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function borrow(uint256)',\n args: [amount.toString()],\n to: borrowPToken,\n chainId: actualHubChainId,\n value: '0',\n },\n batch: true,\n },\n ]\n\n const runtimeBalance: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: hubUnderlying,\n constraints: { gte: '1' },\n }\n\n const userSteps = [\n `Enable ${input.collateralAssets.join(', ')} as active collateral`,\n `Borrow ${input.borrowAmount} ${borrowAssetUpper} from Peridot`,\n ]\n\n // Step 3: Deliver borrowed funds\n if (input.targetChainId && input.targetChainId !== actualHubChainId) {\n const targetToken = getUnderlyingTokenAddress(input.targetChainId, borrowAssetUpper)\n composeFlows.push({\n type: '/instructions/intent-simple',\n data: {\n srcToken: hubUnderlying,\n dstToken: targetToken,\n srcChainId: actualHubChainId,\n dstChainId: input.targetChainId,\n amount: runtimeBalance,\n slippage: input.slippage ?? 0.01,\n },\n batch: false,\n } as ComposeFlow)\n userSteps.push(`Bridge ${borrowAssetUpper} from hub → chain ${input.targetChainId}`)\n } else {\n composeFlows.push({\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function transfer(address,uint256)',\n args: [input.userAddress, runtimeBalance],\n to: hubUnderlying,\n chainId: actualHubChainId,\n value: '0',\n },\n batch: true,\n })\n userSteps.push(`Receive ${borrowAssetUpper} in your wallet on chain ${actualHubChainId}`)\n }\n\n const biconomyResponse = await client.biconomyCompose({\n ownerAddress: input.userAddress as `0x${string}`,\n mode: 'eoa',\n composeFlows,\n })\n\n const destination = input.targetChainId ?? actualHubChainId\n\n return {\n type: 'cross-chain',\n sourceChainId: actualHubChainId,\n destinationChainId: destination,\n summary: `Borrow ${input.borrowAmount} ${borrowAssetUpper} from Peridot, receive on chain ${destination}`,\n userSteps,\n biconomyInstructions: biconomyResponse,\n estimatedGas: biconomyResponse.estimatedGas ?? 'unknown',\n }\n}\n","import { z } from 'zod'\nimport { parseUnits } from 'viem'\nimport { PeridotApiClient } from '../../../../shared/api-client'\nimport {\n ARBITRUM_CHAIN_ID,\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type {\n CrossChainIntent,\n PeridotConfig,\n RuntimeErc20Balance,\n} from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const crossChainRepaySchema = z.object({\n userAddress: evmAddress.describe('The wallet address repaying the debt'),\n sourceChainId: z\n .number()\n .int()\n .default(ARBITRUM_CHAIN_ID)\n .refine((id) => !isHubChain(id), {\n message:\n 'sourceChainId must be a spoke chain (e.g. 42161=Arbitrum, 8453=Base). Use build_hub_repay_intent for hub chains (56, 143, 1868).',\n })\n .describe('Spoke chain the user holds repayment tokens on, e.g. 42161=Arbitrum, 8453=Base'),\n asset: z.string().describe('Asset to repay, e.g. \"USDC\", \"USDT\"'),\n amount: tokenAmount.describe('Human-readable amount to repay, e.g. \"500\" for 500 USDC'),\n repayForAddress: evmAddress\n .optional()\n .describe('Repay on behalf of another address. Defaults to userAddress.'),\n slippage: z.number().default(0.01).describe('Bridge slippage tolerance. Defaults to 1%.'),\n})\n\nexport type CrossChainRepayInput = z.input<typeof crossChainRepaySchema>\n\n/**\n * Repays a Peridot borrow from a spoke chain using Biconomy MEE.\n *\n * Call sequence:\n * 1. Bridge repayment tokens from source chain → BSC hub\n * 2. Approve p{Asset} to pull repayment tokens\n * 3. repayBorrow(amount) — or repayBorrowBehalf if repayForAddress set\n * 4. Return any excess tokens to user's EOA on BSC\n */\nexport async function buildCrossChainRepayIntent(\n input: CrossChainRepayInput,\n config: PeridotConfig,\n): Promise<CrossChainIntent> {\n const client = new PeridotApiClient(config)\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const hubChainId = BSC_MAINNET_CHAIN_ID\n const sourceChainId = input.sourceChainId ?? ARBITRUM_CHAIN_ID\n const sourceToken = getUnderlyingTokenAddress(sourceChainId, assetUpper)\n const hubUnderlying = getUnderlyingTokenAddress(hubChainId, assetUpper)\n const pToken = getPTokenAddress(hubChainId, assetUpper)\n\n const runtimeBalance: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: hubUnderlying,\n }\n\n const repayForAddress = input.repayForAddress ?? input.userAddress\n const isBehalf = input.repayForAddress !== undefined && input.repayForAddress !== input.userAddress\n\n const composeFlows = [\n // Step 1: Bridge from spoke → hub\n {\n type: '/instructions/intent-simple' as const,\n data: {\n srcToken: sourceToken,\n dstToken: hubUnderlying,\n srcChainId: sourceChainId,\n dstChainId: hubChainId,\n amount: amount.toString(),\n slippage: input.slippage ?? 0.01,\n },\n batch: false,\n },\n // Step 2: Approve pToken to pull repayment\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function approve(address,uint256)',\n args: [pToken, runtimeBalance],\n to: hubUnderlying,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n // Step 3: Repay borrow\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: isBehalf\n ? 'function repayBorrowBehalf(address,uint256)'\n : 'function repayBorrow(uint256)',\n args: isBehalf ? [repayForAddress, runtimeBalance] : [runtimeBalance],\n to: pToken,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n // Step 4: Return excess to EOA\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function transfer(address,uint256)',\n args: [\n input.userAddress,\n { type: 'runtimeErc20Balance', tokenAddress: hubUnderlying, constraints: { gte: '0' } } satisfies RuntimeErc20Balance,\n ],\n to: hubUnderlying,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n ]\n\n const biconomyResponse = await client.biconomyCompose({\n ownerAddress: input.userAddress as `0x${string}`,\n mode: 'eoa',\n composeFlows,\n })\n\n const behalfNote = isBehalf ? ` on behalf of ${repayForAddress}` : ''\n\n return {\n type: 'cross-chain',\n sourceChainId,\n destinationChainId: hubChainId,\n summary: `Repay ${input.amount} ${assetUpper}${behalfNote} from chain ${sourceChainId} to Peridot`,\n userSteps: [\n `Bridge ${input.amount} ${assetUpper} from chain ${sourceChainId} → BSC`,\n `Approve Peridot p${assetUpper} to pull repayment tokens`,\n `Repay ${input.amount} ${assetUpper} debt${behalfNote}`,\n `Return any excess ${assetUpper} to your BSC wallet`,\n ],\n biconomyInstructions: biconomyResponse,\n estimatedGas: biconomyResponse.estimatedGas ?? 'unknown',\n }\n}\n","import { z } from 'zod'\nimport { parseUnits } from 'viem'\nimport { PeridotApiClient } from '../../../../shared/api-client'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type {\n CrossChainIntent,\n PeridotConfig,\n RuntimeErc20Balance,\n ComposeFlow,\n} from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const crossChainWithdrawSchema = z.object({\n userAddress: evmAddress.describe('The wallet address withdrawing'),\n asset: z.string().describe('Asset to withdraw, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable underlying amount to withdraw, e.g. \"100\"'),\n targetChainId: z\n .number()\n .int()\n .optional()\n .refine((id) => id === undefined || !isHubChain(id), {\n message:\n 'targetChainId must be a spoke chain (e.g. 42161=Arbitrum, 8453=Base) or omitted to keep funds on the hub.',\n })\n .describe(\n 'Spoke chain to receive the withdrawn funds, e.g. 42161=Arbitrum. ' +\n 'If omitted, funds remain on the hub chain (BSC).',\n ),\n slippage: z.number().default(0.01).describe('Bridge slippage tolerance. Defaults to 1%.'),\n})\n\nexport type CrossChainWithdrawInput = z.input<typeof crossChainWithdrawSchema>\n\n/**\n * Withdraws from Peridot hub and optionally bridges proceeds to a spoke chain.\n *\n * Call sequence (via Biconomy MEE):\n * 1. redeemUnderlying(amount) — redeem pTokens for underlying on hub\n * 2a. Bridge underlying → target spoke chain (if targetChainId set), OR\n * 2b. Transfer to user's EOA on hub chain\n */\nexport async function buildCrossChainWithdrawIntent(\n input: CrossChainWithdrawInput,\n config: PeridotConfig,\n): Promise<CrossChainIntent> {\n const client = new PeridotApiClient(config)\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const hubChainId = BSC_MAINNET_CHAIN_ID\n const pToken = getPTokenAddress(hubChainId, assetUpper)\n const hubUnderlying = getUnderlyingTokenAddress(hubChainId, assetUpper)\n\n const runtimeBalance: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: hubUnderlying,\n constraints: { gte: '1' },\n }\n\n const composeFlows: ComposeFlow[] = [\n // Step 1: Redeem from Peridot\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function redeemUnderlying(uint256)',\n args: [amount.toString()],\n to: pToken,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n ]\n\n const userSteps = [`Redeem ${input.amount} ${assetUpper} from Peridot (p${assetUpper} → ${assetUpper})`]\n\n // Step 2: Deliver funds\n if (input.targetChainId && input.targetChainId !== hubChainId) {\n const targetToken = getUnderlyingTokenAddress(input.targetChainId, assetUpper)\n composeFlows.push({\n type: '/instructions/intent-simple',\n data: {\n srcToken: hubUnderlying,\n dstToken: targetToken,\n srcChainId: hubChainId,\n dstChainId: input.targetChainId,\n amount: runtimeBalance,\n slippage: input.slippage ?? 0.01,\n },\n batch: false,\n } as ComposeFlow)\n userSteps.push(`Bridge ${assetUpper} from hub → chain ${input.targetChainId}`)\n } else {\n composeFlows.push({\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function transfer(address,uint256)',\n args: [input.userAddress, runtimeBalance],\n to: hubUnderlying,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n })\n userSteps.push(`Receive ${assetUpper} in your wallet on BSC`)\n }\n\n const biconomyResponse = await client.biconomyCompose({\n ownerAddress: input.userAddress as `0x${string}`,\n mode: 'eoa',\n composeFlows,\n })\n\n const destination = input.targetChainId ?? hubChainId\n\n return {\n type: 'cross-chain',\n sourceChainId: hubChainId,\n destinationChainId: destination,\n summary: `Withdraw ${input.amount} ${assetUpper} from Peridot, receive on chain ${destination}`,\n userSteps,\n biconomyInstructions: biconomyResponse,\n estimatedGas: biconomyResponse.estimatedGas ?? 'unknown',\n }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { PeridotConfig, TransactionStatus } from '../../../shared/types'\n\nexport const checkTransactionStatusSchema = z.object({\n superTxHash: z\n .string()\n .describe(\n 'The Biconomy super-transaction hash returned after executing a cross-chain intent. ' +\n 'Looks like a regular tx hash (0x...).',\n ),\n})\n\nexport type CheckTransactionStatusInput = z.infer<typeof checkTransactionStatusSchema>\n\n/**\n * Polls Biconomy for the status of a cross-chain super-transaction.\n * Call this after the user has signed and submitted a CrossChainIntent.\n */\nexport async function checkTransactionStatus(\n input: CheckTransactionStatusInput,\n config: PeridotConfig,\n): Promise<TransactionStatus> {\n const client = new PeridotApiClient(config)\n return client.biconomyGetStatus(input.superTxHash)\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { LiquidatablePositions, PeridotConfig } from '../../../shared/types'\n\nexport const getLiquidatablePositionsSchema = z.object({\n chainId: z\n .number()\n .int()\n .optional()\n .describe(\n 'Filter to a single hub chain (56=BSC, 143=Monad, 1868=Somnia). ' +\n 'Omit to return at-risk accounts across all chains.',\n ),\n minShortfall: z\n .number()\n .min(0)\n .optional()\n .describe(\n 'Minimum shortfall_usd threshold in USD (default: 0 — returns all underwater accounts). ' +\n 'Use e.g. 100 to focus only on meaningfully undercollateralised positions.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe('Maximum number of results (default: 50, max: 200). Results are ordered by shortfall descending.'),\n})\n\nexport type GetLiquidatablePositionsInput = z.infer<typeof getLiquidatablePositionsSchema>\n\n/**\n * Fetch accounts currently eligible for liquidation from the platform's\n * health scanner endpoint.\n *\n * Returns the accounts ordered by shortfall_usd descending — the most\n * underwater positions appear first.\n */\nexport async function getLiquidatablePositions(\n input: GetLiquidatablePositionsInput,\n config: PeridotConfig,\n): Promise<LiquidatablePositions> {\n const client = new PeridotApiClient(config)\n const opts: { chainId?: number; minShortfall?: number; limit?: number } = {}\n if (input.chainId !== undefined) opts.chainId = input.chainId\n if (input.minShortfall !== undefined) opts.minShortfall = input.minShortfall\n if (input.limit !== undefined) opts.limit = input.limit\n return client.getLiquidatablePositions(opts)\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits, maxUint256 } from 'viem'\nimport { ERC20_ABI, PTOKEN_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress } from '../../../../shared/zod-utils'\n\nexport const hubLiquidateSchema = z.object({\n liquidatorAddress: evmAddress.describe('The wallet address executing the liquidation (your address)'),\n borrowerAddress: evmAddress.describe('The underwater borrower address to liquidate'),\n repayAsset: z\n .string()\n .describe(\n 'The asset you will repay on behalf of the borrower, e.g. \"USDC\". ' +\n 'This must be an asset the borrower has borrowed.',\n ),\n repayAmount: z\n .string()\n .refine((v) => v.toLowerCase() === 'max' || /^\\d+(\\.\\d+)?$/.test(v), {\n message: 'Amount must be a positive decimal number (e.g. \"500\") or \"max\" for uint256 max.',\n })\n .describe(\n 'Amount of repayAsset to repay (human-readable, e.g. \"500\" for 500 USDC). ' +\n 'A liquidator may repay at most 50% of the borrower\\'s outstanding debt per call (close factor). ' +\n 'Use \"max\" to pass uint256 max — the protocol will cap it at the close factor automatically.',\n ),\n collateralAsset: z\n .string()\n .describe(\n 'The collateral asset you want to seize in return, e.g. \"WETH\". ' +\n 'This must be an asset the borrower has supplied as collateral. ' +\n 'You receive the equivalent value in pTokens (+ liquidation incentive bonus).',\n ),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain where the underwater position exists. Defaults to BSC (56).'),\n})\n\nexport type HubLiquidateInput = z.infer<typeof hubLiquidateSchema>\n\n/**\n * Builds the transaction calls to liquidate an underwater Peridot borrower\n * on a hub chain.\n *\n * Compound V2 liquidation flow:\n * 1. approve(pRepayToken, repayAmount) — allow the repay pToken to pull funds\n * 2. liquidateBorrow(borrower, repayAmount, — repay debt, seize collateral pTokens\n * pCollateralToken)\n *\n * The liquidator receives pToken shares of the collateral asset.\n * To receive the underlying, call redeem() on the collateral pToken afterward.\n *\n * IMPORTANT: verify the borrower is still underwater immediately before\n * submitting — health can change between blocks. Use get_liquidatable_positions\n * or get_account_liquidity to confirm shortfallUsd > 0.\n */\nexport function buildHubLiquidateIntent(\n input: HubLiquidateInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const repayAsset = input.repayAsset.toUpperCase()\n const collateralAsset = input.collateralAsset.toUpperCase()\n\n const repayDecimals = getAssetDecimals(repayAsset)\n const isMax = input.repayAmount.toLowerCase() === 'max'\n const repayAmount = isMax ? maxUint256 : parseUnits(input.repayAmount, repayDecimals)\n\n const pRepayToken = getPTokenAddress(input.chainId, repayAsset)\n const pCollateralToken = getPTokenAddress(input.chainId, collateralAsset)\n const underlyingRepay = getUnderlyingTokenAddress(input.chainId, repayAsset)\n\n const displayAmount = isMax ? 'max (capped at close factor)' : `${input.repayAmount} ${repayAsset}`\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: underlyingRepay,\n data: encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [pRepayToken, repayAmount],\n }),\n value: 0n,\n description: `Approve p${repayAsset} to pull ${displayAmount} for liquidation`,\n },\n {\n to: pRepayToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'liquidateBorrow',\n args: [input.borrowerAddress as `0x${string}`, repayAmount, pCollateralToken],\n }),\n value: 0n,\n description:\n `Liquidate ${input.borrowerAddress}: repay ${displayAmount} of ${repayAsset}, ` +\n `seize p${collateralAsset} collateral`,\n },\n ],\n summary:\n `Liquidate ${input.borrowerAddress} on chain ${input.chainId}: ` +\n `repay ${displayAmount} of ${repayAsset}, receive p${collateralAsset}`,\n warning:\n 'Verify the borrower is still underwater (shortfallUsd > 0) immediately before submitting. ' +\n 'The transaction will revert if the position has been partially repaid between blocks.',\n }\n}\n","/**\n * Lending feature tool registry.\n *\n * Adding a new tool:\n * 1. Implement the function in the appropriate read/ or intents/ subdirectory\n * 2. Add an entry to the `lendingTools` array below\n * 3. It will automatically appear in the MCP server and all framework adapters\n *\n * Adding a new feature (e.g. margin):\n * Create src/features/margin/tools.ts with the same pattern, then add it to\n * src/adapters/mcp/server.ts's `allTools` array.\n */\n\nimport type { ToolDefinition } from '../../shared/types'\n\nimport { listMarketsSchema, listMarkets } from './read/list-markets'\nimport { getPortfolioSchema, getPortfolio } from './read/get-portfolio'\nimport { getLeaderboardSchema, getLeaderboard } from './read/get-leaderboard'\nimport { getMarketRatesSchema, getMarketRates } from './read/get-market-rates'\nimport { getUserPositionSchema, getUserPosition } from './read/get-user-position'\nimport { simulateBorrowSchema, simulateBorrow } from './read/simulate-borrow'\nimport { getAccountLiquiditySchema, getAccountLiquidity } from './read/get-account-liquidity'\nimport { hubSupplySchema, buildHubSupplyIntent } from './intents/hub/supply'\nimport { hubBorrowSchema, buildHubBorrowIntent } from './intents/hub/borrow'\nimport { hubRepaySchema, buildHubRepayIntent } from './intents/hub/repay'\nimport { hubWithdrawSchema, buildHubWithdrawIntent } from './intents/hub/withdraw'\nimport { hubEnableCollateralSchema, buildHubEnableCollateralIntent } from './intents/hub/enable-collateral'\nimport { hubDisableCollateralSchema, buildHubDisableCollateralIntent } from './intents/hub/disable-collateral'\nimport { crossChainSupplySchema, buildCrossChainSupplyIntent } from './intents/cross-chain/supply'\nimport { crossChainBorrowSchema, buildCrossChainBorrowIntent } from './intents/cross-chain/borrow'\nimport { crossChainRepaySchema, buildCrossChainRepayIntent } from './intents/cross-chain/repay'\nimport { crossChainWithdrawSchema, buildCrossChainWithdrawIntent } from './intents/cross-chain/withdraw'\nimport { checkTransactionStatusSchema, checkTransactionStatus } from './status/check-transaction'\nimport { getLiquidatablePositionsSchema, getLiquidatablePositions } from './read/get-liquidatable-positions'\nimport { hubLiquidateSchema, buildHubLiquidateIntent } from './intents/hub/liquidate'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const lendingTools: ToolDefinition<any, any>[] = [\n // ── Read / Simulate ──────────────────────────────────────────────────────\n\n {\n name: 'list_markets',\n description:\n 'List all Peridot lending markets across all chains with key metrics: asset symbol, chainId, ' +\n 'price (USD), TVL (USD), utilization %, available liquidity (USD), and collateral factor %. ' +\n 'Results are sorted by TVL descending — the deepest, most liquid markets appear first. ' +\n 'Call this when the user asks \"what can I lend or borrow?\", \"which assets are available?\", ' +\n 'or before recommending a specific market when you do not already know what is available. ' +\n 'Optionally pass chainId (56=BSC, 143=Monad, 1868=Somnia) to restrict results to one chain.',\n inputSchema: listMarketsSchema,\n execute: listMarkets,\n category: 'lending',\n },\n\n {\n name: 'get_leaderboard',\n description:\n 'Fetch the Peridot points leaderboard: ranked list of top users by total protocol points earned. ' +\n 'Each entry contains: rank, wallet address, totalPoints, supplyCount, borrowCount, repayCount, ' +\n 'redeemCount, and last-updated timestamp. Points reflect on-chain DeFi activity and daily logins. ' +\n 'Call this when the user asks \"who are the top users?\", \"show me the leaderboard\", ' +\n '\"how many points does address X have?\", or \"where do I rank?\". ' +\n 'Use limit (default 50, max 100) to control result size.',\n inputSchema: getLeaderboardSchema,\n execute: getLeaderboard,\n category: 'lending',\n },\n\n {\n name: 'get_market_rates',\n description:\n 'Fetch the full rate breakdown for a specific Peridot market (asset + chainId). ' +\n 'Returns: base supply APY, base borrow APY, PERIDOT token reward APY (supply and borrow), ' +\n 'boost source APY (Morpho vault / PancakeSwap LP / Magma staking), boost reward APY, ' +\n 'total supply APY (= base + peridot + boost_source + boost_rewards), ' +\n 'net borrow APY (= base borrow − peridot borrow reward), ' +\n 'TVL (USD), utilization %, available liquidity (USD), asset price (USD), collateral factor %. ' +\n 'Call this when the user asks about APY, yields, borrow rates, or liquidity for a specific asset. ' +\n 'If you do not know which chainId the asset is on, call list_markets first.',\n inputSchema: getMarketRatesSchema,\n execute: getMarketRates,\n category: 'lending',\n },\n\n {\n name: 'get_portfolio',\n description:\n \"Fetch a wallet's full Peridot portfolio overview: portfolio summary (currentValue, \" +\n 'totalSupplied, totalBorrowed, netApy, simplified healthFactor), per-asset breakdown ' +\n 'with allocation percentages (supplied, borrowed, net, % of portfolio), all transaction ' +\n 'counts (totalCount, supply/borrow/repay/redeem), and lifetime earnings ' +\n '(effectiveApy, totalLifetimeEarnings in USD). ' +\n 'Call this when the user asks \"how is my portfolio performing?\", \"what are my earnings?\", ' +\n '\"show me my full breakdown\", \"what percentage of my portfolio is in X?\", or any question ' +\n 'about lifetime yield or activity history. ' +\n 'Results are cached for 30 s — concurrent calls for the same address share one request. ' +\n 'For a quick pre-action exposure check before borrowing or withdrawing, ' +\n 'use get_user_position instead (lighter, returns simplified health factor).',\n inputSchema: getPortfolioSchema,\n execute: getPortfolio,\n category: 'lending',\n },\n\n {\n name: 'get_user_position',\n description:\n \"Fetch a user's current Peridot portfolio snapshot: totalSuppliedUsd, totalBorrowedUsd, \" +\n 'netWorthUsd, netApyPct, per-asset breakdown, and transaction counts (supply/borrow/repay/redeem). ' +\n 'Also returns a simplified healthFactor estimate (totalSupplied / totalBorrowed). ' +\n 'IMPORTANT: this estimate ignores per-asset collateral factors and will OVERSTATE the real ' +\n 'on-chain health — treat it as a quick indicator only. ' +\n 'Rule of thumb: above 2.0 = low near-term risk; below 2.0 = call get_account_liquidity before ' +\n 'recommending further borrows or large withdrawals. ' +\n 'ALWAYS call this before building any borrow, withdraw, or repay intent so you know the ' +\n \"user's current exposure and can explain the risk to them.\",\n inputSchema: getUserPositionSchema,\n execute: getUserPosition,\n category: 'lending',\n },\n\n {\n name: 'simulate_borrow',\n description:\n \"Simulate the health factor impact of a proposed borrow before submitting any transaction. \" +\n 'Returns: currentHealthFactor, projectedHealthFactor, borrowAmountUsd, isSafe (bool), ' +\n 'riskLevel (safe | moderate | high | critical | liquidatable), and maxSafeBorrowUsd. ' +\n 'ALWAYS call this before build_hub_borrow_intent or build_cross_chain_borrow_intent. ' +\n 'Rules: if isSafe=false → explain the risk and do NOT build the intent. ' +\n 'If riskLevel is \"high\" or worse → warn the user and confirm before proceeding. ' +\n 'If riskLevel is \"moderate\" → note the risk, suggest a smaller amount or adding more collateral. ' +\n 'Never skip this step even if the user sounds confident — you cannot predict the liquidation ' +\n 'threshold without it.',\n inputSchema: simulateBorrowSchema,\n execute: simulateBorrow,\n category: 'lending',\n },\n\n {\n name: 'get_account_liquidity',\n description:\n \"Read the authoritative on-chain borrow capacity and health directly from Peridot's \" +\n 'Comptroller contract. Returns: liquidityUsd (how much more the user can safely borrow), ' +\n 'shortfallUsd (how much underwater — non-zero means they are at risk of liquidation), ' +\n 'and isHealthy (true when shortfall = 0). ' +\n 'Use this instead of get_user_position when precision matters: before large withdrawals, ' +\n 'when the simplified health factor is near 1.5, or when the user asks whether they are ' +\n 'at risk of liquidation. This is the same value the protocol uses on-chain.',\n inputSchema: getAccountLiquiditySchema,\n execute: getAccountLiquidity,\n category: 'lending',\n },\n\n {\n name: 'get_liquidatable_positions',\n description:\n 'Fetch a list of borrowers currently underwater (shortfallUsd > 0) and eligible for liquidation ' +\n 'on Peridot hub chains. Data is sourced from the on-chain health scanner that indexes borrow events ' +\n 'and recomputes account health periodically. ' +\n 'IMPORTANT: if this returns an empty list, the scanner pipeline (scan_borrow_events + ' +\n 'scan_account_health) may not have run yet — the data table could be empty rather than meaning ' +\n 'no positions are underwater. In that case, inform the user that liquidation data is not yet ' +\n 'available and suggest checking back later. ' +\n 'Each result contains: address, chainId, shortfallUsd (how far underwater in USD), ' +\n 'liquidityUsd (0 when underwater), and checkedAt (when last scanned). ' +\n 'Results are ordered by shortfallUsd descending — the most undercollateralised positions first. ' +\n 'Use minShortfall to filter out dust positions (e.g. minShortfall=100 for $100+ shortfall). ' +\n 'Always call get_account_liquidity to re-confirm a position is still underwater immediately ' +\n 'before building a liquidation intent — health can change between scanner runs.',\n inputSchema: getLiquidatablePositionsSchema,\n execute: getLiquidatablePositions,\n category: 'liquidations',\n },\n\n // ── Hub-chain intents (user on BSC / Monad / Somnia) ─────────────────────\n // Hub chains host Peridot lending pools natively.\n // Hub chainIds: BSC (56), Monad (143), Somnia (1868).\n // If the user is on any other chain, use the cross-chain tools instead.\n\n {\n name: 'build_hub_supply_intent',\n description:\n 'Build signed-ready calldata to supply an asset to Peridot on a hub chain. ' +\n 'USE THIS TOOL ONLY when the user is already on a hub chain: BSC (56), Monad (143), or Somnia (1868). ' +\n 'If the user is on Arbitrum (42161), Base (8453), Ethereum (1), Polygon (137), Optimism (10), ' +\n 'or Avalanche (43114), use build_cross_chain_supply_intent instead. ' +\n 'Returns an ordered `calls` array: approve ERC-20 → mint pToken → enterMarkets (enable collateral). ' +\n 'Tell the user to sign and submit each call in sequence using their wallet.',\n inputSchema: hubSupplySchema,\n execute: buildHubSupplyIntent,\n category: 'lending',\n },\n\n {\n name: 'build_hub_borrow_intent',\n description:\n 'Build calldata to borrow from Peridot on a hub chain (BSC 56, Monad 143, or Somnia 1868). ' +\n 'Returns ordered calls: enterMarkets (activate collateral if needed) → borrow. ' +\n 'REQUIRED BEFORE CALLING THIS: run simulate_borrow and confirm isSafe=true. ' +\n 'If the user is on a spoke chain (Arbitrum, Base, Ethereum, etc.), use ' +\n 'build_cross_chain_borrow_intent instead. ' +\n 'Tell the user to sign and submit each call in order.',\n inputSchema: hubBorrowSchema,\n execute: buildHubBorrowIntent,\n category: 'lending',\n },\n\n {\n name: 'build_hub_repay_intent',\n description:\n 'Build calldata to repay an outstanding Peridot borrow on a hub chain (BSC 56, Monad 143, Somnia 1868). ' +\n 'Returns ordered calls: approve ERC-20 → repayBorrow. ' +\n 'Pass amount=\"max\" to repay the entire outstanding debt (recommended to avoid dust). ' +\n 'If the user is on a spoke chain, use build_cross_chain_repay_intent instead. ' +\n 'Tell the user to sign and submit each call in order.',\n inputSchema: hubRepaySchema,\n execute: buildHubRepayIntent,\n category: 'lending',\n },\n\n {\n name: 'build_hub_withdraw_intent',\n description:\n 'Build calldata to withdraw (redeem) supplied assets from Peridot on a hub chain. ' +\n 'ALWAYS call get_user_position first to check for active borrows. ' +\n 'If the user has outstanding debt, also call get_account_liquidity to verify the ' +\n 'withdrawal will not cause a shortfall — the contract will revert on-chain if it does. ' +\n 'If the user is on a spoke chain, use build_cross_chain_withdraw_intent instead.',\n inputSchema: hubWithdrawSchema,\n execute: buildHubWithdrawIntent,\n category: 'lending',\n },\n\n {\n name: 'build_enable_collateral_intent',\n description:\n 'Build the transaction call to enable a supplied asset as collateral in Peridot (enterMarkets). ' +\n 'This is required before you can borrow against a supplied asset. ' +\n 'NOTE: build_hub_supply_intent already calls enterMarkets by default — only call this ' +\n 'separately if the user supplied an asset previously without enabling collateral, ' +\n 'or if they disabled it and want to re-enable it.',\n inputSchema: hubEnableCollateralSchema,\n execute: buildHubEnableCollateralIntent,\n category: 'lending',\n },\n\n {\n name: 'build_disable_collateral_intent',\n description:\n 'Build the transaction call to stop using a supplied asset as collateral (exitMarket). ' +\n 'ALWAYS call get_account_liquidity first and confirm shortfallUsd=0 after the removal — ' +\n 'the contract will revert if any active borrow relies on this asset as collateral. ' +\n 'Explain to the user that disabling collateral reduces their borrow capacity.',\n inputSchema: hubDisableCollateralSchema,\n execute: buildHubDisableCollateralIntent,\n category: 'lending',\n },\n\n {\n name: 'build_liquidation_intent',\n description:\n 'Build calldata to liquidate an underwater Peridot borrower on a hub chain. ' +\n 'The liquidator repays part of the borrower\\'s debt (up to 50% per call — the protocol close factor) ' +\n 'and in return seizes an equivalent value of the borrower\\'s collateral plus the liquidation bonus. ' +\n 'Seized collateral is received as pToken shares — call redeem on the collateral pToken afterward ' +\n 'to convert pTokens back to the underlying asset. ' +\n 'REQUIRED BEFORE CALLING THIS: ' +\n '1. Call get_liquidatable_positions or get_account_liquidity to confirm shortfallUsd > 0. ' +\n '2. Verify the borrower has borrowed repayAsset and supplied collateralAsset as collateral. ' +\n '3. Never build a liquidation intent without confirming the position is still underwater. ' +\n 'Returns ordered calls: approve underlying → liquidateBorrow. ' +\n 'Only works on hub chains (BSC 56, Monad 143, Somnia 1868).',\n inputSchema: hubLiquidateSchema,\n execute: buildHubLiquidateIntent,\n category: 'liquidations',\n },\n\n // ── Cross-chain intents (user on a spoke chain) ───────────────────────────\n // Spoke chains: Arbitrum (42161), Base (8453), Ethereum (1),\n // Polygon (137), Optimism (10), Avalanche (43114).\n // These call Biconomy MEE /compose to produce a single cross-chain payload.\n // The user signs ONE transaction in their dApp; Biconomy executes the bridge + action.\n // Use check_transaction_status to track completion.\n\n {\n name: 'build_cross_chain_supply_intent',\n description:\n 'Build a cross-chain supply intent for a user whose tokens are on a spoke chain. ' +\n 'USE THIS when the user is on Arbitrum (42161), Base (8453), Ethereum (1), Polygon (137), ' +\n 'Optimism (10), or Avalanche (43114). ' +\n 'Do NOT use this for BSC (56), Monad (143), or Somnia (1868) — those are hub chains, ' +\n 'use build_hub_supply_intent instead. ' +\n 'REQUIRES: biconomyApiKey must be set in config (BICONOMY_API_KEY env var on the MCP server). ' +\n 'If it is not set, this tool will fail — inform the user that cross-chain operations are not ' +\n 'available in this deployment. ' +\n 'Bridges tokens from the spoke chain to BSC and deposits into Peridot atomically. ' +\n 'Returns biconomyInstructions — the user signs one transaction in their dApp, which submits ' +\n 'the payload to Biconomy /execute. ' +\n 'After the user submits, call check_transaction_status with the returned superTxHash to track it.',\n inputSchema: crossChainSupplySchema,\n execute: buildCrossChainSupplyIntent,\n category: 'lending',\n },\n\n {\n name: 'build_cross_chain_borrow_intent',\n description:\n 'Borrow from Peridot on BSC and optionally bridge the borrowed amount back to a spoke chain, ' +\n 'all in a single atomic cross-chain operation via Biconomy MEE. ' +\n 'REQUIRED BEFORE CALLING THIS: run simulate_borrow and confirm isSafe=true. ' +\n 'REQUIRES: biconomyApiKey must be set in config (BICONOMY_API_KEY env var on the MCP server). ' +\n 'If it is not set, this tool will fail — inform the user that cross-chain operations are not ' +\n 'available in this deployment. ' +\n 'Returns biconomyInstructions for a single user signature in their dApp. ' +\n 'Use check_transaction_status to track the cross-chain execution.',\n inputSchema: crossChainBorrowSchema,\n execute: buildCrossChainBorrowIntent,\n category: 'lending',\n },\n\n {\n name: 'build_cross_chain_repay_intent',\n description:\n 'Repay a Peridot borrow using tokens held on a spoke chain — for example, repay a ' +\n 'BSC USDC debt by spending USDC on Arbitrum. Bridges and repays in one atomic operation. ' +\n 'Useful when the user wants to repay but their tokens are not on BSC. ' +\n 'REQUIRES: biconomyApiKey must be set in config (BICONOMY_API_KEY env var on the MCP server). ' +\n 'If it is not set, this tool will fail — inform the user that cross-chain operations are not ' +\n 'available in this deployment. ' +\n 'Returns biconomyInstructions for a single user signature in their dApp.',\n inputSchema: crossChainRepaySchema,\n execute: buildCrossChainRepayIntent,\n category: 'lending',\n },\n\n {\n name: 'build_cross_chain_withdraw_intent',\n description:\n 'Withdraw supplied assets from Peridot on BSC and optionally bridge them to a spoke chain, ' +\n 'all in one atomic cross-chain operation. ' +\n 'ALWAYS call get_user_position first to check for active borrows; ' +\n 'if present, also call get_account_liquidity to verify the withdrawal will not cause a shortfall. ' +\n 'REQUIRES: biconomyApiKey must be set in config (BICONOMY_API_KEY env var on the MCP server). ' +\n 'If it is not set, this tool will fail — inform the user that cross-chain operations are not ' +\n 'available in this deployment. ' +\n 'Returns biconomyInstructions for a single user signature in their dApp.',\n inputSchema: crossChainWithdrawSchema,\n execute: buildCrossChainWithdrawIntent,\n category: 'lending',\n },\n\n // ── Status ───────────────────────────────────────────────────────────────\n\n {\n name: 'check_transaction_status',\n description:\n 'Check the execution status of a submitted cross-chain Biconomy transaction by its superTxHash. ' +\n 'Returns one of: pending (not yet picked up), processing (bridge/relay in progress), ' +\n 'success (all cross-chain steps completed), failed (reverted or timed out), ' +\n 'not_found (hash unknown — may not have been submitted yet). ' +\n 'Call this after the user submits a cross-chain intent and poll every ~10s until ' +\n 'status is \"success\" or \"failed\". Only cross-chain intents produce a superTxHash — ' +\n 'hub-chain intents give standard on-chain tx hashes that can be checked on a block explorer.',\n inputSchema: checkTransactionStatusSchema,\n execute: checkTransactionStatus,\n category: 'status',\n },\n]\n"],"mappings":"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","names":["address","z","z","z","z","z","z","z","z","z","z","z","Decimal","z","z","Decimal","z","z","z","encodeFunctionData","parseUnits","z","parseUnits","encodeFunctionData","z","encodeFunctionData","parseUnits","z","parseUnits","encodeFunctionData","z","encodeFunctionData","parseUnits","z","parseUnits","encodeFunctionData","z","encodeFunctionData","z","encodeFunctionData","z","encodeFunctionData","z","encodeFunctionData","z","parseUnits","z","parseUnits","getControllerAddress","z","parseUnits","z","parseUnits","z","parseUnits","z","parseUnits","z","parseUnits","z","parseUnits","z","z","z","z","z","encodeFunctionData","parseUnits","maxUint256","z","maxUint256","parseUnits","encodeFunctionData"]}
1
+ {"version":3,"sources":["../../../src/shared/constants.ts","../../../src/adapters/vercel-ai/index.ts","../../../src/features/lending/read/list-markets.ts","../../../src/shared/api-client.ts","../../../src/features/lending/read/get-portfolio.ts","../../../src/shared/on-chain-position.ts","../../../src/shared/abis.ts","../../../src/shared/zod-utils.ts","../../../src/shared/cache.ts","../../../src/features/lending/read/get-leaderboard.ts","../../../src/features/lending/read/get-market-rates.ts","../../../src/features/lending/read/get-user-position.ts","../../../src/features/lending/read/simulate-borrow.ts","../../../src/features/lending/read/get-account-liquidity.ts","../../../src/features/lending/intents/hub/supply.ts","../../../src/features/lending/intents/hub/borrow.ts","../../../src/features/lending/intents/hub/repay.ts","../../../src/features/lending/intents/hub/withdraw.ts","../../../src/features/lending/intents/hub/enable-collateral.ts","../../../src/features/lending/intents/hub/disable-collateral.ts","../../../src/features/lending/intents/cross-chain/supply.ts","../../../src/features/lending/intents/cross-chain/borrow.ts","../../../src/features/lending/intents/cross-chain/repay.ts","../../../src/features/lending/intents/cross-chain/withdraw.ts","../../../src/features/lending/status/check-transaction.ts","../../../src/features/lending/read/get-liquidatable-positions.ts","../../../src/features/lending/intents/hub/liquidate.ts","../../../src/features/lending/tools.ts"],"sourcesContent":["import type { Address } from 'viem'\n\n// ---------------------------------------------------------------------------\n// API endpoints\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_API_BASE_URL = 'https://app.peridot.finance'\nexport const BICONOMY_API_URL = 'https://api.biconomy.io'\n\n// ---------------------------------------------------------------------------\n// Chain IDs\n// ---------------------------------------------------------------------------\n\n/** Hub chains host the pToken lending pools natively. */\nexport const HUB_CHAIN_IDS = [56, 97, 143, 10143, 1868, 50312] as const\nexport type HubChainId = (typeof HUB_CHAIN_IDS)[number]\n\nexport const BSC_MAINNET_CHAIN_ID = 56\nexport const BSC_TESTNET_CHAIN_ID = 97\nexport const MONAD_MAINNET_CHAIN_ID = 143\nexport const MONAD_TESTNET_CHAIN_ID = 10143\nexport const SOMNIA_MAINNET_CHAIN_ID = 1868\nexport const SOMNIA_TESTNET_CHAIN_ID = 50312\n\n/** Spoke chains — users bridge to the hub to interact with the protocol. */\nexport const ARBITRUM_CHAIN_ID = 42161\nexport const BASE_CHAIN_ID = 8453\nexport const ETHEREUM_CHAIN_ID = 1\nexport const POLYGON_CHAIN_ID = 137\nexport const OPTIMISM_CHAIN_ID = 10\nexport const AVALANCHE_CHAIN_ID = 43114\n\n/** Map of human-readable chain names for error messages. */\nexport const CHAIN_NAMES: Record<number, string> = {\n [BSC_MAINNET_CHAIN_ID]: 'BSC Mainnet',\n [BSC_TESTNET_CHAIN_ID]: 'BSC Testnet',\n [MONAD_MAINNET_CHAIN_ID]: 'Monad Mainnet',\n [MONAD_TESTNET_CHAIN_ID]: 'Monad Testnet',\n [SOMNIA_MAINNET_CHAIN_ID]: 'Somnia Mainnet',\n [SOMNIA_TESTNET_CHAIN_ID]: 'Somnia Testnet',\n [ARBITRUM_CHAIN_ID]: 'Arbitrum',\n [BASE_CHAIN_ID]: 'Base',\n [ETHEREUM_CHAIN_ID]: 'Ethereum',\n [POLYGON_CHAIN_ID]: 'Polygon',\n [OPTIMISM_CHAIN_ID]: 'Optimism',\n [AVALANCHE_CHAIN_ID]: 'Avalanche',\n}\n\nexport function isHubChain(chainId: number): boolean {\n return (HUB_CHAIN_IDS as readonly number[]).includes(chainId)\n}\n\n/** For spoke chains, returns the hub chain that hosts the markets. */\nexport function resolveHubChainId(chainId: number, network: 'mainnet' | 'testnet' = 'mainnet'): number {\n if (isHubChain(chainId)) return chainId\n return network === 'testnet' ? BSC_TESTNET_CHAIN_ID : BSC_MAINNET_CHAIN_ID\n}\n\n// ---------------------------------------------------------------------------\n// Contract addresses — Hub chains\n// ---------------------------------------------------------------------------\n\nexport const PERIDOT_CONTROLLER: Partial<Record<number, Address>> = {\n [BSC_MAINNET_CHAIN_ID]: '0x6fC0c15531CB5901ac72aB3CFCd9dF6E99552e14',\n // [MONAD_MAINNET_CHAIN_ID]: '0x...', // TODO: add when deployed\n // [SOMNIA_MAINNET_CHAIN_ID]: '0x...', // TODO: add when deployed\n}\n\n/** pToken market addresses per hub chain, keyed by asset symbol (uppercase). */\nexport const PERIDOT_MARKETS: Partial<Record<number, Partial<Record<string, Address>>>> = {\n [BSC_MAINNET_CHAIN_ID]: {\n WETH: '0x28E4F2Bb64ac79500ec3CAa074A3C30721B6bC84',\n USDC: '0x1A726369Bfc60198A0ce19C66726C8046c0eC17e',\n WBNB: '0xD9fDF5E2c7a2e7916E7f10Da276D95d4daC5a3c3',\n USDT: '0xc37f3869720B672addFE5F9E22a9459e0E851372',\n WBTC: '0xdCAbDc1F0B5e603b9191be044a912A8A2949e212',\n AUSD: '0x7A9940B77c0B6DFCcA2028b9F3CCa88E5DC36ebb',\n },\n // [MONAD_MAINNET_CHAIN_ID]: { ... }, // TODO: add when deployed\n // [SOMNIA_MAINNET_CHAIN_ID]: { ... }, // TODO: add when deployed\n}\n\n/** Underlying ERC-20 token addresses on BSC Mainnet. */\nexport const BSC_UNDERLYING_TOKENS: Partial<Record<string, Address>> = {\n WETH: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8',\n WBTC: '0x0555E30da8f98308EdB960aa94C0Db47230d2B9c',\n USDC: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',\n AUSD: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n WBNB: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',\n USDT: '0x55d398326f99059fF775485246999027B3197955',\n}\n\n/**\n * Underlying ERC-20 token addresses for all hub chains.\n * Add Monad/Somnia entries here when contracts are deployed.\n */\nexport const HUB_UNDERLYING_TOKENS: Partial<Record<number, Partial<Record<string, Address>>>> = {\n [BSC_MAINNET_CHAIN_ID]: BSC_UNDERLYING_TOKENS,\n // [MONAD_MAINNET_CHAIN_ID]: { USDC: '0x...', WETH: '0x...', ... }, // TODO\n // [SOMNIA_MAINNET_CHAIN_ID]: { USDC: '0x...', WETH: '0x...', ... }, // TODO\n}\n\n/** Token addresses on spoke chains, keyed by chainId then asset symbol. */\nexport const SPOKE_TOKENS: Partial<Record<number, Partial<Record<string, Address>>>> = {\n [ARBITRUM_CHAIN_ID]: {\n USDC: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n USDT: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',\n WETH: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',\n AUSD: '0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a',\n WBTC: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',\n },\n [BASE_CHAIN_ID]: {\n USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n WETH: '0x4200000000000000000000000000000000000006',\n USDT: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2',\n WBTC: '0x0555E30da8f98308EdB960aa94C0Db47230d2B9c',\n },\n [ETHEREUM_CHAIN_ID]: {\n USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7',\n WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',\n WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',\n },\n [POLYGON_CHAIN_ID]: {\n USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',\n WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',\n WBTC: '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6',\n },\n [OPTIMISM_CHAIN_ID]: {\n USDC: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607',\n USDT: '0x94b008aA00579c1307B0eF2c499aD98a8ce58e58',\n WETH: '0x4200000000000000000000000000000000000006',\n },\n [AVALANCHE_CHAIN_ID]: {\n USDC: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n USDT: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',\n WETH: '0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB',\n WBTC: '0x0555E30da8f98308EdB960aa94C0Db47230d2B9c',\n },\n}\n\n/** ERC-20 decimal places by asset symbol. */\nexport const ASSET_DECIMALS: Record<string, number> = {\n USDC: 6,\n USDT: 6,\n WBTC: 8,\n WETH: 18,\n WBNB: 18,\n AUSD: 18,\n}\n\n// ---------------------------------------------------------------------------\n// Address helpers\n// ---------------------------------------------------------------------------\n\nexport function getPTokenAddress(chainId: number, asset: string): Address {\n const markets = PERIDOT_MARKETS[chainId]\n if (!markets) {\n throw new Error(`No pToken markets configured for chain ${chainId} (${CHAIN_NAMES[chainId] ?? 'unknown'})`)\n }\n const address = markets[asset.toUpperCase()]\n if (!address) {\n const available = Object.keys(markets).join(', ')\n throw new Error(`No pToken market for ${asset.toUpperCase()} on chain ${chainId}. Available: ${available}`)\n }\n return address\n}\n\nexport function getUnderlyingTokenAddress(chainId: number, asset: string): Address {\n const symbol = asset.toUpperCase()\n const chainName = CHAIN_NAMES[chainId] ?? `chain ${chainId}`\n\n // Hub chains use HUB_UNDERLYING_TOKENS\n if (isHubChain(chainId)) {\n const hubTokens = HUB_UNDERLYING_TOKENS[chainId]\n if (!hubTokens) throw new Error(`No underlying token config for hub chain ${chainName} — contracts may not be deployed yet`)\n const address = hubTokens[symbol]\n if (!address) throw new Error(`No underlying token for ${symbol} on ${chainName}`)\n return address\n }\n\n // Spoke chains use SPOKE_TOKENS\n const spokeTokens = SPOKE_TOKENS[chainId]\n if (!spokeTokens) throw new Error(`No token config for chain ${chainName}`)\n const address = spokeTokens[symbol]\n if (!address) throw new Error(`No token address for ${symbol} on ${chainName}`)\n return address\n}\n\nexport function getControllerAddress(chainId: number): Address {\n const address = PERIDOT_CONTROLLER[chainId]\n if (!address) throw new Error(`No Peridot controller for chain ${chainId}`)\n return address\n}\n\nexport function getAssetDecimals(asset: string): number {\n const symbol = asset.toUpperCase()\n const decimals = ASSET_DECIMALS[symbol]\n if (decimals === undefined) {\n throw new Error(\n `Unknown asset \"${symbol}\": decimal precision not configured. ` +\n `Add it to ASSET_DECIMALS in constants.ts before use.`,\n )\n }\n return decimals\n}\n\n/** Default public RPC endpoints (no API key required). */\nexport const DEFAULT_RPC_URLS: Partial<Record<number, string>> = {\n [BSC_MAINNET_CHAIN_ID]: 'https://bsc-dataseed.binance.org',\n [BSC_TESTNET_CHAIN_ID]: 'https://data-seed-prebsc-1-s1.binance.org:8545',\n [MONAD_MAINNET_CHAIN_ID]: 'https://rpc.monad.xyz',\n [MONAD_TESTNET_CHAIN_ID]: 'https://testnet-rpc.monad.xyz',\n [SOMNIA_MAINNET_CHAIN_ID]: 'https://dream-rpc.somnia.network',\n [SOMNIA_TESTNET_CHAIN_ID]: 'https://testnet.rpc.somnia.network',\n [ARBITRUM_CHAIN_ID]: 'https://arb1.arbitrum.io/rpc',\n [BASE_CHAIN_ID]: 'https://mainnet.base.org',\n [ETHEREUM_CHAIN_ID]: 'https://eth.llamarpc.com',\n}\n","/**\n * Vercel AI SDK adapter for the Peridot Agent Kit.\n *\n * @example\n * ```typescript\n * import { generateText } from \"ai\"\n * import { openai } from \"@ai-sdk/openai\"\n * import { createVercelAITools } from \"@peridot-agent/agent-kit/vercel-ai\"\n *\n * const tools = createVercelAITools({ network: \"mainnet\" })\n *\n * const { text } = await generateText({\n * model: openai(\"gpt-4o\"),\n * tools,\n * prompt: \"What is my health factor? My address is 0x...\"\n * })\n * ```\n */\n\nimport { tool } from 'ai'\nimport type { z } from 'zod'\nimport { lendingTools } from '../../features/lending/tools'\nimport type { PeridotConfig, ToolDefinition } from '../../shared/types'\n\n// import { marginTools } from '../../features/margin/tools' // Phase 2\n\nfunction toolsForConfig(_config: PeridotConfig): ToolDefinition[] {\n return [\n ...lendingTools,\n // ...marginTools,\n ]\n}\n\n/**\n * Create Vercel AI SDK tools for all Peridot Agent Kit tools.\n * Returns a record of tool name → tool, ready to pass to `generateText` / `streamText`.\n */\n/**\n * Create Vercel AI SDK tools for all Peridot Agent Kit tools.\n * Returns a record of tool name → tool, ready to pass to `generateText` / `streamText`.\n */\nexport function createVercelAITools(\n config: PeridotConfig = {},\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Record<string, any> {\n const tools = toolsForConfig(config)\n\n return Object.fromEntries(\n tools.map((t) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const capturedTool = t as ToolDefinition<any, any>\n return [\n capturedTool.name,\n tool({\n description: capturedTool.description,\n parameters: capturedTool.inputSchema as z.ZodObject<z.ZodRawShape>,\n // eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unsafe-return\n execute: async (input: unknown) => capturedTool.execute(input, config) as unknown,\n }),\n ]\n }),\n )\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { MarketSummary, PeridotConfig } from '../../../shared/types'\n\nexport const listMarketsSchema = z.object({\n chainId: z\n .number()\n .optional()\n .describe(\n 'Filter by hub chain ID. 56=BSC, 143=Monad, 1868=Somnia. Omit to list all markets across all chains.',\n ),\n})\n\nexport type ListMarketsInput = z.infer<typeof listMarketsSchema>\n\nexport async function listMarkets(\n input: ListMarketsInput,\n config: PeridotConfig,\n): Promise<{ markets: MarketSummary[]; count: number }> {\n const client = new PeridotApiClient(config)\n const metrics = await client.getMarketMetrics()\n\n const markets: MarketSummary[] = Object.entries(metrics)\n .filter(([, m]) => input.chainId === undefined || m.chainId === input.chainId)\n .map(([key, m]) => {\n const [asset] = key.split(':')\n const dataAgeSeconds = m.updatedAt\n ? Math.round((Date.now() - new Date(m.updatedAt).getTime()) / 1000)\n : 0\n return {\n asset: asset ?? key,\n chainId: m.chainId,\n priceUsd: m.priceUsd,\n tvlUsd: m.tvlUsd,\n utilizationPct: m.utilizationPct,\n liquidityUsd: m.liquidityUsd,\n collateralFactorPct: m.collateral_factor_pct,\n updatedAt: m.updatedAt,\n dataAgeSeconds,\n }\n })\n .sort((a, b) => b.tvlUsd - a.tvlUsd)\n\n return { markets, count: markets.length }\n}\n","import { BICONOMY_API_URL, DEFAULT_API_BASE_URL } from './constants'\n\n/** Default timeout for Peridot platform API reads (ms). */\nconst PLATFORM_TIMEOUT_MS = 10_000\n/** Longer timeout for Biconomy compose — builds a full cross-chain route (ms). */\nconst BICONOMY_COMPOSE_TIMEOUT_MS = 30_000\n/** Delay before the single automatic retry (ms). */\nconst RETRY_DELAY_MS = 200\n\n/**\n * Fetches a URL with one automatic retry on network errors or 5xx responses.\n * 4xx responses are NOT retried — they indicate a client error.\n */\nasync function fetchWithRetry(url: string, init: RequestInit): Promise<Response> {\n const attempt = () => fetch(url, init)\n let res: Response\n try {\n res = await attempt()\n } catch (err) {\n // Network-level failure (timeout, DNS, etc.) — retry once\n await new Promise((r) => setTimeout(r, RETRY_DELAY_MS))\n return attempt()\n }\n if (res.status >= 500) {\n await new Promise((r) => setTimeout(r, RETRY_DELAY_MS))\n return attempt()\n }\n return res\n}\nimport type {\n BiconomyResponse,\n ComposeRequest,\n LiquidatablePositions,\n PeridotConfig,\n TransactionStatus,\n} from './types'\n\n// ---------------------------------------------------------------------------\n// Raw API response shapes (internal — not exported from package root)\n// ---------------------------------------------------------------------------\n\nexport interface RawMarketMetric {\n utilizationPct: number\n tvlUsd: number\n liquidityUnderlying: number\n liquidityUsd: number\n priceUsd: number\n collateral_factor_pct: number\n updatedAt: string\n chainId: number\n}\n\n/** Shape of one entry from `/api/apy` (from `apy_latest_mainnet` table). */\nexport interface RawMarketApy {\n supplyApy: number\n borrowApy: number\n peridotSupplyApy: number\n peridotBorrowApy: number\n boostSourceSupplyApy: number\n boostRewardsSupplyApy: number\n totalSupplyApy: number\n netBorrowApy: number\n timestamp: string\n}\n\n/**\n * Full response from `/api/apy`.\n * Keys are lowercase asset IDs (e.g. \"usdc\"), values are a map of chainId → APY data.\n */\nexport type RawApyResponse = Record<string, Record<number, RawMarketApy>>\n\n/** Shape of one leaderboard entry from `/api/leaderboard`. */\nexport interface RawTransaction {\n txHash: string\n chainId: number\n blockNumber: number\n actionType: string\n tokenSymbol: string | null\n amount: number\n usdValue: number\n pointsAwarded: number\n verifiedAt: string\n contractAddress: string\n}\n\nexport interface RawTransactionsResponse {\n transactions: RawTransaction[]\n total: number\n}\n\nexport interface RawLeaderboardEntry {\n rank: number\n address: string\n totalPoints: number\n supplyCount: number\n borrowCount: number\n repayCount: number\n redeemCount: number\n updatedAt: string\n}\n\nexport interface RawLeaderboardResponse {\n entries: RawLeaderboardEntry[]\n total: number\n}\n\nexport interface RawUserPortfolio {\n portfolio: {\n currentValue: number\n totalSupplied: number\n totalBorrowed: number\n netApy: number\n /** Note: simplified ratio (totalSupplied / totalBorrowed), not liquidation HF */\n healthFactor: number\n }\n assets: Array<{\n assetId: string\n supplied: number\n borrowed: number\n net: number\n percentage: number\n }>\n transactions: {\n totalCount: number\n supplyCount: number\n borrowCount: number\n repayCount: number\n redeemCount: number\n }\n earnings: {\n effectiveApy: number\n totalLifetimeEarnings: number\n }\n}\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\nexport class PeridotApiClient {\n private readonly baseUrl: string\n private readonly biconomyApiKey: string | undefined\n\n constructor(config: PeridotConfig) {\n this.baseUrl = config.apiBaseUrl ?? DEFAULT_API_BASE_URL\n this.biconomyApiKey = config.biconomyApiKey\n }\n\n /**\n * Fetches all market metrics. Returns a record keyed by `${ASSET}:${chainId}`.\n * Example key: `USDC:56`\n */\n async getMarketMetrics(): Promise<Record<string, RawMarketMetric>> {\n const res = await fetchWithRetry(`${this.baseUrl}/api/markets/metrics`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch market metrics: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: Record<string, RawMarketMetric>; error?: string }\n if (!json.ok) throw new Error(`Market metrics API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches the portfolio overview for a wallet address.\n * Uses the platform's portfolio-data endpoint which aggregates DB snapshots.\n */\n async getUserPortfolio(address: string): Promise<RawUserPortfolio> {\n if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {\n throw new Error(`Invalid address format: \"${address}\". Expected 0x followed by 40 hex characters.`)\n }\n const res = await fetchWithRetry(`${this.baseUrl}/api/user/portfolio-data?address=${address}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch portfolio: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: RawUserPortfolio; error?: string }\n if (!json.ok) throw new Error(`Portfolio API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches the latest APY snapshot for all markets (or a specific chain).\n * Calls `/api/apy` — backed by the `apy_latest_mainnet` DB table.\n *\n * Returns a record keyed by lowercase asset ID, then by chainId.\n * Example: `data[\"usdc\"][56].totalSupplyApy`\n */\n async getMarketApy(chainId?: number): Promise<RawApyResponse> {\n const url = chainId\n ? `${this.baseUrl}/api/apy?chainId=${chainId}`\n : `${this.baseUrl}/api/apy`\n const res = await fetchWithRetry(url, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch APY data: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: RawApyResponse; error?: string }\n if (!json.ok) throw new Error(`APY API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches the Peridot leaderboard (top users by points).\n * Optionally filters by chainId and limits the result set.\n */\n async getLeaderboard(options?: { limit?: number; chainId?: number }): Promise<RawLeaderboardResponse> {\n const params = new URLSearchParams()\n if (options?.limit !== undefined) params.set('limit', String(options.limit))\n if (options?.chainId !== undefined) params.set('chainId', String(options.chainId))\n const query = params.toString() ? `?${params.toString()}` : ''\n const res = await fetchWithRetry(`${this.baseUrl}/api/leaderboard${query}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch leaderboard: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: RawLeaderboardResponse; error?: string }\n if (!json.ok) throw new Error(`Leaderboard API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches accounts that are currently underwater (shortfall_usd > 0) and\n * eligible for liquidation. Data is sourced from the account health scanner.\n */\n async getLiquidatablePositions(options?: {\n chainId?: number\n minShortfall?: number\n limit?: number\n }): Promise<LiquidatablePositions> {\n const params = new URLSearchParams()\n if (options?.chainId !== undefined) params.set('chainId', String(options.chainId))\n if (options?.minShortfall !== undefined) params.set('minShortfall', String(options.minShortfall))\n if (options?.limit !== undefined) params.set('limit', String(options.limit))\n const query = params.toString() ? `?${params.toString()}` : ''\n const res = await fetchWithRetry(`${this.baseUrl}/api/liquidations/at-risk${query}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch liquidatable positions: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: LiquidatablePositions; error?: string }\n if (!json.ok) throw new Error(`Liquidations API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Fetches verified transaction history for a wallet address.\n * Optionally filters by chainId and/or actionType.\n */\n async getUserTransactions(\n address: string,\n options?: { limit?: number; chainId?: number; actionType?: 'supply' | 'borrow' | 'repay' | 'redeem' },\n ): Promise<RawTransactionsResponse> {\n if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {\n throw new Error(`Invalid address format: \"${address}\". Expected 0x followed by 40 hex characters.`)\n }\n const params = new URLSearchParams({ address })\n if (options?.limit !== undefined) params.set('limit', String(options.limit))\n if (options?.chainId !== undefined) params.set('chainId', String(options.chainId))\n if (options?.actionType !== undefined) params.set('actionType', options.actionType)\n const res = await fetchWithRetry(`${this.baseUrl}/api/user/transactions?${params.toString()}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (!res.ok) throw new Error(`Failed to fetch transactions: ${res.status} ${res.statusText}`)\n const json = (await res.json()) as { ok: boolean; data: RawTransactionsResponse; error?: string }\n if (!json.ok) throw new Error(`Transactions API error: ${json.error ?? 'unknown'}`)\n return json.data\n }\n\n /**\n * Calls Biconomy MEE /compose to build a cross-chain transaction payload.\n * Does NOT execute — the returned instructions must be signed by the user.\n */\n async biconomyCompose(request: ComposeRequest): Promise<BiconomyResponse> {\n if (!this.biconomyApiKey) {\n throw new Error('biconomyApiKey is required in PeridotConfig for cross-chain operations')\n }\n const res = await fetch(`${BICONOMY_API_URL}/v1/instructions/compose`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.biconomyApiKey,\n },\n body: JSON.stringify(request),\n signal: AbortSignal.timeout(BICONOMY_COMPOSE_TIMEOUT_MS),\n })\n if (!res.ok) {\n const error: unknown = await res.json().catch(() => ({}))\n throw new Error(`Biconomy compose error: ${JSON.stringify(error)}`)\n }\n return res.json() as Promise<BiconomyResponse>\n }\n\n /** Polls Biconomy for the status of a submitted super-transaction. */\n async biconomyGetStatus(superTxHash: string): Promise<TransactionStatus> {\n const res = await fetchWithRetry(`${BICONOMY_API_URL}/v1/explorer/transaction/${superTxHash}`, { signal: AbortSignal.timeout(PLATFORM_TIMEOUT_MS) })\n if (res.status === 404) return { superTxHash, status: 'not_found' }\n if (!res.ok) throw new Error(`Biconomy status error: ${res.status}`)\n const data = (await res.json()) as Record<string, unknown>\n return parseBiconomyStatus(superTxHash, data)\n }\n}\n\nfunction parseBiconomyStatus(superTxHash: string, data: Record<string, unknown>): TransactionStatus {\n const status = String(data['status'] ?? '').toLowerCase()\n const txHashes = (data['txHashes'] as string[] | undefined) ?? []\n\n if (status.includes('success') || status.includes('completed')) {\n return { superTxHash, status: 'success', chainTxHashes: txHashes }\n }\n if (status.includes('fail') || status.includes('error')) {\n return { superTxHash, status: 'failed', error: String(data['message'] ?? 'Unknown error') }\n }\n if (status.includes('process')) {\n return { superTxHash, status: 'processing', chainTxHashes: txHashes }\n }\n return { superTxHash, status: 'pending' }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport { BSC_MAINNET_CHAIN_ID, isHubChain } from '../../../shared/constants'\nimport { readOnChainPosition } from '../../../shared/on-chain-position'\nimport type { PeridotConfig, PortfolioOverview } from '../../../shared/types'\nimport { evmAddress } from '../../../shared/zod-utils'\nimport { Cache } from '../../../shared/cache'\n\nexport const portfolioCache = new Cache<PortfolioOverview>(30_000)\n\nexport const getPortfolioSchema = z.object({\n address: evmAddress.describe('The wallet address (0x...) to look up'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID to query. Defaults to BSC (56).'),\n})\n\nexport type GetPortfolioInput = z.infer<typeof getPortfolioSchema>\n\nexport async function getPortfolio(\n input: GetPortfolioInput,\n config: PeridotConfig,\n): Promise<PortfolioOverview> {\n const key = `${input.address.toLowerCase()}:${input.chainId}`\n\n return portfolioCache.getOrFetch(key, async () => {\n const apiClient = new PeridotApiClient(config)\n\n const [position, apyData] = await Promise.all([\n readOnChainPosition(input.address, input.chainId, config),\n apiClient.getMarketApy(input.chainId),\n ])\n\n const { totalSuppliedUsd, totalBorrowedUsd, assets } = position\n\n // Net APY: weighted by position size across all active markets\n let netApy = 0\n if (totalSuppliedUsd > 0) {\n let weighted = 0\n for (const asset of assets) {\n const apyEntry = apyData[asset.assetId.toLowerCase()]?.[input.chainId]\n if (apyEntry) {\n weighted += asset.suppliedUsd * (apyEntry.totalSupplyApy ?? 0)\n weighted -= asset.borrowedUsd * (apyEntry.netBorrowApy ?? 0)\n }\n }\n netApy = weighted / totalSuppliedUsd\n }\n\n return {\n address: input.address,\n fetchedAt: new Date().toISOString(),\n portfolio: {\n currentValue: totalSuppliedUsd - totalBorrowedUsd,\n totalSupplied: totalSuppliedUsd,\n totalBorrowed: totalBorrowedUsd,\n netApy,\n healthFactor: totalBorrowedUsd > 0 ? totalSuppliedUsd / totalBorrowedUsd : null,\n },\n assets: assets.map((a) => ({\n assetId: a.assetId,\n supplied: a.suppliedUsd,\n borrowed: a.borrowedUsd,\n net: a.suppliedUsd - a.borrowedUsd,\n percentage:\n totalSuppliedUsd > 0 ? ((a.suppliedUsd - a.borrowedUsd) / totalSuppliedUsd) * 100 : 0,\n })),\n }\n })\n}\n","import Decimal from 'decimal.js'\nimport { createPublicClient, http } from 'viem'\nimport { PTOKEN_ABI } from './abis'\nimport { ASSET_DECIMALS, DEFAULT_RPC_URLS, PERIDOT_MARKETS } from './constants'\nimport { PeridotApiClient } from './api-client'\nimport type { PeridotConfig } from './types'\n\nexport interface OnChainAssetPosition {\n assetId: string\n suppliedUsd: number\n borrowedUsd: number\n suppliedTokens: number\n borrowedTokens: number\n priceUsd: number\n}\n\nexport interface OnChainPosition {\n totalSuppliedUsd: number\n totalBorrowedUsd: number\n assets: OnChainAssetPosition[]\n}\n\n/**\n * Reads a wallet's lending position directly from on-chain pToken contracts.\n * No auth required — uses public RPC + the platform's public market metrics API for prices.\n *\n * For each pToken market on the given hub chain:\n * - balanceOf(address) → cToken balance (8 decimals)\n * - exchangeRateStored() → cToken → underlying conversion rate\n * - borrowBalanceStored(address) → borrow in underlying smallest units\n *\n * Conversion: underlyingAmount = cTokenBalance * exchangeRate / 1e18\n * Then USD value = underlyingAmount / 10^assetDecimals * priceUsd\n */\nexport async function readOnChainPosition(\n address: string,\n chainId: number,\n config: PeridotConfig,\n): Promise<OnChainPosition> {\n const markets = PERIDOT_MARKETS[chainId]\n if (!markets) {\n throw new Error(`No markets configured for chain ${chainId}`)\n }\n\n const marketEntries = Object.entries(markets).filter(\n (entry): entry is [string, `0x${string}`] => entry[1] !== undefined,\n )\n\n if (marketEntries.length === 0) {\n return { totalSuppliedUsd: 0, totalBorrowedUsd: 0, assets: [] }\n }\n\n const rpcUrl = config.rpcUrls?.[chainId] ?? DEFAULT_RPC_URLS[chainId]\n if (!rpcUrl) {\n throw new Error(\n `No RPC URL available for chain ${chainId}. ` +\n `Provide one via config.rpcUrls[${chainId}].`,\n )\n }\n\n const viemClient = createPublicClient({ transport: http(rpcUrl) })\n const apiClient = new PeridotApiClient(config)\n\n // Fetch prices and on-chain balances in parallel — both are public, no auth needed\n const [metricsData, multicallResults] = await Promise.all([\n apiClient.getMarketMetrics(),\n viemClient.multicall({\n contracts: marketEntries.flatMap(([, pTokenAddress]) => [\n {\n address: pTokenAddress,\n abi: PTOKEN_ABI,\n functionName: 'balanceOf',\n args: [address as `0x${string}`],\n },\n {\n address: pTokenAddress,\n abi: PTOKEN_ABI,\n functionName: 'exchangeRateStored',\n },\n {\n address: pTokenAddress,\n abi: PTOKEN_ABI,\n functionName: 'borrowBalanceStored',\n args: [address as `0x${string}`],\n },\n ]),\n allowFailure: true,\n }),\n ])\n\n const assets: OnChainAssetPosition[] = []\n let totalSuppliedUsd = 0\n let totalBorrowedUsd = 0\n\n for (let i = 0; i < marketEntries.length; i++) {\n const entry = marketEntries[i]\n if (!entry) continue\n const [symbol] = entry\n const base = i * 3\n\n const balanceResult = multicallResults[base]\n const exchangeRateResult = multicallResults[base + 1]\n const borrowResult = multicallResults[base + 2]\n\n // Skip markets where any call failed (e.g. not yet deployed) or result is missing\n if (\n !balanceResult || !exchangeRateResult || !borrowResult ||\n balanceResult.status === 'failure' ||\n exchangeRateResult.status === 'failure' ||\n borrowResult.status === 'failure'\n ) {\n continue\n }\n\n const cTokenBalance = balanceResult.result as bigint\n const exchangeRate = exchangeRateResult.result as bigint\n const borrowBalance = borrowResult.result as bigint\n\n const underlyingDecimals = ASSET_DECIMALS[symbol] ?? 18\n const priceUsd = metricsData[`${symbol}:${chainId}`]?.priceUsd ?? 0\n\n // Supplied: cTokenBalance * exchangeRate / 1e18 → underlying in smallest units\n // then divide by 10^underlyingDecimals to get whole tokens\n const suppliedTokens = new Decimal(cTokenBalance.toString())\n .mul(exchangeRate.toString())\n .div('1e18')\n .div(new Decimal(10).pow(underlyingDecimals))\n .toNumber()\n\n // Borrowed: borrowBalanceStored returns underlying in smallest units directly\n const borrowedTokens = new Decimal(borrowBalance.toString())\n .div(new Decimal(10).pow(underlyingDecimals))\n .toNumber()\n\n const suppliedUsd = suppliedTokens * priceUsd\n const borrowedUsd = borrowedTokens * priceUsd\n\n // Only include assets with a meaningful position (>$0.001) to keep output clean\n if (suppliedUsd > 0.001 || borrowedUsd > 0.001) {\n assets.push({ assetId: symbol, suppliedUsd, borrowedUsd, suppliedTokens, borrowedTokens, priceUsd })\n totalSuppliedUsd += suppliedUsd\n totalBorrowedUsd += borrowedUsd\n }\n }\n\n return { totalSuppliedUsd, totalBorrowedUsd, assets }\n}\n","import { parseAbi } from 'viem'\n\n/**\n * Minimal ABI for pToken (Compound V2-style cToken) markets.\n * Only includes functions used by the agent-kit.\n */\nexport const PTOKEN_ABI = parseAbi([\n 'function mint(uint256 mintAmount) returns (uint256)',\n 'function redeem(uint256 redeemTokens) returns (uint256)',\n 'function redeemUnderlying(uint256 redeemAmount) returns (uint256)',\n 'function borrow(uint256 borrowAmount) returns (uint256)',\n 'function repayBorrow(uint256 repayAmount) returns (uint256)',\n 'function repayBorrowBehalf(address borrower, uint256 repayAmount) returns (uint256)',\n 'function liquidateBorrow(address borrower, uint256 repayAmount, address pTokenCollateral) returns (uint256)',\n 'function balanceOf(address owner) view returns (uint256)',\n 'function borrowBalanceStored(address account) view returns (uint256)',\n 'function supplyRatePerBlock() view returns (uint256)',\n 'function borrowRatePerBlock() view returns (uint256)',\n 'function exchangeRateStored() view returns (uint256)',\n 'function underlying() view returns (address)',\n])\n\n/**\n * Minimal ABI for the Peridottroller (Compound V2-style Comptroller).\n */\nexport const COMPTROLLER_ABI = parseAbi([\n 'function enterMarkets(address[] calldata pTokens) returns (uint256[] memory)',\n 'function exitMarket(address pTokenAddress) returns (uint256)',\n 'function getAccountLiquidity(address account) view returns (uint256 errorCode, uint256 liquidity, uint256 shortfall)',\n 'function getAllMarkets() view returns (address[] memory)',\n 'function markets(address pToken) view returns (bool isListed, uint256 collateralFactorMantissa, bool isComped)',\n 'function checkMembership(address account, address pToken) view returns (bool)',\n])\n\n/**\n * Standard ERC-20 ABI subset used for approvals and balance checks.\n */\nexport const 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 owner) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n])\n","import { z } from 'zod'\n\n/**\n * Accepts any valid 0x-prefixed 40-hex-character Ethereum address.\n * Rejects bare hex strings, ENS names, and truncated addresses.\n */\nexport const evmAddress = z\n .string()\n .regex(/^0x[0-9a-fA-F]{40}$/, 'Must be a valid Ethereum address (0x followed by 40 hex chars)')\n\n/**\n * Accepts a positive decimal number expressed as a string.\n * Valid: \"100\", \"0.5\", \"1234.56789\"\n * Invalid: \"-1\", \"NaN\", \"Infinity\", \"1e18\", \"\"\n */\nexport const tokenAmount = z\n .string()\n .regex(/^\\d+(\\.\\d+)?$/, 'Amount must be a positive decimal number (e.g. \"100\" or \"0.5\")')\n","interface Entry<T> {\n data: T\n expiresAt: number\n inflight?: Promise<T>\n}\n\n/**\n * In-memory TTL cache with thundering herd protection.\n *\n * Concurrent callers for the same key share one in-flight promise rather than\n * each triggering a separate upstream request. On fetch error the entry is\n * removed so the next caller can retry (unlike a naïve promise-coalescing\n * cache that would permanently serve the rejection).\n */\nexport class Cache<T> {\n private store = new Map<string, Entry<T>>()\n\n constructor(private ttlMs: number) {}\n\n get(key: string): T | undefined {\n const entry = this.store.get(key)\n if (!entry) return undefined\n // Never evict an entry that has an active in-flight promise — getOrFetch\n // still needs to find it. We just don't return stale data for it.\n if (entry.inflight) return undefined\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key)\n return undefined\n }\n return entry.data\n }\n\n set(key: string, data: T): void {\n this.store.set(key, { data, expiresAt: Date.now() + this.ttlMs })\n }\n\n clear(): void {\n this.store.clear()\n }\n\n /**\n * Return the cached value if fresh, otherwise call `fetcher` once — even\n * when multiple callers arrive simultaneously while the fetch is in-flight.\n * If the fetch throws, the entry is deleted so subsequent callers retry.\n */\n async getOrFetch(key: string, fetcher: () => Promise<T>): Promise<T> {\n const cached = this.get(key)\n if (cached !== undefined) return cached\n\n const existing = this.store.get(key)\n if (existing?.inflight) return existing.inflight\n\n const promise = fetcher()\n .then((data) => {\n this.set(key, data)\n const entry = this.store.get(key)\n if (entry) delete entry.inflight\n return data\n })\n .catch((err: unknown) => {\n // Remove the entry so the next caller triggers a fresh attempt.\n this.store.delete(key)\n throw err\n })\n\n this.store.set(key, { data: undefined as unknown as T, expiresAt: 0, inflight: promise })\n return promise\n }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { LeaderboardEntry, PeridotConfig } from '../../../shared/types'\n\nexport const getLeaderboardSchema = z.object({\n limit: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe('Number of entries to return (1–100, default 50).'),\n chainId: z\n .number()\n .optional()\n .describe('Filter by hub chain ID. 56=BSC, 143=Monad, 1868=Somnia. Omit to show all chains.'),\n})\n\nexport type GetLeaderboardInput = z.infer<typeof getLeaderboardSchema>\n\nexport async function getLeaderboard(\n input: GetLeaderboardInput,\n config: PeridotConfig,\n): Promise<{ entries: LeaderboardEntry[]; total: number }> {\n const client = new PeridotApiClient(config)\n const opts: { limit?: number; chainId?: number } = {}\n if (input.limit !== undefined) opts.limit = input.limit\n if (input.chainId !== undefined) opts.chainId = input.chainId\n const data = await client.getLeaderboard(opts)\n return {\n entries: data.entries,\n total: data.total,\n }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport { BSC_MAINNET_CHAIN_ID } from '../../../shared/constants'\nimport type { MarketRates, PeridotConfig } from '../../../shared/types'\n\nexport const getMarketRatesSchema = z.object({\n asset: z.string().describe('Asset symbol, e.g. \"USDC\", \"WETH\", \"WBTC\", \"WBNB\", \"USDT\", \"AUSD\"'),\n chainId: z\n .number()\n .default(BSC_MAINNET_CHAIN_ID)\n .describe('Hub chain ID where the market lives. 56=BSC (default), 143=Monad, 1868=Somnia'),\n})\n\nexport type GetMarketRatesInput = z.infer<typeof getMarketRatesSchema>\n\nexport async function getMarketRates(\n input: GetMarketRatesInput,\n config: PeridotConfig,\n): Promise<MarketRates> {\n const client = new PeridotApiClient(config)\n const assetUpper = input.asset.toUpperCase()\n\n // Fetch market metrics and APY data in parallel\n const [metrics, apyData] = await Promise.all([\n client.getMarketMetrics(),\n client.getMarketApy(input.chainId),\n ])\n\n // Metrics are keyed as `${ASSET}:${chainId}` (uppercase asset)\n const key = `${assetUpper}:${input.chainId}`\n const metric = metrics[key]\n\n if (!metric) {\n const available = Object.keys(metrics)\n .filter((k) => k.endsWith(`:${input.chainId}`))\n .map((k) => k.split(':')[0])\n throw new Error(\n `No market data found for \"${assetUpper}\" on chain ${input.chainId}. ` +\n `Available assets on this chain: ${available.join(', ')}`,\n )\n }\n\n // APY data is keyed by lowercase asset ID, then by chainId\n const apy = apyData[assetUpper.toLowerCase()]?.[input.chainId]\n const apyDataAvailable = apy !== undefined\n\n const dataAgeSeconds = metric.updatedAt\n ? Math.round((Date.now() - new Date(metric.updatedAt).getTime()) / 1000)\n : 0\n\n const warnings: string[] = []\n if (!apyDataAvailable) {\n warnings.push(\n `APY data is not yet available for ${assetUpper} on chain ${input.chainId}. ` +\n `All yield figures (supplyApyPct, borrowApyPct, totalSupplyApyPct, etc.) are showing 0 as a placeholder — ` +\n `do NOT present them as real rates. The APY indexer may still be catching up.`,\n )\n }\n if (dataAgeSeconds > 300) {\n warnings.push(`Market data is ${Math.round(dataAgeSeconds / 60)} minutes old — figures may not reflect current conditions.`)\n }\n\n return {\n asset: assetUpper,\n chainId: input.chainId,\n supplyApyPct: apy?.supplyApy ?? 0,\n borrowApyPct: apy?.borrowApy ?? 0,\n peridotSupplyApyPct: apy?.peridotSupplyApy ?? 0,\n peridotBorrowApyPct: apy?.peridotBorrowApy ?? 0,\n boostSourceSupplyApyPct: apy?.boostSourceSupplyApy ?? 0,\n boostRewardsSupplyApyPct: apy?.boostRewardsSupplyApy ?? 0,\n totalSupplyApyPct: apy?.totalSupplyApy ?? 0,\n netBorrowApyPct: apy?.netBorrowApy ?? 0,\n tvlUsd: metric.tvlUsd,\n utilizationPct: metric.utilizationPct,\n liquidityUsd: metric.liquidityUsd,\n priceUsd: metric.priceUsd,\n collateralFactorPct: metric.collateral_factor_pct ?? 0,\n updatedAt: metric.updatedAt,\n dataAgeSeconds,\n apyDataAvailable,\n warning: warnings.length > 0 ? warnings.join(' ') : undefined,\n }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport { BSC_MAINNET_CHAIN_ID, isHubChain } from '../../../shared/constants'\nimport { readOnChainPosition } from '../../../shared/on-chain-position'\nimport type { PeridotConfig, UserPosition } from '../../../shared/types'\nimport { evmAddress } from '../../../shared/zod-utils'\n\nexport const getUserPositionSchema = z.object({\n address: evmAddress.describe('The wallet address (0x...) to look up'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID to query. Defaults to BSC (56).'),\n})\n\nexport type GetUserPositionInput = z.infer<typeof getUserPositionSchema>\n\nexport async function getUserPosition(\n input: GetUserPositionInput,\n config: PeridotConfig,\n): Promise<UserPosition> {\n const apiClient = new PeridotApiClient(config)\n\n // Read position on-chain and APY data in parallel — both are public, no auth needed\n const [position, apyData] = await Promise.all([\n readOnChainPosition(input.address, input.chainId, config),\n apiClient.getMarketApy(input.chainId),\n ])\n\n const { totalSuppliedUsd, totalBorrowedUsd, assets } = position\n\n const healthFactor =\n totalBorrowedUsd > 0 ? totalSuppliedUsd / totalBorrowedUsd : null\n\n // Net APY: weighted by position size across all active markets\n let netApyPct = 0\n if (totalSuppliedUsd > 0) {\n let weightedApy = 0\n for (const asset of assets) {\n const apyEntry = apyData[asset.assetId.toLowerCase()]?.[input.chainId]\n if (apyEntry) {\n weightedApy += asset.suppliedUsd * (apyEntry.totalSupplyApy ?? 0)\n weightedApy -= asset.borrowedUsd * (apyEntry.netBorrowApy ?? 0)\n }\n }\n netApyPct = weightedApy / totalSuppliedUsd\n }\n\n return {\n address: input.address,\n totalSuppliedUsd,\n totalBorrowedUsd,\n netWorthUsd: totalSuppliedUsd - totalBorrowedUsd,\n netApyPct,\n healthFactor,\n assets: assets.map((a) => ({\n assetId: a.assetId,\n suppliedUsd: a.suppliedUsd,\n borrowedUsd: a.borrowedUsd,\n netUsd: a.suppliedUsd - a.borrowedUsd,\n })),\n fetchedAt: new Date().toISOString(),\n }\n}\n","import Decimal from 'decimal.js'\nimport { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport { BSC_MAINNET_CHAIN_ID, isHubChain } from '../../../shared/constants'\nimport { readOnChainPosition } from '../../../shared/on-chain-position'\nimport type { PeridotConfig, SimulateBorrowResult } from '../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../shared/zod-utils'\n\nexport const simulateBorrowSchema = z.object({\n address: evmAddress.describe('The wallet address planning to borrow'),\n asset: z.string().describe('The asset to borrow, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable borrow amount, e.g. \"500\" for 500 USDC'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type SimulateBorrowInput = z.infer<typeof simulateBorrowSchema>\n\n/** Risk thresholds for the simplified health factor. */\nconst RISK_THRESHOLDS = {\n safe: 2.0,\n moderate: 1.5,\n high: 1.2,\n critical: 1.0,\n} as const\n\nfunction classifyRisk(hf: number): SimulateBorrowResult['riskLevel'] {\n if (hf >= RISK_THRESHOLDS.safe) return 'safe'\n if (hf >= RISK_THRESHOLDS.moderate) return 'moderate'\n if (hf >= RISK_THRESHOLDS.high) return 'high'\n if (hf >= RISK_THRESHOLDS.critical) return 'critical'\n return 'liquidatable'\n}\n\nexport async function simulateBorrow(\n input: SimulateBorrowInput,\n config: PeridotConfig,\n): Promise<SimulateBorrowResult> {\n const apiClient = new PeridotApiClient(config)\n\n // Read on-chain position and market prices in parallel — both public, no auth needed\n const [position, metricsData] = await Promise.all([\n readOnChainPosition(input.address, input.chainId, config),\n apiClient.getMarketMetrics(),\n ])\n\n const assetUpper = input.asset.toUpperCase()\n const metricKey = `${assetUpper}:${input.chainId}`\n const metric = metricsData[metricKey]\n\n if (!metric) {\n throw new Error(`No market data for ${assetUpper} on chain ${input.chainId}`)\n }\n\n const borrowAmountRaw = parseFloat(input.amount)\n if (isNaN(borrowAmountRaw) || borrowAmountRaw <= 0) {\n throw new Error(`Invalid borrow amount: \"${input.amount}\"`)\n }\n\n const borrowAmount = new Decimal(input.amount)\n const borrowAmountUsd = borrowAmount.mul(metric.priceUsd).toNumber()\n\n const { totalSuppliedUsd, totalBorrowedUsd } = position\n\n const currentHF =\n totalBorrowedUsd > 0\n ? new Decimal(totalSuppliedUsd).div(totalBorrowedUsd).toNumber()\n : null\n\n if (totalSuppliedUsd === 0) {\n return {\n currentHealthFactor: null,\n projectedHealthFactor: null,\n borrowAmountUsd,\n isSafe: false,\n riskLevel: 'liquidatable',\n maxSafeBorrowUsd: 0,\n warning:\n 'No supplied collateral found on-chain for this address. ' +\n 'Supply assets and enable them as collateral before borrowing.',\n }\n }\n\n const projectedBorrowedUsd = new Decimal(totalBorrowedUsd).add(borrowAmountUsd)\n const projectedHF = new Decimal(totalSuppliedUsd).div(projectedBorrowedUsd).toNumber()\n\n // Max safe borrow keeps projected HF at the \"safe\" threshold (2.0)\n const maxSafeBorrowUsd = Decimal.max(\n 0,\n new Decimal(totalSuppliedUsd).div(RISK_THRESHOLDS.safe).sub(totalBorrowedUsd),\n ).toNumber()\n\n const riskLevel = classifyRisk(projectedHF)\n const isSafe = projectedHF >= RISK_THRESHOLDS.high\n\n const warnings: string[] = []\n if (riskLevel === 'liquidatable') {\n warnings.push('This borrow would immediately make you eligible for liquidation.')\n } else if (riskLevel === 'critical') {\n warnings.push('Health factor would drop critically low. Any price movement risks liquidation.')\n } else if (riskLevel === 'high') {\n warnings.push('Health factor would be dangerously low. Consider borrowing less.')\n }\n\n return {\n currentHealthFactor: currentHF,\n projectedHealthFactor: projectedHF,\n borrowAmountUsd,\n isSafe,\n riskLevel,\n maxSafeBorrowUsd,\n warning: warnings[0],\n }\n}\n","import Decimal from 'decimal.js'\nimport { z } from 'zod'\nimport { createPublicClient, http } from 'viem'\nimport { COMPTROLLER_ABI } from '../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n DEFAULT_RPC_URLS,\n getControllerAddress,\n isHubChain,\n} from '../../../shared/constants'\nimport type { AccountLiquidity, PeridotConfig } from '../../../shared/types'\nimport { evmAddress } from '../../../shared/zod-utils'\n\nexport const getAccountLiquiditySchema = z.object({\n address: evmAddress.describe('The wallet address to check'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID to query (must be a hub chain). Defaults to BSC (56).'),\n})\n\nexport type GetAccountLiquidityInput = z.infer<typeof getAccountLiquiditySchema>\n\n/**\n * Reads account liquidity directly from the Peridottroller contract.\n * Returns the precise USD liquidity (excess borrowing power) and shortfall.\n *\n * This is the authoritative source for liquidation risk — more accurate than\n * the portfolio-data API which uses a simplified health factor.\n *\n * Requires an RPC URL for the hub chain (uses public fallback if not configured).\n */\nexport async function getAccountLiquidity(\n input: GetAccountLiquidityInput,\n config: PeridotConfig,\n): Promise<AccountLiquidity> {\n const rpcUrl =\n config.rpcUrls?.[input.chainId] ?? DEFAULT_RPC_URLS[input.chainId]\n\n if (!rpcUrl) {\n throw new Error(\n `No RPC URL available for chain ${input.chainId}. ` +\n `Provide one via config.rpcUrls[${input.chainId}].`,\n )\n }\n\n const controllerAddress = getControllerAddress(input.chainId)\n\n const client = createPublicClient({ transport: http(rpcUrl) })\n\n const [error, liquidity, shortfall] = await client.readContract({\n address: controllerAddress,\n abi: COMPTROLLER_ABI,\n functionName: 'getAccountLiquidity',\n args: [input.address as `0x${string}`],\n })\n\n if (error !== 0n) {\n throw new Error(`Comptroller getAccountLiquidity returned error code ${error.toString()}`)\n }\n\n // Values are in USD with 18 decimal mantissa — use Decimal to avoid float precision loss\n const liquidityUsd = new Decimal(liquidity.toString()).div('1e18').toNumber()\n const shortfallUsd = new Decimal(shortfall.toString()).div('1e18').toNumber()\n\n return {\n address: input.address,\n chainId: input.chainId,\n liquidityUsd,\n shortfallUsd,\n isHealthy: shortfallUsd === 0,\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits } from 'viem'\nimport { ERC20_ABI, PTOKEN_ABI, COMPTROLLER_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getControllerAddress,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const hubSupplySchema = z.object({\n userAddress: evmAddress.describe('The wallet address supplying assets'),\n asset: z.string().describe('Asset to supply, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable amount to supply, e.g. \"100\" for 100 USDC'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia). Use build_cross_chain_supply_intent for spoke chains.' })\n .describe('Hub chain ID. Must be a chain with native Peridot markets. Defaults to BSC (56).'),\n enableAsCollateral: z\n .boolean()\n .default(true)\n .describe('Whether to enable the supplied asset as collateral. Defaults to true.'),\n})\n\nexport type HubSupplyInput = z.input<typeof hubSupplySchema>\n\n/**\n * Builds the transaction calls to supply an asset to a Peridot hub-chain market.\n *\n * Call sequence:\n * 1. approve(pToken, amount) — allow pToken to spend your underlying\n * 2. mint(amount) — supply underlying, receive pTokens\n * 3. enterMarkets([pToken]) — (optional) enable as collateral\n */\nexport function buildHubSupplyIntent(\n input: HubSupplyInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const chainId = input.chainId ?? BSC_MAINNET_CHAIN_ID\n const enableAsCollateral = input.enableAsCollateral ?? true\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const pToken = getPTokenAddress(chainId, assetUpper)\n const underlying = getUnderlyingTokenAddress(chainId, assetUpper)\n const controller = getControllerAddress(chainId)\n\n const calls: HubTransactionIntent['calls'] = [\n {\n to: underlying,\n data: encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [pToken, amount],\n }),\n value: 0n,\n description: `Approve p${assetUpper} contract to spend ${input.amount} ${assetUpper}`,\n },\n {\n to: pToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'mint',\n args: [amount],\n }),\n value: 0n,\n description: `Supply ${input.amount} ${assetUpper} to Peridot and receive p${assetUpper} tokens`,\n },\n ]\n\n if (enableAsCollateral) {\n calls.push({\n to: controller,\n data: encodeFunctionData({\n abi: COMPTROLLER_ABI,\n functionName: 'enterMarkets',\n args: [[pToken]],\n }),\n value: 0n,\n description: `Enable ${assetUpper} position as collateral for borrowing`,\n })\n }\n\n const collateralNote = enableAsCollateral ? ' and enable as collateral' : ''\n return {\n type: 'hub',\n chainId,\n calls,\n summary: `Supply ${input.amount} ${assetUpper} to Peridot on chain ${input.chainId}${collateralNote}`,\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits } from 'viem'\nimport { PTOKEN_ABI, COMPTROLLER_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getControllerAddress,\n getPTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const hubBorrowSchema = z.object({\n userAddress: evmAddress.describe('The wallet address that will borrow'),\n borrowAsset: z.string().describe('Asset to borrow, e.g. \"USDC\", \"WETH\"'),\n borrowAmount: tokenAmount.describe('Human-readable amount to borrow, e.g. \"500\" for 500 USDC'),\n collateralAssets: z\n .array(z.string())\n .min(1)\n .describe(\n 'Assets already supplied that will act as collateral, e.g. [\"WETH\"]. ' +\n 'These will have enterMarkets called to ensure they are active collateral.',\n ),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia). Use build_cross_chain_borrow_intent for spoke chains.' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubBorrowInput = z.infer<typeof hubBorrowSchema>\n\n/**\n * Builds the transaction calls to borrow from a Peridot hub-chain market.\n *\n * Call sequence:\n * 1. enterMarkets(collateralPTokens) — ensure collateral is active\n * 2. borrow(amount) — borrow from the market\n *\n * Prerequisites:\n * - Collateral must already be supplied (use build_hub_supply_intent first)\n * - Borrow amount must not exceed borrowing capacity (use simulate_borrow first)\n */\nexport function buildHubBorrowIntent(\n input: HubBorrowInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const borrowAssetUpper = input.borrowAsset.toUpperCase()\n const decimals = getAssetDecimals(borrowAssetUpper)\n const amount = parseUnits(input.borrowAmount, decimals)\n\n const borrowPToken = getPTokenAddress(input.chainId, borrowAssetUpper)\n const controller = getControllerAddress(input.chainId)\n const collateralPTokens = input.collateralAssets.map((a) =>\n getPTokenAddress(input.chainId, a.toUpperCase()),\n )\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: controller,\n data: encodeFunctionData({\n abi: COMPTROLLER_ABI,\n functionName: 'enterMarkets',\n args: [collateralPTokens],\n }),\n value: 0n,\n description: `Enable ${input.collateralAssets.join(', ')} as active collateral`,\n },\n {\n to: borrowPToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'borrow',\n args: [amount],\n }),\n value: 0n,\n description: `Borrow ${input.borrowAmount} ${borrowAssetUpper} from Peridot`,\n },\n ],\n summary: `Borrow ${input.borrowAmount} ${borrowAssetUpper} using ${input.collateralAssets.join(', ')} as collateral`,\n warning:\n 'Ensure your health factor stays above 1.2 after borrowing. Use simulate_borrow to verify.',\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits, maxUint256 } from 'viem'\nimport { ERC20_ABI, PTOKEN_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress } from '../../../../shared/zod-utils'\n\nexport const hubRepaySchema = z.object({\n userAddress: evmAddress.describe('The wallet address repaying the debt'),\n asset: z.string().describe('Asset to repay, e.g. \"USDC\", \"WETH\"'),\n amount: z\n .string()\n .refine((v) => v.toLowerCase() === 'max' || /^\\d+(\\.\\d+)?$/.test(v), {\n message: 'Amount must be a positive decimal number (e.g. \"500\") or \"max\" to repay all.',\n })\n .describe(\n 'Human-readable amount to repay, e.g. \"500\" for 500 USDC. ' +\n 'Use \"max\" to repay the full outstanding balance (sets uint256 max).',\n ),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubRepayInput = z.infer<typeof hubRepaySchema>\n\n/**\n * Builds the transaction calls to repay a borrow on a Peridot hub-chain market.\n *\n * Call sequence:\n * 1. approve(pToken, amount) — allow pToken to pull repayment tokens\n * 2. repayBorrow(amount) — repay outstanding debt\n *\n * Use amount = \"max\" to repay the full debt (passes uint256 max to the contract,\n * which the pToken interprets as \"repay all\").\n */\nexport function buildHubRepayIntent(\n input: HubRepayInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const isMax = input.amount.toLowerCase() === 'max'\n const amount = isMax ? maxUint256 : parseUnits(input.amount, decimals)\n\n const pToken = getPTokenAddress(input.chainId, assetUpper)\n const underlying = getUnderlyingTokenAddress(input.chainId, assetUpper)\n\n const displayAmount = isMax ? 'full balance' : `${input.amount} ${assetUpper}`\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: underlying,\n data: encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [pToken, amount],\n }),\n value: 0n,\n description: `Approve p${assetUpper} to pull repayment tokens`,\n },\n {\n to: pToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'repayBorrow',\n args: [amount],\n }),\n value: 0n,\n description: `Repay ${displayAmount} of ${assetUpper} debt`,\n },\n ],\n summary: `Repay ${displayAmount} of ${assetUpper} on Peridot (chain ${input.chainId})`,\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits } from 'viem'\nimport { PTOKEN_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const hubWithdrawSchema = z.object({\n userAddress: evmAddress.describe('The wallet address withdrawing'),\n asset: z.string().describe('Asset to withdraw, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable underlying amount to withdraw, e.g. \"100\" for 100 USDC'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubWithdrawInput = z.infer<typeof hubWithdrawSchema>\n\n/**\n * Builds the transaction call to withdraw (redeem) a supplied asset.\n * Uses redeemUnderlying so the user specifies the exact underlying amount to receive.\n *\n * Will revert on-chain if the withdrawal would cause the user's health factor\n * to drop below the liquidation threshold (i.e., they still have open borrows).\n */\nexport function buildHubWithdrawIntent(\n input: HubWithdrawInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const pToken = getPTokenAddress(input.chainId, assetUpper)\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: pToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'redeemUnderlying',\n args: [amount],\n }),\n value: 0n,\n description: `Withdraw ${input.amount} ${assetUpper} from Peridot`,\n },\n ],\n summary: `Withdraw ${input.amount} ${assetUpper} from Peridot (chain ${input.chainId})`,\n warning:\n 'This will revert if withdrawing would make your outstanding borrows undercollateralized.',\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData } from 'viem'\nimport { COMPTROLLER_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getControllerAddress,\n getPTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress } from '../../../../shared/zod-utils'\n\nexport const hubEnableCollateralSchema = z.object({\n userAddress: evmAddress.describe('The wallet address enabling collateral'),\n assets: z\n .array(z.string())\n .min(1)\n .describe('Assets to enable as collateral, e.g. [\"WETH\", \"USDC\"]'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubEnableCollateralInput = z.infer<typeof hubEnableCollateralSchema>\n\n/**\n * Builds the enterMarkets call to enable one or more supplied assets as collateral.\n * Must be called after supplying assets if they were not enabled during supply.\n * Enabling collateral is required before borrowing against that asset.\n */\nexport function buildHubEnableCollateralIntent(\n input: HubEnableCollateralInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const controller = getControllerAddress(input.chainId)\n const pTokens = input.assets.map((a) => getPTokenAddress(input.chainId, a.toUpperCase()))\n const assetsDisplay = input.assets.map((a) => a.toUpperCase()).join(', ')\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: controller,\n data: encodeFunctionData({\n abi: COMPTROLLER_ABI,\n functionName: 'enterMarkets',\n args: [pTokens],\n }),\n value: 0n,\n description: `Enable ${assetsDisplay} as collateral on Peridot`,\n },\n ],\n summary: `Enable ${assetsDisplay} as collateral on chain ${input.chainId}`,\n }\n}\n","import { z } from 'zod'\nimport { encodeFunctionData } from 'viem'\nimport { COMPTROLLER_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getControllerAddress,\n getPTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress } from '../../../../shared/zod-utils'\n\nexport const hubDisableCollateralSchema = z.object({\n userAddress: evmAddress.describe('The wallet address disabling collateral'),\n asset: z.string().describe('Asset to disable as collateral, e.g. \"USDC\"'),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain ID. Defaults to BSC (56).'),\n})\n\nexport type HubDisableCollateralInput = z.infer<typeof hubDisableCollateralSchema>\n\n/**\n * Builds the exitMarket call to disable a supplied asset as collateral.\n *\n * Will revert on-chain if disabling this collateral would make existing borrows\n * undercollateralized. Repay borrows or add more collateral first.\n */\nexport function buildHubDisableCollateralIntent(\n input: HubDisableCollateralInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const assetUpper = input.asset.toUpperCase()\n const controller = getControllerAddress(input.chainId)\n const pToken = getPTokenAddress(input.chainId, assetUpper)\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: controller,\n data: encodeFunctionData({\n abi: COMPTROLLER_ABI,\n functionName: 'exitMarket',\n args: [pToken],\n }),\n value: 0n,\n description: `Disable ${assetUpper} as collateral on Peridot`,\n },\n ],\n summary: `Disable ${assetUpper} as collateral on chain ${input.chainId}`,\n warning:\n 'This will revert if you have outstanding borrows that rely on this collateral.',\n }\n}\n","import { z } from 'zod'\nimport { parseUnits } from 'viem'\nimport { PeridotApiClient } from '../../../../shared/api-client'\nimport {\n ARBITRUM_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n resolveHubChainId,\n} from '../../../../shared/constants'\nimport type {\n CrossChainIntent,\n PeridotConfig,\n RuntimeErc20Balance,\n ComposeFlow,\n} from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const crossChainSupplySchema = z.object({\n userAddress: evmAddress.describe('The wallet address on the source chain'),\n sourceChainId: z\n .number()\n .int()\n .default(ARBITRUM_CHAIN_ID)\n .refine((id) => !isHubChain(id), { message: 'sourceChainId must be a spoke chain (e.g. 42161=Arbitrum, 8453=Base). Use build_hub_supply_intent for hub chains (56, 143, 1868).' })\n .describe(\n 'The spoke chain the user is on, e.g. 42161=Arbitrum, 8453=Base, 1=Ethereum. ' +\n 'This is where the user holds the tokens they want to supply.',\n ),\n asset: z.string().describe('Asset to supply, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable amount to supply, e.g. \"100\" for 100 USDC'),\n enableAsCollateral: z\n .boolean()\n .default(true)\n .describe('Whether to enable the supplied asset as collateral. Defaults to true.'),\n slippage: z\n .number()\n .default(0.01)\n .describe('Bridge slippage tolerance as a decimal (0.01 = 1%). Defaults to 1%.'),\n})\n\nexport type CrossChainSupplyInput = z.input<typeof crossChainSupplySchema>\n\n/**\n * Builds a cross-chain supply intent using Biconomy MEE.\n *\n * Biconomy orchestrates all steps atomically from a single user signature:\n * 1. Bridge asset from source chain → BSC (via Axelar/Squid internally)\n * 2. Approve p{Asset} to spend underlying on BSC\n * 3. mint(amount) — supply to Peridot, receive pTokens\n * 4. enterMarkets([]) — (optional) enable as collateral\n * 5. transfer pTokens — return pTokens to user's EOA on BSC\n *\n * Returns a CrossChainIntent — the user's dApp must pass biconomyInstructions\n * to POST /api/biconomy/execute (or directly to Biconomy's execute endpoint).\n */\nexport async function buildCrossChainSupplyIntent(\n input: CrossChainSupplyInput,\n config: PeridotConfig,\n): Promise<CrossChainIntent> {\n const client = new PeridotApiClient(config)\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const sourceChainId = input.sourceChainId ?? ARBITRUM_CHAIN_ID\n const enableAsCollateral = input.enableAsCollateral ?? true\n const hubChainId = resolveHubChainId(sourceChainId, config.network ?? 'mainnet')\n const sourceToken = getUnderlyingTokenAddress(sourceChainId, assetUpper)\n const hubUnderlying = getUnderlyingTokenAddress(hubChainId, assetUpper)\n const pToken = getPTokenAddress(hubChainId, assetUpper)\n\n const runtimeBalance: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: hubUnderlying,\n }\n\n const composeFlows: ComposeFlow[] = [\n // Step 1: Bridge from spoke → hub\n {\n type: '/instructions/intent-simple' as const,\n data: {\n srcToken: sourceToken,\n dstToken: hubUnderlying,\n srcChainId: sourceChainId,\n dstChainId: hubChainId,\n amount: amount.toString(),\n slippage: input.slippage ?? 0.01,\n },\n batch: false,\n },\n // Step 2: Approve pToken to spend underlying\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function approve(address,uint256)',\n args: [pToken, runtimeBalance],\n to: hubUnderlying,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n // Step 3: Mint pTokens\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function mint(uint256)',\n args: [runtimeBalance],\n to: pToken,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n ]\n\n // Step 4: Enable as collateral\n if (enableAsCollateral) {\n const { getControllerAddress } = await import('../../../../shared/constants')\n const controller = getControllerAddress(hubChainId)\n composeFlows.push({\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function enterMarkets(address[] memory)',\n args: [[pToken]],\n to: controller,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n })\n }\n\n // Step 5: Return pTokens to user's EOA\n const pTokenRuntime: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: pToken,\n constraints: { gte: '1' },\n }\n composeFlows.push({\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function transfer(address,uint256)',\n args: [input.userAddress, pTokenRuntime],\n to: pToken,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n })\n\n const biconomyResponse = await client.biconomyCompose({\n ownerAddress: input.userAddress as `0x${string}`,\n mode: 'eoa',\n composeFlows,\n })\n\n const collateralNote = enableAsCollateral ? ' and enable as collateral' : ''\n const userSteps = [\n `Bridge ${input.amount} ${assetUpper} from chain ${sourceChainId} → hub (chain ${hubChainId})`,\n `Approve Peridot p${assetUpper} market to spend ${assetUpper}`,\n `Supply ${input.amount} ${assetUpper} to Peridot, receiving p${assetUpper}`,\n ...(enableAsCollateral ? [`Enable ${assetUpper} as collateral`] : []),\n `Return p${assetUpper} tokens to your wallet`,\n ]\n\n return {\n type: 'cross-chain',\n sourceChainId,\n destinationChainId: hubChainId,\n summary: `Cross-chain supply ${input.amount} ${assetUpper} from chain ${sourceChainId} to Peridot${collateralNote}`,\n userSteps,\n biconomyInstructions: biconomyResponse,\n estimatedGas: biconomyResponse.estimatedGas ?? 'unknown',\n }\n}\n","import { z } from 'zod'\nimport { parseUnits } from 'viem'\nimport { PeridotApiClient } from '../../../../shared/api-client'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getControllerAddress,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type {\n CrossChainIntent,\n PeridotConfig,\n RuntimeErc20Balance,\n ComposeFlow,\n} from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const crossChainBorrowSchema = z.object({\n userAddress: evmAddress.describe('The wallet address borrowing'),\n collateralAssets: z\n .array(z.string())\n .min(1)\n .describe('Assets already supplied as collateral, e.g. [\"WETH\"]'),\n borrowAsset: z.string().describe('Asset to borrow, e.g. \"USDC\"'),\n borrowAmount: tokenAmount.describe('Human-readable amount, e.g. \"500\" for 500 USDC'),\n targetChainId: z\n .number()\n .int()\n .optional()\n .refine((id) => id === undefined || !isHubChain(id), {\n message:\n 'targetChainId must be a spoke chain (e.g. 42161=Arbitrum, 8453=Base) or omitted to keep funds on the hub.',\n })\n .describe(\n 'Spoke chain to receive borrowed funds, e.g. 42161=Arbitrum. ' +\n 'If omitted, borrowed funds remain on the hub chain (BSC).',\n ),\n slippage: z.number().default(0.01).describe('Bridge slippage tolerance. Defaults to 1%.'),\n})\n\nexport type CrossChainBorrowInput = z.input<typeof crossChainBorrowSchema>\n\n/**\n * Borrows from Peridot hub and optionally bridges the proceeds to a spoke chain.\n *\n * Call sequence (via Biconomy MEE):\n * 1. enterMarkets(collateralPTokens) — ensure collateral is active\n * 2. borrow(amount) — borrow from pToken market on hub\n * 3a. Bridge borrowed tokens → target chain (if targetChainId provided), OR\n * 3b. Transfer borrowed tokens to user's EOA on hub chain\n */\nexport async function buildCrossChainBorrowIntent(\n input: CrossChainBorrowInput,\n config: PeridotConfig,\n): Promise<CrossChainIntent> {\n const client = new PeridotApiClient(config)\n const borrowAssetUpper = input.borrowAsset.toUpperCase()\n const decimals = getAssetDecimals(borrowAssetUpper)\n const amount = parseUnits(input.borrowAmount, decimals)\n\n // Hub chain is always BSC for mainnet\n const actualHubChainId = BSC_MAINNET_CHAIN_ID\n\n const borrowPToken = getPTokenAddress(actualHubChainId, borrowAssetUpper)\n const controller = getControllerAddress(actualHubChainId)\n const hubUnderlying = getUnderlyingTokenAddress(actualHubChainId, borrowAssetUpper)\n const collateralPTokens = input.collateralAssets.map((a) =>\n getPTokenAddress(actualHubChainId, a.toUpperCase()),\n )\n\n const composeFlows: ComposeFlow[] = [\n // Step 1: Enable collateral\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function enterMarkets(address[] memory)',\n args: [collateralPTokens],\n to: controller,\n chainId: actualHubChainId,\n value: '0',\n },\n batch: true,\n },\n // Step 2: Borrow\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function borrow(uint256)',\n args: [amount.toString()],\n to: borrowPToken,\n chainId: actualHubChainId,\n value: '0',\n },\n batch: true,\n },\n ]\n\n const runtimeBalance: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: hubUnderlying,\n constraints: { gte: '1' },\n }\n\n const userSteps = [\n `Enable ${input.collateralAssets.join(', ')} as active collateral`,\n `Borrow ${input.borrowAmount} ${borrowAssetUpper} from Peridot`,\n ]\n\n // Step 3: Deliver borrowed funds\n if (input.targetChainId && input.targetChainId !== actualHubChainId) {\n const targetToken = getUnderlyingTokenAddress(input.targetChainId, borrowAssetUpper)\n composeFlows.push({\n type: '/instructions/intent-simple',\n data: {\n srcToken: hubUnderlying,\n dstToken: targetToken,\n srcChainId: actualHubChainId,\n dstChainId: input.targetChainId,\n amount: runtimeBalance,\n slippage: input.slippage ?? 0.01,\n },\n batch: false,\n } as ComposeFlow)\n userSteps.push(`Bridge ${borrowAssetUpper} from hub → chain ${input.targetChainId}`)\n } else {\n composeFlows.push({\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function transfer(address,uint256)',\n args: [input.userAddress, runtimeBalance],\n to: hubUnderlying,\n chainId: actualHubChainId,\n value: '0',\n },\n batch: true,\n })\n userSteps.push(`Receive ${borrowAssetUpper} in your wallet on chain ${actualHubChainId}`)\n }\n\n const biconomyResponse = await client.biconomyCompose({\n ownerAddress: input.userAddress as `0x${string}`,\n mode: 'eoa',\n composeFlows,\n })\n\n const destination = input.targetChainId ?? actualHubChainId\n\n return {\n type: 'cross-chain',\n sourceChainId: actualHubChainId,\n destinationChainId: destination,\n summary: `Borrow ${input.borrowAmount} ${borrowAssetUpper} from Peridot, receive on chain ${destination}`,\n userSteps,\n biconomyInstructions: biconomyResponse,\n estimatedGas: biconomyResponse.estimatedGas ?? 'unknown',\n }\n}\n","import { z } from 'zod'\nimport { parseUnits } from 'viem'\nimport { PeridotApiClient } from '../../../../shared/api-client'\nimport {\n ARBITRUM_CHAIN_ID,\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type {\n CrossChainIntent,\n PeridotConfig,\n RuntimeErc20Balance,\n} from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const crossChainRepaySchema = z.object({\n userAddress: evmAddress.describe('The wallet address repaying the debt'),\n sourceChainId: z\n .number()\n .int()\n .default(ARBITRUM_CHAIN_ID)\n .refine((id) => !isHubChain(id), {\n message:\n 'sourceChainId must be a spoke chain (e.g. 42161=Arbitrum, 8453=Base). Use build_hub_repay_intent for hub chains (56, 143, 1868).',\n })\n .describe('Spoke chain the user holds repayment tokens on, e.g. 42161=Arbitrum, 8453=Base'),\n asset: z.string().describe('Asset to repay, e.g. \"USDC\", \"USDT\"'),\n amount: tokenAmount.describe('Human-readable amount to repay, e.g. \"500\" for 500 USDC'),\n repayForAddress: evmAddress\n .optional()\n .describe('Repay on behalf of another address. Defaults to userAddress.'),\n slippage: z.number().default(0.01).describe('Bridge slippage tolerance. Defaults to 1%.'),\n})\n\nexport type CrossChainRepayInput = z.input<typeof crossChainRepaySchema>\n\n/**\n * Repays a Peridot borrow from a spoke chain using Biconomy MEE.\n *\n * Call sequence:\n * 1. Bridge repayment tokens from source chain → BSC hub\n * 2. Approve p{Asset} to pull repayment tokens\n * 3. repayBorrow(amount) — or repayBorrowBehalf if repayForAddress set\n * 4. Return any excess tokens to user's EOA on BSC\n */\nexport async function buildCrossChainRepayIntent(\n input: CrossChainRepayInput,\n config: PeridotConfig,\n): Promise<CrossChainIntent> {\n const client = new PeridotApiClient(config)\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const hubChainId = BSC_MAINNET_CHAIN_ID\n const sourceChainId = input.sourceChainId ?? ARBITRUM_CHAIN_ID\n const sourceToken = getUnderlyingTokenAddress(sourceChainId, assetUpper)\n const hubUnderlying = getUnderlyingTokenAddress(hubChainId, assetUpper)\n const pToken = getPTokenAddress(hubChainId, assetUpper)\n\n const runtimeBalance: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: hubUnderlying,\n }\n\n const repayForAddress = input.repayForAddress ?? input.userAddress\n const isBehalf = input.repayForAddress !== undefined && input.repayForAddress !== input.userAddress\n\n const composeFlows = [\n // Step 1: Bridge from spoke → hub\n {\n type: '/instructions/intent-simple' as const,\n data: {\n srcToken: sourceToken,\n dstToken: hubUnderlying,\n srcChainId: sourceChainId,\n dstChainId: hubChainId,\n amount: amount.toString(),\n slippage: input.slippage ?? 0.01,\n },\n batch: false,\n },\n // Step 2: Approve pToken to pull repayment\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function approve(address,uint256)',\n args: [pToken, runtimeBalance],\n to: hubUnderlying,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n // Step 3: Repay borrow\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: isBehalf\n ? 'function repayBorrowBehalf(address,uint256)'\n : 'function repayBorrow(uint256)',\n args: isBehalf ? [repayForAddress, runtimeBalance] : [runtimeBalance],\n to: pToken,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n // Step 4: Return excess to EOA\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function transfer(address,uint256)',\n args: [\n input.userAddress,\n { type: 'runtimeErc20Balance', tokenAddress: hubUnderlying, constraints: { gte: '0' } } satisfies RuntimeErc20Balance,\n ],\n to: hubUnderlying,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n ]\n\n const biconomyResponse = await client.biconomyCompose({\n ownerAddress: input.userAddress as `0x${string}`,\n mode: 'eoa',\n composeFlows,\n })\n\n const behalfNote = isBehalf ? ` on behalf of ${repayForAddress}` : ''\n\n return {\n type: 'cross-chain',\n sourceChainId,\n destinationChainId: hubChainId,\n summary: `Repay ${input.amount} ${assetUpper}${behalfNote} from chain ${sourceChainId} to Peridot`,\n userSteps: [\n `Bridge ${input.amount} ${assetUpper} from chain ${sourceChainId} → BSC`,\n `Approve Peridot p${assetUpper} to pull repayment tokens`,\n `Repay ${input.amount} ${assetUpper} debt${behalfNote}`,\n `Return any excess ${assetUpper} to your BSC wallet`,\n ],\n biconomyInstructions: biconomyResponse,\n estimatedGas: biconomyResponse.estimatedGas ?? 'unknown',\n }\n}\n","import { z } from 'zod'\nimport { parseUnits } from 'viem'\nimport { PeridotApiClient } from '../../../../shared/api-client'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type {\n CrossChainIntent,\n PeridotConfig,\n RuntimeErc20Balance,\n ComposeFlow,\n} from '../../../../shared/types'\nimport { evmAddress, tokenAmount } from '../../../../shared/zod-utils'\n\nexport const crossChainWithdrawSchema = z.object({\n userAddress: evmAddress.describe('The wallet address withdrawing'),\n asset: z.string().describe('Asset to withdraw, e.g. \"USDC\", \"WETH\"'),\n amount: tokenAmount.describe('Human-readable underlying amount to withdraw, e.g. \"100\"'),\n targetChainId: z\n .number()\n .int()\n .optional()\n .refine((id) => id === undefined || !isHubChain(id), {\n message:\n 'targetChainId must be a spoke chain (e.g. 42161=Arbitrum, 8453=Base) or omitted to keep funds on the hub.',\n })\n .describe(\n 'Spoke chain to receive the withdrawn funds, e.g. 42161=Arbitrum. ' +\n 'If omitted, funds remain on the hub chain (BSC).',\n ),\n slippage: z.number().default(0.01).describe('Bridge slippage tolerance. Defaults to 1%.'),\n})\n\nexport type CrossChainWithdrawInput = z.input<typeof crossChainWithdrawSchema>\n\n/**\n * Withdraws from Peridot hub and optionally bridges proceeds to a spoke chain.\n *\n * Call sequence (via Biconomy MEE):\n * 1. redeemUnderlying(amount) — redeem pTokens for underlying on hub\n * 2a. Bridge underlying → target spoke chain (if targetChainId set), OR\n * 2b. Transfer to user's EOA on hub chain\n */\nexport async function buildCrossChainWithdrawIntent(\n input: CrossChainWithdrawInput,\n config: PeridotConfig,\n): Promise<CrossChainIntent> {\n const client = new PeridotApiClient(config)\n const assetUpper = input.asset.toUpperCase()\n const decimals = getAssetDecimals(assetUpper)\n const amount = parseUnits(input.amount, decimals)\n\n const hubChainId = BSC_MAINNET_CHAIN_ID\n const pToken = getPTokenAddress(hubChainId, assetUpper)\n const hubUnderlying = getUnderlyingTokenAddress(hubChainId, assetUpper)\n\n const runtimeBalance: RuntimeErc20Balance = {\n type: 'runtimeErc20Balance',\n tokenAddress: hubUnderlying,\n constraints: { gte: '1' },\n }\n\n const composeFlows: ComposeFlow[] = [\n // Step 1: Redeem from Peridot\n {\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function redeemUnderlying(uint256)',\n args: [amount.toString()],\n to: pToken,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n },\n ]\n\n const userSteps = [`Redeem ${input.amount} ${assetUpper} from Peridot (p${assetUpper} → ${assetUpper})`]\n\n // Step 2: Deliver funds\n if (input.targetChainId && input.targetChainId !== hubChainId) {\n const targetToken = getUnderlyingTokenAddress(input.targetChainId, assetUpper)\n composeFlows.push({\n type: '/instructions/intent-simple',\n data: {\n srcToken: hubUnderlying,\n dstToken: targetToken,\n srcChainId: hubChainId,\n dstChainId: input.targetChainId,\n amount: runtimeBalance,\n slippage: input.slippage ?? 0.01,\n },\n batch: false,\n } as ComposeFlow)\n userSteps.push(`Bridge ${assetUpper} from hub → chain ${input.targetChainId}`)\n } else {\n composeFlows.push({\n type: '/instructions/build' as const,\n data: {\n functionSignature: 'function transfer(address,uint256)',\n args: [input.userAddress, runtimeBalance],\n to: hubUnderlying,\n chainId: hubChainId,\n value: '0',\n },\n batch: true,\n })\n userSteps.push(`Receive ${assetUpper} in your wallet on BSC`)\n }\n\n const biconomyResponse = await client.biconomyCompose({\n ownerAddress: input.userAddress as `0x${string}`,\n mode: 'eoa',\n composeFlows,\n })\n\n const destination = input.targetChainId ?? hubChainId\n\n return {\n type: 'cross-chain',\n sourceChainId: hubChainId,\n destinationChainId: destination,\n summary: `Withdraw ${input.amount} ${assetUpper} from Peridot, receive on chain ${destination}`,\n userSteps,\n biconomyInstructions: biconomyResponse,\n estimatedGas: biconomyResponse.estimatedGas ?? 'unknown',\n }\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { PeridotConfig, TransactionStatus } from '../../../shared/types'\n\nexport const checkTransactionStatusSchema = z.object({\n superTxHash: z\n .string()\n .describe(\n 'The Biconomy super-transaction hash returned after executing a cross-chain intent. ' +\n 'Looks like a regular tx hash (0x...).',\n ),\n})\n\nexport type CheckTransactionStatusInput = z.infer<typeof checkTransactionStatusSchema>\n\n/**\n * Polls Biconomy for the status of a cross-chain super-transaction.\n * Call this after the user has signed and submitted a CrossChainIntent.\n */\nexport async function checkTransactionStatus(\n input: CheckTransactionStatusInput,\n config: PeridotConfig,\n): Promise<TransactionStatus> {\n const client = new PeridotApiClient(config)\n return client.biconomyGetStatus(input.superTxHash)\n}\n","import { z } from 'zod'\nimport { PeridotApiClient } from '../../../shared/api-client'\nimport type { LiquidatablePositions, PeridotConfig } from '../../../shared/types'\n\nexport const getLiquidatablePositionsSchema = z.object({\n chainId: z\n .number()\n .int()\n .optional()\n .describe(\n 'Filter to a single hub chain (56=BSC, 143=Monad, 1868=Somnia). ' +\n 'Omit to return at-risk accounts across all chains.',\n ),\n minShortfall: z\n .number()\n .min(0)\n .optional()\n .describe(\n 'Minimum shortfall_usd threshold in USD (default: 0 — returns all underwater accounts). ' +\n 'Use e.g. 100 to focus only on meaningfully undercollateralised positions.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe('Maximum number of results (default: 50, max: 200). Results are ordered by shortfall descending.'),\n})\n\nexport type GetLiquidatablePositionsInput = z.infer<typeof getLiquidatablePositionsSchema>\n\n/**\n * Fetch accounts currently eligible for liquidation from the platform's\n * health scanner endpoint.\n *\n * Returns the accounts ordered by shortfall_usd descending — the most\n * underwater positions appear first.\n */\nexport async function getLiquidatablePositions(\n input: GetLiquidatablePositionsInput,\n config: PeridotConfig,\n): Promise<LiquidatablePositions> {\n const client = new PeridotApiClient(config)\n const opts: { chainId?: number; minShortfall?: number; limit?: number } = {}\n if (input.chainId !== undefined) opts.chainId = input.chainId\n if (input.minShortfall !== undefined) opts.minShortfall = input.minShortfall\n if (input.limit !== undefined) opts.limit = input.limit\n return client.getLiquidatablePositions(opts)\n}\n","import { z } from 'zod'\nimport { encodeFunctionData, parseUnits, maxUint256 } from 'viem'\nimport { ERC20_ABI, PTOKEN_ABI } from '../../../../shared/abis'\nimport {\n BSC_MAINNET_CHAIN_ID,\n getAssetDecimals,\n getPTokenAddress,\n getUnderlyingTokenAddress,\n isHubChain,\n} from '../../../../shared/constants'\nimport type { HubTransactionIntent, PeridotConfig } from '../../../../shared/types'\nimport { evmAddress } from '../../../../shared/zod-utils'\n\nexport const hubLiquidateSchema = z.object({\n liquidatorAddress: evmAddress.describe('The wallet address executing the liquidation (your address)'),\n borrowerAddress: evmAddress.describe('The underwater borrower address to liquidate'),\n repayAsset: z\n .string()\n .describe(\n 'The asset you will repay on behalf of the borrower, e.g. \"USDC\". ' +\n 'This must be an asset the borrower has borrowed.',\n ),\n repayAmount: z\n .string()\n .refine((v) => v.toLowerCase() === 'max' || /^\\d+(\\.\\d+)?$/.test(v), {\n message: 'Amount must be a positive decimal number (e.g. \"500\") or \"max\" for uint256 max.',\n })\n .describe(\n 'Amount of repayAsset to repay (human-readable, e.g. \"500\" for 500 USDC). ' +\n 'A liquidator may repay at most 50% of the borrower\\'s outstanding debt per call (close factor). ' +\n 'Use \"max\" to pass uint256 max — the protocol will cap it at the close factor automatically.',\n ),\n collateralAsset: z\n .string()\n .describe(\n 'The collateral asset you want to seize in return, e.g. \"WETH\". ' +\n 'This must be an asset the borrower has supplied as collateral. ' +\n 'You receive the equivalent value in pTokens (+ liquidation incentive bonus).',\n ),\n chainId: z\n .number()\n .int()\n .default(BSC_MAINNET_CHAIN_ID)\n .refine(isHubChain, { message: 'chainId must be a hub chain (56=BSC, 143=Monad, 1868=Somnia).' })\n .describe('Hub chain where the underwater position exists. Defaults to BSC (56).'),\n})\n\nexport type HubLiquidateInput = z.infer<typeof hubLiquidateSchema>\n\n/**\n * Builds the transaction calls to liquidate an underwater Peridot borrower\n * on a hub chain.\n *\n * Compound V2 liquidation flow:\n * 1. approve(pRepayToken, repayAmount) — allow the repay pToken to pull funds\n * 2. liquidateBorrow(borrower, repayAmount, — repay debt, seize collateral pTokens\n * pCollateralToken)\n *\n * The liquidator receives pToken shares of the collateral asset.\n * To receive the underlying, call redeem() on the collateral pToken afterward.\n *\n * IMPORTANT: verify the borrower is still underwater immediately before\n * submitting — health can change between blocks. Use get_liquidatable_positions\n * or get_account_liquidity to confirm shortfallUsd > 0.\n */\nexport function buildHubLiquidateIntent(\n input: HubLiquidateInput,\n _config: PeridotConfig,\n): HubTransactionIntent {\n const repayAsset = input.repayAsset.toUpperCase()\n const collateralAsset = input.collateralAsset.toUpperCase()\n\n const repayDecimals = getAssetDecimals(repayAsset)\n const isMax = input.repayAmount.toLowerCase() === 'max'\n const repayAmount = isMax ? maxUint256 : parseUnits(input.repayAmount, repayDecimals)\n\n const pRepayToken = getPTokenAddress(input.chainId, repayAsset)\n const pCollateralToken = getPTokenAddress(input.chainId, collateralAsset)\n const underlyingRepay = getUnderlyingTokenAddress(input.chainId, repayAsset)\n\n const displayAmount = isMax ? 'max (capped at close factor)' : `${input.repayAmount} ${repayAsset}`\n\n return {\n type: 'hub',\n chainId: input.chainId,\n calls: [\n {\n to: underlyingRepay,\n data: encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [pRepayToken, repayAmount],\n }),\n value: 0n,\n description: `Approve p${repayAsset} to pull ${displayAmount} for liquidation`,\n },\n {\n to: pRepayToken,\n data: encodeFunctionData({\n abi: PTOKEN_ABI,\n functionName: 'liquidateBorrow',\n args: [input.borrowerAddress as `0x${string}`, repayAmount, pCollateralToken],\n }),\n value: 0n,\n description:\n `Liquidate ${input.borrowerAddress}: repay ${displayAmount} of ${repayAsset}, ` +\n `seize p${collateralAsset} collateral`,\n },\n ],\n summary:\n `Liquidate ${input.borrowerAddress} on chain ${input.chainId}: ` +\n `repay ${displayAmount} of ${repayAsset}, receive p${collateralAsset}`,\n warning:\n 'Verify the borrower is still underwater (shortfallUsd > 0) immediately before submitting. ' +\n 'The transaction will revert if the position has been partially repaid between blocks.',\n }\n}\n","/**\n * Lending feature tool registry.\n *\n * Adding a new tool:\n * 1. Implement the function in the appropriate read/ or intents/ subdirectory\n * 2. Add an entry to the `lendingTools` array below\n * 3. It will automatically appear in the MCP server and all framework adapters\n *\n * Adding a new feature (e.g. margin):\n * Create src/features/margin/tools.ts with the same pattern, then add it to\n * src/adapters/mcp/server.ts's `allTools` array.\n */\n\nimport type { ToolDefinition } from '../../shared/types'\n\nimport { listMarketsSchema, listMarkets } from './read/list-markets'\nimport { getPortfolioSchema, getPortfolio } from './read/get-portfolio'\nimport { getLeaderboardSchema, getLeaderboard } from './read/get-leaderboard'\nimport { getMarketRatesSchema, getMarketRates } from './read/get-market-rates'\nimport { getUserPositionSchema, getUserPosition } from './read/get-user-position'\nimport { simulateBorrowSchema, simulateBorrow } from './read/simulate-borrow'\nimport { getAccountLiquiditySchema, getAccountLiquidity } from './read/get-account-liquidity'\nimport { hubSupplySchema, buildHubSupplyIntent } from './intents/hub/supply'\nimport { hubBorrowSchema, buildHubBorrowIntent } from './intents/hub/borrow'\nimport { hubRepaySchema, buildHubRepayIntent } from './intents/hub/repay'\nimport { hubWithdrawSchema, buildHubWithdrawIntent } from './intents/hub/withdraw'\nimport { hubEnableCollateralSchema, buildHubEnableCollateralIntent } from './intents/hub/enable-collateral'\nimport { hubDisableCollateralSchema, buildHubDisableCollateralIntent } from './intents/hub/disable-collateral'\nimport { crossChainSupplySchema, buildCrossChainSupplyIntent } from './intents/cross-chain/supply'\nimport { crossChainBorrowSchema, buildCrossChainBorrowIntent } from './intents/cross-chain/borrow'\nimport { crossChainRepaySchema, buildCrossChainRepayIntent } from './intents/cross-chain/repay'\nimport { crossChainWithdrawSchema, buildCrossChainWithdrawIntent } from './intents/cross-chain/withdraw'\nimport { checkTransactionStatusSchema, checkTransactionStatus } from './status/check-transaction'\nimport { getLiquidatablePositionsSchema, getLiquidatablePositions } from './read/get-liquidatable-positions'\nimport { hubLiquidateSchema, buildHubLiquidateIntent } from './intents/hub/liquidate'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const lendingTools: ToolDefinition<any, any>[] = [\n // ── Read / Simulate ──────────────────────────────────────────────────────\n\n {\n name: 'list_markets',\n description:\n 'List all Peridot lending markets across all chains with key metrics: asset symbol, chainId, ' +\n 'price (USD), TVL (USD), utilization %, available liquidity (USD), and collateral factor %. ' +\n 'Results are sorted by TVL descending — the deepest, most liquid markets appear first. ' +\n 'Call this when the user asks \"what can I lend or borrow?\", \"which assets are available?\", ' +\n 'or before recommending a specific market when you do not already know what is available. ' +\n 'Optionally pass chainId (56=BSC, 143=Monad, 1868=Somnia) to restrict results to one chain.',\n inputSchema: listMarketsSchema,\n execute: listMarkets,\n category: 'lending',\n },\n\n {\n name: 'get_leaderboard',\n description:\n 'Fetch the Peridot points leaderboard: ranked list of top users by total protocol points earned. ' +\n 'Each entry contains: rank, wallet address, totalPoints, supplyCount, borrowCount, repayCount, ' +\n 'redeemCount, and last-updated timestamp. Points reflect on-chain DeFi activity and daily logins. ' +\n 'Call this when the user asks \"who are the top users?\", \"show me the leaderboard\", ' +\n '\"how many points does address X have?\", or \"where do I rank?\". ' +\n 'Use limit (default 50, max 100) to control result size.',\n inputSchema: getLeaderboardSchema,\n execute: getLeaderboard,\n category: 'lending',\n },\n\n {\n name: 'get_market_rates',\n description:\n 'Fetch the full rate breakdown for a specific Peridot market (asset + chainId). ' +\n 'Returns: base supply APY, base borrow APY, PERIDOT token reward APY (supply and borrow), ' +\n 'boost source APY (Morpho vault / PancakeSwap LP / Magma staking), boost reward APY, ' +\n 'total supply APY (= base + peridot + boost_source + boost_rewards), ' +\n 'net borrow APY (= base borrow − peridot borrow reward), ' +\n 'TVL (USD), utilization %, available liquidity (USD), asset price (USD), collateral factor %. ' +\n 'Call this when the user asks about APY, yields, borrow rates, or liquidity for a specific asset. ' +\n 'If you do not know which chainId the asset is on, call list_markets first.',\n inputSchema: getMarketRatesSchema,\n execute: getMarketRates,\n category: 'lending',\n },\n\n {\n name: 'get_portfolio',\n description:\n \"Fetch a wallet's full Peridot portfolio overview: portfolio summary (currentValue, \" +\n 'totalSupplied, totalBorrowed, netApy, simplified healthFactor), per-asset breakdown ' +\n 'with allocation percentages (supplied, borrowed, net, % of portfolio), all transaction ' +\n 'counts (totalCount, supply/borrow/repay/redeem), and lifetime earnings ' +\n '(effectiveApy, totalLifetimeEarnings in USD). ' +\n 'Call this when the user asks \"how is my portfolio performing?\", \"what are my earnings?\", ' +\n '\"show me my full breakdown\", \"what percentage of my portfolio is in X?\", or any question ' +\n 'about lifetime yield or activity history. ' +\n 'Results are cached for 30 s — concurrent calls for the same address share one request. ' +\n 'For a quick pre-action exposure check before borrowing or withdrawing, ' +\n 'use get_user_position instead (lighter, returns simplified health factor).',\n inputSchema: getPortfolioSchema,\n execute: getPortfolio,\n category: 'lending',\n },\n\n {\n name: 'get_user_position',\n description:\n \"Fetch a user's current Peridot portfolio snapshot: totalSuppliedUsd, totalBorrowedUsd, \" +\n 'netWorthUsd, netApyPct, per-asset breakdown, and transaction counts (supply/borrow/repay/redeem). ' +\n 'Also returns a simplified healthFactor estimate (totalSupplied / totalBorrowed). ' +\n 'IMPORTANT: this estimate ignores per-asset collateral factors and will OVERSTATE the real ' +\n 'on-chain health — treat it as a quick indicator only. ' +\n 'Rule of thumb: above 2.0 = low near-term risk; below 2.0 = call get_account_liquidity before ' +\n 'recommending further borrows or large withdrawals. ' +\n 'ALWAYS call this before building any borrow, withdraw, or repay intent so you know the ' +\n \"user's current exposure and can explain the risk to them.\",\n inputSchema: getUserPositionSchema,\n execute: getUserPosition,\n category: 'lending',\n },\n\n {\n name: 'simulate_borrow',\n description:\n \"Simulate the health factor impact of a proposed borrow before submitting any transaction. \" +\n 'Returns: currentHealthFactor, projectedHealthFactor, borrowAmountUsd, isSafe (bool), ' +\n 'riskLevel (safe | moderate | high | critical | liquidatable), and maxSafeBorrowUsd. ' +\n 'ALWAYS call this before build_hub_borrow_intent or build_cross_chain_borrow_intent. ' +\n 'Rules: if isSafe=false → explain the risk and do NOT build the intent. ' +\n 'If riskLevel is \"high\" or worse → warn the user and confirm before proceeding. ' +\n 'If riskLevel is \"moderate\" → note the risk, suggest a smaller amount or adding more collateral. ' +\n 'Never skip this step even if the user sounds confident — you cannot predict the liquidation ' +\n 'threshold without it.',\n inputSchema: simulateBorrowSchema,\n execute: simulateBorrow,\n category: 'lending',\n },\n\n {\n name: 'get_account_liquidity',\n description:\n \"Read the authoritative on-chain borrow capacity and health directly from Peridot's \" +\n 'Comptroller contract. Returns: liquidityUsd (how much more the user can safely borrow), ' +\n 'shortfallUsd (how much underwater — non-zero means they are at risk of liquidation), ' +\n 'and isHealthy (true when shortfall = 0). ' +\n 'Use this instead of get_user_position when precision matters: before large withdrawals, ' +\n 'when the simplified health factor is near 1.5, or when the user asks whether they are ' +\n 'at risk of liquidation. This is the same value the protocol uses on-chain.',\n inputSchema: getAccountLiquiditySchema,\n execute: getAccountLiquidity,\n category: 'lending',\n },\n\n {\n name: 'get_liquidatable_positions',\n description:\n 'Fetch a list of borrowers currently underwater (shortfallUsd > 0) and eligible for liquidation ' +\n 'on Peridot hub chains. Data is sourced from the on-chain health scanner that indexes borrow events ' +\n 'and recomputes account health periodically. ' +\n 'IMPORTANT: if this returns an empty list, the scanner pipeline (scan_borrow_events + ' +\n 'scan_account_health) may not have run yet — the data table could be empty rather than meaning ' +\n 'no positions are underwater. In that case, inform the user that liquidation data is not yet ' +\n 'available and suggest checking back later. ' +\n 'Each result contains: address, chainId, shortfallUsd (how far underwater in USD), ' +\n 'liquidityUsd (0 when underwater), and checkedAt (when last scanned). ' +\n 'Results are ordered by shortfallUsd descending — the most undercollateralised positions first. ' +\n 'Use minShortfall to filter out dust positions (e.g. minShortfall=100 for $100+ shortfall). ' +\n 'Always call get_account_liquidity to re-confirm a position is still underwater immediately ' +\n 'before building a liquidation intent — health can change between scanner runs.',\n inputSchema: getLiquidatablePositionsSchema,\n execute: getLiquidatablePositions,\n category: 'liquidations',\n },\n\n // ── Hub-chain intents (user on BSC / Monad / Somnia) ─────────────────────\n // Hub chains host Peridot lending pools natively.\n // Hub chainIds: BSC (56), Monad (143), Somnia (1868).\n // If the user is on any other chain, use the cross-chain tools instead.\n\n {\n name: 'build_hub_supply_intent',\n description:\n 'Build signed-ready calldata to supply an asset to Peridot on a hub chain. ' +\n 'USE THIS TOOL ONLY when the user is already on a hub chain: BSC (56), Monad (143), or Somnia (1868). ' +\n 'If the user is on Arbitrum (42161), Base (8453), Ethereum (1), Polygon (137), Optimism (10), ' +\n 'or Avalanche (43114), use build_cross_chain_supply_intent instead. ' +\n 'Returns an ordered `calls` array: approve ERC-20 → mint pToken → enterMarkets (enable collateral). ' +\n 'Tell the user to sign and submit each call in sequence using their wallet.',\n inputSchema: hubSupplySchema,\n execute: buildHubSupplyIntent,\n category: 'lending',\n },\n\n {\n name: 'build_hub_borrow_intent',\n description:\n 'Build calldata to borrow from Peridot on a hub chain (BSC 56, Monad 143, or Somnia 1868). ' +\n 'Returns ordered calls: enterMarkets (activate collateral if needed) → borrow. ' +\n 'REQUIRED BEFORE CALLING THIS: run simulate_borrow and confirm isSafe=true. ' +\n 'If the user is on a spoke chain (Arbitrum, Base, Ethereum, etc.), use ' +\n 'build_cross_chain_borrow_intent instead. ' +\n 'Tell the user to sign and submit each call in order.',\n inputSchema: hubBorrowSchema,\n execute: buildHubBorrowIntent,\n category: 'lending',\n },\n\n {\n name: 'build_hub_repay_intent',\n description:\n 'Build calldata to repay an outstanding Peridot borrow on a hub chain (BSC 56, Monad 143, Somnia 1868). ' +\n 'Returns ordered calls: approve ERC-20 → repayBorrow. ' +\n 'Pass amount=\"max\" to repay the entire outstanding debt (recommended to avoid dust). ' +\n 'If the user is on a spoke chain, use build_cross_chain_repay_intent instead. ' +\n 'Tell the user to sign and submit each call in order.',\n inputSchema: hubRepaySchema,\n execute: buildHubRepayIntent,\n category: 'lending',\n },\n\n {\n name: 'build_hub_withdraw_intent',\n description:\n 'Build calldata to withdraw (redeem) supplied assets from Peridot on a hub chain. ' +\n 'ALWAYS call get_user_position first to check for active borrows. ' +\n 'If the user has outstanding debt, also call get_account_liquidity to verify the ' +\n 'withdrawal will not cause a shortfall — the contract will revert on-chain if it does. ' +\n 'If the user is on a spoke chain, use build_cross_chain_withdraw_intent instead.',\n inputSchema: hubWithdrawSchema,\n execute: buildHubWithdrawIntent,\n category: 'lending',\n },\n\n {\n name: 'build_enable_collateral_intent',\n description:\n 'Build the transaction call to enable a supplied asset as collateral in Peridot (enterMarkets). ' +\n 'This is required before you can borrow against a supplied asset. ' +\n 'NOTE: build_hub_supply_intent already calls enterMarkets by default — only call this ' +\n 'separately if the user supplied an asset previously without enabling collateral, ' +\n 'or if they disabled it and want to re-enable it.',\n inputSchema: hubEnableCollateralSchema,\n execute: buildHubEnableCollateralIntent,\n category: 'lending',\n },\n\n {\n name: 'build_disable_collateral_intent',\n description:\n 'Build the transaction call to stop using a supplied asset as collateral (exitMarket). ' +\n 'ALWAYS call get_account_liquidity first and confirm shortfallUsd=0 after the removal — ' +\n 'the contract will revert if any active borrow relies on this asset as collateral. ' +\n 'Explain to the user that disabling collateral reduces their borrow capacity.',\n inputSchema: hubDisableCollateralSchema,\n execute: buildHubDisableCollateralIntent,\n category: 'lending',\n },\n\n {\n name: 'build_liquidation_intent',\n description:\n 'Build calldata to liquidate an underwater Peridot borrower on a hub chain. ' +\n 'The liquidator repays part of the borrower\\'s debt (up to 50% per call — the protocol close factor) ' +\n 'and in return seizes an equivalent value of the borrower\\'s collateral plus the liquidation bonus. ' +\n 'Seized collateral is received as pToken shares — call redeem on the collateral pToken afterward ' +\n 'to convert pTokens back to the underlying asset. ' +\n 'REQUIRED BEFORE CALLING THIS: ' +\n '1. Call get_liquidatable_positions or get_account_liquidity to confirm shortfallUsd > 0. ' +\n '2. Verify the borrower has borrowed repayAsset and supplied collateralAsset as collateral. ' +\n '3. Never build a liquidation intent without confirming the position is still underwater. ' +\n 'Returns ordered calls: approve underlying → liquidateBorrow. ' +\n 'Only works on hub chains (BSC 56, Monad 143, Somnia 1868).',\n inputSchema: hubLiquidateSchema,\n execute: buildHubLiquidateIntent,\n category: 'liquidations',\n },\n\n // ── Cross-chain intents (user on a spoke chain) ───────────────────────────\n // Spoke chains: Arbitrum (42161), Base (8453), Ethereum (1),\n // Polygon (137), Optimism (10), Avalanche (43114).\n // These call Biconomy MEE /compose to produce a single cross-chain payload.\n // The user signs ONE transaction in their dApp; Biconomy executes the bridge + action.\n // Use check_transaction_status to track completion.\n\n {\n name: 'build_cross_chain_supply_intent',\n description:\n 'Build a cross-chain supply intent for a user whose tokens are on a spoke chain. ' +\n 'USE THIS when the user is on Arbitrum (42161), Base (8453), Ethereum (1), Polygon (137), ' +\n 'Optimism (10), or Avalanche (43114). ' +\n 'Do NOT use this for BSC (56), Monad (143), or Somnia (1868) — those are hub chains, ' +\n 'use build_hub_supply_intent instead. ' +\n 'REQUIRES: biconomyApiKey must be set in config (BICONOMY_API_KEY env var on the MCP server). ' +\n 'If it is not set, this tool will fail — inform the user that cross-chain operations are not ' +\n 'available in this deployment. ' +\n 'Bridges tokens from the spoke chain to BSC and deposits into Peridot atomically. ' +\n 'Returns biconomyInstructions — the user signs one transaction in their dApp, which submits ' +\n 'the payload to Biconomy /execute. ' +\n 'After the user submits, call check_transaction_status with the returned superTxHash to track it.',\n inputSchema: crossChainSupplySchema,\n execute: buildCrossChainSupplyIntent,\n category: 'lending',\n },\n\n {\n name: 'build_cross_chain_borrow_intent',\n description:\n 'Borrow from Peridot on BSC and optionally bridge the borrowed amount back to a spoke chain, ' +\n 'all in a single atomic cross-chain operation via Biconomy MEE. ' +\n 'REQUIRED BEFORE CALLING THIS: run simulate_borrow and confirm isSafe=true. ' +\n 'REQUIRES: biconomyApiKey must be set in config (BICONOMY_API_KEY env var on the MCP server). ' +\n 'If it is not set, this tool will fail — inform the user that cross-chain operations are not ' +\n 'available in this deployment. ' +\n 'Returns biconomyInstructions for a single user signature in their dApp. ' +\n 'Use check_transaction_status to track the cross-chain execution.',\n inputSchema: crossChainBorrowSchema,\n execute: buildCrossChainBorrowIntent,\n category: 'lending',\n },\n\n {\n name: 'build_cross_chain_repay_intent',\n description:\n 'Repay a Peridot borrow using tokens held on a spoke chain — for example, repay a ' +\n 'BSC USDC debt by spending USDC on Arbitrum. Bridges and repays in one atomic operation. ' +\n 'Useful when the user wants to repay but their tokens are not on BSC. ' +\n 'REQUIRES: biconomyApiKey must be set in config (BICONOMY_API_KEY env var on the MCP server). ' +\n 'If it is not set, this tool will fail — inform the user that cross-chain operations are not ' +\n 'available in this deployment. ' +\n 'Returns biconomyInstructions for a single user signature in their dApp.',\n inputSchema: crossChainRepaySchema,\n execute: buildCrossChainRepayIntent,\n category: 'lending',\n },\n\n {\n name: 'build_cross_chain_withdraw_intent',\n description:\n 'Withdraw supplied assets from Peridot on BSC and optionally bridge them to a spoke chain, ' +\n 'all in one atomic cross-chain operation. ' +\n 'ALWAYS call get_user_position first to check for active borrows; ' +\n 'if present, also call get_account_liquidity to verify the withdrawal will not cause a shortfall. ' +\n 'REQUIRES: biconomyApiKey must be set in config (BICONOMY_API_KEY env var on the MCP server). ' +\n 'If it is not set, this tool will fail — inform the user that cross-chain operations are not ' +\n 'available in this deployment. ' +\n 'Returns biconomyInstructions for a single user signature in their dApp.',\n inputSchema: crossChainWithdrawSchema,\n execute: buildCrossChainWithdrawIntent,\n category: 'lending',\n },\n\n // ── Status ───────────────────────────────────────────────────────────────\n\n {\n name: 'check_transaction_status',\n description:\n 'Check the execution status of a submitted cross-chain Biconomy transaction by its superTxHash. ' +\n 'Returns one of: pending (not yet picked up), processing (bridge/relay in progress), ' +\n 'success (all cross-chain steps completed), failed (reverted or timed out), ' +\n 'not_found (hash unknown — may not have been submitted yet). ' +\n 'Call this after the user submits a cross-chain intent and poll every ~10s until ' +\n 'status is \"success\" or \"failed\". Only cross-chain intents produce a superTxHash — ' +\n 'hub-chain intents give standard on-chain tx hashes that can be checked on a block explorer.',\n inputSchema: checkTransactionStatusSchema,\n execute: checkTransactionStatus,\n category: 'status',\n },\n]\n"],"mappings":"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","names":["address","z","z","z","z","z","z","z","z","z","Decimal","z","z","Decimal","Decimal","z","createPublicClient","http","z","createPublicClient","http","Decimal","z","z","z","encodeFunctionData","parseUnits","z","parseUnits","encodeFunctionData","z","encodeFunctionData","parseUnits","z","parseUnits","encodeFunctionData","z","encodeFunctionData","parseUnits","z","parseUnits","encodeFunctionData","z","encodeFunctionData","z","encodeFunctionData","z","encodeFunctionData","z","encodeFunctionData","z","parseUnits","z","parseUnits","getControllerAddress","z","parseUnits","z","parseUnits","z","parseUnits","z","parseUnits","z","parseUnits","z","parseUnits","z","z","z","z","z","encodeFunctionData","parseUnits","maxUint256","z","maxUint256","parseUnits","encodeFunctionData"]}