/** * TransactionTrait — x402-native economic action handler (H2 'transaction' family). * * Provides a ledger of economic actions (pay, transfer, stake, unstake) for a * node, with balance tracking, spend-limit enforcement, and receipt generation. * All arithmetic uses integer micro-units (avoid float drift on money). * * ## Design principles * * - Pure value semantics: every operation returns a `TxReceipt` and does NOT * call any network/chain API. The trait records intent and local ledger state; * a plugin that wraps this in a real x402 call is free to do so. * - Idempotency key: each action carries an optional `idempotencyKey`. Duplicate * keys on the same node are rejected (returns `{ ok: false, reason: 'duplicate' }`). * - Spend limits: per-action type caps (`payLimit`, `transferLimit`, `stakeLimit`) * expressed in micro-units. Operations exceeding the limit are rejected without * touching the ledger. * - Stake escrow: staked amounts are held in a separate escrow balance, not * deducted from the spendable balance. Unstake returns them to spendable. * * ## Micro-unit convention * * All amounts are integers in micro-units (e.g. 1 USD = 1_000_000 μUSD). The * `unit` field on the config is informational only; arithmetic never converts. * * ## Domain-neutrality * * No domain nouns appear here. The trait applies to x402 agent wallets, * HoloProtocol creator earnings, HoloMesh marketplace transactions, and any * closed-loop simulated economy. * * ## Trait usage * * onAttach: initialises ledger from config.initialBalance. * onEvent 'transaction.pay': debit from balance → receipt. * onEvent 'transaction.transfer': debit from balance → receipt. * onEvent 'transaction.stake': move from balance → escrow → receipt. * onEvent 'transaction.unstake': move from escrow → balance → receipt. * onEvent 'transaction.deposit': credit to balance → receipt. * onEvent 'transaction.ledger': write full ledger to node.__tx_ledger. */ import type { TraitHandler } from './TraitTypes'; /** Outcome of a single transaction action. */ export interface TxReceipt { /** Whether the action succeeded. */ ok: boolean; /** Action type. */ action: 'pay' | 'transfer' | 'stake' | 'unstake' | 'deposit'; /** Amount in micro-units (always non-negative). */ amount: number; /** Caller-supplied idempotency key, if any. */ idempotencyKey?: string; /** Reason for rejection if ok=false. */ reason?: 'insufficient_funds' | 'limit_exceeded' | 'negative_amount' | 'duplicate' | 'insufficient_escrow'; /** Balance after the action (if ok=true). */ balanceAfter?: number; /** Escrow balance after the action (if ok=true). */ escrowAfter?: number; } /** A ledger entry — one committed receipt. */ export interface LedgerEntry extends TxReceipt { /** Sequential entry index (0-based). */ index: number; } /** Spend limits by action type (micro-units). Zero = no limit. */ export interface SpendLimits { /** Max single pay amount. 0 = unlimited. Default: 0. */ payLimit?: number; /** Max single transfer amount. 0 = unlimited. Default: 0. */ transferLimit?: number; /** Max single stake amount. 0 = unlimited. Default: 0. */ stakeLimit?: number; } /** Trait configuration. */ export interface TransactionConfig { /** Starting spendable balance in micro-units. Default: 0. */ initialBalance?: number; /** Starting escrow balance in micro-units (rare; usually 0). Default: 0. */ initialEscrow?: number; /** Currency/unit label (informational). Default: 'μUSD'. */ unit?: string; /** Per-action spend limits. */ limits?: SpendLimits; } interface TxEventBase { /** Amount in micro-units. Must be a non-negative integer. */ amount: number; /** Optional idempotency key; duplicate key on same node → rejected. */ idempotencyKey?: string; } export interface PayRequest extends TxEventBase { type: 'transaction.pay'; } export interface TransferRequest extends TxEventBase { type: 'transaction.transfer'; } export interface StakeRequest extends TxEventBase { type: 'transaction.stake'; } export interface UnstakeRequest extends TxEventBase { type: 'transaction.unstake'; } export interface DepositRequest extends TxEventBase { type: 'transaction.deposit'; } export interface TxNodeState { balance: number; escrow: number; ledger: LedgerEntry[]; seenKeys: Set; } /** Debit `amount` from balance (pay or transfer). */ export declare function debitBalance(state: TxNodeState, action: 'pay' | 'transfer', amount: number, limit: number, idempotencyKey?: string): TxReceipt; /** Move `amount` from balance → escrow. */ export declare function stakeBalance(state: TxNodeState, amount: number, limit: number, idempotencyKey?: string): TxReceipt; /** Move `amount` from escrow → balance. */ export declare function unstakeBalance(state: TxNodeState, amount: number, idempotencyKey?: string): TxReceipt; /** Credit `amount` to balance. */ export declare function depositBalance(state: TxNodeState, amount: number, idempotencyKey?: string): TxReceipt; export declare const transactionHandler: TraitHandler; export {};