check_spend_limit
Verify payment amounts against wallet spend limits before processing transactions. Returns approval status with remaining budget details to prevent queuing issues.
Instructions
Check whether a proposed payment amount is within the wallet's autonomous spend limits. Returns a clear yes/no with remaining budget details. Use this before send_payment to avoid surprise queuing.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| amount_eth | Yes | Amount in ETH to check (e.g. "0.01") | |
| token | No | Token address. Omit for native ETH. |
Implementation Reference
- src/tools/wallet.ts:163-215 (handler)The handleCheckSpendLimit function implementation which executes the core logic of checking a spend limit against a budget.
export async function handleCheckSpendLimit( input: CheckSpendLimitInput ): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> { try { const wallet = getWallet(); const token = (input.token as Address | undefined) ?? NATIVE_TOKEN; const tokenLabel = token === NATIVE_TOKEN ? 'ETH' : token; // Parse amount (ETH string → wei bigint) const amountEth = parseFloat(input.amount_eth); if (isNaN(amountEth) || amountEth <= 0) { throw new Error(`Invalid amount: "${input.amount_eth}". Must be a positive number.`); } const amountWei = BigInt(Math.round(amountEth * 1e18)); const budget = await checkBudget(wallet, token); const forecast = await getBudgetForecast(wallet, token); const perTxOk = amountWei <= budget.perTxLimit && budget.perTxLimit > 0n; const periodOk = amountWei <= budget.remainingInPeriod && budget.remainingInPeriod > 0n; const canExecute = perTxOk && periodOk; let out = `🔍 **Spend Limit Check**\n\n`; out += ` Token: ${tokenLabel}\n`; out += ` Amount: ${formatEth(amountWei)}\n\n`; out += ` Per-tx limit: ${formatSpendLimit(budget.perTxLimit)}\n`; out += ` Within per-tx: ${perTxOk ? '✅ Yes' : '❌ No (exceeds per-tx limit)'}\n\n`; out += ` Remaining period: ${formatEth(budget.remainingInPeriod)}\n`; out += ` Within period: ${periodOk ? '✅ Yes' : '❌ No (would exceed period budget)'}\n\n`; out += ` Resets in: ${formatDuration(forecast.secondsUntilReset)}\n\n`; if (canExecute) { out += `✅ **APPROVED** — This payment can execute autonomously.\n`; } else if (budget.perTxLimit === 0n) { out += `🚫 **BLOCKED** — No spend policy configured for ${tokenLabel}. Set a spend policy first.\n`; } else { out += `⏳ **QUEUED** — This payment will be queued for owner approval.\n`; if (!perTxOk) { out += ` Reason: Amount exceeds per-tx limit of ${formatEth(budget.perTxLimit)}.\n`; } else { out += ` Reason: Amount exceeds remaining period budget of ${formatEth(budget.remainingInPeriod)}.\n`; out += ` Budget resets in: ${formatDuration(forecast.secondsUntilReset)}\n`; } } return { content: [textContent(out)] }; } catch (error: unknown) { return { content: [textContent(formatError(error, 'check_spend_limit'))], isError: true, }; } } - src/tools/wallet.ts:126-137 (schema)Zod schema definition for the check_spend_limit tool input.
export const CheckSpendLimitSchema = z.object({ amount_eth: z .string() .describe('Amount in ETH to check (e.g. "0.01"). Use this for native ETH payments.'), token: z .string() .optional() .describe( 'Token contract address to check against. ' + 'Omit or use zero address for ETH.' ), }); - src/tools/wallet.ts:141-161 (registration)Tool registration object for check_spend_limit.
export const checkSpendLimitTool = { name: 'check_spend_limit', description: 'Check whether a proposed payment amount is within the wallet\'s autonomous spend limits. ' + 'Returns a clear yes/no with remaining budget details. ' + 'Use this before send_payment to avoid surprise queuing.', inputSchema: { type: 'object' as const, properties: { amount_eth: { type: 'string', description: 'Amount in ETH to check (e.g. "0.01")', }, token: { type: 'string', description: 'Token address. Omit for native ETH.', }, }, required: ['amount_eth'], }, };