/** * budget.ts — set_spend_policy, check_budget tools. * * set_spend_policy: configure a SpendingPolicy (in-process, persists for server lifetime). * check_budget: query on-chain remaining budget via checkBudget(). * * Payment flow uses the SDK 6.3.0 reserve → execute → commit | release | lock * surface. `check()` is the backward-compatible reserve-then-commit wrapper * and is not used on the payment path. */ import { z } from 'zod'; import { SpendingPolicy, type SpendOutcome, type SpendReservation as SdkSpendReservation } from 'agentwallet-sdk'; /** 1 whole token = 1e9 policy units. SpendingPolicy 6.3.0 rejects > MAX_SAFE_INTEGER. */ export declare const POLICY_SCALE_DECIMALS = 9; export declare function _resetPolicyStore(): void; export type SpendPolicyDecision = { status: 'approved'; } | { status: 'rejected' | 'draft'; reason?: string; draftId?: string; }; export interface SpendReservationItem { policy: InstanceType; held: SdkSpendReservation; } export interface SpendReservation { amount: number; items: SpendReservationItem[]; } /** * Return held capacity after a definite not-charged outcome. * Uses SpendingPolicy.release — locked (hold-unknown) reservations refuse. */ export declare function releaseSpendReservation(reservation: SpendReservation | null | undefined): void; /** * Finalize held capacity after a settled outcome. */ export declare function commitSpendReservation(reservation: SpendReservation | null | undefined): void; /** * Keep held capacity after a hold-unknown outcome. A timer never unlocks. */ export declare function lockSpendReservation(reservation: SpendReservation | null | undefined): void; /** * Apply a classified SDK spend outcome to every held reservation. * settled → commit; released → release; hold-unknown → lock. */ export declare function applySpendOutcome(reservation: SpendReservation | null | undefined, outcome: SpendOutcome): void; /** * Reserve spend, run the attempt, then commit | release | lock. * Definite not-charged failures release so a retry can use the same cap. * Unclear post-broadcast errors lock the hold (never auto-unlock). */ export declare function withReservedSpend(input: { merchant: string; amount: number | bigint; decimals: number | (() => number); }, run: () => Promise): Promise; /** * Enforce the in-process spend policy for a payment attempt. * If no policy is configured at all, the payment is allowed. * * Scopes: every configured policy — the "global" scope and any policy set * under a custom scopeKey — is enforced together (union). All of them must * approve; the first rejection or draft decision wins. This keeps scoped * policies fail-closed: a policy stored under any scopeKey is consulted on * every value-moving path, never silently ignored. * * Units: `amount` is in the asset's own base units (wei for ETH, 1e-6 for * USDC), with `decimals` naming that asset's decimals. Policy caps from * set_spend_policy are stored in 9-decimal ETH-equivalent policy units * (parseEther of the human string / 1e9). SpendingPolicy 6.3.0 requires a * safe integer, so 18-decimal wei cannot be the engine unit: 10 USDC would * become 1e19. One whole token still counts as 1 ETH-equivalent: with * perTxCapEth "5", a 10 USDC payment (10_000_000 base units → 1e10) is over * the 5e9 cap and blocked. Never compare 6-decimal USDC base units against * wei-scale caps directly — that silently loosens every cap by 1e12. * * `decimals` may be a thunk so that asset-decimal resolution (which can throw * for unregistered assets) only runs when a policy is actually configured. * * Fail closed: ANY error while evaluating the policy — decimals resolution, * numeric conversion, or the policy engine itself — rejects the payment, and * unrecognised policy statuses are treated as rejections. * * Payment-path callers that still use `enforceSpendPolicy` get reserve-then * commit (the same net effect as the legacy `check()` wrapper). Prefer * `withReservedSpend` or explicit reserve/commit/release when the outcome * is known after execute. */ export declare function reserveSpendPolicy(input: { merchant: string; /** Amount in the asset's base units. BigInt is preferred for exactness. */ amount: number | bigint; /** Decimals of the asset `amount` is denominated in (0–18), or a thunk. */ decimals: number | (() => number); }): Promise<{ decision: SpendPolicyDecision; reservation: SpendReservation | null; }>; export declare function enforceSpendPolicy(input: { merchant: string; /** Amount in the asset's base units. BigInt is preferred for exactness. */ amount: number | bigint; /** Decimals of the asset `amount` is denominated in (0–18), or a thunk. */ decimals: number | (() => number); }): Promise; export declare const SetSpendPolicySchema: z.ZodObject<{ scopeKey: z.ZodOptional; dailyLimitEth: z.ZodOptional; perTxCapEth: z.ZodOptional; allowedRecipients: z.ZodOptional>; }, z.core.$strip>; export type SetSpendPolicyInput = z.infer; export declare const setSpendPolicyTool: { name: string; description: string; inputSchema: { type: "object"; properties: { scopeKey: { type: string; description: string; }; dailyLimitEth: { type: string; description: string; }; perTxCapEth: { type: string; description: string; }; allowedRecipients: { type: string; items: { type: string; }; description: string; }; }; required: never[]; }; }; export declare function handleSetSpendPolicy(input: SetSpendPolicyInput): Promise<{ content: Array<{ type: 'text'; text: string; }>; isError?: boolean; }>; export declare const CheckBudgetSchema: z.ZodObject<{ scopeKey: z.ZodOptional; token: z.ZodOptional; }, z.core.$strip>; export type CheckBudgetInput = z.infer; export declare const checkBudgetTool: { name: string; description: string; inputSchema: { type: "object"; properties: { scopeKey: { type: string; description: string; }; token: { type: string; description: string; }; }; required: never[]; }; }; export declare function handleCheckBudget(input: CheckBudgetInput): Promise<{ content: Array<{ type: 'text'; text: string; }>; isError?: boolean; }>; //# sourceMappingURL=budget.d.ts.map