import { type PaymentChain } from "./paymentChains.js"; /** * B2BSplitter v1.4 settlement — the client half. * * v1.4 inverts who authorises a payment. Through v1.3 the agent built its own * calldata and settled unilaterally; the backend verified afterwards. In v1.4 * both entrypoints go through `_verifyQuote`, which requires a 65-byte ECDSA * signature from a SIGN_OPERATOR_ROLE holder. The agent cannot produce one, so * the quote arrives already signed and the agent's job is to CHECK it and * submit it — never to construct it. * * That makes this module mostly refusals, and deliberately so. Spec: * evm-contract@feat/v14_migration docs/V14_QUOTE_FORMAT.md §8, "SDK / Frontend * Responsibilities". Each check below cites the clause it implements, because * a check nobody can trace back to a requirement is a check somebody deletes. */ import { type PublicClient, type WalletClient, type Address, type Hex } from "viem"; /** The Quote struct, exactly as B2BSplitterV14 declares it. Field ORDER is part * of the EIP-712 hash — this mirrors _QUOTE_TYPEHASH and must not be reordered. */ export interface V14Quote { payer: Address; merchant: Address; token: Address; grossAmount: string; ipCreator: Address; validUntil: string; orderIdHash: Hex; nonce: string; routeId: Hex; } /** What `/v1/quote` returns under `settlement_call` when settlement_version is 1.4. */ export interface V14SettlementCall { chain: string; contract: Address; splitter_version: "1.4"; route: string; asset: string; function: string; arg_encoding: "struct+signature"; field_order: string[]; value_wei: string; args: { quote: V14Quote; signature: Hex; }; bound_to_payer?: Address; nonce_at_signing?: string; /** settleStable only: what to approve first — exactly the signed gross. */ approval?: { token: Address; spender: Address; amount: string; function?: string; }; } export declare class V14SettlementError extends Error { readonly code: string; constructor(code: string, message: string); } /** * Routes this SDK understands, by NAME. * * §8.7 requires an allow-list and says old SDKs must refuse routes added after * they shipped rather than guess. Names rather than hashes because the contract * derives one from the other — Profiles.routeId(name) == keccak256(bytes(name)), * verified against the deployed Amoy Profiles on 2026-09-02 for both entries — * so hardcoding the hashes would be storing a derived value and inviting the * two to disagree. */ export declare const KNOWN_V14_ROUTES: readonly ["merchant-aifp1", "agent-x402"]; export type KnownV14Route = (typeof KNOWN_V14_ROUTES)[number]; export declare function routeIdOf(name: string): Hex; /** name → routeId, for every route this SDK will submit. */ export declare function knownRouteIds(): Record; export interface V14ValidateOptions { /** The off-chain order id, when the caller knows it (§8.3). Omitted means the * orderIdHash cannot be checked, and this module says so rather than * pretending it verified something. */ orderId?: string; /** The wallet that will send the transaction. §8.2 and the contract's own * `payer == msg.sender` make this the difference between a quote that * settles and one that reverts after gas. */ payer?: Address; /** Seconds of headroom required before validUntil. A quote that expires while * the transaction is in the mempool reverts SignatureExpired and the agent * pays for the attempt. */ minSecondsRemaining?: number; nowMs?: number; /** Extra route names this deployment understands. Additive only. */ allowRoutes?: readonly string[]; } /** * Read-only structural checks. Success does not authenticate the signer, * deployment, fees or treasury and does not authorize settlement. * * Throws on the first failure with a code, because these are not equivalent: * an expired quote should be re-requested, a foreign payer is a caller bug, and * an unknown route means this SDK is older than the deployment. */ export declare function validateV14SettlementCall(call: V14SettlementCall, opts?: V14ValidateOptions): { route: string; expiresInSeconds: number; orderIdChecked: boolean; }; /** * §8.6 — never re-broadcast a settled quote. * * The contract keeps two things and they answer different questions: * consumedNonce[payer][nonce] has THIS nonce already been spent * payerNonce[payer] which nonce the contract will accept next * * A quote is submittable only if its nonce is unspent AND is the one the * contract expects. Two outstanding quotes for one wallet cannot both settle: * the second carries a stale nonce and reverts InvalidNonce. That is a property * of the contract, so it is reported here rather than discovered on-chain. */ export declare function checkV14Submittable(publicClient: PublicClient, call: V14SettlementCall): Promise<{ submittable: true; } | { submittable: false; reason: string; code: string; }>; /** Read-only recovery evidence. The independently configured owner chain wins; * no clock/profile check here may invalidate an already broadcast payment. */ export declare function assertPreparedV14Recovery(call: V14SettlementCall, transaction: { hash: Hex; serializedTransaction: Hex; }, expectedChain: PaymentChain, payer: string, orderId: string): Promise; export interface V14ExecutionContext { publicClient: PublicClient; walletClient: WalletClient; account: Address; orderId?: string; minSecondsRemaining?: number; /** Independently authorized purchase, not defaults copied from settlement_call. */ expectedMerchant?: Address; expectedGrossAmount?: bigint; /** Trusted chain selected by the caller. Every non-Polygon mainnet must be explicit; legacy Polygon/Amoy callers remain valid. */ expectedChain?: PaymentChain | "amoy"; /** The token the purchase was authorized in; address(0) or omitted = selected native currency. */ expectedToken?: Address; /** Native fee budget. Base includes buffered L1/operator estimates, which can vary before inclusion. */ maxGasWei?: bigint; /** Persist before broadcast. A failed write prevents transmission. Never log the raw transaction. */ onPrepared?: (tx: { hash: Hex; serializedTransaction: Hex; }) => Promise; /** @deprecated Preflight is mandatory; true is rejected. */ skipPreflight?: boolean; } /** * Execute the existing v1.4 native ABI using independently pinned deployments. * Profiles/treasury remain administratively mutable by the accepted v1.4 trust * model; preflight checks their current values, not an immutable fee guarantee. * All legacy calls lacking explicit purchase authorization remain disabled. * Only local signing is supported so an exact transaction hash can be persisted * before transmission, including when the RPC loses the broadcast response. */ export declare function executeV14Settlement(call: V14SettlementCall, ctx: V14ExecutionContext): Promise<{ hash: Hex; route: string; }>; //# sourceMappingURL=settlementV14.d.ts.map