@t2000/sdk 9.12.0 → 9.13.0

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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/preflight.ts","../src/token-registry.ts","../src/wallet/coinSelection.ts","../src/protocols/cetus-swap.ts","../src/swap-quote.ts","../src/constants.ts","../src/utils/sui.ts","../src/wallet/keyManager.ts","../src/wallet/keypairSigner.ts","../src/wallet/executeTx.ts","../src/wallet/pay.ts","../src/mpp-cost.ts","../src/wallet/zkLoginSigner.ts","../src/wallet/send.ts","../src/utils/format.ts","../src/wallet/balance.ts","../src/wallet/classify.ts","../src/wallet/history.ts","../src/t2000.ts","../src/utils/suins.ts","../src/inference.ts","../src/verify.ts","../src/limits/config.ts","../src/limits/errors.ts","../src/limits/enforce.ts","../src/index.ts","../src/wallet/job.ts","../src/composeTx.ts","../src/utils/simulate.ts","../src/protocols/suins-leaf.ts"],"names":["isValidSuiAddress","normalizeSuiAddress","requested","swapAll","effectiveAmount","coin","SUI_TYPE","T2000Error","selectSuiCoin","selectAndSplitCoin","findSwapRoute","resolveTokenType","serializeCetusRoute","body","result","buildCoinToAddressBalanceMigration","SuiGrpcClient","getDecimalsForCoinType","Transaction","canonical","homedir","dirname","DEFAULT_CONFIG_DIR","join","buildSwapTx","preflightSwap","coinWithBalance","getSwapQuote","CLOCK_ID","hexToBytes","bytesToHex"],"mappings":"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","file":"index.js","sourcesContent":["export type T2000ErrorCode =\n | 'INSUFFICIENT_BALANCE'\n | 'ADDRESS_BALANCE_UNSPONSORABLE'\n | 'INSUFFICIENT_GAS'\n | 'INVALID_ADDRESS'\n | 'INVALID_AMOUNT'\n | 'WALLET_NOT_FOUND'\n | 'WALLET_LOCKED'\n | 'WALLET_EXISTS'\n | 'WALLET_CORRUPT'\n | 'INVALID_KEY'\n | 'SIMULATION_FAILED'\n | 'TRANSACTION_FAILED'\n | 'ASSET_NOT_SUPPORTED'\n | 'INVALID_ASSET'\n | 'PROTOCOL_UNAVAILABLE'\n | 'RPC_ERROR'\n | 'RPC_UNREACHABLE'\n | 'PRICE_EXCEEDS_LIMIT'\n | 'UNSUPPORTED_NETWORK'\n | 'PAYMENT_EXPIRED'\n | 'DUPLICATE_PAYMENT'\n | 'FACILITATOR_REJECTION'\n | 'CONTACT_NOT_FOUND'\n | 'INVALID_CONTACT_NAME'\n | 'SUINS_NOT_REGISTERED'\n | 'FACILITATOR_TIMEOUT'\n | 'SAFEGUARD_BLOCKED'\n | 'SWAP_NO_ROUTE'\n | 'SWAP_FAILED'\n | 'DIALECT_UNSUPPORTED'\n | 'ESCROW_REQUIRED'\n | 'CHAIN_MODE_INVALID'\n | 'INFERENCE_FAILED'\n | 'UNKNOWN';\n\nexport interface T2000ErrorData {\n reason?: string;\n [key: string]: unknown;\n}\n\nexport class T2000Error extends Error {\n readonly code: T2000ErrorCode;\n readonly data?: T2000ErrorData;\n readonly retryable: boolean;\n\n constructor(code: T2000ErrorCode, message: string, data?: T2000ErrorData, retryable = false) {\n super(message);\n this.name = 'T2000Error';\n this.code = code;\n this.data = data;\n this.retryable = retryable;\n }\n\n toJSON() {\n return {\n error: this.code,\n message: this.message,\n ...(this.data && { data: this.data }),\n retryable: this.retryable,\n };\n }\n}\n\nexport function mapWalletError(error: unknown): T2000Error {\n const msg = error instanceof Error ? error.message : String(error);\n\n if (msg.includes('rejected') || msg.includes('cancelled')) {\n return new T2000Error('TRANSACTION_FAILED', 'Transaction cancelled');\n }\n if (msg.includes('Insufficient') || msg.includes('insufficient')) {\n return new T2000Error('INSUFFICIENT_BALANCE', 'Insufficient balance');\n }\n\n return new T2000Error('UNKNOWN', msg, undefined, true);\n}\n\nexport function mapMoveAbortCode(code: number): string {\n const abortMessages: Record<number, string> = {\n 1: 'Protocol is temporarily paused',\n 2: 'Amount must be greater than zero',\n 3: 'Invalid operation type',\n 4: 'Fee rate exceeds maximum',\n 5: 'Insufficient treasury balance',\n 6: 'Not authorized',\n 7: 'Package version mismatch — upgrade required',\n 8: 'Timelock is active — wait for expiry',\n 9: 'No pending change to execute',\n 10: 'Already at current version',\n // NAVI Protocol abort codes\n 1502: 'Oracle price is stale — try again in a moment',\n 1503: 'Withdrawal amount is invalid (zero or dust) — try a specific amount instead of \"all\"',\n 1600: 'Health factor too low — withdrawal would risk liquidation',\n 1605: 'Asset borrowing is disabled or at capacity on this protocol',\n // NAVI utils abort codes\n 46000: 'Insufficient balance to repay — withdraw some savings first to get cash',\n };\n return abortMessages[code] ?? `Move abort code: ${code}`;\n}\n\n/**\n * Check if an error message contains a MoveAbort — these are on-chain\n * failures that will fail no matter how many times you retry.\n */\nexport function isMoveAbort(msg: string): boolean {\n return msg.includes('MoveAbort') || msg.includes('MovePrimitiveRuntimeError');\n}\n\nexport function parseMoveAbortMessage(msg: string): string {\n const abortMatch = msg.match(/abort code:\\s*(\\d+)/i) ?? msg.match(/MoveAbort[^,]*,\\s*(\\d+)/);\n if (abortMatch) {\n const code = parseInt(abortMatch[1], 10);\n\n const moduleMatch = msg.match(/Identifier\\(\"([^\"]+)\"\\)/) ?? msg.match(/in '([^']+)'/);\n const fnMatch = msg.match(/function_name:\\s*Some\\(\"([^\"]+)\"\\)/);\n const context = `${moduleMatch?.[1] ?? ''}${fnMatch ? `::${fnMatch[1]}` : ''}`.toLowerCase();\n const suffix = moduleMatch\n ? ` [${moduleMatch[1]}${fnMatch ? `::${fnMatch[1]}` : ''}]`\n : '';\n\n if (context.includes('slippage')) {\n return `Slippage too high — price moved during execution${suffix}`;\n }\n if (context.includes('balance::split') || context.includes('balance::ENotEnough')) {\n return `Insufficient on-chain balance${suffix}`;\n }\n\n const mapped = mapMoveAbortCode(code);\n return `${mapped}${suffix}`;\n }\n return msg;\n}\n","// Builder-appropriate safety, layer 2 (SPEC_AUDRIC_V3 §7 / safeguards-defense-\n// in-depth.mdc). `preflight()` is CHEAP, PURE, SYNCHRONOUS input validation —\n// no network, no I/O, no context lookup. It runs BEFORE the LLM round-trip /\n// before the tap-to-confirm card, so a malformed intent is rejected without\n// the user ever seeing a confirm for it.\n//\n// Each write builder co-locates its own `preflight*` validator (send.ts →\n// `preflightSend`, pay.ts → `preflightPay`, cetus-swap.ts → `preflightSwap`).\n// This module owns ONLY the shared result type + the two pure primitives those\n// validators compose (amount sanity + sync address validity). The agent-loop\n// guards that read conversation/session state stay in the v3 HOST (they are\n// NOT builder-appropriate, S.442/S.443).\n\nimport { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport type { T2000ErrorCode } from './errors.js';\n\n/**\n * The result of a synchronous preflight check. `valid: false` carries a\n * `T2000ErrorCode` + human message so the host can surface a precise reason\n * (and the builder can rethrow it as a `T2000Error` verbatim).\n */\nexport type PreflightResult =\n | { valid: true }\n | { valid: false; code: T2000ErrorCode; error: string };\n\n/**\n * Fat-finger / overflow ceiling for an asset amount. NOT a spending policy\n * (that's the `@t2000/sdk/limits` module — USD-denominated, opt-in, stateful);\n * this is the \"obviously wrong number\" guard the safeguards rule prescribes\n * (`amount > 1_000_000` → unreasonable).\n */\nexport const PREFLIGHT_MAX_AMOUNT = 1_000_000;\n\nexport const PREFLIGHT_OK: PreflightResult = { valid: true };\n\nexport function preflightFail(code: T2000ErrorCode, error: string): PreflightResult {\n return { valid: false, code, error };\n}\n\n/**\n * Pure positive-finite-amount sanity check (no network). Rejects NaN/Infinity\n * and non-positive values. The absurd-value ceiling defaults to\n * {@link PREFLIGHT_MAX_AMOUNT} but callers can raise it — pass\n * `max: Number.POSITIVE_INFINITY` for swaps of low-unit-value tokens\n * (memecoins legitimately trade in millions/billions of units), where a fixed\n * display-amount ceiling would be a false positive.\n */\nexport function checkPositiveAmount(\n amount: number,\n label = 'Amount',\n max: number = PREFLIGHT_MAX_AMOUNT,\n): PreflightResult {\n if (typeof amount !== 'number' || !Number.isFinite(amount)) {\n return preflightFail('INVALID_AMOUNT', `${label} must be a finite number`);\n }\n if (amount <= 0) {\n return preflightFail('INVALID_AMOUNT', `${label} must be greater than zero`);\n }\n if (amount > max) {\n return preflightFail('INVALID_AMOUNT', `${label} ${amount} exceeds the sane maximum (${max})`);\n }\n return PREFLIGHT_OK;\n}\n\n/**\n * Pure, synchronous Sui-address validity (no throw, no network) — the\n * non-throwing sibling of `validateAddress`. Use in preflight; use\n * `validateAddress` when you need the normalized form.\n */\nexport function checkSuiAddress(address: string, label = 'recipient'): PreflightResult {\n try {\n // `normalizeSuiAddress('')` pads to the zero address (which is \"valid\"), so\n // guard empty / whitespace-only input before normalizing.\n if (typeof address === 'string' && address.trim() !== '' &&\n isValidSuiAddress(normalizeSuiAddress(address))) {\n return PREFLIGHT_OK;\n }\n } catch {\n // normalizeSuiAddress throws on malformed input → fall through to the fail.\n }\n return preflightFail('INVALID_ADDRESS', `Invalid ${label} address: ${address}`);\n}\n","/**\n * Unified token registry — single source of truth for coin types, decimals,\n * and symbols. ZERO heavy dependencies; safe to import anywhere (server,\n * browser, Edge).\n *\n * Used for swap-by-symbol resolution, amount formatting (decimals), and\n * history/balance display. USDC is the settlement stable (send / receive /\n * x402 pay); everything else is holdable / swappable. There is no curated\n * \"tier\" gate — swaps accept any coin type (Cetus routes); the registry just\n * makes the common tokens ergonomic to reference by symbol.\n *\n * To add a token: add ONE entry to COIN_REGISTRY below — everything derives\n * from it.\n */\n\nexport interface CoinMeta {\n type: string;\n decimals: number;\n symbol: string;\n}\n\n/**\n * Canonical coin registry.\n * Key = user-friendly name (used in swap, CLI, prompts).\n */\nexport const COIN_REGISTRY: Record<string, CoinMeta> = {\n // ── Settlement stable ─────────────────────────────────────────────────\n USDC: { type: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC', decimals: 6, symbol: 'USDC' },\n\n // ── Common swap assets (symbol ergonomics — any coin type still swaps) ─\n SUI: { type: '0x2::sui::SUI', decimals: 9, symbol: 'SUI' },\n wBTC: { type: '0x0041f9f9344cac094454cd574e333c4fdb132d7bcc9379bcd4aab485b2a63942::wbtc::WBTC', decimals: 8, symbol: 'wBTC' },\n ETH: { type: '0xd0e89b2af5e4910726fbcd8b8dd37bb79b29e5f83f7491bca830e94f7f226d29::eth::ETH', decimals: 8, symbol: 'ETH' },\n GOLD: { type: '0x9d297676e7a4b771ab023291377b2adfaa4938fb9080b8d12430e4b108b836a9::xaum::XAUM', decimals: 9, symbol: 'GOLD' },\n DEEP: { type: '0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP', decimals: 6, symbol: 'DEEP' },\n WAL: { type: '0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL', decimals: 9, symbol: 'WAL' },\n NS: { type: '0x5145494a5f5100e645e4b0aa950fa6b68f614e8c59e17bc5ded3495123a79178::ns::NS', decimals: 6, symbol: 'NS' },\n IKA: { type: '0x7262fb2f7a3a14c888c438a3cd9b912469a58cf60f367352c46584262e8299aa::ika::IKA', decimals: 9, symbol: 'IKA' },\n CETUS: { type: '0x06864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b::cetus::CETUS', decimals: 9, symbol: 'CETUS' },\n NAVX: { type: '0xa99b8952d4f7d947ea77fe0ecdcc9e5fc0bcab2841d6e2a5aa00c3044e5544b5::navx::NAVX', decimals: 9, symbol: 'NAVX' },\n vSUI: { type: '0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT', decimals: 9, symbol: 'vSUI' },\n haSUI: { type: '0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d::hasui::HASUI', decimals: 9, symbol: 'haSUI' },\n afSUI: { type: '0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc::afsui::AFSUI', decimals: 9, symbol: 'afSUI' },\n LOFI: { type: '0xf22da9a24ad027cccb5f2d496cbe91de953d363513db08a3a734d361c7c17503::LOFI::LOFI', decimals: 9, symbol: 'LOFI' },\n MANIFEST: { type: '0xc466c28d87b3d5cd34f3d5c088751532d71a38d93a8aae4551dd56272cfb4355::manifest::MANIFEST', decimals: 9, symbol: 'MANIFEST' },\n\n // ── Other stables (display / classification) ──────────────────────────\n USDT: { type: '0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT', decimals: 6, symbol: 'USDT' },\n USDe: { type: '0x41d587e5336f1c86cad50d38a7136db99333bb9bda91cea4ba69115defeb1402::sui_usde::SUI_USDE', decimals: 6, symbol: 'USDe' },\n USDSUI: { type: '0x44f838219cf67b058f3b37907b655f226153c18e33dfcd0da559a844fea9b1c1::usdsui::USDSUI', decimals: 6, symbol: 'USDsui' },\n};\n\n/** Reverse lookup: coin type → CoinMeta. Built once at import time. */\nconst BY_TYPE = new Map<string, CoinMeta>();\nfor (const meta of Object.values(COIN_REGISTRY)) {\n BY_TYPE.set(meta.type, meta);\n}\n\n// ── Lookup helpers ───────────────────────────────────────────────────────\n\n/**\n * Returns the registry metadata for a coin type, or `undefined` if the coin\n * is not in the registry. Used for canonical-symbol + decimal resolution.\n */\nexport function getCoinMeta(coinType: string): CoinMeta | undefined {\n return BY_TYPE.get(coinType);\n}\n\n/**\n * Returns true if the coin type appears in COIN_REGISTRY. Useful as a\n * canonical-symbol gate — e.g. so the registry's mixed-case `USDsui` wins\n * over a vendor feed's uppercase `USDSUI`.\n */\nexport function isInRegistry(coinType: string): boolean {\n return BY_TYPE.has(coinType);\n}\n\n// ── Lookup helpers ───────────────────────────────────────────────────────\n\n/**\n * Get decimals for any coin type. Checks full type match, then suffix match,\n * then defaults to 9. Works for any token, registered or not.\n */\nexport function getDecimalsForCoinType(coinType: string): number {\n const direct = BY_TYPE.get(coinType);\n if (direct) return direct.decimals;\n\n const suffix = coinType.split('::').slice(1).join('::').toUpperCase();\n if (suffix) {\n for (const meta of BY_TYPE.values()) {\n const metaSuffix = meta.type.split('::').slice(1).join('::').toUpperCase();\n if (metaSuffix === suffix) return meta.decimals;\n }\n }\n\n return 9;\n}\n\n/** Minimal structural client — just the coin-metadata read this needs. */\ninterface CoinMetadataClient {\n core: { getCoinMetadata: (opts: { coinType: string }) => Promise<unknown> };\n}\n\n/**\n * [2.11] Decimals for any coin type, resolved correctly for arbitrary tokens.\n * Registry tokens return their known decimals (no network). A coin type NOT in\n * the registry is read ON-CHAIN via coin metadata — never the 9-default guess,\n * because a wrong `from` decimal would corrupt a swap's input amount\n * (financial-amounts rule). Falls back to the registry heuristic only if the\n * on-chain read fails or returns no usable decimals.\n */\nexport async function resolveCoinDecimals(\n client: CoinMetadataClient,\n coinType: string,\n): Promise<number> {\n if (isInRegistry(coinType)) return getDecimalsForCoinType(coinType);\n try {\n const res = (await client.core.getCoinMetadata({ coinType })) as {\n metadata?: { decimals?: number };\n decimals?: number;\n };\n const d = res?.metadata?.decimals ?? res?.decimals;\n if (typeof d === 'number' && Number.isFinite(d)) return d;\n } catch {\n /* on-chain read failed — fall through to the registry heuristic */\n }\n return getDecimalsForCoinType(coinType);\n}\n\n/**\n * Resolve a full coin type to a user-friendly symbol.\n * Returns the last `::` segment if not in the registry.\n */\nexport function resolveSymbol(coinType: string): string {\n const direct = BY_TYPE.get(coinType);\n if (direct) return direct.symbol;\n\n const suffix = coinType.split('::').slice(1).join('::').toUpperCase();\n if (suffix) {\n for (const meta of BY_TYPE.values()) {\n const metaSuffix = meta.type.split('::').slice(1).join('::').toUpperCase();\n if (metaSuffix === suffix) return meta.symbol;\n }\n }\n\n return coinType.split('::').pop() ?? coinType;\n}\n\n/**\n * Name → type map for swap resolution. Derived from COIN_REGISTRY.\n * Contains BOTH original-case and UPPERCASE keys for case-insensitive lookup.\n */\nexport const TOKEN_MAP: Record<string, string> = (() => {\n const map: Record<string, string> = {};\n for (const [name, meta] of Object.entries(COIN_REGISTRY)) {\n map[name] = meta.type;\n map[name.toUpperCase()] = meta.type;\n }\n return map;\n})();\n\n/**\n * Resolve a user-friendly token name to its full coin type.\n * Returns the input unchanged if already a full coin type (contains \"::\").\n * Case-insensitive: 'usde', 'USDe', 'USDE' all resolve correctly.\n */\nexport function resolveTokenType(nameOrType: string): string | null {\n if (nameOrType.includes('::')) return nameOrType;\n return TOKEN_MAP[nameOrType] ?? TOKEN_MAP[nameOrType.toUpperCase()] ?? null;\n}\n\n/** Common type constants for direct import. */\nexport const SUI_TYPE = COIN_REGISTRY.SUI.type;\nexport const USDC_TYPE = COIN_REGISTRY.USDC.type;\nexport const USDT_TYPE = COIN_REGISTRY.USDT.type;\nexport const USDSUI_TYPE = COIN_REGISTRY.USDSUI.type;\nexport const USDE_TYPE = COIN_REGISTRY.USDe.type;\nexport const ETH_TYPE = COIN_REGISTRY.ETH.type;\nexport const WBTC_TYPE = COIN_REGISTRY.wBTC.type;\nexport const WAL_TYPE = COIN_REGISTRY.WAL.type;\nexport const NAVX_TYPE = COIN_REGISTRY.NAVX.type;\nexport const IKA_TYPE = COIN_REGISTRY.IKA.type;\nexport const LOFI_TYPE = COIN_REGISTRY.LOFI.type;\nexport const MANIFEST_TYPE = COIN_REGISTRY.MANIFEST.type;\n","/**\n * Wallet-side coin selection helpers — single source of truth for the\n * \"produce a `Coin<T>` argument holding `amount` raw units of `coinType`,\n * owned by `address`\" pattern. Used by every wallet-mode appender that\n * needs a coin input (save, send, swap, repay, stake, etc.).\n *\n * **2026-05-22 — address-balance migration.** Sui mainnet's address-balance\n * feature ships funds account-style instead of as discrete `Coin<T>` objects.\n * After a payment via `0x2::balance::send_funds`, the leftover lands in the\n * sender's address balance with a synthetic \"coin reservation\" representing\n * the deposit. `client.getCoins()` correctly filters those reservations out\n * (they aren't real owned objects), so the old fetch+merge+split pattern\n * threw `INSUFFICIENT_BALANCE` for users whose stables had drifted into\n * address balance — even when `getBalance().totalBalance` showed plenty.\n *\n * The fix is structural: hand the work to `coinWithBalance({ type, balance })`\n * from `@mysten/sui/transactions`. Its build-time resolver inspects coins +\n * address balance together (`getBalance` + `listCoins`), then emits the\n * right shape — direct `redeem_funds` from address balance when AB ≥\n * required, or merge-and-split across coins + AB withdrawal when not. Multi\n * intents per coin type get batched into a single merge in one PTB, so the\n * old per-PTB merge cache is no longer needed.\n *\n * Pre-flight uses `client.getBalance().totalBalance` (sums coins + AB)\n * instead of summing the paginated `getCoins` page. That's the OTHER half\n * of the migration — the legacy path could see `0` from `getCoins` and\n * mistakenly throw before `coinWithBalance` ever ran.\n */\nimport {\n Transaction,\n coinWithBalance,\n type TransactionObjectArgument,\n} from '@mysten/sui/transactions';\nimport type { SuiCoreClient } from '../utils/sui.js';\nimport { T2000Error } from '../errors.js';\n\nexport interface CoinPage {\n ids: string[];\n totalBalance: bigint;\n}\n\n/**\n * Sum every coin of `coinType` owned by `owner`, INCLUDING address balance.\n * Returns the IDs of any discrete coin objects that exist (callers\n * occasionally need this for non-`coinWithBalance` paths, e.g. SUIns name\n * registration which expects raw object IDs).\n *\n * Pre-2026-05-22 this function paginated `client.getCoins` and summed\n * the page balances. That misses address-balance funds (the SDK filters\n * them out of `getCoins` for back-compat). The new implementation calls\n * `getBalance` for the canonical total and `getCoins` for the optional\n * ID list — both round-trips, but they happen in parallel.\n */\nexport async function fetchAllCoins(\n client: SuiCoreClient,\n owner: string,\n coinType: string,\n): Promise<CoinPage> {\n const [balance, ids] = await Promise.all([\n client.core.getBalance({ owner, coinType }),\n (async () => {\n const out: string[] = [];\n let cursor: string | null | undefined;\n let hasNext = true;\n while (hasNext) {\n const page = await client.core.listCoins({ owner, coinType, cursor: cursor ?? undefined });\n for (const c of page.objects) out.push(c.objectId);\n cursor = page.cursor;\n hasNext = page.hasNextPage;\n }\n return out;\n })(),\n ]);\n return { ids, totalBalance: BigInt(balance.balance.balance) };\n}\n\nexport interface SelectAndSplitResult {\n /** TransactionObjectArgument for a coin holding `effectiveAmount` raw units. */\n coin: TransactionObjectArgument;\n /** Actual raw amount the returned coin holds. May be < requested if `swapAll` is true. */\n effectiveAmount: bigint;\n /** True iff the request consumed the entire wallet balance (no split needed). */\n swapAll: boolean;\n}\n\n/**\n * Wallet-mode coin selection prelude. Pre-flights against\n * `getBalance().totalBalance` (coins + address balance combined), then\n * returns a `coinWithBalance({ type, balance })` argument that the\n * `@mysten/sui` resolver fulfills at build time.\n *\n * Throws `T2000Error` (`INSUFFICIENT_BALANCE`) when:\n * - `amount` is bigger than the total balance AND the caller did NOT\n * opt into `swapAll: true` clipping.\n * - `amount === 'all'` AND total balance is zero.\n *\n * @param tx — PTB to register the `coinWithBalance` intent against.\n * @param client — Sui RPC client for the pre-flight `getBalance` lookup.\n * @param owner — wallet address whose coins to source from.\n * @param coinType — fully-qualified Sui coin type (e.g. `\"0x...::usdc::USDC\"`).\n * @param amount — raw amount to source (in MIST / smallest unit). Pass\n * `'all'` to consume the entire balance.\n * @param options.allowSwapAll — if true (default), `amount` >= totalBalance\n * auto-clips to total. If false, throws when the request would over-consume.\n * @param options.sponsoredContext — when true, source ONLY from discrete coin\n * objects (never the address balance). See the long note below — this exists\n * because Enoki's gas station can't yet deserialize a `TransactionData` that\n * contains the address-balance `FundsWithdrawal` reservation that\n * `coinWithBalance` emits. Self-funded callers leave this false: the fullnode\n * handles `FundsWithdrawal` fine, so the address-balance path is preferred\n * (it can reach funds that aren't held as coin objects).\n *\n * @returns\n * - `coin` — `TransactionObjectArgument` ready for downstream consumption.\n * - `effectiveAmount` — the raw amount the returned coin holds (handles\n * swapAll clipping).\n * - `swapAll` — true iff the entire balance was consumed.\n */\nexport async function selectAndSplitCoin(\n tx: Transaction,\n client: SuiCoreClient,\n owner: string,\n coinType: string,\n amount: bigint | 'all',\n options: {\n allowSwapAll?: boolean;\n sponsoredContext?: boolean;\n mergeCache?: SponsoredCoinMergeCache;\n } = {},\n): Promise<SelectAndSplitResult> {\n // [2026-05-30] Sponsored Enoki path — coin objects only. `coinWithBalance`\n // reaches into the address balance (mysten Address Balances feature) when\n // `addressBalance >= required`, emitting `0x2::coin::redeem_funds` + a\n // `FundsWithdrawal` reservation input. That input is a newer `TransactionData`\n // field; Enoki's sponsor endpoint accepts the kind bytes (200) but its gas\n // station rejects the assembled `TransactionData` at execute with\n // \"Invalid bcs bytes for TransactionData\". The fullnode parses it fine — only\n // Enoki can't (yet). So under sponsorship we source from discrete coin objects\n // and surface a clear error when the user's funds are address-balance-only.\n // See github.com/mission69b/t2000 issue #93.\n if (options.sponsoredContext) {\n return selectCoinObjectsOnly(\n tx,\n client,\n owner,\n coinType,\n amount,\n options.allowSwapAll ?? true,\n options.mergeCache,\n );\n }\n\n const balanceResp = await client.core.getBalance({ owner, coinType });\n const totalBalance = BigInt(balanceResp.balance.balance);\n\n if (totalBalance === 0n) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `No balance found for ${coinType}`);\n }\n\n const allowSwapAll = options.allowSwapAll ?? true;\n\n if (amount !== 'all' && amount > totalBalance && !allowSwapAll) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient balance for ${coinType}`, {\n available: totalBalance.toString(),\n required: amount.toString(),\n });\n }\n\n const requested = amount === 'all' ? totalBalance : amount;\n const swapAll = amount === 'all' || requested >= totalBalance;\n const effectiveAmount = swapAll ? totalBalance : requested;\n\n const coin = coinWithBalance({ type: coinType, balance: effectiveAmount })(tx);\n\n return { coin, effectiveAmount, swapAll };\n}\n\n/**\n * Coin-object-only selection for sponsored (Enoki) transactions. Fetches the\n * owner's discrete `Coin<T>` objects (NOT the address balance — `getCoins`\n * excludes it), merges them, and splits the requested amount. Never emits a\n * `FundsWithdrawal` reservation, so the resulting `TransactionData` stays on\n * the shape Enoki's gas station can serialize.\n *\n * Throws `ADDRESS_BALANCE_UNSPONSORABLE` when the coin objects don't cover the\n * request — which, for a user whose `getBalance().totalBalance` shows funds,\n * means those funds live in the address balance (e.g. received via a gasless\n * stablecoin transfer) and can't be moved through a sponsored transaction yet.\n */\n/**\n * Per-PTB cache of merged sponsored coin-object primaries, keyed by coin\n * type. The FIRST `selectCoinObjectsOnly` call for a given coin type in a\n * PTB fetches the owner's discrete `Coin<T>` objects, merges them into one\n * `primary`, and records it here alongside the remaining (unspent) balance.\n * EVERY subsequent leg sourcing the same coin type splits from that cached\n * `primary` instead of re-fetching + re-merging.\n *\n * Why this exists (S.xxx, 2026-06-02): a sponsored bundle with 2+ legs\n * sourcing the same coin (e.g. `SUI→WAL` + `SUI→DEEP`, or `swap USDC` +\n * `save USDC`) called `selectCoinObjectsOnly` once per leg. Each call\n * emitted its own `mergeCoins` over the SAME coin objects, so the second\n * leg's merge referenced coins the first leg already consumed → Enoki\n * dry-run failed with `CommandArgumentError { ArgumentWithoutValue }`.\n *\n * This is NOT SUI-specific. Under sponsorship, `selectAndSplitCoin` routes\n * EVERY asset through `selectCoinObjectsOnly` (the `coinWithBalance`\n * batching that would otherwise dedup these merges only runs for\n * non-sponsored CLI/direct flows — its address-balance `FundsWithdrawal`\n * reservation is what Enoki can't deserialize, issue #93). So the cache is\n * the dedup layer for ALL coin types in a sponsored multi-leg PTB, keyed\n * by coin type. SUI was simply the first asset observed failing in the\n * wild because it's the most common swap source.\n */\nexport type SponsoredCoinMergeCache = Map<\n string,\n { primary: TransactionObjectArgument; remaining: bigint }\n>;\n\nasync function selectCoinObjectsOnly(\n tx: Transaction,\n client: SuiCoreClient,\n owner: string,\n coinType: string,\n amount: bigint | 'all',\n allowSwapAll: boolean,\n mergeCache?: SponsoredCoinMergeCache,\n): Promise<SelectAndSplitResult> {\n // Cache hit — a prior leg in THIS PTB already merged this coin type's\n // objects into `cached.primary`. Re-running the fetch+merge below would\n // emit a second `mergeCoins` over already-consumed coins → dry-run\n // `ArgumentWithoutValue`. Split from the cached primary instead.\n const cached = mergeCache?.get(coinType);\n if (cached) {\n const requested = amount === 'all' ? cached.remaining : amount;\n if (cached.remaining === 0n || requested > cached.remaining) {\n throw new T2000Error(\n 'ADDRESS_BALANCE_UNSPONSORABLE',\n `Not enough ${coinType} in coin objects to cover all legs of this ` +\n `sponsored bundle. The remaining funds are in your address balance, ` +\n `which sponsored transactions can't access yet.`,\n { remaining: cached.remaining.toString(), requested: requested.toString(), coinType },\n );\n }\n const swapAll = amount === 'all' || requested >= cached.remaining;\n const effectiveAmount = swapAll ? cached.remaining : requested;\n const coin = swapAll\n ? cached.primary\n : tx.splitCoins(cached.primary, [effectiveAmount])[0];\n cached.remaining -= effectiveAmount;\n return { coin, effectiveAmount, swapAll };\n }\n\n const objects: { objectId: string; balance: bigint }[] = [];\n let coinObjectTotal = 0n;\n let cursor: string | null | undefined;\n let hasNext = true;\n while (hasNext) {\n const page = await client.core.listCoins({ owner, coinType, cursor: cursor ?? undefined });\n for (const c of page.objects) {\n objects.push({ objectId: c.objectId, balance: BigInt(c.balance) });\n coinObjectTotal += BigInt(c.balance);\n }\n cursor = page.cursor;\n hasNext = page.hasNextPage;\n }\n\n const unsponsorable = (): T2000Error =>\n new T2000Error(\n 'ADDRESS_BALANCE_UNSPONSORABLE',\n `These funds are in your address balance, which sponsored transactions ` +\n `can't access yet. (Funds received via gasless transfers land there.) ` +\n `This will work once the gas sponsor adds address-balance support.`,\n { coinObjectTotal: coinObjectTotal.toString(), coinType },\n );\n\n if (coinObjectTotal === 0n) {\n throw unsponsorable();\n }\n\n const requested = amount === 'all' ? coinObjectTotal : amount;\n if (requested > coinObjectTotal) {\n // Not enough in coin objects. If the caller allows clipping to the\n // available coin-object total (\"swap all\"), do so; otherwise the shortfall\n // is sitting in the address balance → unsponsorable.\n if (allowSwapAll && amount === 'all') {\n // unreachable (requested === coinObjectTotal here) — kept for clarity.\n } else {\n throw unsponsorable();\n }\n }\n\n const swapAll = amount === 'all' || requested >= coinObjectTotal;\n const effectiveAmount = swapAll ? coinObjectTotal : requested;\n\n const [first, ...rest] = objects;\n const primary = tx.object(first.objectId);\n if (rest.length > 0) {\n tx.mergeCoins(\n primary,\n rest.map((o) => tx.object(o.objectId)),\n );\n }\n\n // Consume the whole merged coin when taking everything; otherwise split the\n // exact amount and leave the remainder on the (sender-owned) primary coin.\n const coin = swapAll ? primary : tx.splitCoins(primary, [effectiveAmount])[0];\n\n // Record the merged primary so later legs in the same PTB reuse it\n // rather than re-fetching + re-merging the same (now-consumed) coins.\n // When `swapAll`, the primary was consumed (remaining 0) — a later leg\n // hitting the cache then throws the unsponsorable shortfall above.\n mergeCache?.set(coinType, {\n primary,\n remaining: coinObjectTotal - effectiveAmount,\n });\n\n return { coin, effectiveAmount, swapAll };\n}\n\n/**\n * Build a GASLESS coin→address-balance migration.\n *\n * Sends WHOLE `Coin<T>` objects to `owner`'s OWN SIP-58 address balance via\n * `0x2::coin::send_funds(coin, owner)` — one allowlisted framework MoveCall\n * per coin, with NO native `SplitCoins` / `MergeCoins` commands. That shape is\n * what makes it gasless: the gRPC build resolver only zeros gas for PTBs whose\n * every command is a MoveCall into the `0x2` gasless allowlist (`send_funds` /\n * `redeem_funds` / `withdrawal_split` / `into_balance`). The same eligibility\n * the gasless `balance::send_funds` send + the x402 `redeem_funds`+`send_funds`\n * withdrawal rely on. (The old migration merged+split first → native commands →\n * fell outside the allowlist → needed SUI. See `pay.ts ensureAddressBalanceCovers`.)\n *\n * Selects the FEWEST coins (largest first) whose combined balance covers\n * `minAmount`, minimizing the MoveCall count. Over-migration is harmless — the\n * surplus just lands in the address balance. Pure / network-free: callers pass\n * coins they've already fetched, so this is unit-testable offline.\n *\n * Throws `INSUFFICIENT_BALANCE` when the supplied coin objects can't cover\n * `minAmount`.\n */\nexport function buildCoinToAddressBalanceMigration(args: {\n coins: { objectId: string; balance: bigint }[];\n coinType: string;\n owner: string;\n minAmount: bigint;\n}): { tx: Transaction; migratedRaw: bigint } {\n const { coins, coinType, owner, minAmount } = args;\n\n // Largest first → fewest whole-coin sends to cover the shortfall.\n const sorted = [...coins]\n .filter((c) => c.balance > 0n)\n .sort((a, b) => (b.balance > a.balance ? 1 : b.balance < a.balance ? -1 : 0));\n\n const selected: { objectId: string; balance: bigint }[] = [];\n let migratedRaw = 0n;\n for (const c of sorted) {\n if (migratedRaw >= minAmount) break;\n selected.push(c);\n migratedRaw += c.balance;\n }\n\n if (migratedRaw < minAmount) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${coinType} coin objects to migrate`, {\n available: migratedRaw.toString(),\n required: minAmount.toString(),\n });\n }\n\n const tx = new Transaction();\n for (const c of selected) {\n tx.moveCall({\n target: '0x2::coin::send_funds',\n typeArguments: [coinType],\n arguments: [tx.object(c.objectId), tx.pure.address(owner)],\n });\n }\n return { tx, migratedRaw };\n}\n\n/**\n * SUI-specific coin selection. Branches on sponsorship context:\n *\n * - **Self-funded (`sponsoredContext: false`)** — splits from `tx.gas`\n * directly (the user's gas coin IS their SUI). More efficient — no\n * `getBalance` RTT.\n *\n * - **Sponsored (`sponsoredContext: true`)** — sources from the user's\n * discrete SUI coin objects (`selectCoinObjectsOnly`). This both (a) avoids\n * `tx.gas`, which belongs to the Enoki sponsor — NOT the user — under\n * sponsored flows (the original S.260 reason for `useGasCoin: false`), AND\n * (b) avoids `coinWithBalance`'s address-balance `FundsWithdrawal`, which\n * Enoki's gas station can't deserialize (issue #93). If the user's SUI is\n * address-balance-only, it raises `ADDRESS_BALANCE_UNSPONSORABLE`.\n */\nexport async function selectSuiCoin(\n tx: Transaction,\n client: SuiCoreClient,\n owner: string,\n amountMist: bigint,\n sponsoredContext: boolean,\n mergeCache?: SponsoredCoinMergeCache,\n): Promise<SelectAndSplitResult> {\n if (sponsoredContext) {\n const { SUI_TYPE } = await import('../token-registry.js');\n return selectCoinObjectsOnly(tx, client, owner, SUI_TYPE, amountMist, false, mergeCache);\n }\n\n const [coin] = tx.splitCoins(tx.gas, [amountMist]);\n return { coin, effectiveAmount: amountMist, swapAll: false };\n}\n","/**\n * Cetus Aggregator V3 SDK wrapper — the ONLY file that imports @cetusprotocol/aggregator-sdk.\n * Documented CLAUDE.md exception: multi-DEX routing cannot be feasibly replaced by thin tx builders.\n *\n * [B5 v2 / @t2000/sdk@1.1.0 / 2026-04-30]\n * Overlay fee config is now per-call instead of a module-level singleton. CLI / direct\n * SDK callers (`T2000.swap()`) DON'T pass `overlayFee` → fee-free swap. Audric's\n * prepare/route.ts ALWAYS passes `overlayFee = { rate: OVERLAY_FEE_RATE, receiver:\n * T2000_OVERLAY_FEE_WALLET }` → fee charged. Structural inclusion (Audric's code can't\n * forget to pass it because it IS the code), not a toggle that defaults to safe.\n *\n * Pre-1.1.0: a module-level `OVERLAY_FEE_RECEIVER` constant defaulted to a Move object\n * ID. USDC sent there became OwnedObjects keyed to the object and was inaccessible.\n * Fixed by making the receiver a regular wallet address (T2000_OVERLAY_FEE_WALLET) AND\n * by removing the singleton pattern that hid the misconfig.\n */\nimport { AggregatorClient, Env, type FindRouterParams, type RouterDataV3 } from '@cetusprotocol/aggregator-sdk';\nimport { Transaction, type TransactionObjectArgument } from '@mysten/sui/transactions';\nimport BN from 'bn.js';\nimport { resolveTokenType, getDecimalsForCoinType } from '../token-registry.js';\nimport type { SuiCoreClient } from '../utils/sui.js';\nimport type { SponsoredCoinMergeCache } from '../wallet/coinSelection.js';\nimport {\n type PreflightResult,\n PREFLIGHT_OK,\n preflightFail,\n checkPositiveAmount,\n} from '../preflight.js';\n\n/**\n * Synchronous, network-free preflight for `swap`. Validates the from/to token\n * args + amount sanity, and rejects an identity swap — the cheap checks the\n * host runs before routing. Returns a `PreflightResult`; never throws.\n * Route-finding, liquidity, slippage + decimals resolution stay in the async\n * path (`findSwapRoute`/`buildSwapTx`/`getSwapQuote`).\n *\n * v3 drops the swap *tool*, but `swap` survives as an SDK/CLI builder (§8) so\n * it gets the same builder-appropriate preflight as send/pay.\n */\nexport function preflightSwap(input: {\n from: string;\n to: string;\n amount: number;\n}): PreflightResult {\n if (typeof input.from !== 'string' || input.from.trim() === '') {\n return preflightFail('INVALID_ASSET', 'A `from` token is required to swap');\n }\n if (typeof input.to !== 'string' || input.to.trim() === '') {\n return preflightFail('INVALID_ASSET', 'A `to` token is required to swap');\n }\n\n // No upper ceiling — swaps route arbitrary tokens, and low-unit-value tokens\n // legitimately trade in millions/billions of units.\n const amountCheck = checkPositiveAmount(input.amount, 'Amount', Number.POSITIVE_INFINITY);\n if (!amountCheck.valid) return amountCheck;\n\n // Identity swap is a no-op the router can't route — catch it cheaply.\n // Resolve symbol → coin type so \"USDC\" and the USDC coin type compare equal.\n // Guard the null===null case (two unknown symbols both resolve to null) by\n // also requiring the resolved value to be non-null, falling back to a raw\n // string compare.\n const resolvedFrom = resolveTokenType(input.from);\n const resolvedTo = resolveTokenType(input.to);\n const sameToken =\n input.from.trim() === input.to.trim() ||\n (resolvedFrom !== null && resolvedFrom === resolvedTo);\n if (sameToken) {\n return preflightFail('INVALID_ASSET', `Cannot swap ${input.from} to itself`);\n }\n\n return PREFLIGHT_OK;\n}\n\nexport interface OverlayFeeConfig {\n /** Fee rate as a fraction (e.g. 0.001 = 0.1%). Pass 0 to disable. */\n rate: number;\n /** Wallet address that receives the overlay fee. */\n receiver: string;\n}\n\nexport interface SwapRouteResult {\n routerData: RouterDataV3;\n amountIn: string;\n amountOut: string;\n byAmountIn: boolean;\n priceImpact: number;\n insufficientLiquidity: boolean;\n}\n\n// [SPEC 20.2 / D-1 (a)] Typed JSON-friendly representation of a Cetus\n// `RouterDataV3` for cross-process / cross-network transport. The native\n// shape contains `BN` instances (`bn.js`) and a `Map<string, string>`\n// (`packages`) that don't survive JSON.stringify / JSON.parse cleanly:\n// - `BN.toJSON()` returns the internal `{negative,words,length,red}` blob\n// - `Map.toJSON()` returns `{}`\n// Round-tripping via `serializeCetusRoute` + `deserializeCetusRoute`\n// converts BN ↔ decimal string and Map ↔ Record. Engine + audric both\n// reference fields by path (`route.routerData.paths[i].provider`) without\n// needing to know about the underlying BN/Map types.\nexport interface SerializedCetusRoutePath {\n id: string;\n direction: boolean;\n provider: string;\n from: string;\n target: string;\n feeRate: number;\n amountIn: string;\n amountOut: string;\n version?: string;\n publishedAt?: string;\n extendedDetails?: Record<string, unknown>;\n}\n\nexport interface SerializedRouterDataV3 {\n quoteID?: string;\n /** RouterDataV3.amountIn (BN) → decimal string */\n amountIn: string;\n /** RouterDataV3.amountOut (BN) → decimal string */\n amountOut: string;\n byAmountIn: boolean;\n paths: SerializedCetusRoutePath[];\n insufficientLiquidity: boolean;\n deviationRatio: number;\n /** RouterDataV3.packages (Map) → Record */\n packages?: Record<string, string>;\n totalDeepFee?: number;\n error?: { code: number; msg: string };\n overlayFee?: number;\n}\n\nexport interface SerializedCetusRoute {\n routerData: SerializedRouterDataV3;\n amountIn: string;\n amountOut: string;\n byAmountIn: boolean;\n priceImpact: number;\n insufficientLiquidity: boolean;\n /**\n * Wall-clock timestamp (ms since epoch) at which the route was discovered.\n * Used by audric's prepare-route for SPEC 20.2 D-3 TTL re-validation: if\n * the route is older than the threshold AND price impact has shifted\n * beyond tolerance, fall back to a fresh `findSwapRoute()` call.\n */\n discoveredAt: number;\n /**\n * Snapshot of the input/output coin types the route was discovered for.\n * SPEC 20.2 D-2 (b) structural verification: prepare-route asserts\n * input/output coins match before using the fast-path; mismatch falls\n * back to fresh discovery (defense against client-side tampering and\n * against legitimate token-type drift in the request).\n */\n fromCoinType: string;\n toCoinType: string;\n}\n\nexport function serializeCetusRoute(\n route: SwapRouteResult,\n context: { fromCoinType: string; toCoinType: string },\n): SerializedCetusRoute {\n return {\n routerData: serializeRouterDataV3(route.routerData),\n amountIn: route.amountIn,\n amountOut: route.amountOut,\n byAmountIn: route.byAmountIn,\n priceImpact: route.priceImpact,\n insufficientLiquidity: route.insufficientLiquidity,\n discoveredAt: Date.now(),\n fromCoinType: context.fromCoinType,\n toCoinType: context.toCoinType,\n };\n}\n\nexport function deserializeCetusRoute(serialized: SerializedCetusRoute): SwapRouteResult {\n return {\n routerData: deserializeRouterDataV3(serialized.routerData),\n amountIn: serialized.amountIn,\n amountOut: serialized.amountOut,\n byAmountIn: serialized.byAmountIn,\n priceImpact: serialized.priceImpact,\n insufficientLiquidity: serialized.insufficientLiquidity,\n };\n}\n\nfunction serializeRouterDataV3(rd: RouterDataV3): SerializedRouterDataV3 {\n const out: SerializedRouterDataV3 = {\n amountIn: rd.amountIn.toString(),\n amountOut: rd.amountOut.toString(),\n byAmountIn: rd.byAmountIn,\n paths: rd.paths.map(serializeCetusRoutePath),\n insufficientLiquidity: rd.insufficientLiquidity,\n deviationRatio: rd.deviationRatio,\n };\n if (rd.quoteID !== undefined) out.quoteID = rd.quoteID;\n if (rd.packages) {\n const obj: Record<string, string> = {};\n for (const [k, v] of rd.packages) obj[k] = v;\n out.packages = obj;\n }\n if (rd.totalDeepFee !== undefined) out.totalDeepFee = rd.totalDeepFee;\n if (rd.error) out.error = { code: rd.error.code, msg: rd.error.msg };\n if (rd.overlayFee !== undefined) out.overlayFee = rd.overlayFee;\n return out;\n}\n\nfunction deserializeRouterDataV3(s: SerializedRouterDataV3): RouterDataV3 {\n const out: RouterDataV3 = {\n amountIn: new BN(s.amountIn),\n amountOut: new BN(s.amountOut),\n byAmountIn: s.byAmountIn,\n paths: s.paths.map(deserializeCetusRoutePath),\n insufficientLiquidity: s.insufficientLiquidity,\n deviationRatio: s.deviationRatio,\n };\n if (s.quoteID !== undefined) out.quoteID = s.quoteID;\n if (s.packages) out.packages = new Map(Object.entries(s.packages));\n if (s.totalDeepFee !== undefined) out.totalDeepFee = s.totalDeepFee;\n if (s.error) out.error = { code: s.error.code, msg: s.error.msg };\n if (s.overlayFee !== undefined) out.overlayFee = s.overlayFee;\n return out;\n}\n\nfunction serializeCetusRoutePath(p: RouterDataV3['paths'][number]): SerializedCetusRoutePath {\n const out: SerializedCetusRoutePath = {\n id: p.id,\n direction: p.direction,\n provider: p.provider,\n from: p.from,\n target: p.target,\n feeRate: p.feeRate,\n amountIn: p.amountIn,\n amountOut: p.amountOut,\n };\n if (p.version !== undefined) out.version = p.version;\n if (p.publishedAt !== undefined) out.publishedAt = p.publishedAt;\n if (p.extendedDetails) out.extendedDetails = { ...p.extendedDetails };\n return out;\n}\n\nfunction deserializeCetusRoutePath(p: SerializedCetusRoutePath): RouterDataV3['paths'][number] {\n const out: RouterDataV3['paths'][number] = {\n id: p.id,\n direction: p.direction,\n provider: p.provider,\n from: p.from,\n target: p.target,\n feeRate: p.feeRate,\n amountIn: p.amountIn,\n amountOut: p.amountOut,\n };\n if (p.version !== undefined) out.version = p.version;\n if (p.publishedAt !== undefined) out.publishedAt = p.publishedAt;\n if (p.extendedDetails) out.extendedDetails = { ...p.extendedDetails };\n return out;\n}\n\n/**\n * SPEC 20.2 D-2 (b) structural verification helper. Returns true when the\n * serialized route matches the requested coin types (i.e. it's safe to use\n * as the prepare-route fast-path), false otherwise (tampered, or input\n * mismatch from a legitimate but stale pending action). Caller falls back\n * to a fresh `findSwapRoute()` call when verification fails.\n */\nexport function verifyCetusRouteCoinMatch(\n serialized: SerializedCetusRoute,\n expected: { fromCoinType: string; toCoinType: string },\n): boolean {\n return serialized.fromCoinType === expected.fromCoinType && serialized.toCoinType === expected.toCoinType;\n}\n\n/**\n * SPEC 20.2 D-3 (b) TTL helper. Returns true when the serialized route is\n * fresh enough to use as the fast-path (< `maxAgeMs` old). Returns false\n * for stale routes — caller falls back to fresh `findSwapRoute()` to pick\n * up any pool-price drift since route discovery.\n *\n * Default 30s aligns with the existing quote-freshness contract surfaced\n * to users via `pending_action.quoteAge` (the PermissionCard \"QUOTE Ns OLD\"\n * badge starts warning the user past 30s).\n */\nexport function isCetusRouteFresh(serialized: SerializedCetusRoute, maxAgeMs: number = 30_000): boolean {\n return Date.now() - serialized.discoveredAt < maxAgeMs;\n}\n\n/**\n * Default Audric swap overlay fee — 0.1%. Exported for consumers that want to use\n * the canonical Audric rate (the Audric prepare-route does this). Changing this\n * rate requires a coordinated SDK + audric release.\n */\nexport const OVERLAY_FEE_RATE = 0.001;\n\n/**\n * Cache `AggregatorClient` instances by `(signer + overlay rate + overlay receiver)`.\n * Per-call instantiation is cheap (the client is mostly config), but caching avoids\n * pointless re-allocation when the same caller swaps multiple times in a loop.\n */\nconst clientCache = new Map<string, AggregatorClient>();\n\nfunction getClient(walletAddress: string, overlayFee?: OverlayFeeConfig): AggregatorClient {\n const rate = overlayFee?.rate ?? 0;\n const receiver = overlayFee?.receiver ?? '';\n const key = `${walletAddress}|${rate}|${receiver}`;\n\n const cached = clientCache.get(key);\n if (cached) return cached;\n\n const client = new AggregatorClient({\n signer: walletAddress,\n env: Env.Mainnet,\n ...(rate > 0 && receiver\n ? { overlayFeeRate: rate, overlayFeeReceiver: receiver }\n : {}),\n });\n clientCache.set(key, client);\n return client;\n}\n\n/**\n * [Bug A defense-in-depth / 2026-05-10] Returns true when every path\n * provider in `route.routerData.paths` is present in the active\n * `providers` allow-list. Cetus's `getProvidersExcluding(...)` returns\n * an inclusion list (the complement of the exclusion), so when a caller\n * passes `providers`, every walked provider must be IN that list to be\n * compatible.\n *\n * When `providers` is undefined (non-sponsored caller, e.g. CLI) every\n * route is compatible — same semantics as `findSwapRoute` itself.\n *\n * Why per-path: a Cetus aggregator route can split across multiple DEXes\n * (e.g. 60% Cetus + 40% Bluefin). A single excluded provider in any path\n * triggers `tx.gas` usage in `routerSwap`. Reject the whole route if any\n * leg is excluded.\n */\nexport function isPrecomputedRouteCompatibleWithProviders(\n route: SwapRouteResult,\n providers: string[] | undefined,\n): boolean {\n if (!providers || providers.length === 0) return true;\n const allowed = new Set(providers);\n for (const path of route.routerData.paths) {\n if (!allowed.has(path.provider)) return false;\n }\n return true;\n}\n\n/**\n * Find the optimal swap route via Cetus Aggregator REST API.\n *\n * Pass `overlayFee` to charge an overlay fee on the output (Audric's pattern).\n * Omit it for a fee-free swap (CLI / direct SDK pattern).\n */\nexport async function findSwapRoute(params: {\n walletAddress: string;\n from: string;\n to: string;\n amount: bigint;\n byAmountIn: boolean;\n overlayFee?: OverlayFeeConfig;\n /**\n * Optional Cetus provider allow-list. When omitted, all 30+ DEXes\n * are eligible. Sponsored flows (Enoki) MUST pass an exclusion list\n * computed via `getProvidersExcluding([...])` from the Cetus SDK to\n * remove Pyth-dependent providers (HAEDALPMM, METASTABLE, OBRIC,\n * STEAMM_OMM, STEAMM_OMM_V2, SEVENK, HAEDALHMMV2) — those reference\n * `tx.gas` for oracle fees, which Enoki rejects in sponsored txs.\n * Non-sponsored callers (CLI, direct SDK) leave this undefined.\n */\n providers?: string[];\n}): Promise<SwapRouteResult | null> {\n const client = getClient(params.walletAddress, params.overlayFee);\n\n const findParams: FindRouterParams = {\n from: params.from,\n target: params.to,\n amount: params.amount.toString(),\n byAmountIn: params.byAmountIn,\n ...(params.providers ? { providers: params.providers } : {}),\n };\n\n const routerData = await client.findRouters(findParams);\n if (!routerData) return null;\n\n if (routerData.insufficientLiquidity) {\n return {\n routerData,\n amountIn: routerData.amountIn.toString(),\n amountOut: routerData.amountOut.toString(),\n byAmountIn: params.byAmountIn,\n priceImpact: normalizePriceImpact(routerData.deviationRatio),\n insufficientLiquidity: true,\n };\n }\n\n if (routerData.error) {\n const { T2000Error } = await import('../errors.js');\n throw new T2000Error('SWAP_FAILED', `Cetus routing error: ${routerData.error.msg} (code ${routerData.error.code})`);\n }\n\n return {\n routerData,\n amountIn: routerData.amountIn.toString(),\n amountOut: routerData.amountOut.toString(),\n byAmountIn: params.byAmountIn,\n priceImpact: normalizePriceImpact(routerData.deviationRatio),\n insufficientLiquidity: false,\n };\n}\n\n/**\n * Cetus' aggregator types `deviationRatio` as `number`, but in some routes\n * the router actually returns a string (\"0.001234\"). The SDK type lies, so we\n * always coerce to a finite number here (NaN/null/undefined → 0). Without\n * this every downstream consumer that calls `priceImpact.toFixed(...)` will\n * crash at runtime — including the Audric SwapQuoteCard, which takes the\n * whole chat UI down through its error boundary.\n */\nfunction normalizePriceImpact(value: unknown): number {\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : 0;\n}\n\n/**\n * Build a swap PTB from a route result. The caller must provide an input coin\n * obtained by splitting/merging wallet coins.\n *\n * **Important:** Cetus's `routerSwap` reads the overlay-fee config from the\n * AggregatorClient instance. The `overlayFee` param here MUST match the one\n * passed to `findSwapRoute` for the same swap (otherwise you'll hit the cache\n * boundary and get a different client with different overlay config).\n */\nexport async function buildSwapTx(params: {\n walletAddress: string;\n route: SwapRouteResult;\n tx: Transaction;\n inputCoin: TransactionObjectArgument;\n slippage: number;\n overlayFee?: OverlayFeeConfig;\n}): Promise<TransactionObjectArgument> {\n const client = getClient(params.walletAddress, params.overlayFee);\n const clampedSlippage = Math.max(0.001, Math.min(params.slippage, 0.05));\n\n const outputCoin = await client.routerSwap({\n router: params.route.routerData,\n inputCoin: params.inputCoin,\n slippage: clampedSlippage,\n txb: params.tx,\n });\n\n return outputCoin;\n}\n\n/**\n * Append a swap fragment to an existing PTB. SPEC 7 § \"Layer 1\" Cetus\n * appender. Two modes, dispatched by the presence of `input.inputCoin`:\n *\n * - **Wallet mode** (`inputCoin` omitted) — sources `from`-asset funds\n * via `coinWithBalance({ type, balance })` (resolves coin objects +\n * address balance at build time), runs the swap. Mirrors the audric\n * host's `transactions/prepare/route.ts` swap branch (P2.2c will\n * retire that branch in favor of this appender via `composeTx`).\n *\n * - **Chain mode** (`inputCoin` provided) — consumes the passed-in coin\n * reference (typically produced by an upstream appender like\n * `addWithdrawToTx`) directly, no wallet fetch / no merge / no\n * split. This is the SPEC 7 multi-write enabler (\"withdraw → swap →\n * save\" without intermediate wallet materialization).\n *\n * **SUI in wallet mode:** ALWAYS sources through `selectSuiCoin` (which\n * routes via `coinWithBalance({ type: SUI, useGasCoin: false })` under\n * sponsored flows, OR `tx.splitCoins(tx.gas, ...)` under self-funded\n * flows). The caller MUST set `sponsoredContext` correctly — otherwise\n * sponsored swaps with SUI source fail with `Cannot use GasCoin as a\n * transaction argument` (Enoki owns `tx.gas`, the PTB body referencing\n * it as an argument is invalid for sponsorship). 2.14.0 shipped without\n * this branch and broke audric/web-v2 SUI→USDC swaps; restored in 2.14.1\n * (S.260). For non-sponsored flows (CLI), `T2000.swap()` pre-builds the\n * inputCoin via `tx.splitCoins(tx.gas, [rawAmount])[0]` and uses chain\n * mode, sidestepping wallet-mode entirely — this branch is a defensive\n * safety net for future direct SDK users who pass SUI in wallet mode.\n *\n * **`swapAll` semantics (wallet mode):** if the requested raw amount\n * is >= the wallet's total `from` balance, the appender consumes the\n * entire merged primary coin (not a split), matching audric's host\n * route's `swapAll` clipping. The returned `effectiveAmountIn` reflects\n * the actual consumed amount in display units.\n *\n * **Slippage:** clamped to [0.001, 0.05] (0.1% – 5%). Defaults to 0.01.\n *\n * @returns\n * - `coin` — output coin reference, ready for downstream consumption\n * (e.g. `addSaveToTx`) or wallet transfer (`tx.transferObjects`).\n * - `effectiveAmountIn` — display-units input amount the swap actually\n * consumes (handles `swapAll` clipping in wallet mode; in chain mode\n * echoes the requested `input.amount`).\n * - `expectedAmountOut` — display-units output amount per the route\n * quote. Actual on-chain output may differ within slippage.\n * - `route` — raw `SwapRouteResult` for downstream telemetry / logging.\n */\nexport async function addSwapToTx(\n tx: Transaction,\n client: SuiCoreClient,\n address: string,\n input: {\n from: string;\n to: string;\n amount: number;\n slippage?: number;\n byAmountIn?: boolean;\n overlayFee?: OverlayFeeConfig;\n inputCoin?: TransactionObjectArgument;\n /**\n * Optional Cetus provider allow-list. Forwarded to `findSwapRoute`.\n * Sponsored flows (Enoki) MUST pass `getProvidersExcluding([...])`\n * to remove Pyth-dependent providers — see `findSwapRoute`'s JSDoc\n * for the exclusion list. Non-sponsored callers omit this.\n */\n providers?: string[];\n /**\n * [SPEC 20.2 D-3 (b)] Precomputed route from a prior `findSwapRoute()`\n * call (typically captured by `swap_quote` and threaded through\n * `pending_action.cetusRoute`). When present AND not stale (per\n * `isCetusRouteFresh`) AND the input/output coins match, this skips\n * the ~400-500ms `findSwapRoute()` discovery call. Stale routes are\n * silently ignored (caller falls back to fresh discovery).\n *\n * Caller responsibility: pass the SAME `overlayFee` / `providers` /\n * `byAmountIn` that produced the precomputed route. Mismatch will\n * still produce a working swap but may use the wrong overlay-fee\n * config (the route data already encodes the chosen DEX path).\n */\n precomputedRoute?: SwapRouteResult;\n /**\n * Whether this swap is being built inside a sponsored-tx flow (Enoki)\n * vs self-funded (CLI / direct sign). Load-bearing for SUI-source\n * swaps in wallet mode: under sponsored flows, `tx.gas` belongs to\n * the sponsor and CANNOT be referenced as a transaction argument\n * (Sui protocol rejects with `Cannot use GasCoin as a transaction\n * argument`). When `true`, SUI source routes through `selectSuiCoin`\n * with `useGasCoin: false` so the resolver sources from the user's\n * SUI coin objects + address balance instead. Defaults to `false`\n * (back-compat — pre-2.14.1 behavior). Audric/web-v2's compose path\n * threads this through via `composeTx({ sponsoredContext: true })`.\n */\n sponsoredContext?: boolean;\n /**\n * Per-PTB merge cache for sponsored coin-object sourcing (any coin\n * type — SUI in the dedicated branch, USDC/USDsui/etc. in the wallet\n * branch). Provided by `composeTx`'s orchestration loop so multiple\n * legs sourcing the same coin in one bundle share a single merged\n * primary coin instead of each emitting its own `mergeCoins` (the\n * second of which references already-consumed coins → Enoki dry-run\n * `ArgumentWithoutValue`). Single swaps don't need it; omit. See\n * `SponsoredCoinMergeCache` JSDoc.\n */\n coinMergeCache?: SponsoredCoinMergeCache;\n },\n): Promise<{\n coin: TransactionObjectArgument;\n effectiveAmountIn: number;\n expectedAmountOut: number;\n route: SwapRouteResult;\n /** True when `precomputedRoute` was used (no `findSwapRoute()` call). */\n usedPrecomputedRoute: boolean;\n}> {\n const { T2000Error } = await import('../errors.js');\n\n const fromType = resolveTokenType(input.from);\n const toType = resolveTokenType(input.to);\n if (!fromType) throw new T2000Error('ASSET_NOT_SUPPORTED', `Unknown token: ${input.from}. Provide the symbol (USDC, SUI, ...) or full coin type.`);\n if (!toType) throw new T2000Error('ASSET_NOT_SUPPORTED', `Unknown token: ${input.to}. Provide the symbol (USDC, SUI, ...) or full coin type.`);\n if (fromType === toType) throw new T2000Error('SWAP_FAILED', 'Cannot swap a token to itself');\n if (!Number.isFinite(input.amount) || input.amount <= 0) {\n throw new T2000Error('INVALID_AMOUNT', 'Amount must be greater than zero');\n }\n\n const fromDecimals = getDecimalsForCoinType(fromType);\n const toDecimals = getDecimalsForCoinType(toType);\n const requestedRaw = BigInt(Math.floor(input.amount * 10 ** fromDecimals));\n\n const slippage = Math.max(0.001, Math.min(input.slippage ?? 0.01, 0.05));\n const byAmountIn = input.byAmountIn ?? true;\n\n let inputCoin: TransactionObjectArgument;\n let effectiveRaw: bigint;\n\n if (input.inputCoin) {\n inputCoin = input.inputCoin;\n effectiveRaw = requestedRaw;\n } else if (fromType === '0x2::sui::SUI') {\n // SUI source needs special handling: under sponsored flows (Enoki),\n // referencing `tx.gas` as a transaction argument is forbidden (sponsor\n // owns the gas coin). `selectSuiCoin` does the right thing for both\n // sponsored (uses `coinWithBalance({ useGasCoin: false })`) and\n // self-funded (splits from `tx.gas` directly). The 2.14.0 release\n // shipped without this branch and broke audric/web-v2 SUI→USDC swaps\n // (\"Cannot use GasCoin as a transaction argument\" from Enoki); fixed\n // in 2.14.1 (S.260).\n const { selectSuiCoin } = await import('../wallet/coinSelection.js');\n const result = await selectSuiCoin(\n tx,\n client,\n address,\n requestedRaw,\n input.sponsoredContext ?? false,\n input.coinMergeCache,\n );\n inputCoin = result.coin;\n effectiveRaw = result.effectiveAmount;\n } else {\n // Non-SUI wallet-mode source — delegate to the canonical prelude.\n // NON-sponsored: pre-flights against `getBalance().totalBalance` and\n // returns a `coinWithBalance({ type, balance })` arg, whose `@mysten/sui`\n // resolver batches all intents for a coin type into a single build-time\n // merge — so same-asset multi-leg bundles dedup automatically.\n //\n // SPONSORED: routes through `selectCoinObjectsOnly` instead (coinWithBalance's\n // address-balance `FundsWithdrawal` reservation is what Enoki can't\n // deserialize, issue #93). That manual path has NO build-time batching, so\n // two legs sourcing the same coin would each emit their own `mergeCoins`\n // over the SAME objects → second merge references consumed coins → Enoki\n // dry-run `ArgumentWithoutValue`. The `coinMergeCache` supplies the dedup:\n // first leg merges once + caches the primary, later legs split from it.\n const { selectAndSplitCoin } = await import('../wallet/coinSelection.js');\n const result = await selectAndSplitCoin(tx, client, address, fromType, requestedRaw, {\n sponsoredContext: input.sponsoredContext ?? false,\n mergeCache: input.coinMergeCache,\n });\n inputCoin = result.coin;\n effectiveRaw = result.effectiveAmount;\n }\n\n // [SPEC 20.2 D-3 (b)] Use the precomputed route when available + valid.\n // Validity = same input/output coin types AND the requested raw amount\n // matches what the route was discovered for (mismatch indicates the user\n // edited the amount post-quote, in which case we must re-discover at the\n // new amount because price impact is amount-dependent). The caller\n // (`audric prepare-route`) owns the staleness check (`isCetusRouteFresh`)\n // and only forwards `precomputedRoute` when fresh.\n //\n // [Bug A defense-in-depth / 2026-05-10] Even with the engine fix that\n // makes `swap_quote` discover sponsor-safe routes, this layer also\n // validates the precomputed route against the active providers\n // allow-list. If the route walks any excluded provider (e.g. a stale\n // `pending_action.cetusRoute` from before the engine fix shipped, or a\n // provider list that drifted between quote and execute), fall back to\n // fresh discovery. Better to eat 400ms than to let a Pyth-dependent\n // route reach Enoki and revert with HTTP 400.\n let route: SwapRouteResult | null;\n let usedPrecomputedRoute = false;\n if (\n input.precomputedRoute &&\n input.precomputedRoute.amountIn === effectiveRaw.toString() &&\n input.precomputedRoute.byAmountIn === byAmountIn &&\n isPrecomputedRouteCompatibleWithProviders(input.precomputedRoute, input.providers)\n ) {\n route = input.precomputedRoute;\n usedPrecomputedRoute = true;\n } else {\n route = await findSwapRoute({\n walletAddress: address,\n from: fromType,\n to: toType,\n amount: effectiveRaw,\n byAmountIn,\n overlayFee: input.overlayFee,\n providers: input.providers,\n });\n }\n\n if (!route) {\n throw new T2000Error('SWAP_NO_ROUTE', `No swap route found for ${input.from} → ${input.to}`);\n }\n if (route.insufficientLiquidity) {\n throw new T2000Error('SWAP_NO_ROUTE', `Insufficient liquidity for ${input.from} → ${input.to}`);\n }\n\n const outputCoin = await buildSwapTx({\n walletAddress: address,\n route,\n tx,\n inputCoin,\n slippage,\n overlayFee: input.overlayFee,\n });\n\n return {\n coin: outputCoin,\n effectiveAmountIn: Number(effectiveRaw) / 10 ** fromDecimals,\n expectedAmountOut: Number(route.amountOut) / 10 ** toDecimals,\n route,\n usedPrecomputedRoute,\n };\n}\n\n// Re-export from the canonical token registry for backward-compat.\nexport { TOKEN_MAP, resolveTokenType } from '../token-registry.js';\n","/**\n * Standalone swap quote — no T2000 agent instance required.\n * Only needs a wallet address for Cetus Aggregator routing.\n */\nimport { T2000Error } from './errors.js';\nimport { getDecimalsForCoinType } from './token-registry.js';\nimport type { SwapQuoteResult } from './types.js';\n\nexport async function getSwapQuote(params: {\n walletAddress: string;\n from: string;\n to: string;\n amount: number;\n byAmountIn?: boolean;\n /**\n * [Bug A fix / 2026-05-10] Optional Cetus provider allow-list, forwarded to\n * `findSwapRoute`. Sponsored callers (Enoki) MUST pass\n * `getSponsoredSwapProviders()` to remove Pyth-dependent providers\n * (HAEDALPMM, METASTABLE, OBRIC, STEAMM_OMM/_V2, SEVENK, HAEDALHMMV2).\n * Those providers cause the Cetus aggregator's internal `routerSwap` to\n * insert a `tx.splitCoins(tx.gas, ...)` call for the Pyth update fee,\n * which Enoki rejects with HTTP 400 \"Cannot use GasCoin as a transaction\n * argument\" (3-step bundle smoke 2026-05-10).\n *\n * Pre-fix: `getSwapQuote` discovered routes against the FULL provider set,\n * stashed Pyth-dependent routes onto `pending_action.cetusRoute` (SPEC\n * 20.2 fast-path), and the audric `prepare` route's `swap_execute`\n * appender used the precomputed route AS-IS — bypassing the providers\n * filter that `composeTx` correctly applied. Result: every swap whose\n * best route happened to include a Pyth-dependent provider failed at\n * Enoki sponsorship.\n *\n * Non-sponsored callers (e.g. CLI direct swap) leave this undefined to\n * keep access to the full provider set including Pyth-dependent pools.\n */\n providers?: string[];\n /**\n * [2.11] On-chain-resolved decimals for `from` / `to`, supplied by callers\n * that hold a client (e.g. `T2000.swapQuote`). When omitted (standalone /\n * sponsored callers), falls back to the registry — correct for registry\n * tokens, a 9-decimal guess for an unknown coin type.\n */\n fromDecimals?: number;\n toDecimals?: number;\n}): Promise<SwapQuoteResult> {\n const { findSwapRoute, resolveTokenType } = await import('./protocols/cetus-swap.js');\n\n const fromType = resolveTokenType(params.from);\n const toType = resolveTokenType(params.to);\n // [S.123 v1.24.7] Use T2000Error('ASSET_NOT_SUPPORTED') consistently with the\n // other 4 throw sites in t2000.ts / cetus-swap.ts. Allows tools to branch\n // on `err.code === 'ASSET_NOT_SUPPORTED'` and return a structured recovery\n // hint to the LLM instead of re-throwing a generic error string.\n if (!fromType) {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n `Unknown token: ${params.from}. Provide the symbol (USDC, SUI, ...) or full coin type.`,\n );\n }\n if (!toType) {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n `Unknown token: ${params.to}. Provide the symbol (USDC, SUI, ...) or full coin type.`,\n );\n }\n\n const byAmountIn = params.byAmountIn ?? true;\n\n const fromDecimals = params.fromDecimals ?? getDecimalsForCoinType(fromType);\n const rawAmount = BigInt(Math.floor(params.amount * 10 ** fromDecimals));\n\n const route = await findSwapRoute({\n walletAddress: params.walletAddress,\n from: fromType,\n to: toType,\n amount: rawAmount,\n byAmountIn,\n providers: params.providers,\n });\n\n if (!route) throw new T2000Error('SWAP_FAILED', `No swap route found for ${params.from} -> ${params.to}.`);\n if (route.insufficientLiquidity) {\n throw new T2000Error('SWAP_FAILED', `Insufficient liquidity for ${params.from} -> ${params.to}.`);\n }\n\n const toDecimals = params.toDecimals ?? getDecimalsForCoinType(toType);\n const fromAmount = Number(route.amountIn) / 10 ** fromDecimals;\n const toAmount = Number(route.amountOut) / 10 ** toDecimals;\n\n const routeDesc = route.routerData.paths\n ?.map((p: { provider?: string }) => p.provider)\n .filter(Boolean)\n .slice(0, 3)\n .join(' + ') ?? 'Cetus Aggregator';\n\n // [SPEC 20.2 / D-1 (a)] Serialize the Cetus route at quote time so the\n // engine can attach it to `pending_action.cetusRoute`. The serialized\n // form survives the SSE → client → POST → prepare-route hop without losing\n // BN/Map fidelity (raw RouterDataV3 doesn't JSON-stringify cleanly).\n const { serializeCetusRoute } = await import('./protocols/cetus-swap.js');\n const serializedRoute = serializeCetusRoute(route, { fromCoinType: fromType, toCoinType: toType });\n\n return {\n fromToken: params.from,\n toToken: params.to,\n fromAmount,\n toAmount,\n priceImpact: route.priceImpact,\n route: routeDesc,\n serializedRoute,\n };\n}\n","import { T2000Error } from './errors.js';\n\nexport const MIST_PER_SUI = 1_000_000_000n;\nexport const SUI_DECIMALS = 9;\nexport const USDC_DECIMALS = 6;\n\nexport const PRECISION = 1_000_000_000_000_000_000n;\n\nexport const MIN_DEPOSIT = 1_000_000n; // 1 USDC (6 decimals)\n\nexport const CLOCK_ID = '0x6';\n\nexport const SUPPORTED_ASSETS = {\n USDC: {\n type: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n symbol: 'USDC',\n displayName: 'USDC',\n },\n USDT: {\n type: '0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT',\n decimals: 6,\n symbol: 'USDT',\n displayName: 'suiUSDT',\n },\n USDe: {\n type: '0x41d587e5336f1c86cad50d38a7136db99333bb9bda91cea4ba69115defeb1402::sui_usde::SUI_USDE',\n decimals: 6,\n symbol: 'USDe',\n displayName: 'suiUSDe',\n },\n USDsui: {\n type: '0x44f838219cf67b058f3b37907b655f226153c18e33dfcd0da559a844fea9b1c1::usdsui::USDSUI',\n decimals: 6,\n symbol: 'USDsui',\n displayName: 'USDsui',\n },\n SUI: {\n type: '0x2::sui::SUI',\n decimals: 9,\n symbol: 'SUI',\n displayName: 'SUI',\n },\n WAL: {\n type: '0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL',\n decimals: 9,\n symbol: 'WAL',\n displayName: 'WAL',\n },\n ETH: {\n type: '0xd0e89b2af5e4910726fbcd8b8dd37bb79b29e5f83f7491bca830e94f7f226d29::eth::ETH',\n decimals: 8,\n symbol: 'ETH',\n displayName: 'suiETH',\n },\n NAVX: {\n type: '0xa99b8952d4f7d947ea77fe0ecdcc9e5fc0bcab2841d6e2a5aa00c3044e5544b5::navx::NAVX',\n decimals: 9,\n symbol: 'NAVX',\n displayName: 'NAVX',\n },\n GOLD: {\n type: '0x9d297676e7a4b771ab023291377b2adfaa4938fb9080b8d12430e4b108b836a9::xaum::XAUM',\n decimals: 6,\n symbol: 'GOLD',\n displayName: 'XAUM',\n },\n} as const;\n\nexport type SupportedAsset = keyof typeof SUPPORTED_ASSETS;\n\n// [SPEC_AGENTIC_STACK P1 / SDK F3 — 2026-05-25]\n// `StableAsset` = \"what we treat as worth $1 for wallet pricing and balance roll-up\".\n// Pre-Phase 1: USDC only — left USDsui wallet holdings invisible to balance.ts.\n// Phase 1: widened to USDC + USDsui (both are NAVI-native stables with $1 peg).\n// USDT / USDe stay OUT of this set deliberately — they are stables, but the\n// codebase has never priced them at $1, and adding them here would require\n// auditing balance.ts callers downstream. Keep the carve minimal.\nexport type StableAsset = 'USDC' | 'USDsui';\nexport const STABLE_ASSETS: readonly StableAsset[] = ['USDC', 'USDsui'] as const;\n\n// ---------------------------------------------------------------------------\n// Operation → allowed asset rules (single source of truth)\n// ---------------------------------------------------------------------------\n\n// [v4.0 Phase A Day 2 — 2026-05-26] `send` is constrained to\n// `['USDC', 'USDsui', 'SUI']`. Rationale (SPEC_AGENT_WALLET_GREENFIELD §A):\n// - USDC + USDsui are gasless via `0x2::balance::send_funds` (Sui mainnet\n// protocol allowlist) — the two foundation stables.\n// - SUI is the only non-stable kept on the allowlist so users with no\n// stablecoin balance can still pay gas-native SUI transfers.\n// - USDT, USDe, WAL, ETH, NAVX, GOLD are NOT sendable — users must swap to\n// USDC/USDsui first (one-step) or hold SUI and use a manual Move call.\n// `swap` is unrestricted (Cetus routes any pair). The DeFi operations\n// (save/borrow/withdraw/repay) were removed with NAVI.\nexport const OPERATION_ASSETS = {\n send: ['USDC', 'USDsui', 'SUI'],\n swap: '*',\n} as const;\n\nexport type Operation = keyof typeof OPERATION_ASSETS;\n\nexport function isAllowedAsset(op: Operation, asset: string): boolean {\n const allowed = OPERATION_ASSETS[op];\n if (allowed === '*') return true;\n // [v0.51.0] Mixed-case canonical keys (USDsui, suiUSDT) need case-insensitive\n // membership. Pre-v0.51 we only had USDC ↔ USDC (uppercase identity), so\n // a one-sided uppercase compare looked correct. Now that USDsui is in the\n // set, normalize both sides.\n const target = asset.toLowerCase();\n return (allowed as readonly string[]).some((a) => a.toLowerCase() === target);\n}\n\n/**\n * Throws if the asset is not permitted for the given operation.\n *\n * [v4.0 Phase A Day 2] Pre-v4 this allowed `undefined` as a silent default\n * to USDC. Removed because every write path now requires explicit asset\n * (see `T2000.send` + `buildSendTx` + `composeTx.send_transfer`). The\n * `undefined → no-op` branch is kept defensively; the `send_transfer` flow\n * validates non-undefined.\n */\nexport function assertAllowedAsset(op: Operation, asset: string | undefined): void {\n if (!asset) return;\n if (!isAllowedAsset(op, asset)) {\n const allowed = OPERATION_ASSETS[op];\n const list = Array.isArray(allowed) ? allowed.join(', ') : 'any';\n const swapHint =\n op === 'send' ? ' Swap to USDC or USDsui first, or send SUI.' : '';\n throw new T2000Error(\n 'INVALID_ASSET',\n `${op} only supports ${list}. Cannot use ${asset}.${swapHint}`,\n );\n }\n}\n\n/**\n * [v4.0 Phase A Day 2] Narrow type alias for assets sendable through the\n * Agent Wallet. Matches `OPERATION_ASSETS.send` exactly. Exported so the\n * CLI / SDK / composeTx can share one type without re-declaring it.\n */\nexport type SendableAsset = 'USDC' | 'USDsui' | 'SUI';\nexport const SENDABLE_ASSETS: readonly SendableAsset[] = ['USDC', 'USDsui', 'SUI'] as const;\n\n/**\n * [v4.0 Phase A Day 2] Coin types for the two gasless-allowlisted stables.\n * Used by `wallet/send.ts` + `composeTx.send_transfer` to construct the\n * `0x2::balance::send_funds` Move call's `typeArguments`. SUI is excluded\n * because SUI transfers are NOT gasless (gas-native, uses `tx.gas` split +\n * `transferObjects` per the existing path).\n */\nexport const GASLESS_STABLE_TYPES: Record<'USDC' | 'USDsui', string> = {\n USDC: SUPPORTED_ASSETS.USDC.type,\n USDsui: SUPPORTED_ASSETS.USDsui.type,\n};\n\n// Swap overlay fees route here. Audric's prepare/route.ts passes\n// `overlayFee.receiver = T2000_OVERLAY_FEE_WALLET` to the Cetus aggregator. The\n// CLI/SDK never charge fees — this constant is exported for consumer apps only.\n//\n// Address corresponds to the treasury admin wallet. Override via env for local dev /\n// testnet only — production must use the canonical mainnet address below.\nexport const T2000_OVERLAY_FEE_WALLET = process.env.T2000_OVERLAY_FEE_WALLET\n ?? '0x5366efbf2b4fe5767fe2e78eb197aa5f5d138d88ac3333fbf3f80a1927da473a';\n\nexport const DEFAULT_NETWORK = 'mainnet' as const;\n// gRPC fullnode endpoint. Post-flip this is the canonical transport for the\n// whole SDK: `getSuiClient()` (reads + execution) AND `getSuiGrpcClient()`\n// (gasless stablecoin build detection) both target it. Override the read/exec\n// client with T2000_RPC_URL and the build client with T2000_GRPC_URL.\nexport const DEFAULT_RPC_URL = 'https://fullnode.mainnet.sui.io:443';\nexport const DEFAULT_GRPC_URL = 'https://fullnode.mainnet.sui.io:443';\n// [gRPC migration] GraphQL endpoint for the query surface that has NO gRPC\n// `core` equivalent — `transactionBlocks` (history). Used by\n// `getSuiGraphQLClient()`. The canonical mainnet host is `graphql.mainnet.sui.io`\n// (parallel to the gRPC fullnode); the older `sui-mainnet.mystenlabs.com/graphql`\n// host was dropped 2026-06-15 after it began resetting TLS connections (live\n// smoke). Public endpoint is rate-limited — production hosts override with\n// T2000_GRAPHQL_URL to a dedicated provider.\nexport const DEFAULT_GRAPHQL_URL = 'https://graphql.mainnet.sui.io/graphql';\nexport const DEFAULT_KEY_PATH = '~/.t2000/wallet.key';\nexport const DEFAULT_CONFIG_PATH = '~/.t2000/config.json';\n\n// [v4.0 Phase A Day 2] Minimum stablecoin amount for protocol-level gasless\n// transfers via `0x2::balance::send_funds`. The Sui mainnet allowlist enforces\n// this floor at the protocol level to prevent dust spam; we surface a clear\n// error before signing rather than letting the tx revert on-chain.\nexport const GASLESS_MIN_STABLE_AMOUNT = 0.01;\n\n// Cetus USDC/SUI pool — read-only for SUI price oracle (no SDK dependency)\nexport const CETUS_USDC_SUI_POOL = '0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab';\n\nexport const GAS_RESERVE_MIN = 0.05; // minimum SUI to keep for gas\n","import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';\nimport { SuiGrpcClient } from '@mysten/sui/grpc';\nimport { SuiGraphQLClient } from '@mysten/sui/graphql';\nimport { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport { DEFAULT_GRAPHQL_URL, DEFAULT_GRPC_URL, DEFAULT_RPC_URL } from '../constants.js';\nimport { T2000Error } from '../errors.js';\n\n/**\n * [gRPC migration / S.438] Transport-agnostic client type for the migration.\n *\n * Both `SuiJsonRpcClient` and `SuiGrpcClient` extend `BaseClient` and expose\n * an identical `.core.*` API. During the migration, call sites are rewritten\n * from legacy methods (`getBalance`, `getObject`, `executeTransactionBlock`)\n * to the unified `client.core.*` API and typed against this union — so the\n * rewrite is behavior-preserving while still on JSON-RPC, and the final\n * transport flip (gRPC) is a one-line change in `getSuiClient()`.\n *\n * The query surface that has no gRPC `core` equivalent (`queryTransactionBlocks`\n * / `queryEvents`, Stage 0 finding A) uses `getSuiGraphQLClient()` instead.\n */\nexport type SuiCoreClient = SuiJsonRpcClient | SuiGrpcClient;\n\n/**\n * Resolve the effective JSON-RPC URL: explicit arg > env var > default.\n * `T2000_RPC_URL` is an OPTIONAL override per the Greenfield SPEC's env\n * contract — no required vars, so we read inline (allowed by\n * `env-validation-gate.mdc` carve-out for packages with zero required\n * env vars).\n */\nfunction resolveRpcUrl(rpcUrl?: string): string {\n if (rpcUrl) return rpcUrl;\n const envUrl = process.env.T2000_RPC_URL?.trim();\n if (envUrl) return envUrl;\n return DEFAULT_RPC_URL;\n}\n\n/**\n * Same shape as `resolveRpcUrl` for the gRPC endpoint.\n */\nfunction resolveGrpcUrl(grpcUrl?: string): string {\n if (grpcUrl) return grpcUrl;\n const envUrl = process.env.T2000_GRPC_URL?.trim();\n if (envUrl) return envUrl;\n return DEFAULT_GRPC_URL;\n}\n\n/**\n * Same shape as `resolveRpcUrl` for the GraphQL endpoint.\n */\nfunction resolveGraphqlUrl(graphqlUrl?: string): string {\n if (graphqlUrl) return graphqlUrl;\n const envUrl = process.env.T2000_GRAPHQL_URL?.trim();\n if (envUrl) return envUrl;\n return DEFAULT_GRAPHQL_URL;\n}\n\n/**\n * Canonical agent client cache, keyed by URL. The earlier impl cached\n * unconditionally and ignored URL changes after the first call —\n * brittle for testnet smokes and custom-RPC test setups.\n */\nconst rpcClientCache = new Map<string, SuiGrpcClient>();\n\n/**\n * [gRPC cutover] The canonical agent client is now gRPC. Mysten deactivates\n * the JSON-RPC fullnode interface on 2026-07-31, so reads (`.core.*`) and\n * execution route over gRPC — transaction *builds* already do\n * (`getSuiGrpcClient`). The whole SDK was first refactored onto the unified\n * `.core` API (behavior-preserving on JSON-RPC), then flipped here. The\n * `rpcUrl` arg / `T2000_RPC_URL` override now resolve a gRPC `baseUrl`\n * (`DEFAULT_RPC_URL` is the same host as `DEFAULT_GRPC_URL`). The historical\n * query surface stays on `getSuiGraphQLClient()`.\n */\nexport function getSuiClient(rpcUrl?: string): SuiGrpcClient {\n const url = resolveRpcUrl(rpcUrl);\n const cached = rpcClientCache.get(url);\n if (cached) return cached;\n const client = new SuiGrpcClient({ baseUrl: url, network: 'mainnet' });\n rpcClientCache.set(url, client);\n return client;\n}\n\n/**\n * gRPC client cache, keyed by URL. Same rationale as the JSON-RPC cache:\n * different URLs must produce different clients.\n */\nconst grpcClientCache = new Map<string, SuiGrpcClient>();\n\n/**\n * Cached `SuiGrpcClient` for gasless stablecoin transfer builds.\n *\n * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]\n *\n * Why this exists: Sui mainnet's protocol-level gasless stablecoin transfers\n * (`0x2::balance::send_funds` on the USDC + USDsui allowlist) are detected\n * ONLY when the transaction is built through a `SuiGrpcClient`. The gRPC\n * client's build resolver inspects the PTB at `tx.build()` time and, if it\n * matches the gasless pattern, sets `gasPrice=0` + `gasBudget=0` automatically.\n * Building the SAME PTB through `SuiJsonRpcClient` produces the same bytes\n * but with non-zero gas — the tx still works, but the user pays SUI gas.\n *\n * Execution stays on JSON-RPC (`SuiJsonRpcClient.executeTransactionBlock`)\n * because (a) the rest of the SDK expects JSON-RPC and (b) Sui's docs\n * explicitly support a \"build via gRPC, execute via JSON-RPC\" hybrid:\n * https://docs.sui.io/develop/transaction-payment/gasless-stablecoin-transfers\n *\n * Override the endpoint with the `T2000_GRPC_URL` env var or the\n * `grpcUrl` arg. Cache is keyed by URL so multiple endpoints can\n * co-exist (e.g., the rare testnet smoke + production usage from the\n * same process).\n */\nexport function getSuiGrpcClient(grpcUrl?: string): SuiGrpcClient {\n const baseUrl = resolveGrpcUrl(grpcUrl);\n const cached = grpcClientCache.get(baseUrl);\n if (cached) return cached;\n const client = new SuiGrpcClient({ baseUrl, network: 'mainnet' });\n grpcClientCache.set(baseUrl, client);\n return client;\n}\n\n/**\n * GraphQL client cache, keyed by URL. Same rationale as the other caches.\n */\nconst graphqlClientCache = new Map<string, SuiGraphQLClient>();\n\n/**\n * Cached `SuiGraphQLClient` for the query surface that has NO gRPC `core`\n * equivalent: `queryTransactionBlocks` + `queryEvents` (Stage 0 finding A —\n * `SPEC_FULL_GRPC_MIGRATION.md`). Mysten's gRPC successor doesn't cover the\n * historical query/event API; GraphQL is its documented home. Consumers:\n * `wallet/history.ts` + the swap-event read in `protocols/cetus-swap.ts`.\n *\n * Override the endpoint with `T2000_GRAPHQL_URL` or the `graphqlUrl` arg.\n */\nexport function getSuiGraphQLClient(graphqlUrl?: string): SuiGraphQLClient {\n const url = resolveGraphqlUrl(graphqlUrl);\n const cached = graphqlClientCache.get(url);\n if (cached) return cached;\n const client = new SuiGraphQLClient({ url, network: 'mainnet' });\n graphqlClientCache.set(url, client);\n return client;\n}\n\nexport function validateAddress(address: string): string {\n const normalized = normalizeSuiAddress(address);\n if (!isValidSuiAddress(normalized)) {\n throw new T2000Error('INVALID_ADDRESS', `Invalid Sui address: ${address}`);\n }\n return normalized;\n}\n\nexport function truncateAddress(address: string): string {\n if (address.length <= 10) return address;\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n\n/**\n * Normalize a Sui coin type to its canonical long-form 64-hex address.\n * `0x2::sui::SUI` → `0x0000…0002::sui::SUI`. Idempotent on already-long\n * forms. Returns the input unchanged if it doesn't look like a coin type\n * (`<address>::<module>::<name>`) so callers can pass arbitrary strings\n * without crashing.\n *\n * Why this exists: BlockVision's `/v2/sui/coin/price/list` endpoint\n * silently returns an empty `prices` map for short-form coin types\n * (notably `0x2::sui::SUI` — the native gas coin). Internal callers must\n * pass the long form, but external callers (LLM tool args, cached\n * coin-type strings, audit logs) commonly use the short form. Normalize\n * before the network call, denormalize back to the caller's input shape\n * after, and short/long become interchangeable.\n */\nexport function normalizeCoinType(coinType: string): string {\n const parts = coinType.split('::');\n if (parts.length !== 3) return coinType;\n const [addr, mod, name] = parts;\n if (!addr.startsWith('0x')) return coinType;\n return `${normalizeSuiAddress(addr)}::${mod}::${name}`;\n}\n","// v4.0 wallet auth model: plain Bech32 secret in a versioned JSON file,\n// 0o600 perms. Matches the Sui CLI convention. No AES, no PIN, no scrypt.\n// Anything that isn't `{ version: 2, secret: \"suiprivkey1...\" }` throws\n// `WALLET_CORRUPT` — the user moves/deletes the file and runs `t2 init`.\n\nimport { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { decodeSuiPrivateKey } from '@mysten/sui/cryptography';\nimport { readFile, writeFile, mkdir, access } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { T2000Error } from '../errors.js';\nimport { DEFAULT_KEY_PATH } from '../constants.js';\n\ninterface PlainKey {\n version: 2;\n secret: string;\n}\n\nfunction expandPath(p: string): string {\n if (p.startsWith('~')) return resolve(homedir(), p.slice(2));\n return resolve(p);\n}\n\nexport function generateKeypair(): Ed25519Keypair {\n return Ed25519Keypair.generate();\n}\n\nexport function keypairFromPrivateKey(privateKey: string): Ed25519Keypair {\n if (privateKey.startsWith('suiprivkey')) {\n const decoded = decodeSuiPrivateKey(privateKey);\n return Ed25519Keypair.fromSecretKey(decoded.secretKey);\n }\n const bytes = Buffer.from(privateKey.replace(/^0x/, ''), 'hex');\n return Ed25519Keypair.fromSecretKey(bytes);\n}\n\n/**\n * Save a keypair as a v2 plain Bech32 JSON file with `0o600` perms.\n *\n * `_passphrase` is accepted but IGNORED — kept in the signature for\n * back-compat with v3.x callers. Will be removed when all callers\n * are off PIN (Phase A Day 5+).\n */\nexport async function saveKey(\n keypair: Ed25519Keypair,\n _passphrase: string | undefined,\n keyPath?: string,\n): Promise<string> {\n const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);\n\n try {\n await access(filePath);\n throw new T2000Error('WALLET_EXISTS', `Wallet already exists at ${filePath}`);\n } catch (error) {\n if (error instanceof T2000Error) throw error;\n }\n\n await mkdir(dirname(filePath), { recursive: true });\n\n const payload: PlainKey = {\n version: 2,\n secret: keypair.getSecretKey(),\n };\n\n await writeFile(filePath, JSON.stringify(payload, null, 2), { mode: 0o600 });\n\n return filePath;\n}\n\n/**\n * Save a Bech32 secret directly as a v2 plain wallet file. Used by any\n * path where the secret is supplied externally rather than freshly\n * generated. Kept exported because external tooling may still want it\n * even though the CLI no longer ships an `--import` flag.\n */\nexport async function saveBech32(secret: string, keyPath?: string): Promise<string> {\n if (!secret.startsWith('suiprivkey')) {\n throw new T2000Error(\n 'INVALID_KEY',\n `Secret must be a Bech32 suiprivkey1... string. Got: ${secret.slice(0, 12)}...`,\n );\n }\n decodeSuiPrivateKey(secret);\n\n const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);\n\n try {\n await access(filePath);\n throw new T2000Error('WALLET_EXISTS', `Wallet already exists at ${filePath}`);\n } catch (error) {\n if (error instanceof T2000Error) throw error;\n }\n\n await mkdir(dirname(filePath), { recursive: true });\n\n const payload: PlainKey = { version: 2, secret };\n\n await writeFile(filePath, JSON.stringify(payload, null, 2), { mode: 0o600 });\n\n return filePath;\n}\n\n/**\n * Load a keypair from disk.\n *\n * `_passphrase` is accepted but IGNORED — kept for back-compat. The\n * actual file format determines the load path:\n *\n * - **v2 plain JSON** (`{ version: 2, secret: \"suiprivkey1...\" }`) →\n * decode + return keypair.\n * - **Anything else** → throw `WALLET_CORRUPT`. The user moves or\n * deletes the file and runs `t2 init` to create a fresh wallet.\n */\nexport async function loadKey(\n _passphrase?: string,\n keyPath?: string,\n): Promise<Ed25519Keypair> {\n const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);\n\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n throw new T2000Error('WALLET_NOT_FOUND', `No wallet found at ${filePath}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n throw new T2000Error(\n 'WALLET_CORRUPT',\n `Wallet file at ${filePath} is not a valid v4 wallet. Move or delete the file, then run \\`t2 init\\`.`,\n );\n }\n\n if (!isPlainKey(parsed)) {\n throw new T2000Error(\n 'WALLET_CORRUPT',\n `Wallet file at ${filePath} is not a valid v4 wallet. Expected { version: 2, secret: \"suiprivkey1...\" }. Move or delete the file, then run \\`t2 init\\`.`,\n );\n }\n\n const decoded = decodeSuiPrivateKey(parsed.secret);\n return Ed25519Keypair.fromSecretKey(decoded.secretKey);\n}\n\nexport async function walletExists(keyPath?: string): Promise<boolean> {\n const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function exportPrivateKey(keypair: Ed25519Keypair): string {\n return keypair.getSecretKey();\n}\n\nexport function getAddress(keypair: Ed25519Keypair): string {\n return keypair.getPublicKey().toSuiAddress();\n}\n\nfunction isPlainKey(value: unknown): value is PlainKey {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { version?: unknown }).version === 2 &&\n typeof (value as { secret?: unknown }).secret === 'string'\n );\n}\n","import type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport type { TransactionSigner } from '../signer.js';\n\nexport class KeypairSigner implements TransactionSigner {\n readonly kind = 'keypair' as const;\n\n constructor(private readonly keypair: Ed25519Keypair) {}\n\n getAddress(): string {\n return this.keypair.getPublicKey().toSuiAddress();\n }\n\n async signTransaction(txBytes: Uint8Array): Promise<{ signature: string }> {\n return this.keypair.signTransaction(txBytes);\n }\n\n async signPersonalMessage(messageBytes: Uint8Array): Promise<{ signature: string; bytes: string }> {\n return this.keypair.signPersonalMessage(messageBytes);\n }\n\n /** Access the underlying keypair for APIs that still require it directly. */\n getKeypair(): Ed25519Keypair {\n return this.keypair;\n }\n}\n","import type { SuiClientTypes } from '@mysten/sui/client';\nimport type { Transaction } from '@mysten/sui/transactions';\nimport type { TransactionSigner } from '../signer.js';\nimport type { SuiCoreClient } from '../utils/sui.js';\n\n// ---------------------------------------------------------------------------\n// executeTx — build + sign + submit + wait, the SDK's one tx-execution helper.\n//\n// Browser-safe (no fs / keyManager imports) so it can back\n// both the Node-side `T2000` methods AND the browser-side `payWithMpp`\n// (gasless MPP runs client-side on the zkLogin session key). Moved out of\n// `t2000.ts` so `wallet/pay.ts` can share it without pulling the Node-only\n// `T2000` module graph into the browser bundle.\n//\n// [gRPC migration] Submit + wait go through the unified `client.core.*`\n// API (`executeTransaction` + `waitForTransaction`), which is transport-\n// agnostic across the JSON-RPC and gRPC clients.\n// ---------------------------------------------------------------------------\n\nexport type SuiTransactionEffects = SuiClientTypes.TransactionEffects;\nexport type BuildClient = NonNullable<Parameters<Transaction['build']>[0]>['client'];\n\nexport async function executeTx(\n client: SuiCoreClient,\n signer: TransactionSigner,\n buildTx: () => Promise<Transaction> | Transaction,\n options: { buildClient?: BuildClient } = {},\n): Promise<{ digest: string; gasCostSui: number; effects: SuiTransactionEffects | undefined }> {\n const tx = await buildTx();\n tx.setSender(signer.getAddress());\n // [2026-05-22] Optional buildClient. When set, `tx.build()` uses it to\n // resolve the PTB — relevant for gasless stablecoin transfers where the\n // SuiGrpcClient build path auto-detects allowlisted ops and zeros out\n // gasPrice/gasBudget/gasPayment. See `payWithMpp`.\n const txBytes = await tx.build({ client: options.buildClient ?? client });\n const { signature } = await signer.signTransaction(txBytes);\n const result = await client.core.executeTransaction({\n transaction: txBytes,\n signatures: [signature],\n include: { effects: true },\n });\n const txn = result.$kind === 'Transaction' ? result.Transaction : result.FailedTransaction;\n try {\n await client.core.waitForTransaction({ digest: txn.digest });\n } catch (err) {\n // A successful executeTransaction already returned the certified effects —\n // the wait only provides read-your-write index visibility. On a lagging\n // fullnode it can time out AFTER the tx landed; propagating that turns a\n // SUCCESSFUL on-chain payment into a reported failure, which bait-invites\n // a double-pay retry (S.453 JMPR e2e: two 0.02 USDC charges for one call).\n // Effects in hand = executed + certified → proceed. No effects = nothing\n // proves execution → rethrow.\n if (!txn.effects) throw err;\n }\n const effects = txn.effects ?? undefined;\n const gasUsed = effects?.gasUsed;\n let gasCostSui = 0;\n if (gasUsed) {\n const total = BigInt(gasUsed.computationCost) + BigInt(gasUsed.storageCost) - BigInt(gasUsed.storageRebate);\n gasCostSui = Number(total) / 1e9;\n }\n return { digest: txn.digest, gasCostSui, effects };\n}\n","import type { SuiGrpcClient } from '@mysten/sui/grpc';\nimport { fromBase64 } from '@mysten/sui/utils';\nimport type { X402Requirements } from '@suimpp/mpp/x402';\nimport type { TransactionSigner } from '../signer.js';\nimport type { PayOptions, PayResult } from '../types.js';\nimport { T2000Error } from '../errors.js';\nimport { parseChallengeAmount } from '../mpp-cost.js';\nimport { executeTx } from './executeTx.js';\nimport {\n type PreflightResult,\n PREFLIGHT_OK,\n preflightFail,\n checkPositiveAmount,\n} from '../preflight.js';\n\n/**\n * Synchronous, network-free preflight for `pay` (x402 Service call). Validates\n * the target URL shape and the `maxPrice` ceiling when present — the cheap\n * checks the v3 host runs before dispatching the paid tool / showing the\n * tap-to-confirm card. Returns a `PreflightResult`; never throws. The probe +\n * 402 handshake + balance migration stay in `payWithMpp` (network).\n */\nexport function preflightPay(input: { url: string; maxPrice?: number }): PreflightResult {\n if (typeof input.url !== 'string' || input.url.trim() === '') {\n return preflightFail('FACILITATOR_REJECTION', 'A target URL is required to pay');\n }\n let parsed: URL;\n try {\n parsed = new URL(input.url);\n } catch {\n return preflightFail('FACILITATOR_REJECTION', `Invalid URL: ${input.url}`);\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return preflightFail(\n 'FACILITATOR_REJECTION',\n `URL must be http(s): got ${parsed.protocol}//`,\n );\n }\n // `maxPrice` is optional (no ceiling = pay whatever the 402 asks). Validate\n // only when the caller set one — a malformed ceiling is a fat-finger.\n if (input.maxPrice !== undefined) {\n const priceCheck = checkPositiveAmount(input.maxPrice, 'maxPrice');\n if (!priceCheck.valid) return priceCheck;\n }\n return PREFLIGHT_OK;\n}\n\n// ---------------------------------------------------------------------------\n// payWithMpp — the SDK's single source of truth for the pay loop. Browser-safe\n// (no fs / keyManager / SafeguardEnforcer), so the Audric client can run it\n// in-browser on the zkLogin session key. `T2000.pay()` delegates here.\n//\n// TWO dialects, ONE preference order (both ride the SAME gasless\n// `send_funds<USDC>` rail; the only difference is who submits):\n//\n// 1. x402 `sui-exact` (preferred — SPEC_AGENT_PAYMENTS_X402 1.2; scheme =\n// SUIMPP_X402_SCHEME.md v0.3): the 402 body carries `accepts[]`; the\n// client signs an authorization, the SERVER settles (settle-then-serve,\n// so a failed upstream is never charged). The withdrawal form draws from\n// the SIP-58 address balance, so coin-object funds are migrated in first\n// when needed (S.414 finding).\n//\n// 2. MPP header dialect (fallback — suimpp.dev/spec): the 402 carries only a\n// `WWW-Authenticate: Payment … method=\"sui\"` challenge, no x402 body. The\n// CLIENT broadcasts the gasless USDC transfer and retries with the digest\n// credential. S.452 retired this path assuming all sellers were our\n// gateway (which dual-serves); the first EXTERNAL seller (JMPR, S.453)\n// shipped header-only — the client must speak everything the gateway and\n// suimpp spec serve, so the fallback is back. Trade-off vs x402: the\n// client pays BEFORE the server proves it can deliver, so a broken seller\n// can charge without serving — x402 stays preferred whenever offered.\n// ---------------------------------------------------------------------------\n\nexport async function payWithMpp(args: {\n signer: TransactionSigner;\n client: SuiGrpcClient;\n options: PayOptions;\n}): Promise<PayResult> {\n const { signer, client } = args;\n let options = args.options;\n\n // Layer 2 — cheap synchronous preflight (URL shape + maxPrice sanity) before\n // any network round-trip. Rethrow the precise code+message verbatim.\n const pf = preflightPay({ url: options.url, maxPrice: options.maxPrice });\n if (!pf.valid) throw new T2000Error(pf.code, pf.error);\n\n const method = (options.method ?? 'GET').toUpperCase();\n const canHaveBody = method !== 'GET' && method !== 'HEAD';\n\n // Default `content-type: application/json` when the body IS JSON and the\n // caller didn't say otherwise. Without it, fetch stamps `text/plain` and\n // strict servers (FastAPI et al.) receive the body as a string — a 422\n // before the 402 ever fires (live finding vs JMPR, the first external\n // seller). Every retry below reads from the normalized `options`.\n if (\n canHaveBody &&\n typeof options.body === 'string' &&\n isJsonText(options.body) &&\n !hasContentType(options.headers)\n ) {\n options = {\n ...options,\n headers: { ...(options.headers ?? {}), 'content-type': 'application/json' },\n };\n }\n\n const reqInit: RequestInit = {\n method,\n headers: options.headers,\n body: canHaveBody ? options.body : undefined,\n };\n\n // Probe (no payment). A paid endpoint answers 402; a free/cached one serves.\n const probe = await fetch(options.url, reqInit);\n if (probe.status !== 402) {\n return finalize(probe, { paid: false });\n }\n\n const requirements = await pickSuiExactRequirements(probe, client.network);\n if (requirements) {\n // Job-class (escrow-intent) 402 — SPEC_A2A_ESCROW slice 2. The entry\n // advertises escrow TERMS, not an instant settlement challenge: paying\n // it with a signed transfer would move money with no delivery contract.\n // Fail closed and route the caller to the escrow flow.\n const { isX402EscrowRequirements } = await import('@suimpp/mpp/x402');\n if (isX402EscrowRequirements(requirements)) {\n const escrow = requirements.extra.escrow;\n const price = atomicToHuman(\n BigInt(requirements.maxAmountRequired),\n await assetDecimals(requirements.asset),\n );\n throw new T2000Error(\n 'ESCROW_REQUIRED',\n 'This endpoint sells deliverable work through on-chain escrow, not an instant call. ' +\n `Create a job instead: t2 job create ${price} ${requirements.payTo} --spec <your-brief> ` +\n '— funds lock in a Job object and release on delivery. No payment was made.',\n { payTo: requirements.payTo, priceUsdc: price, escrow },\n );\n }\n const result = await payViaX402({ signer, client, options, reqInit, requirements });\n await reportDirectPayment(result, options.url);\n return result;\n }\n\n // No x402 envelope — fall back to the MPP header dialect when the 402\n // advertises a `sui` method challenge.\n const headerChallenge = await parseMppSuiChallenge(probe);\n if (headerChallenge) {\n // Fail CLOSED before any money moves: the header dialect pays first and\n // proves identity with a personal-message signature the SELLER verifies.\n // zkLogin signatures are ZK constructs external sellers can't check —\n // the payment settles on-chain, then the retry 402s and the buyer ate\n // the charge (live: JMPR × Audric Passport, 2026-07-17). x402 is immune\n // (the tx itself carries the zkLogin sig; the CHAIN verifies it), so\n // zkLogin payers require sellers that offer x402.\n if (signer.kind === 'zklogin') {\n throw new T2000Error(\n 'DIALECT_UNSUPPORTED',\n 'This seller only offers the MPP header dialect, which zkLogin (Passport) wallets ' +\n 'cannot safely pay: the seller cannot verify zkLogin signatures, so the payment ' +\n 'would settle on-chain without the service delivering. No payment was made. ' +\n 'Use an x402-capable service, or pay from a keypair wallet (t2 CLI / MCP).',\n { dialect: 'mpp-header', signerKind: 'zklogin' },\n );\n }\n const result = await payViaMppHeader({ signer, client, options });\n await reportDirectPayment(result, options.url);\n return result;\n }\n\n throw new T2000Error(\n 'FACILITATOR_REJECTION',\n `Endpoint returned 402 without an x402 'exact' / sui:${client.network} requirement in the body ` +\n `or an MPP 'sui' challenge in WWW-Authenticate. Nothing this SDK can pay.`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Direct-seller activity reporting (S.743). Gateway-proxied payments are\n// logged server-side by the gateway itself; DIRECT payments (catalog\n// federation — seller's own origin) never touch it, leaving the activity\n// feed blind. After a paid call to a non-gateway origin, tell the gateway\n// \"look at this digest for this url\" — it verifies on-chain (USDC inflow to\n// the cataloged seller's pinned payTo) before recording, so the report\n// carries no trusted data. Best-effort by construction: timeout-capped and\n// error-swallowed, a lost report never fails or delays the payment. Awaited\n// (not fire-and-forget) so short-lived CLI processes don't drop it on exit.\n// ---------------------------------------------------------------------------\n\nconst MPP_REPORT_URL = 'https://mpp.t2000.ai/api/mpp/report';\nconst REPORT_TIMEOUT_MS = 2_000;\n\nasync function reportDirectPayment(result: PayResult, url: string): Promise<void> {\n if (!result.paid || !result.receipt?.reference) return;\n try {\n if (new URL(url).origin === new URL(MPP_REPORT_URL).origin) return;\n await fetch(MPP_REPORT_URL, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ digest: result.receipt.reference, url }),\n signal: AbortSignal.timeout(REPORT_TIMEOUT_MS),\n });\n } catch {\n // Best-effort: the payment already succeeded; the feed row is analytics.\n }\n}\n\n/**\n * Parse the MPP header dialect from a 402 response: the\n * `WWW-Authenticate: Payment …` challenge(s), looking for `method=\"sui\"`.\n * Returns the decoded `{ amount, currency, recipient }` request (amount is a\n * decimal string, e.g. \"0.02\") or `undefined` when the response carries no\n * sui challenge. Exported for the CLI's `t2 pay --estimate`.\n */\nexport async function parseMppSuiChallenge(\n response: Response,\n): Promise<{ amount: string; currency: string; recipient: string; description?: string } | undefined> {\n try {\n const { Challenge } = await import('mppx');\n const challenges = Challenge.fromResponseList(response);\n const suiChallenge = challenges.find((c) => c.method === 'sui' && c.intent === 'charge');\n if (!suiChallenge) return undefined;\n const req = suiChallenge.request as Record<string, unknown>;\n if (typeof req?.amount !== 'string' || typeof req?.recipient !== 'string') return undefined;\n return {\n amount: req.amount,\n currency: typeof req.currency === 'string' ? req.currency : '',\n recipient: req.recipient,\n description: suiChallenge.description,\n };\n } catch {\n return undefined;\n }\n}\n\n// ---------------------------------------------------------------------------\n// x402 `sui-exact` — sign-then-settle\n// ---------------------------------------------------------------------------\n\nasync function pickSuiExactRequirements(\n response: Response,\n network: string,\n): Promise<X402Requirements | undefined> {\n try {\n const body = (await response.clone().json()) as { accepts?: X402Requirements[] };\n const want = `sui:${network === 'testnet' ? 'testnet' : 'mainnet'}`;\n return body.accepts?.find((a) => a.scheme === 'exact' && a.network === want);\n } catch {\n return undefined;\n }\n}\n\nasync function payViaX402(args: {\n signer: TransactionSigner;\n client: SuiGrpcClient;\n options: PayOptions;\n reqInit: RequestInit;\n requirements: X402Requirements;\n}): Promise<PayResult> {\n const { signer, client, options, reqInit, requirements } = args;\n const { buildX402SignedPayment, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER } = await import(\n '@suimpp/mpp/x402'\n );\n\n const amountRaw = BigInt(requirements.maxAmountRequired);\n assertWithinMaxPrice(atomicToHuman(amountRaw, await assetDecimals(requirements.asset)), options.maxPrice);\n\n // The x402 withdrawal form spends ONLY the SIP-58 address balance. A wallet\n // funded by ordinary coin transfers (or swap output) holds Coin<USDC>\n // objects → migrate enough in first (S.414 finding; SUIMPP_X402_SCHEME §4).\n const migrationGasSui = await ensureAddressBalanceCovers({\n signer,\n client,\n asset: requirements.asset,\n amountRaw,\n });\n\n // Build + sign — NEVER submitted client-side; the gateway settles. The\n // builder only reads toSuiAddress() + signTransaction(), both of which every\n // TransactionSigner (keypair AND zkLogin) provides.\n const signerAdapter = {\n toSuiAddress: () => signer.getAddress(),\n signTransaction: (bytes: Uint8Array) => signer.signTransaction(bytes),\n } as unknown as Parameters<typeof buildX402SignedPayment>[0]['signer'];\n\n const { header } = await buildX402SignedPayment({ requirements, signer: signerAdapter });\n\n const res = await fetch(options.url, {\n ...reqInit,\n headers: { ...(options.headers ?? {}), [X402_PAYMENT_HEADER]: header },\n });\n\n // Settled iff the gateway returned the x402 receipt header.\n const settleHeader = res.headers.get(X402_PAYMENT_RESPONSE_HEADER);\n const paid = !!settleHeader;\n let digest: string | undefined;\n if (settleHeader) {\n try {\n digest = (JSON.parse(new TextDecoder().decode(fromBase64(settleHeader))) as { transaction?: string })\n .transaction;\n } catch {\n digest = undefined;\n }\n }\n\n const result = await finalize(res, { paid });\n if (!paid) return { ...result, dialect: 'x402' };\n return {\n ...result,\n dialect: 'x402',\n cost: atomicToHuman(amountRaw, await assetDecimals(requirements.asset)),\n gasCostSui: migrationGasSui,\n receipt: digest\n ? { reference: digest, timestamp: new Date().toISOString() }\n : result.receipt,\n };\n}\n\n// ---------------------------------------------------------------------------\n// MPP header dialect — client broadcasts, retries with the digest credential.\n// The pre-S.452 `payViaLegacy`, restored (S.453) for header-only external\n// sellers. mppx's client handles the 402 → pay → retry loop; we plug in the\n// Sui charge method with an `execute` override that routes the on-chain leg\n// through `executeTx` (gRPC build → gasless resolver → the same\n// `send_funds<USDC>` rail as x402).\n// ---------------------------------------------------------------------------\n\nasync function payViaMppHeader(args: {\n signer: TransactionSigner;\n client: SuiGrpcClient;\n options: PayOptions;\n}): Promise<PayResult> {\n const { signer, client, options } = args;\n\n const { Mppx } = await import('mppx/client');\n const { sui, USDC, USDC_TESTNET } = await import('@suimpp/mpp/client');\n\n const signerAddress = signer.getAddress();\n const network: 'mainnet' | 'testnet' = client.network === 'testnet' ? 'testnet' : 'mainnet';\n const grpcClient = await makeGrpcBuildClient(client);\n\n let paymentDigest: string | undefined;\n let gasCostSui = 0;\n // The real amount charged on-chain is the 402 challenge price (a decimal\n // USDC string like \"0.01\"), NOT the caller's `maxPrice` ceiling (Bug 1,\n // dogfood 2026-05-31). Capture it in `onChallenge` — and enforce the\n // ceiling THERE, before any credential is created: the header dialect pays\n // client-side, so this hook is the last stop before money moves.\n let chargedAmount: number | undefined;\n\n const mppx = Mppx.create({\n polyfill: false,\n onChallenge: async (challenge: { request?: { amount?: unknown } }) => {\n const parsed = parseChallengeAmount(challenge);\n if (parsed !== undefined) {\n chargedAmount = parsed;\n assertWithinMaxPrice(parsed, options.maxPrice);\n }\n return undefined;\n },\n methods: [\n sui({\n client,\n currency: network === 'testnet' ? USDC_TESTNET : USDC,\n signer: {\n toSuiAddress: () => signerAddress,\n signPersonalMessage: (bytes: Uint8Array) => signer.signPersonalMessage(bytes),\n } as unknown as Parameters<typeof sui>[0]['signer'],\n execute: async (tx) => {\n const result = await executeTx(client, signer, () => tx, { buildClient: grpcClient });\n paymentDigest = result.digest;\n gasCostSui = result.gasCostSui;\n return { digest: result.digest };\n },\n }),\n ],\n });\n\n const method = (options.method ?? 'GET').toUpperCase();\n const canHaveBody = method !== 'GET' && method !== 'HEAD';\n\n const response = await mppx.fetch(options.url, {\n method,\n headers: options.headers,\n body: canHaveBody ? options.body : undefined,\n });\n\n const paid = !!paymentDigest;\n const result = await finalize(response, { paid });\n if (!paid) return { ...result, dialect: 'legacy' };\n return {\n ...result,\n dialect: 'legacy',\n cost: chargedAmount ?? options.maxPrice ?? undefined,\n gasCostSui,\n receipt: paymentDigest\n ? { reference: paymentDigest, timestamp: new Date().toISOString() }\n : undefined,\n };\n}\n\n/** Throw `PRICE_EXCEEDS_LIMIT` when the challenge price exceeds the caller's\n * `maxPrice` ceiling (no ceiling = pay whatever the 402 asks). */\nfunction assertWithinMaxPrice(price: number, maxPrice: number | undefined): void {\n if (maxPrice !== undefined && price > maxPrice) {\n throw new T2000Error(\n 'PRICE_EXCEEDS_LIMIT',\n `Service price $${price} exceeds maxPrice ceiling $${maxPrice}`,\n { price, maxPrice },\n );\n }\n}\n\n/**\n * Ensure the sender's SIP-58 address balance covers `amountRaw` of `asset`.\n * Returns the SUI gas spent migrating (0 when no migration was needed or the\n * migration was gasless). Throws `INSUFFICIENT_BALANCE` when the wallet\n * doesn't hold enough of the asset at all (coins + address balance combined).\n */\nasync function ensureAddressBalanceCovers(args: {\n signer: TransactionSigner;\n client: SuiGrpcClient;\n asset: string;\n amountRaw: bigint;\n}): Promise<number> {\n const { signer, client, asset, amountRaw } = args;\n const owner = signer.getAddress();\n\n // total = coins + address balance (the canonical combined read)\n const balanceResp = await client.core.getBalance({ owner, coinType: asset });\n const total = BigInt(balanceResp.balance.balance);\n if (total < amountRaw) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${asset} to pay`, {\n available: total.toString(),\n required: amountRaw.toString(),\n });\n }\n\n // address balance = total − discrete coin-object sum (listCoins excludes AB).\n // Collect the coin objects too — we reuse them to build the migration.\n const coins: { objectId: string; balance: bigint }[] = [];\n let coinSum = 0n;\n let cursor: string | null | undefined;\n let hasNext = true;\n while (hasNext) {\n const page = await client.core.listCoins({ owner, coinType: asset, cursor: cursor ?? undefined });\n for (const c of page.objects) {\n coins.push({ objectId: c.objectId, balance: BigInt(c.balance) });\n coinSum += BigInt(c.balance);\n }\n cursor = page.cursor;\n hasNext = page.hasNextPage;\n }\n const addressBalance = total - coinSum;\n if (addressBalance >= amountRaw) return 0; // address balance already covers it\n\n // Move the shortfall from coin objects into the address balance by sending\n // WHOLE coin objects to self via `0x2::coin::send_funds` — one allowlisted\n // framework MoveCall per coin, NO native merge/split. Built on the gRPC\n // client so its resolver detects the all-allowlisted-MoveCall shape and zeros\n // gas: the migration itself is gasless (the same eligibility the x402\n // withdrawal + the gasless send rely on). The old merge+split+send shape had\n // native `SplitCoins`/`MergeCoins` commands → fell outside the allowlist →\n // forced SUI gas, breaking coin-object holders with 0 SUI.\n const shortfall = amountRaw - addressBalance;\n const { buildCoinToAddressBalanceMigration } = await import('./coinSelection.js');\n const grpcClient = await makeGrpcBuildClient(client);\n const { tx } = buildCoinToAddressBalanceMigration({ coins, coinType: asset, owner, minAmount: shortfall });\n const migration = await executeTx(client, signer, () => tx, { buildClient: grpcClient });\n return migration.gasCostSui;\n}\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\n/** Cheap \"is this JSON?\" check — parse, don't guess from the first char. */\nfunction isJsonText(text: string): boolean {\n try {\n JSON.parse(text);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Case-insensitive content-type presence check on a plain header record. */\nfunction hasContentType(headers: Record<string, string> | undefined): boolean {\n if (!headers) return false;\n return Object.keys(headers).some((k) => k.toLowerCase() === 'content-type');\n}\n\n/** Read the response body (json or text) and assemble the base PayResult. */\nasync function finalize(response: Response, opts: { paid: boolean }): Promise<PayResult> {\n const contentType = response.headers.get('content-type') ?? '';\n let body: unknown;\n try {\n body = contentType.includes('application/json') ? await response.json() : await response.text();\n } catch {\n body = null;\n }\n return { status: response.status, body, paid: opts.paid };\n}\n\n/** A gRPC client for tx BUILD — its resolver auto-detects the gasless\n * stablecoin shape (gasPrice/gasBudget/gasPayment zeroed). */\nasync function makeGrpcBuildClient(client: SuiGrpcClient): Promise<SuiGrpcClient> {\n const { SuiGrpcClient } = await import('@mysten/sui/grpc');\n const network: 'mainnet' | 'testnet' = client.network === 'testnet' ? 'testnet' : 'mainnet';\n const baseUrl =\n network === 'testnet' ? 'https://fullnode.testnet.sui.io' : 'https://fullnode.mainnet.sui.io';\n return new SuiGrpcClient({ baseUrl, network });\n}\n\nfunction atomicToHuman(raw: bigint, decimals: number): number {\n return Number(raw) / 10 ** decimals;\n}\n\nasync function assetDecimals(coinType: string): Promise<number> {\n try {\n const { getDecimalsForCoinType } = await import('../token-registry.js');\n const d = getDecimalsForCoinType(coinType);\n return typeof d === 'number' ? d : 6;\n } catch {\n return 6;\n }\n}\n","/**\n * MPP cost extraction — the truthful-`cost` fix (Bug 1, dogfood 2026-05-31).\n *\n * `T2000.pay()` used to report `options.maxPrice` (the caller's ceiling, default\n * 1.0 in MCP) as the `cost`, wildly overstating the real charge. The real\n * amount is the 402 challenge price, a decimal USDC string like \"0.01\" carried\n * on `challenge.request.amount`. mppx surfaces the parsed challenge via its\n * `onChallenge` hook; this pure helper pulls the amount out so the extraction\n * is unit-testable in isolation (the ordering/format invariant can't silently\n * regress).\n */\n\n/** Minimal structural view of an mppx payment challenge. */\nexport type MppChallenge = { request?: { amount?: unknown } } | null | undefined;\n\n/**\n * Parse the charged amount (USD) from a payment challenge. Returns `undefined`\n * when the challenge has no usable numeric amount, so callers can fall back to\n * the `maxPrice` ceiling rather than reporting a wrong number.\n */\nexport function parseChallengeAmount(challenge: MppChallenge): number | undefined {\n const raw = challenge?.request?.amount;\n const n =\n typeof raw === 'string' ? Number(raw) : typeof raw === 'number' ? raw : Number.NaN;\n return Number.isFinite(n) ? n : undefined;\n}\n","import type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport type { TransactionSigner } from '../signer.js';\n\nexport interface ZkLoginProof {\n proofPoints: {\n a: string[];\n b: string[][];\n c: string[];\n };\n issBase64Details: {\n indexMod4: number;\n value: string;\n };\n headerBase64: string;\n addressSeed: string;\n}\n\nexport class ZkLoginSigner implements TransactionSigner {\n readonly kind = 'zklogin' as const;\n\n constructor(\n private readonly ephemeralKeypair: Ed25519Keypair,\n private readonly zkProof: ZkLoginProof,\n private readonly userAddress: string,\n private readonly maxEpoch: number,\n ) {}\n\n getAddress(): string {\n return this.userAddress;\n }\n\n async signTransaction(txBytes: Uint8Array): Promise<{ signature: string }> {\n const { getZkLoginSignature } = await import('@mysten/zklogin');\n const ephSig = await this.ephemeralKeypair.signTransaction(txBytes);\n return {\n signature: getZkLoginSignature({\n inputs: this.zkProof,\n maxEpoch: this.maxEpoch,\n userSignature: ephSig.signature,\n }),\n };\n }\n\n async signPersonalMessage(messageBytes: Uint8Array): Promise<{ signature: string; bytes: string }> {\n const { getZkLoginSignature } = await import('@mysten/zklogin');\n const { signature: ephSig, bytes } = await this.ephemeralKeypair.signPersonalMessage(messageBytes);\n return {\n signature: getZkLoginSignature({\n inputs: this.zkProof,\n maxEpoch: this.maxEpoch,\n userSignature: ephSig,\n }),\n bytes,\n };\n }\n\n isExpired(currentEpoch: number): boolean {\n return currentEpoch >= this.maxEpoch;\n }\n}\n","import {\n Transaction,\n type TransactionObjectArgument,\n} from '@mysten/sui/transactions';\nimport {\n GASLESS_MIN_STABLE_AMOUNT,\n GASLESS_STABLE_TYPES,\n SUPPORTED_ASSETS,\n assertAllowedAsset,\n type SendableAsset,\n} from '../constants.js';\nimport { T2000Error } from '../errors.js';\nimport { validateAddress, type SuiCoreClient } from '../utils/sui.js';\nimport { displayToRaw } from '../utils/format.js';\nimport {\n type PreflightResult,\n PREFLIGHT_OK,\n preflightFail,\n checkPositiveAmount,\n checkSuiAddress,\n} from '../preflight.js';\n\n/**\n * Synchronous, network-free preflight for `send`. Validates asset membership,\n * amount sanity, the gasless stable floor, and recipient address shape — the\n * cheap checks the v3 host runs before the LLM round-trip / tap-to-confirm.\n * Returns a `PreflightResult`; never throws. `buildSendTx` calls this first,\n * then layers the network balance read on top.\n */\nexport function preflightSend(input: {\n to: string;\n amount: number;\n asset: string;\n}): PreflightResult {\n // Asset membership — reuse the canonical message (single source of truth).\n try {\n assertAllowedAsset('send', input.asset);\n } catch (e) {\n return preflightFail('INVALID_ASSET', (e as T2000Error).message);\n }\n\n const amountCheck = checkPositiveAmount(input.amount);\n if (!amountCheck.valid) return amountCheck;\n\n // Gasless protocol allowlist enforces a 0.01 minimum on the stables.\n if (\n (input.asset === 'USDC' || input.asset === 'USDsui') &&\n input.amount < GASLESS_MIN_STABLE_AMOUNT\n ) {\n return preflightFail(\n 'INVALID_AMOUNT',\n `Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${input.asset}. Got ${input.amount}.`,\n );\n }\n\n const addressCheck = checkSuiAddress(input.to);\n if (!addressCheck.valid) return addressCheck;\n\n return PREFLIGHT_OK;\n}\n\n/**\n * Build a PTB that sends `amount` of `asset` from `address` to `to`.\n *\n * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]\n *\n * Asset constraint: `'USDC' | 'USDsui' | 'SUI'` only. Other assets throw\n * `INVALID_ASSET` via `assertAllowedAsset('send', asset)`. The constrained\n * set matches Sui mainnet's gasless allowlist (USDC + USDsui) plus SUI\n * for users who want a gas-native transfer.\n *\n * Build paths:\n * - **USDC / USDsui** — `0x2::balance::send_funds` Move call with a\n * `tx.balance({ type, balance })` input. When built via `SuiGrpcClient`,\n * the gRPC resolver auto-detects gasless eligibility and zeros gas.\n * When built via `SuiJsonRpcClient`, the same PTB still executes but\n * the caller pays normal gas. Minimum 0.01 (protocol allowlist floor).\n * - **SUI** — `tx.splitCoins(tx.gas, [amount]) → tx.transferObjects()`.\n * Standard gas-native transfer. No minimum.\n *\n * Pre-flight balance check stays on JSON-RPC (`client.getBalance`) — it\n * sums coin objects + address balance so the legacy `getCoins` page miss\n * doesn't break for users whose stables landed via gasless deposits.\n *\n * `asset` is REQUIRED (no implicit USDC default — pre-v4 hid LLM intent\n * errors). Callers passing the wrong asset get an explicit error rather\n * than a silent currency substitution.\n */\nexport async function buildSendTx({\n client,\n address,\n to,\n amount,\n asset,\n}: {\n client: SuiCoreClient;\n address: string;\n to: string;\n amount: number;\n asset: SendableAsset;\n}): Promise<Transaction> {\n // Layer 2 — cheap synchronous preflight (asset / amount / gasless floor /\n // recipient shape). Rethrow the precise code+message verbatim.\n const pf = preflightSend({ to, amount, asset });\n if (!pf.valid) throw new T2000Error(pf.code, pf.error);\n\n const recipient = validateAddress(to);\n const assetInfo = SUPPORTED_ASSETS[asset];\n if (!assetInfo) throw new T2000Error('ASSET_NOT_SUPPORTED', `Asset ${asset} is not supported`);\n\n const rawAmount = displayToRaw(amount, assetInfo.decimals);\n const tx = new Transaction();\n tx.setSender(address);\n\n // Balance pre-flight against `core.getBalance().balance.balance` (sums\n // coins + address balance). The legacy `getCoins` page miss broke for\n // users whose stables had drifted into address balance via @suimpp/mpp 0.7+.\n const balanceResp = await client.core.getBalance({ owner: address, coinType: assetInfo.type });\n const totalBalance = BigInt(balanceResp.balance.balance);\n if (totalBalance < rawAmount) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${asset} balance`, {\n available: Number(totalBalance) / 10 ** assetInfo.decimals,\n required: amount,\n });\n }\n\n if (asset === 'SUI') {\n // Standard gas-native transfer — split from the gas coin, transfer\n // the resulting object. NOT gasless (SUI is not on the protocol\n // allowlist for `balance::send_funds`).\n const [sendCoin] = tx.splitCoins(tx.gas, [rawAmount]);\n tx.transferObjects([sendCoin], recipient);\n return tx;\n }\n\n // USDC / USDsui — gasless via `0x2::balance::send_funds`. The gRPC\n // build resolver inspects this PTB shape at `tx.build()` time and,\n // when it matches the protocol allowlist, sets gasPrice=0/gasBudget=0\n // automatically. The Move signature is:\n // public fun send_funds<T>(balance: Balance<T>, recipient: address)\n // `tx.balance({ type, balance })` produces a Balance<T> input sourced\n // from the sender's address balance + coin objects (auto-merged).\n const coinType = GASLESS_STABLE_TYPES[asset];\n tx.moveCall({\n target: '0x2::balance::send_funds',\n typeArguments: [coinType],\n arguments: [\n tx.balance({ type: coinType, balance: rawAmount }),\n tx.pure.address(recipient),\n ],\n });\n return tx;\n}\n\n/**\n * Fragment-appender for the chain-mode send leg of SPEC 7 multi-write\n * Payment Intents. Consumes a coin reference produced by a previous\n * appender (e.g. `addWithdrawToTx`, `addSwapToTx`) and transfers it to\n * `recipient` within the same Payment Intent — no intermediate wallet\n * materialization.\n *\n * Codifies the hand-built send leg from\n * `scripts/smoke-spec7-withdraw-then-send.ts` (P2.1) into a typed\n * appender. SPEC 7 § \"Layer 1\" — P2.2b will register this in the\n * `WRITE_APPENDER_REGISTRY` under `send_transfer` for chain-mode\n * dispatch; the registry adapter will handle the wallet-fetch fallback\n * by delegating to `buildSendTx` when no upstream coin is available.\n *\n * For single-step send_transfer flows (no chained predecessor), use\n * `buildSendTx` directly — it builds a complete tx including the\n * wallet-coin selection / merge / split prelude.\n *\n * [v4.0 Phase A Day 2] Stays on the legacy `transferObjects` path\n * because chain-mode bundles are NEVER gasless — by definition they\n * combine multiple Move calls (`withdraw → send`, `swap → send`) which\n * fail the protocol allowlist check (only `balance::send_funds` and\n * a few related helpers are eligible). The bundled flow still works,\n * the user just pays gas (or has it sponsored by audric via Enoki).\n *\n * @returns void — the coin is consumed by `tx.transferObjects`. Callers\n * that need the post-transfer \"effective amount\" should rely on the\n * upstream appender's `effectiveAmount` (e.g. `addWithdrawToTx`'s\n * return), not on this appender.\n */\nexport function addSendToTx(\n tx: Transaction,\n coin: TransactionObjectArgument,\n recipient: string,\n): void {\n const validRecipient = validateAddress(recipient);\n tx.transferObjects([coin], validRecipient);\n}\n","import { MIST_PER_SUI, USDC_DECIMALS, SUPPORTED_ASSETS } from '../constants.js';\nimport type { SupportedAsset } from '../constants.js';\n\nexport function mistToSui(mist: bigint): number {\n return Number(mist) / Number(MIST_PER_SUI);\n}\n\nexport function suiToMist(sui: number): bigint {\n return BigInt(Math.round(sui * Number(MIST_PER_SUI)));\n}\n\nexport function usdcToRaw(amount: number): bigint {\n return BigInt(Math.round(amount * 10 ** USDC_DECIMALS));\n}\n\nexport function rawToUsdc(raw: bigint): number {\n return Number(raw) / 10 ** USDC_DECIMALS;\n}\n\nexport function stableToRaw(amount: number, decimals: number): bigint {\n return BigInt(Math.round(amount * 10 ** decimals));\n}\n\nexport function rawToStable(raw: bigint, decimals: number): number {\n return Number(raw) / 10 ** decimals;\n}\n\nexport function getDecimals(asset: SupportedAsset): number {\n return SUPPORTED_ASSETS[asset].decimals;\n}\n\nexport function rawToDisplay(raw: bigint, decimals: number): number {\n return Number(raw) / 10 ** decimals;\n}\n\nexport function displayToRaw(amount: number, decimals: number): bigint {\n return BigInt(Math.round(amount * 10 ** decimals));\n}\n\nexport function formatUsd(amount: number): string {\n return `$${amount.toFixed(2)}`;\n}\n\nexport function formatSui(amount: number): string {\n if (amount < 0.001) return `${amount.toFixed(6)} SUI`;\n return `${amount.toFixed(3)} SUI`;\n}\n\nexport function formatLargeNumber(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return n.toFixed(2);\n}\n\nexport function formatAssetAmount(amount: number, asset: string): string {\n if (asset === 'BTC') return amount.toFixed(8);\n if (asset === 'GOLD') return amount.toFixed(6);\n if (asset === 'ETH') return amount.toFixed(6);\n return amount.toFixed(4);\n}\n\nconst ASSET_LOOKUP: Map<string, string> = new Map();\nfor (const [key, info] of Object.entries(SUPPORTED_ASSETS)) {\n ASSET_LOOKUP.set(key.toUpperCase(), key);\n if (info.displayName && info.displayName.toUpperCase() !== key.toUpperCase()) {\n ASSET_LOOKUP.set(info.displayName.toUpperCase(), key);\n }\n}\n\n/**\n * Case-insensitive lookup against SUPPORTED_ASSETS keys AND display names.\n * 'usde' → 'USDe', 'suiusde' → 'USDe', 'suiusdt' → 'USDT', 'usdsui' → 'USDsui'.\n * Returns the original input if not found so downstream validation can reject it.\n */\nexport function normalizeAsset(input: string): string {\n return ASSET_LOOKUP.get(input.toUpperCase()) ?? input;\n}\n","import { normalizeStructTag } from '@mysten/sui/utils';\nimport { SUPPORTED_ASSETS, STABLE_ASSETS, MIST_PER_SUI, CETUS_USDC_SUI_POOL } from '../constants.js';\nimport type { StableAsset } from '../constants.js';\nimport { resolveSymbol, resolveCoinDecimals } from '../token-registry.js';\nimport type { SuiCoreClient } from '../utils/sui.js';\nimport type { BalanceResponse, TokenHolding } from '../types.js';\n\nconst SUI_PRICE_FALLBACK = 1.0;\nlet _cachedSuiPrice = 0;\nlet _priceLastFetched = 0;\nconst PRICE_CACHE_TTL_MS = 60_000;\n\n/**\n * Fetch SUI price in USD from the Cetus USDC/SUI pool's sqrt_price.\n *\n * Pool is Pool<USDC, SUI> so coin_a = USDC (6 dec), coin_b = SUI (9 dec).\n * current_sqrt_price (Q64 fixed-point) encodes sqrt(raw_price) where\n * raw_price = SUI_raw / USDC_raw.\n *\n * USDC per SUI = 10^(decimals_a - decimals_b) / raw_price\n * = 10^(6-9) / raw_price\n * = 1 / (raw_price * 1000)\n *\n * Equivalently: 1000 / raw_price\n */\nasync function fetchSuiPrice(client: SuiCoreClient): Promise<number> {\n const now = Date.now();\n if (_cachedSuiPrice > 0 && now - _priceLastFetched < PRICE_CACHE_TTL_MS) {\n return _cachedSuiPrice;\n }\n\n try {\n // [gRPC migration] `core.getObject` returns BCS content; request `json`\n // to read parsed Move fields (the legacy `content.fields` path is gone).\n const pool = await client.core.getObject({\n objectId: CETUS_USDC_SUI_POOL,\n include: { json: true },\n });\n\n const fields = pool.object?.json as Record<string, unknown> | null | undefined;\n if (fields) {\n const currentSqrtPrice = BigInt(String(fields.current_sqrt_price ?? '0'));\n\n if (currentSqrtPrice > 0n) {\n const Q64 = 2n ** 64n;\n const sqrtPriceFloat = Number(currentSqrtPrice) / Number(Q64);\n const rawPrice = sqrtPriceFloat * sqrtPriceFloat;\n const price = 1000 / rawPrice;\n if (price > 0.01 && price < 1000) {\n _cachedSuiPrice = price;\n _priceLastFetched = now;\n }\n }\n }\n } catch {\n // Use cached/fallback price\n }\n\n return _cachedSuiPrice || SUI_PRICE_FALLBACK;\n}\n\nfunction safeNorm(coinType: string): string {\n try {\n return normalizeStructTag(coinType);\n } catch {\n return coinType;\n }\n}\n\nconst SUI_TYPE_NORM = safeNorm(SUPPORTED_ASSETS.SUI.type);\nconst STABLE_BY_NORM: Record<string, StableAsset> = (() => {\n const m: Record<string, StableAsset> = {};\n for (const asset of STABLE_ASSETS) m[safeNorm(SUPPORTED_ASSETS[asset].type)] = asset;\n return m;\n})();\n\n/**\n * Full wallet balance: **every** held coin, not just the curated stables + SUI.\n *\n * Uses one `listBalances` (paginated) instead of N `getBalance` calls, then\n * partitions: stables → priced $1, SUI → Cetus-oracle priced, **everything else\n * → `tokens[]` amount-only** (`usdValue: null` — no price oracle for arbitrary\n * tokens; we don't guess). Decimals for non-registry tokens are read on-chain\n * (the only added call, and only for tokens you actually hold — necessary for a\n * correct amount). `totalUsd` sums **priced holdings only** so it never\n * overstates; `tokens` surfaces the rest honestly.\n */\nexport async function queryBalance(\n client: SuiCoreClient,\n address: string,\n): Promise<BalanceResponse> {\n const held: Array<{ coinType: string; raw: bigint }> = [];\n let cursor: string | null | undefined;\n do {\n const page = await client.core.listBalances({ owner: address, cursor: cursor ?? undefined });\n for (const b of page.balances) {\n const raw = BigInt(b.balance);\n if (raw > 0n) held.push({ coinType: b.coinType, raw });\n }\n cursor = page.hasNextPage ? page.cursor : null;\n } while (cursor);\n\n const suiPriceUsd = await fetchSuiPrice(client);\n\n const stables = {} as Record<StableAsset, number>;\n for (const asset of STABLE_ASSETS) stables[asset] = 0;\n let totalStables = 0;\n let suiAmount = 0;\n const otherCoins: Array<{ coinType: string; raw: bigint }> = [];\n\n for (const { coinType, raw } of held) {\n const norm = safeNorm(coinType);\n if (norm === SUI_TYPE_NORM) {\n suiAmount = Number(raw) / Number(MIST_PER_SUI);\n } else if (STABLE_BY_NORM[norm]) {\n const asset = STABLE_BY_NORM[norm];\n const amount = Number(raw) / 10 ** SUPPORTED_ASSETS[asset].decimals;\n stables[asset] = amount;\n totalStables += amount;\n } else {\n otherCoins.push({ coinType, raw });\n }\n }\n\n // Non-stable, non-SUI holdings — amount-only (no price oracle). Decimals come\n // from the registry (no call) or on-chain coin metadata (unknown tokens only).\n const tokens: TokenHolding[] = await Promise.all(\n otherCoins.map(async ({ coinType, raw }) => {\n const decimals = await resolveCoinDecimals(client, coinType);\n return {\n coinType,\n symbol: resolveSymbol(coinType),\n amount: Number(raw) / 10 ** decimals,\n usdValue: null,\n };\n }),\n );\n tokens.sort((a, b) => a.symbol.localeCompare(b.symbol));\n\n const suiUsdValue = suiAmount * suiPriceUsd;\n\n return {\n stables,\n available: totalStables,\n sui: { amount: suiAmount, usdValue: suiUsdValue },\n tokens,\n totalUsd: totalStables + suiUsdValue,\n };\n}\n","/**\n * Shared transaction classifier.\n *\n * Consumed by both the SDK's `parseTxRecord` (production agent path) and\n * the engine's `transaction_history` tool (cold-start RPC path). Keeping\n * a single source of truth here prevents the two paths from drifting —\n * see v1.5.3 regression where the SDK path was emitting `action:\n * 'transaction'` (rendered as \"On-chain\") while the engine path was\n * already producing fine-grained labels.\n */\n\nimport { getDecimalsForCoinType, resolveSymbol, SUI_TYPE } from '../token-registry.js';\n\n/**\n * Coarse action bucket — one of `'send' | 'lending' | 'swap' |\n * 'transaction'`. Used by the ACI `action` filter on the\n * `transaction_history` tool. STABLE: downstream queries depend on\n * exactly these values.\n *\n * Order matters: more specific buckets first. Lending patterns precede\n * swap patterns so a NAVI `::swap` helper (if one ever existed) would\n * still bucket as lending.\n */\nexport const KNOWN_TARGETS: readonly [RegExp, string][] = [\n [/::suilend|::obligation/, 'lending'],\n [/::navi|::lending_core|::incentive_v\\d+|::oracle_pro/, 'lending'],\n /**\n * DEX modules — both direct calls and aggregator legs. The Cetus\n * aggregator dispatches through a per-DEX module (e.g.\n * `cetus::swap`, `flowx_amm::swap`, `aftermath::swap`, …) plus\n * router glue functions. We list every DEX module the aggregator\n * supports today so a single-DEX call still classifies cleanly.\n */\n [/::cetus(?:_dlmm)?::|::pool::|::deepbook|::flowx_(?:amm|clmm)::|::kriya_(?:amm|clmm)::|::turbos::|::aftermath::|::afsui::|::bluefin::|::bluemove::|::ferra_(?:clmm|dlmm)::|::haedal_hmm::|::hasui::|::hawal::|::magma::|::momentum::|::obric::|::springsui::|::steamm_cpmm::|::fullsail::|::alphafi::|::volo_swap::/, 'swap'],\n /**\n * Cetus aggregator router glue. These are the swap-context and\n * balance-handling helpers the aggregator emits around per-DEX\n * legs. Without this entry a tx that ONLY had router calls\n * (theoretically possible for setup/cleanup) would slip through;\n * in practice these always coexist with a DEX leg, but the entry\n * is cheap insurance.\n */\n [/::router::(?:new_swap_context(?:_v)?|confirm_swap|transfer_balance|take_balance|transfer_or_destroy_coin)/, 'swap'],\n [/::transfer::public_transfer/, 'send'],\n];\n\n/**\n * Finer-grained display labels — derived from MoveCall function names.\n * The card renders `label ?? action`, so when this map matches we get\n * \"Deposit\" / \"Withdraw\" / \"Borrow\" / \"Repay\" / \"Payment link\" instead\n * of the generic \"Lending\" or \"Transaction\".\n *\n * Order matters: more specific patterns first. Each entry is\n * (regex, label) where the regex is matched against the\n * fully-qualified MoveCall target `pkg::module::function`.\n */\nexport const LABEL_PATTERNS: readonly [RegExp, string][] = [\n [/::pay(?:ment_kit|_kit)?::|::create_payment_link|::pay_link/, 'payment_link'],\n [/::create_invoice|::invoice::/, 'invoice'],\n [/::deposit|::supply|::mint_ctokens/, 'deposit'],\n [/::withdraw|::redeem|::redeem_ctokens/, 'withdraw'],\n [/::borrow/, 'borrow'],\n [/::repay/, 'repay'],\n [/::claim_reward|::claim::|::claim_incentive/, 'claim'],\n [/::stake/, 'stake'],\n [/::unstake|::burn::/, 'unstake'],\n [/::liquidate/, 'liquidate'],\n];\n\nexport interface ClassifyBalanceChange {\n owner: { AddressOwner?: string } | string;\n coinType: string;\n amount: string;\n}\n\nfunction resolveOwner(owner: ClassifyBalanceChange['owner']): string | null {\n if (typeof owner === 'object' && owner.AddressOwner) return owner.AddressOwner;\n if (typeof owner === 'string') return owner;\n return null;\n}\n\nexport function classifyAction(targets: string[], commandTypes: string[]): string {\n for (const target of targets) {\n for (const [pattern, label] of KNOWN_TARGETS) {\n if (pattern.test(target)) return label;\n }\n }\n if (commandTypes.includes('TransferObjects') && !commandTypes.includes('MoveCall')) return 'send';\n return 'transaction';\n}\n\n/**\n * Last-resort fallback when neither `LABEL_PATTERNS` nor the action\n * bucket produces something useful.\n *\n * Returns the first MoveCall's *module* name (e.g. \"navi\", \"spam\") so\n * the card shows something better than the literal word \"transaction\".\n * When no MoveCall exists, returns 'on-chain'.\n *\n * Note: callers should prefer `classifyLabel` which now layers\n * pattern-match → coarse action → module name (see commentary there).\n */\nexport function fallbackLabel(targets: string[]): string {\n if (!targets.length) return 'on-chain';\n const first = targets[0];\n const parts = first.split('::');\n if (parts.length >= 2 && parts[1]) return parts[1].toLowerCase();\n return 'on-chain';\n}\n\n/**\n * Three-tier label resolution for the transaction history card:\n * 1. Specific keyword match in `LABEL_PATTERNS` (\"deposit\",\n * \"payment_link\", …).\n * 2. Coarse action bucket from `classifyAction` (\"swap\", \"send\",\n * \"lending\") — prevents leaking opaque internal module names like\n * \"router\" (Cetus aggregator) or \"cross_swap\" (third-party DEX\n * aggregators) for txs that we already classified as a swap.\n * 3. Module name from the first MoveCall (`fallbackLabel`) — only\n * used when the action bucket itself is the generic \"transaction\".\n *\n * Pre-v0.46.2 we skipped tier 2, so swaps showed labels like \"router\",\n * \"cross_swap\", \"scallop_router\", etc. instead of the clean \"swap\".\n */\nexport function classifyLabel(targets: string[], commandTypes: string[]): string {\n for (const target of targets) {\n for (const [pattern, label] of LABEL_PATTERNS) {\n if (pattern.test(target)) return label;\n }\n }\n if (commandTypes.includes('TransferObjects') && !commandTypes.includes('MoveCall')) return 'send';\n const action = classifyAction(targets, commandTypes);\n if (action !== 'transaction') return action;\n return fallbackLabel(targets);\n}\n\n/**\n * Balance-direction tiebreaker for ambiguous lending calls.\n *\n * Many lending modules expose generic entry points (NAVI's bundled\n * flash actions, `lending_core::*::entry_*`, etc.) that don't carry\n * a `deposit`/`withdraw`/`borrow`/`repay` keyword in the function\n * name. When `classifyLabel` falls back to a bare module name like\n * `\"lending\"` for a known lending tx, infer direction from the user's\n * non-SUI balance change:\n * - net outflow of the supplied asset → deposit (also covers repay,\n * but repay-without-keyword is essentially never emitted).\n * - net inflow of the supplied asset → withdraw (also covers borrow).\n * SUI is excluded so gas-only transactions don't get mislabeled.\n *\n * If `LABEL_PATTERNS` matched a specific keyword, the existing label is\n * returned unchanged.\n */\nexport function refineLendingLabel(\n currentAction: string,\n currentLabel: string,\n moveCallTargets: string[],\n changes: ClassifyBalanceChange[],\n address: string,\n): string {\n if (currentAction !== 'lending') return currentLabel;\n const labelMatchedSpecific = LABEL_PATTERNS.some(([p]) =>\n moveCallTargets.some((t) => p.test(t)),\n );\n if (labelMatchedSpecific) return currentLabel;\n\n const userNonSuiOutflow = changes.find(\n (c) => resolveOwner(c.owner) === address && c.coinType !== SUI_TYPE && BigInt(c.amount) < 0n,\n );\n if (userNonSuiOutflow) return 'deposit';\n\n const userNonSuiInflow = changes.find(\n (c) => resolveOwner(c.owner) === address && c.coinType !== SUI_TYPE && BigInt(c.amount) > 0n,\n );\n if (userNonSuiInflow) return 'withdraw';\n\n return currentLabel;\n}\n\nexport interface ClassifyResult {\n action: string;\n label: string;\n}\n\nexport function classifyTransaction(\n moveCallTargets: string[],\n commandTypes: string[],\n balanceChanges: ClassifyBalanceChange[],\n address: string,\n): ClassifyResult {\n const action = classifyAction(moveCallTargets, commandTypes);\n const baseLabel = classifyLabel(moveCallTargets, commandTypes);\n const label = refineLendingLabel(action, baseLabel, moveCallTargets, balanceChanges, address);\n return { action, label };\n}\n\n/**\n * Direction of the user's net non-gas movement for this transaction.\n *\n * - `'out'` — the user spent the asset (sends, deposits, repays,\n * swap-in, payment-link payouts).\n * - `'in'` — the user received the asset (withdraws, borrows,\n * swap-out, claims, deposits credited from another wallet).\n *\n * Used by the `TransactionHistoryCard` to choose the `+`/`−` sign and\n * color. Direction is computed from the actual on-chain balance change\n * — never from the textual label — so opaque action types (`'router'`,\n * `'cross_swap'`, …) still render the correct sign.\n */\nexport type TxDirection = 'in' | 'out';\n\nexport interface ExtractedTransfer {\n amount?: number;\n asset?: string;\n recipient?: string;\n direction?: TxDirection;\n}\n\n/**\n * Extracts the principal amount/asset/direction for a transaction\n * from its `balanceChanges`.\n *\n * Algorithm:\n * 1. Restrict to the user's *own* balance changes.\n * 2. Prefer non-SUI changes (gas-only SUI deltas are noise).\n * 3. Pick the change with the largest absolute value — the \"principal\".\n * 4. If no non-SUI change exists, fall back to the largest SUI change\n * so pure-SUI transfers (stake/unstake/native send) still render.\n * 5. Direction follows the sign of the principal.\n * 6. Recipient is set only on outflows, by finding a matching inflow\n * on a *non-user* address with the same coinType.\n *\n * Pre-v0.46.2 this function only inspected outflows, so withdraws,\n * borrows, claims, swap-receives and payment-link receives all\n * rendered with no amount on the rich card (and with a wrong sign,\n * because the card guessed direction from the label string).\n */\nexport function extractTransferDetails(\n changes: ClassifyBalanceChange[] | undefined,\n sender: string,\n): ExtractedTransfer {\n if (!changes || changes.length === 0) return {};\n\n const userChanges = changes.filter((c) => resolveOwner(c.owner) === sender);\n if (userChanges.length === 0) return {};\n\n const userNonSui = userChanges.filter((c) => c.coinType !== SUI_TYPE);\n const pool = userNonSui.length > 0 ? userNonSui : userChanges;\n\n let primary = pool[0];\n let primaryAbs = bigintAbs(BigInt(primary.amount));\n for (let i = 1; i < pool.length; i++) {\n const abs = bigintAbs(BigInt(pool[i].amount));\n if (abs > primaryAbs) {\n primary = pool[i];\n primaryAbs = abs;\n }\n }\n\n const raw = BigInt(primary.amount);\n if (raw === 0n) return {};\n\n const decimals = getDecimalsForCoinType(primary.coinType);\n const amount = Number(primaryAbs) / 10 ** decimals;\n const asset = resolveSymbol(primary.coinType);\n const direction: TxDirection = raw < 0n ? 'out' : 'in';\n\n let recipient: string | undefined;\n if (direction === 'out') {\n const recipientChange = changes.find(\n (c) =>\n resolveOwner(c.owner) !== sender &&\n c.coinType === primary.coinType &&\n BigInt(c.amount) > 0n,\n );\n recipient = recipientChange ? resolveOwner(recipientChange.owner) ?? undefined : undefined;\n }\n\n return { amount, asset, recipient, direction };\n}\n\nfunction bigintAbs(n: bigint): bigint {\n return n < 0n ? -n : n;\n}\n\n/**\n * Extract every non-zero user balance leg for a transaction — not\n * just the largest one. Order is RPC order; callers responsible for\n * any sorting (e.g. audric sorts by USD value once it's priced).\n *\n * Sui collapses balance changes by coin type, so a 3-step bundle\n * touching USDC three times surfaces as ONE leg of net USDC delta.\n * Distinguishing per-step legs would require parsing the PTB's\n * commands; this helper deliberately stops at the balance-change\n * granularity because that's what's reliably available across all\n * Sui RPC versions.\n *\n * Pre-v1.27.2 the only public API was `extractTransferDetails`,\n * which returned a single \"primary\" leg and made swap rows\n * unrenderable (showed `Swapped 987.60 MANIFEST` because MANIFEST\n * was the largest raw delta even though USDC was the value side).\n */\nexport function extractAllUserLegs(\n changes: ClassifyBalanceChange[] | undefined,\n sender: string,\n): import('../types.js').TransactionLeg[] {\n if (!changes || changes.length === 0) return [];\n\n const legs: import('../types.js').TransactionLeg[] = [];\n for (const c of changes) {\n if (resolveOwner(c.owner) !== sender) continue;\n const raw = BigInt(c.amount);\n if (raw === 0n) continue;\n const decimals = getDecimalsForCoinType(c.coinType);\n const absAmount = bigintAbs(raw);\n legs.push({\n coinType: c.coinType,\n asset: resolveSymbol(c.coinType),\n decimals,\n amount: Number(absAmount) / 10 ** decimals,\n rawAmount: raw.toString(),\n direction: raw < 0n ? 'out' : 'in',\n });\n }\n\n return legs;\n}\n","import type { TransactionRecord } from '../types.js';\nimport { getSuiGraphQLClient } from '../utils/sui.js';\nimport {\n classifyTransaction,\n extractAllUserLegs,\n extractTransferDetails,\n type ClassifyBalanceChange,\n} from './classify.js';\n\n// ---------------------------------------------------------------------------\n// [gRPC migration / S.447 + S.450] Transaction history is the one surface with\n// NO gRPC `core.*` equivalent (Stage 0 finding A): list-by-affected-address +\n// per-tx-by-digest live in the GraphQL RPC, not gRPC. Both go through the\n// Sui GraphQL endpoint (`getSuiGraphQLClient()`), share one node fragment +\n// one mapper, and feed the existing (tested) classifier in `classify.ts`.\n//\n// LIVE-VERIFIED 2026-06-15 (S.450) against `graphql.mainnet.sui.io` with a\n// real sender (send + Cetus swap digests). The live schema differs from the\n// older `transactionBlocks` one: the query is `transactions` / `transaction`\n// (filter `affectedAddress` — sender, sponsor, or recipient), the programmable kind is `ProgrammableTransaction`\n// (was `ProgrammableTransactionBlock`) with `commands { nodes }` (was\n// `transactions`), and a move call is `MoveCallCommand` with a nested\n// `function { name module { name package { address } } }` (was a flat\n// `MoveCallTransaction { package module functionName }`). GraphQL errors are\n// now SURFACED, not swallowed (the old `?? []` hid this schema drift as an\n// empty history for a whole session). Schema ref: https://docs.sui.io/references/sui-graphql\n// ---------------------------------------------------------------------------\n\nconst TX_NODE_FRAGMENT = `\n digest\n effects {\n timestamp\n gasEffects { gasSummary { computationCost storageCost storageRebate } }\n balanceChanges { nodes { amount coinType { repr } owner { address } } }\n }\n kind {\n __typename\n ... on ProgrammableTransaction {\n commands {\n nodes {\n __typename\n ... on MoveCallCommand { function { name module { name package { address } } } }\n }\n }\n }\n }\n`;\n\n// `affectedAddress` (not `sentAddress`) so history includes INCOMING transactions\n// — received payments, x402/MPP refunds, airdrops — not just ones the agent\n// signed. Per the Sui GraphQL schema: \"transactions that interacted with the\n// given address … as a sender, sponsor, or recipient.\" The shared classifier\n// already labels each leg's direction ('in' / 'out'), so inbound txns render\n// correctly downstream.\nconst HISTORY_QUERY = `query History($address: SuiAddress!, $last: Int!) {\n transactions(last: $last, filter: { affectedAddress: $address }) {\n nodes {${TX_NODE_FRAGMENT}}\n }\n}`;\n\nconst TX_BY_DIGEST_QUERY = `query TxByDigest($digest: String!) {\n transaction(digest: $digest) {${TX_NODE_FRAGMENT}}\n}`;\n\n/** Minimal shape of a Sui GraphQL transaction node we consume. */\ninterface GqlTxNode {\n digest?: string;\n effects?: {\n timestamp?: string;\n // Live schema returns gas as numbers; `Number()` in the mapper tolerates both.\n gasEffects?: { gasSummary?: { computationCost?: string | number; storageCost?: string | number; storageRebate?: string | number } };\n balanceChanges?: { nodes?: Array<{ amount?: string; coinType?: { repr?: string }; owner?: { address?: string } }> };\n };\n kind?: {\n __typename?: string;\n commands?: {\n nodes?: Array<{\n __typename?: string;\n function?: { name?: string; module?: { name?: string; package?: { address?: string } } };\n }>;\n };\n };\n}\n\n/** GraphQL transport result with the optional `errors` array surfaced. */\ninterface GqlResult<T> {\n data?: T;\n errors?: Array<{ message?: string }>;\n}\n\nfunction assertNoGqlErrors(res: GqlResult<unknown>, what: string): void {\n if (res.errors?.length) {\n throw new Error(\n `Sui GraphQL ${what} failed: ${res.errors.map((e) => e.message ?? 'unknown error').join('; ')}`,\n );\n }\n}\n\nexport async function queryHistory(\n address: string,\n limit = 20,\n): Promise<TransactionRecord[]> {\n const gql = getSuiGraphQLClient();\n const res = (await gql.query({ query: HISTORY_QUERY, variables: { address, last: limit } })) as GqlResult<{\n transactions?: { nodes?: GqlTxNode[] };\n }>;\n assertNoGqlErrors(res, 'history query');\n const nodes = res.data?.transactions?.nodes ?? [];\n // GraphQL `last` returns ascending; the legacy JSON-RPC path returned\n // descending (newest first) — reverse to preserve caller expectations.\n return nodes.map((n) => recordFromGqlNode(n, address)).reverse();\n}\n\nexport async function queryTransaction(\n digest: string,\n senderAddress: string,\n): Promise<TransactionRecord | null> {\n const gql = getSuiGraphQLClient();\n const res = (await gql.query({ query: TX_BY_DIGEST_QUERY, variables: { digest } })) as GqlResult<{\n transaction?: GqlTxNode | null;\n }>;\n assertNoGqlErrors(res, 'transaction query');\n const node = res.data?.transaction;\n if (!node) return null; // genuine not-found (distinct from a query error, which throws above)\n return recordFromGqlNode(node, senderAddress);\n}\n\n/**\n * Map a Sui GraphQL transactionBlock node → the primitives the shared\n * classifier consumes, then build the record. Isolated so the legacy\n * JSON-RPC `parseTxRecord` (back-compat, below) and this GraphQL path\n * converge on one classification routine.\n */\nfunction recordFromGqlNode(node: GqlTxNode, address: string): TransactionRecord {\n const gs = node.effects?.gasEffects?.gasSummary;\n const gasCost = gs\n ? (Number(gs.computationCost ?? 0) + Number(gs.storageCost ?? 0) - Number(gs.storageRebate ?? 0)) / 1e9\n : undefined;\n\n const balanceChanges: ClassifyBalanceChange[] = (node.effects?.balanceChanges?.nodes ?? [])\n .filter((b) => b.coinType?.repr && b.amount != null)\n .map((b) => ({ coinType: b.coinType!.repr!, amount: String(b.amount), owner: b.owner?.address ?? '' }));\n\n const moveCallTargets: string[] = [];\n const commandTypes: string[] = [];\n if (node.kind?.__typename === 'ProgrammableTransaction') {\n for (const cmd of node.kind.commands?.nodes ?? []) {\n if (cmd.__typename === 'MoveCallCommand') {\n commandTypes.push('MoveCall');\n const fn = cmd.function;\n const pkg = fn?.module?.package?.address;\n const mod = fn?.module?.name;\n const name = fn?.name;\n if (pkg && mod && name) {\n moveCallTargets.push(`${pkg}::${mod}::${name}`);\n }\n } else if (cmd.__typename === 'TransferObjectsCommand') {\n commandTypes.push('TransferObjects');\n }\n }\n }\n\n // GraphQL effects.timestamp is an ISO datetime; the record wants ms.\n const ts = node.effects?.timestamp ? Date.parse(node.effects.timestamp) : 0;\n\n return buildRecord({\n digest: node.digest ?? '',\n moveCallTargets,\n commandTypes,\n balanceChanges,\n timestampMs: Number.isFinite(ts) ? ts : 0,\n gasCost,\n address,\n });\n}\n\n/** Shared record builder — classification + leg/transfer extraction. */\nfunction buildRecord(args: {\n digest: string;\n moveCallTargets: string[];\n commandTypes: string[];\n balanceChanges: ClassifyBalanceChange[];\n timestampMs: number;\n gasCost: number | undefined;\n address: string;\n}): TransactionRecord {\n const { digest, moveCallTargets, commandTypes, balanceChanges, timestampMs, gasCost, address } = args;\n const legs = extractAllUserLegs(balanceChanges, address);\n const { amount, asset, recipient, direction } = extractTransferDetails(balanceChanges, address);\n const { action, label } = classifyTransaction(moveCallTargets, commandTypes, balanceChanges, address);\n return { digest, action, label, legs, amount, asset, recipient, direction, timestamp: timestampMs, gasCost };\n}\n\n/**\n * Shape of a transaction block as returned by `suix_queryTransactionBlocks`\n * with `showEffects | showInput | showBalanceChanges` enabled. Exported so\n * downstream consumers (audric dashboard `/api/history`, `/api/activity`,\n * etc.) can type their RPC calls without redeclaring the structure.\n */\nexport interface SuiRpcTxBlock {\n digest: string;\n timestampMs?: string;\n transaction?: unknown;\n effects?: { gasUsed?: { computationCost: string; storageCost: string; storageRebate: string } };\n balanceChanges?: ClassifyBalanceChange[];\n}\n\n/**\n * Convert a single Sui RPC transaction block to a {@link TransactionRecord}\n * using the canonical (shared) classifier and balance-change extractor.\n *\n * This is the single source of truth for transaction parsing across the\n * agent-tool path AND the dashboard-API path. Use it instead of writing\n * a bespoke parser per surface.\n *\n * @param tx Raw RPC tx block (must include `effects`, `input`, `balanceChanges`).\n * @param address Wallet address whose perspective we're parsing from.\n */\nexport function parseSuiRpcTx(tx: SuiRpcTxBlock, address: string): TransactionRecord {\n return parseTxRecord(tx, address);\n}\n\n/**\n * Extract the sender (signer) address from a raw RPC tx block.\n * Returns `null` if the block shape is unexpected.\n */\nexport function extractTxSender(txBlock: unknown): string | null {\n try {\n if (!txBlock || typeof txBlock !== 'object') return null;\n const data = 'data' in txBlock ? (txBlock as Record<string, unknown>).data : undefined;\n if (!data || typeof data !== 'object') return null;\n return ((data as Record<string, unknown>).sender as string) ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract MoveCall targets (`<pkg>::<module>::<function>`) and the\n * sequence of programmable-transaction command types (e.g. `MoveCall`,\n * `TransferObjects`) from a raw RPC tx block. Tolerates both the\n * legacy `inner.transactions` field and the newer `inner.commands`\n * field.\n */\nexport function extractTxCommands(txBlock: unknown): {\n moveCallTargets: string[];\n commandTypes: string[];\n} {\n return extractCommands(txBlock);\n}\n\n// [back-compat] Legacy JSON-RPC-shape parser. The live history path is now\n// GraphQL (above); this stays for external consumers that already hold a\n// JSON-RPC tx block (e.g. via `parseSuiRpcTx`). Routes through `buildRecord`\n// so classification is identical to the GraphQL path.\nfunction parseTxRecord(tx: SuiRpcTxBlock, address: string): TransactionRecord {\n const gasUsed = tx.effects?.gasUsed;\n const gasCost = gasUsed\n ? (Number(gasUsed.computationCost) +\n Number(gasUsed.storageCost) -\n Number(gasUsed.storageRebate)) /\n 1e9\n : undefined;\n\n const { moveCallTargets, commandTypes } = extractCommands(tx.transaction);\n return buildRecord({\n digest: tx.digest,\n moveCallTargets,\n commandTypes,\n balanceChanges: tx.balanceChanges ?? [],\n timestampMs: Number(tx.timestampMs ?? 0),\n gasCost,\n address,\n });\n}\n\ninterface CommandInfo {\n moveCallTargets: string[];\n commandTypes: string[];\n}\n\nfunction extractCommands(txBlock: unknown): CommandInfo {\n const result: CommandInfo = { moveCallTargets: [], commandTypes: [] };\n try {\n if (!txBlock || typeof txBlock !== 'object') return result;\n const data = 'data' in txBlock ? (txBlock as Record<string, unknown>).data : undefined;\n if (!data || typeof data !== 'object') return result;\n const inner = 'transaction' in (data as Record<string, unknown>)\n ? (data as Record<string, unknown>).transaction\n : undefined;\n if (!inner || typeof inner !== 'object') return result;\n const commands = 'commands' in (inner as Record<string, unknown>)\n ? (inner as Record<string, unknown>).commands\n : 'transactions' in (inner as Record<string, unknown>)\n ? (inner as Record<string, unknown>).transactions\n : undefined;\n if (!Array.isArray(commands)) return result;\n\n for (const cmd of commands as Record<string, unknown>[]) {\n if (cmd.MoveCall) {\n const mc = cmd.MoveCall as { package: string; module: string; function: string };\n result.moveCallTargets.push(`${mc.package}::${mc.module}::${mc.function}`);\n result.commandTypes.push('MoveCall');\n } else if (cmd.TransferObjects) {\n result.commandTypes.push('TransferObjects');\n }\n }\n } catch { /* best effort */ }\n return result;\n}\n","import { EventEmitter } from 'eventemitter3';\nimport type { SuiGrpcClient } from '@mysten/sui/grpc';\nimport type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction, coinWithBalance, type TransactionObjectArgument } from '@mysten/sui/transactions';\nimport { createPaymentTransactionUri } from '@mysten/payment-kit';\nimport { getSuiClient, getSuiGrpcClient } from './utils/sui.js';\nimport {\n generateKeypair,\n keypairFromPrivateKey,\n saveKey,\n loadKey,\n walletExists,\n exportPrivateKey,\n getAddress,\n} from './wallet/keyManager.js';\nimport type { TransactionSigner } from './signer.js';\nimport { KeypairSigner } from './wallet/keypairSigner.js';\nimport { executeTx } from './wallet/executeTx.js';\nimport { payWithMpp } from './wallet/pay.js';\nimport { ZkLoginSigner, type ZkLoginProof } from './wallet/zkLoginSigner.js';\nimport { buildSendTx } from './wallet/send.js';\nimport { queryBalance } from './wallet/balance.js';\nimport { queryHistory, queryTransaction } from './wallet/history.js';\nimport { resolveSymbol, resolveCoinDecimals } from './token-registry.js';\nimport {\n SUI_ADDRESS_REGEX,\n SuinsNotRegisteredError,\n looksLikeSuiNs,\n resolveSuinsViaRpc,\n} from './utils/suins.js';\n// [B5 v2 / 2026-04-30] No fee imports — CLI / direct SDK is fee-free. Consumer\n// apps (Audric) own fee policy (Cetus `overlayFee` on swaps → T2000_OVERLAY_FEE_WALLET).\nimport type {\n T2000Options,\n BalanceResponse,\n SendResult,\n TransactionRecord,\n DepositInfo,\n PaymentRequest,\n PayOptions,\n PayResult,\n SwapResult,\n SwapQuoteResult,\n} from './types.js';\nimport { T2000Error } from './errors.js';\nimport {\n chatCompletion,\n chatCompletionStream,\n listModels,\n type ApiModel,\n type ChatParams,\n type ChatResult,\n} from './inference.js';\nimport { verifyReceipt, type VerifyOptions, type VerifyResult } from './verify.js';\nimport { SUPPORTED_ASSETS, assertAllowedAsset, type SendableAsset, type SupportedAsset } from './constants.js';\n\nimport { truncateAddress } from './utils/sui.js';\nimport { LimitEnforcer, approxUsdValue } from './limits/index.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.t2000');\n\ninterface T2000Events {\n balanceChange: (event: { asset: string; previous: number; current: number; cause: string; tx?: string }) => void;\n healthWarning: (event: { healthFactor: number; threshold: number; severity: 'warning' }) => void;\n healthCritical: (event: { healthFactor: number; threshold: number; severity: 'critical' }) => void;\n yield: (event: { earned: number; total: number; apy: number; timestamp: number }) => void;\n error: (error: T2000Error) => void;\n}\n\n// Sign + execute a transaction with the agent's signer. Replaces the pre-v2 gas\n// manager — every transaction is now self-funded by the agent's wallet.\nexport class T2000 extends EventEmitter<T2000Events> {\n private readonly _signer: TransactionSigner;\n private readonly _keypair?: Ed25519Keypair;\n private readonly client: SuiGrpcClient;\n private readonly _address: string;\n /** Unified spending-limit gate (per-tx + cumulative daily, USD). Shared by\n * CLI + MCP + programmatic writes — one gate, no bypass (R-0 Finding 1). */\n readonly limits: LimitEnforcer;\n\n private constructor(keypair: Ed25519Keypair, client: SuiGrpcClient, configDir?: string);\n private constructor(signer: TransactionSigner, client: SuiGrpcClient, configDir: string | undefined, isSignerMode: true);\n private constructor(\n keypairOrSigner: Ed25519Keypair | TransactionSigner,\n client: SuiGrpcClient,\n configDir?: string,\n isSignerMode?: boolean,\n ) {\n super();\n if (isSignerMode) {\n this._signer = keypairOrSigner as TransactionSigner;\n this._keypair = undefined;\n this._address = this._signer.getAddress();\n } else {\n const kp = keypairOrSigner as Ed25519Keypair;\n this._keypair = kp;\n this._signer = new KeypairSigner(kp);\n this._address = getAddress(kp);\n }\n this.client = client;\n this.limits = new LimitEnforcer(configDir);\n }\n\n static async create(options: T2000Options = {}): Promise<T2000> {\n const { keyPath, rpcUrl } = options;\n\n const client = getSuiClient(rpcUrl);\n\n const exists = await walletExists(keyPath);\n if (!exists) {\n throw new T2000Error(\n 'WALLET_NOT_FOUND',\n 'No wallet found. Run `t2 init` to create one.',\n );\n }\n\n // [v4.0] loadKey reads v2 plain Bech32 JSON. Anything else throws\n // WALLET_CORRUPT. PIN/passphrase fields on T2000Options are accepted\n // for back-compat but IGNORED.\n const keypair = await loadKey(undefined, keyPath);\n return new T2000(keypair, client, DEFAULT_CONFIG_DIR);\n }\n\n static fromPrivateKey(privateKey: string, options: { network?: 'mainnet' | 'testnet'; rpcUrl?: string } = {}): T2000 {\n const keypair = keypairFromPrivateKey(privateKey);\n const client = getSuiClient(options.rpcUrl);\n return new T2000(keypair, client);\n }\n\n static async init(options: { pin?: string; passphrase?: string; keyPath?: string; name?: string } = {}): Promise<{ agent: T2000; address: string }> {\n // [v4.0] pin/passphrase accepted for back-compat but IGNORED.\n const keypair = generateKeypair();\n await saveKey(keypair, undefined, options.keyPath);\n\n const client = getSuiClient();\n const agent = new T2000(keypair, client, DEFAULT_CONFIG_DIR);\n const address = agent.address();\n\n return { agent, address };\n }\n\n // -- Gas --\n\n /** SuiGrpcClient used by this agent — exposed for integrations. */\n get suiClient(): SuiGrpcClient {\n return this.client;\n }\n\n /** Ed25519Keypair used by this agent — exposed for CLI/MCP integrations. */\n get keypair(): Ed25519Keypair {\n if (!this._keypair) {\n throw new T2000Error('WALLET_NOT_FOUND', 'Keypair not available — this instance uses zkLogin');\n }\n return this._keypair;\n }\n\n /** Transaction signer (works for both keypair and zkLogin). */\n get signer(): TransactionSigner {\n return this._signer;\n }\n\n // -- MPP Payments --\n\n async pay(options: PayOptions): Promise<PayResult> {\n // Gate on the maxPrice ceiling pre-flight (USD); record the ACTUAL cost\n // post-settle. `force` bypasses (caller owns consent).\n this.limits.assert({ operation: 'pay', amountUsd: options.maxPrice ?? 0, force: options.force });\n\n // Canonical gasless MPP pay loop lives in `wallet/pay.ts` (browser-safe,\n // shared with the Audric client's unified gasless write path). T2000\n // owns only the limit book-ends; the server budget ledger is the cap on\n // the browser side, so the browser caller skips the SDK limit gate.\n const result = await payWithMpp({ signer: this._signer, client: this.client, options });\n\n if (result.paid) {\n this.limits.record(result.cost ?? options.maxPrice ?? 0);\n }\n\n return result;\n }\n\n // [S.323 / 2026-05-25] VOLO vSUI staking surfaces removed (full cut).\n // Engine cut Volo in S.277; SDK + CLI + MCP followed in S.323 because the\n // product surface (five products: Passport / Intelligence / Finance / Pay\n // / Store) doesn't include a staking primitive. vSUI still appears in the\n // codebase as a passive token (NAVI reward rewards, Cetus swap routing),\n // but there is no longer any way to MINT or REDEEM vSUI through t2000.\n // History: see spec/archive/v07e/AUDIT_V07E_EARNS_ITS_KEEP_2026-05-23.md\n // and the S.323 build-tracker entry.\n\n // -- Private Inference API (SPEC_AUDRIC_API, S.575) --\n //\n // Inference as a wallet verb — the agent's brain + wallet in one package.\n // Key-based today (`apiKey` / `T2000_API_KEY`); the x402 no-key pay-per-call\n // path is a later add. The model runs on t2000 Private Inference (ZDR; a\n // `phala/*` confidential tier runs in a GPU-TEE).\n\n /** Non-streaming chat completion against Private Inference. */\n async chat(params: ChatParams): Promise<ChatResult> {\n return chatCompletion(params);\n }\n\n /** Streaming chat completion — async-iterate the assistant text deltas;\n * the generator returns `{ receiptId }` (confidential attestation) at the end. */\n chatStream(\n params: ChatParams\n ): AsyncGenerator<string, { receiptId?: string }, unknown> {\n return chatCompletionStream(params);\n }\n\n /** The Private Inference model catalog (`GET /v1/models`). */\n async models(opts?: { apiKey?: string; apiBase?: string }): Promise<ApiModel[]> {\n return listModels(opts);\n }\n\n /** Verify a confidential response by receipt id — checks the signed receipt\n * + its trustless on-chain Sui anchor. Fails closed on any mismatch. */\n async verify(receiptId: string, opts?: VerifyOptions): Promise<VerifyResult> {\n return verifyReceipt(receiptId, opts);\n }\n\n // -- Swap --\n\n async swap(params: {\n from: string;\n to: string;\n amount: number;\n byAmountIn?: boolean;\n slippage?: number;\n force?: boolean;\n }): Promise<SwapResult> {\n // Gate on the input-side USD value (stables 1:1; SUI/other → ungated).\n this.limits.assert({\n operation: 'swap',\n amountUsd: approxUsdValue(params.from, params.amount) ?? 0,\n force: params.force,\n });\n\n const { findSwapRoute, buildSwapTx, resolveTokenType, preflightSwap } = await import('./protocols/cetus-swap.js');\n\n // Layer 2 — cheap synchronous preflight (from/to/amount sanity, identity\n // swap). Runs before any route-finding network call.\n const pf = preflightSwap({ from: params.from, to: params.to, amount: params.amount });\n if (!pf.valid) throw new T2000Error(pf.code, pf.error);\n\n const fromType = resolveTokenType(params.from);\n const toType = resolveTokenType(params.to);\n if (!fromType) throw new T2000Error('ASSET_NOT_SUPPORTED', `Unknown token: ${params.from}. Provide the full coin type.`);\n if (!toType) throw new T2000Error('ASSET_NOT_SUPPORTED', `Unknown token: ${params.to}. Provide the full coin type.`);\n\n const byAmountIn = params.byAmountIn ?? true;\n const slippage = Math.min(params.slippage ?? 0.01, 0.05);\n\n const fromDecimals = await resolveCoinDecimals(this.client, fromType);\n const rawAmount = BigInt(Math.floor(params.amount * 10 ** fromDecimals));\n\n const route = await findSwapRoute({\n walletAddress: this._address,\n from: fromType,\n to: toType,\n amount: rawAmount,\n byAmountIn,\n });\n\n if (!route) throw new T2000Error('SWAP_NO_ROUTE', `No swap route found for ${params.from} -> ${params.to}.`);\n if (route.insufficientLiquidity) throw new T2000Error('SWAP_NO_ROUTE', `Insufficient liquidity for ${params.from} -> ${params.to}.`);\n if (route.priceImpact > 0.05) {\n console.warn(`[swap] High price impact: ${(route.priceImpact * 100).toFixed(2)}%`);\n }\n\n const toDecimals = await resolveCoinDecimals(this.client, toType);\n\n // Snapshot pre-swap balance for fallback diff calculation\n let preBalRaw = 0n;\n try {\n const preBal = await this.client.core.getBalance({ owner: this._address, coinType: toType });\n preBalRaw = BigInt(preBal.balance.balance);\n } catch { /* first time holding this token — balance is 0 */ }\n\n const gasResult = await executeTx(this.client, this._signer, async () => {\n const tx = new Transaction();\n tx.setSender(this._address);\n\n let inputCoin: TransactionObjectArgument;\n if (fromType === '0x2::sui::SUI') {\n [inputCoin] = tx.splitCoins(tx.gas, [rawAmount]);\n } else {\n const bal = await this.client.core.getBalance({ owner: this._address, coinType: fromType });\n if (BigInt(bal.balance.balance) < rawAmount) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${params.from} balance.`, {\n available: Number(bal.balance.balance) / 10 ** fromDecimals,\n required: params.amount,\n });\n }\n inputCoin = coinWithBalance({ type: fromType, balance: rawAmount })(tx);\n }\n\n const outputCoin = await buildSwapTx({\n walletAddress: this._address,\n route,\n tx,\n inputCoin,\n slippage,\n });\n\n tx.transferObjects([outputCoin], this._address);\n return tx;\n });\n\n const fromAmount = Number(route.amountIn) / 10 ** fromDecimals;\n let toAmount = Number(route.amountOut) / 10 ** toDecimals;\n\n // --- Primary: parse balance changes from the finalized transaction ---\n const toTypeSuffix = toType.split('::').slice(1).join('::');\n try {\n // [gRPC migration] core.waitForTransaction returns a discriminated union;\n // balanceChanges are `{ coinType, address, amount }` (signed string),\n // not the legacy `{ owner: { AddressOwner } }` shape.\n const fullTx = await this.client.core.waitForTransaction({\n digest: gasResult.digest,\n include: { balanceChanges: true },\n timeout: 8_000,\n });\n const txn = fullTx.$kind === 'Transaction' ? fullTx.Transaction : fullTx.FailedTransaction;\n const changes = txn.balanceChanges ?? [];\n const received = changes.find((c) => {\n if (BigInt(c.amount) <= 0n) return false;\n if (!c.address || c.address.toLowerCase() !== this._address.toLowerCase()) return false;\n if (c.coinType === toType) return true;\n return c.coinType.endsWith(toTypeSuffix);\n });\n if (received) {\n const actual = Number(BigInt(received.amount)) / 10 ** toDecimals;\n if (actual > 0) toAmount = actual;\n }\n } catch {\n // waitForTransaction timeout — fall through to balance diff\n }\n\n // --- Fallback: pre/post getBalance diff ---\n const cetusEstimate = Number(route.amountOut) / 10 ** toDecimals;\n if (Math.abs(toAmount - cetusEstimate) < 0.001) {\n try {\n await new Promise((r) => setTimeout(r, 2000));\n const postBal = await this.client.core.getBalance({ owner: this._address, coinType: toType });\n const postRaw = BigInt(postBal.balance.balance);\n const delta = Number(postRaw - preBalRaw) / 10 ** toDecimals;\n if (delta > 0) toAmount = delta;\n } catch {\n // Balance diff fallback failed — use Cetus estimate\n }\n }\n\n // Resolve full coin types to user-friendly token names\n const fromName = resolveSymbol(fromType);\n const toName = resolveSymbol(toType);\n\n const routeDesc = route.routerData.paths\n ?.map((p) => p.provider)\n .filter(Boolean)\n .slice(0, 3)\n .join(' + ') ?? 'Cetus Aggregator';\n\n // Record the settled input-side USD against the cumulative daily total.\n this.limits.record(approxUsdValue(params.from, params.amount) ?? 0);\n\n return {\n success: true,\n tx: gasResult.digest,\n fromToken: fromName,\n toToken: toName,\n fromAmount,\n toAmount,\n priceImpact: route.priceImpact,\n route: routeDesc,\n gasCost: gasResult.gasCostSui,\n };\n }\n\n /**\n * [SPEC_AGENTIC_STACK P1 / SDK F2 — 2026-05-25]\n * Thin wrapper around the standalone `getSwapQuote()`. Pre-Phase 1 this method\n * was ~50 LoC duplicating `swap-quote.ts` — missing `serializedRoute` (SPEC 20.2\n * fast-path) and the `providers` allow-list (Bug A fix / Pyth-dependent\n * provider filter for sponsored callers). Routing both API surfaces through\n * one implementation ensures fixes land for both.\n */\n async swapQuote(params: {\n from: string;\n to: string;\n amount: number;\n byAmountIn?: boolean;\n providers?: string[];\n }): Promise<SwapQuoteResult> {\n const { getSwapQuote } = await import('./swap-quote.js');\n const { resolveTokenType } = await import('./protocols/cetus-swap.js');\n // [2.11] Resolve decimals on-chain for non-registry coin types so the quote\n // matches what a real swap would compute (the standalone getSwapQuote can't\n // — it has no client). Falls back to its registry default if unresolved.\n const fromType = resolveTokenType(params.from);\n const toType = resolveTokenType(params.to);\n return getSwapQuote({\n walletAddress: this._address,\n from: params.from,\n to: params.to,\n amount: params.amount,\n byAmountIn: params.byAmountIn,\n providers: params.providers,\n fromDecimals: fromType ? await resolveCoinDecimals(this.client, fromType) : undefined,\n toDecimals: toType ? await resolveCoinDecimals(this.client, toType) : undefined,\n });\n }\n\n // -- Wallet --\n\n address(): string {\n return this._address;\n }\n\n /**\n * Send `amount` of `asset` to `to` (hex address or SuiNS name).\n *\n * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]\n *\n * **Breaking changes from v3.x:**\n * - `asset` is now REQUIRED (no implicit `?? 'USDC'` default). Callers\n * must specify `'USDC' | 'USDsui' | 'SUI'`. Sending `'USDT'` /\n * `'USDe'` / `'WAL'` / `'ETH'` / `'NAVX'` / `'GOLD'` now errors\n * with `INVALID_ASSET` — swap to a stable first.\n * - USDC + USDsui builds go through `SuiGrpcClient` so the gRPC build\n * resolver auto-detects `0x2::balance::send_funds` eligibility and\n * zeros gas at simulate time. Result: **gasless USDC / USDsui sends\n * from a zero-SUI wallet.** SUI sends stay on the standard gas-paid\n * path.\n *\n * Submission stays on the JSON-RPC client (the rest of the SDK\n * expects JSON-RPC for read paths, and Sui's docs explicitly support\n * the \"build via gRPC, execute via JSON-RPC\" hybrid).\n */\n async send(params: { to: string; amount: number; asset: SupportedAsset; force?: boolean }): Promise<SendResult> {\n // [v4.0 Phase A Day 2] Asset is REQUIRED at runtime (no more silent\n // USDC default). The parameter type is `SupportedAsset` (the wider\n // SDK surface) rather than `SendableAsset` so callers that still\n // hand a wide-typed asset through — primarily the engine LLM tool\n // surface — compile without modification. Runtime narrowing happens\n // via `assertAllowedAsset('send', asset)`, which throws\n // `INVALID_ASSET` for anything outside `['USDC', 'USDsui', 'SUI']`.\n // This matches the SPEC verification gate `asset: 'USDY'` →\n // `INVALID_ASSET` (runtime check, not compile check).\n const asset = params.asset;\n if (!asset) {\n throw new T2000Error(\n 'INVALID_ASSET',\n \"send() requires an explicit asset. Use one of: USDC, USDsui, SUI.\",\n );\n }\n assertAllowedAsset('send', asset);\n // `assertAllowedAsset('send', asset)` narrows the runtime value to\n // one of `SendableAsset` (USDC / USDsui / SUI). Cast statically.\n const sendableAsset = asset as SendableAsset;\n\n // Spending-limit gate (USD; stables 1:1, SUI ungated). `force` bypasses.\n this.limits.assert({\n operation: 'send',\n amountUsd: approxUsdValue(sendableAsset, params.amount) ?? 0,\n force: params.force,\n });\n\n const resolved = await this.resolveRecipient(params.to);\n const sendAmount = params.amount;\n const sendTo = resolved.address;\n\n // Gasless-eligible stables (USDC / USDsui) build via the dedicated gRPC\n // client so the resolver can zero gas at simulate. SUI is not on the\n // `balance::send_funds` allowlist, so it builds via the default client\n // (also gRPC post-cutover) with normal gas — no separate build client.\n const useGrpc = sendableAsset === 'USDC' || sendableAsset === 'USDsui';\n const buildClient = useGrpc ? getSuiGrpcClient() : undefined;\n\n const gasResult = await executeTx(\n this.client,\n this._signer,\n () => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset: sendableAsset }),\n { buildClient },\n );\n\n this.limits.record(approxUsdValue(sendableAsset, sendAmount) ?? 0);\n const balance = await this.balance();\n\n this.emitBalanceChange(sendableAsset, sendAmount, 'send', gasResult.digest);\n\n return {\n success: true,\n tx: gasResult.digest,\n amount: sendAmount,\n to: resolved.address,\n suinsName: resolved.suinsName,\n gasCost: gasResult.gasCostSui,\n gasCostUnit: 'SUI',\n balance,\n };\n }\n\n /**\n * Resolve a recipient string into a canonical 0x address:\n * 1. **hex** — `0x…` is used directly (no RPC round-trip).\n * 2. **SuiNS** — `alex.sui` resolves via `suix_resolveNameServiceAddress`.\n *\n * Anything else is rejected. (The legacy `contacts.json` alias map was\n * removed — SuiNS supersedes local contacts.)\n *\n * Returns `{ address, suinsName? }` so `send()` can stamp the name source\n * on the receipt without re-resolving. Throws\n * `T2000Error('SUINS_NOT_REGISTERED', …)` for well-formed but unregistered\n * SuiNS names, keeping the SDK error surface `T2000Error`-only.\n *\n * Public so MCP's `t2000_send` dryRun preview shares one resolution path\n * with the live execute path (never resolve the same input two ways).\n */\n async resolveRecipient(\n input: string,\n ): Promise<{ address: string; suinsName?: string }> {\n const trimmed = input.trim();\n if (SUI_ADDRESS_REGEX.test(trimmed)) {\n return { address: trimmed.toLowerCase() };\n }\n if (looksLikeSuiNs(trimmed)) {\n try {\n const name = trimmed.toLowerCase();\n const address = await resolveSuinsViaRpc(name);\n if (!address) {\n throw new SuinsNotRegisteredError(name);\n }\n return { address: address.toLowerCase(), suinsName: name };\n } catch (err) {\n if (err instanceof SuinsNotRegisteredError) {\n throw new T2000Error(\n 'SUINS_NOT_REGISTERED',\n err.message,\n );\n }\n throw err;\n }\n }\n throw new T2000Error(\n 'INVALID_ADDRESS',\n `Cannot resolve recipient \"${input}\". Provide a 0x address or a .sui name.`,\n );\n }\n\n async balance(): Promise<BalanceResponse> {\n // [NAVI removed] Wallet-only balance: spendable stables + SUI gas reserve.\n return queryBalance(this.client, this._address);\n }\n\n async history(params?: { limit?: number }): Promise<TransactionRecord[]> {\n return queryHistory(this._address, params?.limit);\n }\n\n async transactionDetail(digest: string): Promise<TransactionRecord | null> {\n return queryTransaction(digest, this._address);\n }\n\n async deposit(): Promise<DepositInfo> {\n return {\n address: this._address,\n network: 'mainnet',\n supportedAssets: ['USDC', 'USDT', 'SUI'],\n instructions: [\n `Send USDC to: ${this._address}`,\n `Network: Sui Mainnet`,\n `Or buy USDC on an exchange and withdraw to this address.`,\n `USDC contract: ${SUPPORTED_ASSETS.USDC.type}`,\n ].join('\\n'),\n };\n }\n\n /**\n * [SPEC_AGENTIC_STACK P1 / SDK F2 — 2026-05-25; refreshed S.342 / 2026-05-26]\n * Preferred alias of `deposit()`. Was introduced to mirror the v3 `t2000 fund`\n * CLI command; the v4 CLI surface is `t2 fund` (renamed back from the\n * interim `t2 receive` in S.464). `deposit()` stays as the canonical method name for\n * back-compat; `fund()` stays as a programmatic alias for audric + other\n * SDK consumers that prefer the verb.\n */\n async fund(): Promise<DepositInfo> {\n return this.deposit();\n }\n\n receive(params?: { amount?: number; currency?: string; memo?: string; label?: string }): PaymentRequest {\n const amount = params?.amount ?? null;\n const currency = params?.currency ?? 'USDC';\n const memo = params?.memo ?? null;\n const label = params?.label ?? null;\n const nonce = crypto.randomUUID();\n\n let qrUri: string;\n if (amount != null && amount > 0) {\n const decimals = currency === 'SUI' ? 9 : 6;\n const coinType = currency === 'SUI'\n ? '0x2::sui::SUI'\n : SUPPORTED_ASSETS.USDC.type;\n const rawAmount = BigInt(Math.floor(amount * 10 ** decimals));\n qrUri = createPaymentTransactionUri({\n receiverAddress: this._address,\n amount: rawAmount,\n coinType,\n nonce,\n ...(label ? { label } : {}),\n ...(memo ? { message: memo } : {}),\n });\n } else {\n const qrParts = [`sui:${this._address}`];\n const queryParams: string[] = [];\n if (currency !== 'SUI') queryParams.push(`currency=${currency}`);\n if (memo) queryParams.push(`memo=${encodeURIComponent(memo)}`);\n if (label) queryParams.push(`label=${encodeURIComponent(label)}`);\n qrUri = queryParams.length > 0 ? `${qrParts[0]}?${queryParams.join('&')}` : qrParts[0];\n }\n\n const amountStr = amount != null ? `$${amount.toFixed(2)} ` : '';\n const displayParts = [`Send ${amountStr}${currency} to ${truncateAddress(this._address)}`];\n if (memo) displayParts.push(`Memo: ${memo}`);\n\n return {\n address: this._address,\n network: 'mainnet',\n amount,\n currency,\n memo,\n label,\n nonce,\n qrUri,\n displayText: displayParts.join('\\n'),\n };\n }\n\n exportKey(): string {\n return exportPrivateKey(this.keypair);\n }\n\n static fromZkLogin(opts: {\n ephemeralKeypair: Ed25519Keypair;\n zkProof: ZkLoginProof;\n userAddress: string;\n maxEpoch: number;\n rpcUrl?: string;\n }): T2000 {\n const signer = new ZkLoginSigner(opts.ephemeralKeypair, opts.zkProof, opts.userAddress, opts.maxEpoch);\n const client = getSuiClient(opts.rpcUrl);\n return new T2000(signer, client, undefined, true);\n }\n\n private emitBalanceChange(asset: string, amount: number, cause: string, tx?: string): void {\n this.emit('balanceChange', { asset, previous: 0, current: 0, cause, tx });\n }\n}\n\n","// ---------------------------------------------------------------------------\n// Sui address + SuiNS normalization — single source of truth.\n//\n// [S.279 / CLI-CONTACTS-CLEANUP — 2026-05-23] Promoted from the deleted\n// `@t2000/engine` package to the SDK so the CLI's `T2000.send()` can accept\n// SuiNS names (`alex.sui`) alongside hex addresses — one canonical resolver.\n//\n// Background. Host read tools accept an optional `address` parameter so the\n// LLM can inspect any public Sui wallet. Each calls `normalizeAddressInput()`\n// to accept either `0x...` or `alex.sui` and returns a structured\n// `{ address, suinsName, raw }` triple. The SDK's `T2000.send()` uses the\n// same primitive, so a CLI user can run\n// `t2000 send alex.sui 10 USDC` without looking up the hex address first.\n//\n// Single source of truth — see `.cursor/rules/single-source-of-truth.mdc`\n// and `.cursor/rules/engineering-principles.mdc` Principle 2.\n// ---------------------------------------------------------------------------\n\nimport { getSuiGraphQLClient } from './sui.js';\n\n// [gRPC migration] SuiNS resolution moved off JSON-RPC\n// (`suix_resolveNameServiceAddress` / `suix_resolveNameServiceNames`) onto the\n// Sui GraphQL endpoint — the last JSON-RPC caller in the SDK. Both directions\n// use the unified `address(...)` query: `address(name:)` for forward\n// (name → address) and `address(address:){ defaultNameRecord { domain } }` for\n// reverse (address → primary name).\nconst RESOLVE_NAME_QUERY = `query ResolveSuins($name: String!) {\n address(name: $name) { address }\n}`;\n\nconst REVERSE_NAME_QUERY = `query ReverseSuins($address: SuiAddress!) {\n address(address: $address) { defaultNameRecord { domain } }\n}`;\n\ninterface GqlResult<T> {\n data?: T;\n errors?: Array<{ message?: string }>;\n}\n\n/**\n * Canonical 0x-address shape. Loose lower bound (>= 1 hex char) so\n * pre-v1.0 short addresses still validate; tools that need a full 64-hex\n * address can additionally check `length === 66`. Case-insensitive on\n * the `0x` prefix because some upstream callers (and historic tests)\n * uppercase the prefix as part of address normalization tests; the\n * normalizer always returns the lowercased canonical form regardless.\n */\nexport const SUI_ADDRESS_REGEX = /^0x[a-fA-F0-9]{1,64}$/i;\n\n/**\n * Strict canonical 0x-address shape (66 chars total). Used by the\n * resolver's \"looks like\" check to disambiguate \"user pasted an\n * address\" vs \"user typed a SuiNS name\".\n */\nexport const SUI_ADDRESS_STRICT_REGEX = /^0x[a-fA-F0-9]{64}$/i;\n\n/**\n * Mirrors the pattern in `audric/apps/web-v2/lib/suins-cache.ts` so the\n * host-side send executor and the engine-side read normalizer agree on\n * what counts as a SuiNS name. SuiNS allows nested labels (`team.alex.sui`)\n * but every label must use only `[a-z0-9-]`.\n */\nexport const SUINS_NAME_REGEX = /^[a-z0-9-]+(\\.[a-z0-9-]+)*\\.sui$/;\n\nexport class InvalidAddressError extends Error {\n constructor(public readonly raw: string) {\n super(\n `\"${raw}\" isn't a valid Sui address or SuiNS name. ` +\n `Pass a 0x-prefixed hex address (e.g. 0x40cd…3e62) or a SuiNS name ending in .sui (e.g. alex.sui).`,\n );\n this.name = 'InvalidAddressError';\n }\n}\n\nexport class SuinsNotRegisteredError extends Error {\n constructor(public readonly name_: string) {\n super(\n `\"${name_}\" isn't a registered SuiNS name. Double-check the spelling, ` +\n `or paste the full Sui address (0x… 64 hex characters).`,\n );\n this.name = 'SuinsNotRegisteredError';\n }\n}\n\nexport class SuinsRpcError extends Error {\n constructor(public readonly name_: string, detail: string) {\n super(`SuiNS lookup failed for \"${name_}\" (${detail}). Try again, or paste the full Sui address.`);\n this.name = 'SuinsRpcError';\n }\n}\n\n/**\n * Returns true if `value` looks like a SuiNS name (case-insensitive).\n * Cheap synchronous check — use to avoid an unnecessary RPC round-trip\n * for inputs that obviously aren't names (0x addresses, contact handles).\n */\nexport function looksLikeSuiNs(value: string): boolean {\n if (!value) return false;\n return SUINS_NAME_REGEX.test(value.trim().toLowerCase());\n}\n\n/**\n * Resolve a SuiNS name to its on-chain Sui address via the Sui GraphQL\n * `address(name:)` query. Returns `null` if the name resolves to no address\n * (= not registered or expired). Throws `SuinsRpcError` on transport failure.\n *\n * `ctx.signal` is honored for cancellation. (`ctx.suiRpcUrl` is retained for\n * call-site back-compat but no longer used — resolution runs against the\n * canonical GraphQL endpoint via `getSuiGraphQLClient()`.)\n */\nexport async function resolveSuinsViaRpc(\n rawName: string,\n ctx: { suiRpcUrl?: string; signal?: AbortSignal } = {},\n): Promise<string | null> {\n const name = rawName.trim().toLowerCase();\n if (!SUINS_NAME_REGEX.test(name)) {\n throw new InvalidAddressError(rawName);\n }\n\n const gql = getSuiGraphQLClient();\n let res: GqlResult<{ address?: { address?: string } | null }>;\n try {\n res = (await gql.query({\n query: RESOLVE_NAME_QUERY,\n variables: { name },\n signal: ctx.signal,\n })) as typeof res;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new SuinsRpcError(name, msg);\n }\n\n if (res.errors?.length) {\n throw new SuinsRpcError(name, res.errors.map((e) => e.message ?? 'unknown error').join('; '));\n }\n\n // `address(name:)` returns the Address the name points to, or null when the\n // name has never been registered (or has expired and the record was reaped).\n return res.data?.address?.address ?? null;\n}\n\n/**\n * Reverse-resolve a 0x address to its SuiNS name via the Sui GraphQL\n * `address(address:){ defaultNameRecord { domain } }` query. Returns a\n * single-element array with the address's **default (primary)** name, or\n * `[]` when it has none. Throws `SuinsRpcError` on transport failure.\n *\n * Behavior note: the legacy JSON-RPC path returned *all* names for the\n * address; GraphQL exposes the explicitly-configured default record, which is\n * the one every consumer here actually uses (the LLM `resolve_suins` tool +\n * card titles only ever render the primary). Returning `[primary]` keeps the\n * `string[]` contract intact.\n *\n * Why this is its own helper (not folded into `normalizeAddressInput`): a\n * reverse lookup adds a second round-trip per tool call. We don't want every\n * read tool that takes an `address` to silently double its latency. The lookup\n * primitive is opt-in via the `resolve_suins` tool; normalizers stay\n * forward-only.\n */\nexport async function resolveAddressToSuinsViaRpc(\n rawAddress: string,\n ctx: { suiRpcUrl?: string; signal?: AbortSignal } = {},\n): Promise<string[]> {\n const address = rawAddress.trim().toLowerCase();\n if (!SUI_ADDRESS_REGEX.test(address)) {\n throw new InvalidAddressError(rawAddress);\n }\n\n const gql = getSuiGraphQLClient();\n let res: GqlResult<{ address?: { defaultNameRecord?: { domain?: string } | null } | null }>;\n try {\n res = (await gql.query({\n query: REVERSE_NAME_QUERY,\n variables: { address },\n signal: ctx.signal,\n })) as typeof res;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new SuinsRpcError(address, msg);\n }\n\n if (res.errors?.length) {\n throw new SuinsRpcError(address, res.errors.map((e) => e.message ?? 'unknown error').join('; '));\n }\n\n const domain = res.data?.address?.defaultNameRecord?.domain;\n return domain ? [domain] : [];\n}\n\nexport interface NormalizedAddress {\n /**\n * Canonical 0x-prefixed lowercase hex address. Always set on success.\n * Tools should use this for any downstream query (BlockVision, NAVI,\n * positionFetcher, etc.) and for cache keys.\n */\n address: string;\n /**\n * The user-facing name when the input was resolved via SuiNS, otherwise\n * `null`. Tools should stamp this on result data so card titles can\n * render \"Balance · obehi.sui\" instead of \"Balance · 0x1234…abcd\".\n */\n suinsName: string | null;\n /**\n * The original input (pre-normalization). Useful for error narration —\n * \"I tried to resolve `Obehi.Sui` and …\" reads better than the\n * post-trim/lowercase form.\n */\n raw: string;\n}\n\n/**\n * Canonical normalizer. Accepts a 0x address OR a SuiNS name; returns\n * a structured `NormalizedAddress`. Throws:\n * - `InvalidAddressError` if the input matches neither shape.\n * - `SuinsNotRegisteredError` if the SuiNS name is well-formed but\n * resolves to null (= not registered).\n * - `SuinsRpcError` if the RPC fails.\n *\n * Every read tool (engine) and write helper (SDK `T2000.send()`) that\n * accepts a user-supplied recipient MUST call this helper before any\n * downstream lookup. Doing the check inline (1) duplicates the regex,\n * (2) silently rejects SuiNS names, (3) makes cache keys inconsistent\n * across tools.\n */\nexport async function normalizeAddressInput(\n value: string,\n ctx: { suiRpcUrl?: string; signal?: AbortSignal } = {},\n): Promise<NormalizedAddress> {\n const trimmed = value.trim();\n if (SUI_ADDRESS_REGEX.test(trimmed)) {\n return { address: trimmed.toLowerCase(), suinsName: null, raw: value };\n }\n if (looksLikeSuiNs(trimmed)) {\n const name = trimmed.toLowerCase();\n const address = await resolveSuinsViaRpc(name, ctx);\n if (!address) {\n throw new SuinsNotRegisteredError(name);\n }\n return { address: address.toLowerCase(), suinsName: name, raw: value };\n }\n throw new InvalidAddressError(value);\n}\n","import { T2000Error } from './errors.js';\n\n// Private Inference API client (SPEC_AUDRIC_API — agent-native layer, S.575).\n// Key-based access to t2000 Private Inference (OpenAI-compatible) at\n// `api.t2000.ai/v1`. The x402 pay-per-call (no-key) path is a later add; this\n// is the key-based distribution surface used by `t2 chat` + the MCP `t2000_chat`\n// tool. Browser-safe (fetch + ReadableStream only — no wallet/Node deps).\n\nexport const DEFAULT_API_BASE = 'https://api.t2000.ai/v1';\n\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface ChatParams {\n model: string;\n messages: ChatMessage[];\n /** Private Inference key (`sk-…`). Falls back to `T2000_API_KEY` env. */\n apiKey?: string;\n /** Override the API base (default `api.t2000.ai/v1`; e.g. for testing). */\n apiBase?: string;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface ChatUsage {\n promptTokens?: number;\n completionTokens?: number;\n totalTokens?: number;\n}\n\nexport interface ChatResult {\n content: string;\n model: string;\n usage?: ChatUsage;\n /** Confidential calls (`phala/*`) return a TEE attestation receipt id —\n * fetch + verify it at `/v1/aci/receipts/{id}`. Absent for ZDR models. */\n receiptId?: string;\n /** The verbatim OpenAI-shaped response body. */\n raw: unknown;\n}\n\nexport interface ApiModel {\n id: string;\n contextWindow?: number;\n inputPer1M?: number;\n outputPer1M?: number;\n /** Privacy tier surfaced by the API (e.g. `zdr`, `confidential`). */\n privacy?: string;\n /** True for reasoning models — deeper but slower (a hidden reasoning trace\n * before the answer). Surfaced so callers pick the speed/depth tradeoff. */\n reasoning?: boolean;\n}\n\nfunction envApiKey(): string | undefined {\n return typeof process !== 'undefined' ? process.env?.T2000_API_KEY : undefined;\n}\n\nfunction resolveApiKey(apiKey?: string): string {\n const key = apiKey ?? envApiKey();\n if (!key) {\n throw new T2000Error(\n 'INVALID_KEY',\n 'No Private Inference key. Pass `apiKey` or set T2000_API_KEY. Generate one at agents.t2000.ai/manage.',\n );\n }\n return key;\n}\n\nasync function failBody(res: Response): Promise<never> {\n const text = await res.text().catch(() => '');\n let msg = text.slice(0, 300);\n try {\n const j = JSON.parse(text) as { error?: { message?: string } | string };\n msg =\n (typeof j.error === 'object' ? j.error?.message : j.error) ?? msg;\n } catch {\n // keep the raw text\n }\n throw new T2000Error(\n 'INFERENCE_FAILED',\n `Inference request failed (${res.status}): ${msg}`,\n { status: res.status },\n res.status >= 500,\n );\n}\n\nfunction usageOf(raw: unknown): ChatUsage | undefined {\n const u = (raw as { usage?: Record<string, number> })?.usage;\n if (!u) {\n return;\n }\n return {\n promptTokens: u.prompt_tokens,\n completionTokens: u.completion_tokens,\n totalTokens: u.total_tokens,\n };\n}\n\nfunction body(params: ChatParams, stream: boolean): string {\n return JSON.stringify({\n model: params.model,\n messages: params.messages,\n // include_usage → the final stream chunk carries usage + x_receipt_id\n // (the confidential attestation receipt) so we can surface it after a stream.\n ...(stream ? { stream: true, stream_options: { include_usage: true } } : {}),\n ...(params.maxTokens != null ? { max_tokens: params.maxTokens } : {}),\n ...(params.temperature != null ? { temperature: params.temperature } : {}),\n });\n}\n\n/** Non-streaming chat completion. Returns the assistant text + usage + the\n * verbatim OpenAI response body. */\nexport async function chatCompletion(params: ChatParams): Promise<ChatResult> {\n const key = resolveApiKey(params.apiKey);\n const base = params.apiBase ?? DEFAULT_API_BASE;\n const res = await fetch(`${base}/chat/completions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${key}` },\n body: body(params, false),\n });\n if (!res.ok) {\n await failBody(res);\n }\n const receiptId = res.headers.get('x-receipt-id') ?? undefined;\n const raw = await res.json();\n const content =\n (raw as { choices?: { message?: { content?: string } }[] })?.choices?.[0]\n ?.message?.content ?? '';\n return {\n content,\n model: (raw as { model?: string })?.model ?? params.model,\n usage: usageOf(raw),\n receiptId,\n raw,\n };\n}\n\n/** Streaming chat completion — yields assistant text deltas as they arrive\n * (parses the OpenAI SSE `data:` frames). */\nexport async function* chatCompletionStream(\n params: ChatParams,\n): AsyncGenerator<string, { receiptId?: string }, unknown> {\n const key = resolveApiKey(params.apiKey);\n const base = params.apiBase ?? DEFAULT_API_BASE;\n const res = await fetch(`${base}/chat/completions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${key}` },\n body: body(params, true),\n });\n if (!(res.ok && res.body)) {\n await failBody(res);\n return {};\n }\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let receiptId: string | undefined;\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith('data:')) {\n continue;\n }\n const data = trimmed.slice(5).trim();\n if (data === '[DONE]') {\n return { receiptId };\n }\n try {\n const json = JSON.parse(data) as {\n choices?: { delta?: { content?: string } }[];\n x_receipt_id?: string;\n };\n // The confidential TEE receipt rides the final usage chunk.\n if (json.x_receipt_id) {\n receiptId = json.x_receipt_id;\n }\n const delta = json.choices?.[0]?.delta?.content;\n if (typeof delta === 'string' && delta) {\n yield delta;\n }\n } catch {\n // keep-alive or partial frame — ignore\n }\n }\n }\n return { receiptId };\n}\n\n/** List Private Inference model catalog (`GET /v1/models`). The key is sent when\n * available but not required (the catalog may be public). */\nexport async function listModels(opts?: {\n apiKey?: string;\n apiBase?: string;\n}): Promise<ApiModel[]> {\n const base = opts?.apiBase ?? DEFAULT_API_BASE;\n const key = opts?.apiKey ?? envApiKey();\n const res = await fetch(`${base}/models`, {\n headers: key ? { authorization: `Bearer ${key}` } : {},\n });\n if (!res.ok) {\n await failBody(res);\n }\n const json = (await res.json()) as {\n data?: {\n id: string;\n context_window?: number;\n context_length?: number;\n privacy?: string;\n privacy_tier?: string;\n reasoning?: boolean;\n pricing?: {\n input_per_1m?: number;\n output_per_1m?: number;\n prompt?: number;\n completion?: number;\n };\n }[];\n };\n const data = Array.isArray(json.data) ? json.data : [];\n return data.map((m) => ({\n id: m.id,\n contextWindow: m.context_window ?? m.context_length,\n inputPer1M: m.pricing?.input_per_1m ?? m.pricing?.prompt,\n outputPer1M: m.pricing?.output_per_1m ?? m.pricing?.completion,\n privacy: m.privacy ?? m.privacy_tier,\n reasoning: m.reasoning,\n }));\n}\n","import { SuiGrpcClient } from '@mysten/sui/grpc';\nimport { ed25519 } from '@noble/curves/ed25519';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, hexToBytes } from '@noble/hashes/utils';\nimport { DEFAULT_API_BASE } from './inference.js';\n\n// Confidential receipt verifier (SPEC_CONFIDENTIAL_API v3.0, Phase D).\n//\n// Lets anyone CHECK — not just trust — a t2000 confidential response, by\n// receipt id. The Sui-anchor check is FULLY TRUSTLESS: it reads the on-chain\n// `ReceiptAnchored` event straight from a public Sui fullnode and confirms the\n// committed `wire_hash` + `workload_id` match the signed receipt — t2000 can't\n// forge that (a wrong/missing anchor → fails closed). The confidential-upstream\n// check reads the attestation evidence embedded in the signed receipt\n// (`upstream.verified`).\n//\n// All three core checks are trustless client-side: the Sui anchor (read from a\n// fullnode), the receipt signature (recompute dstack ACI canonical bytes per\n// `canonical.rs` + verify against the attested key — ed25519 current,\n// secp256k1-recover legacy), and the TDX quote\n// (@phala/dcap-qvl chains to Intel's root — removing the server-side-DCAP SPOF).\n// The remaining hop is keyset_endorsement (tying the receipt key to the quote's\n// identity key); the receipt-sig check already proves the receipt is signed by\n// the published keyset key. Per the spec: a wrong \"verifiable\" claim is worse\n// than honest ZDR — so each check states exactly what it proves.\n\nconst RECEIPT_ANCHORED_SUFFIX = '::anchor::ReceiptAnchored';\n\nexport type CheckStatus = 'pass' | 'fail' | 'skip';\nexport type TrustMode = 'trustless' | 'receipt-asserted' | 'roadmap';\n\nexport interface VerifyCheck {\n name: string;\n status: CheckStatus;\n detail: string;\n trust: TrustMode;\n}\n\nexport interface VerifyAnchor {\n txDigest: string;\n anchoredAtMs?: string;\n anchoredBy?: string;\n explorer: string;\n}\n\n/** A typed TCB claim from the attested upstream (dstack ACI §tcb-and-claims). */\nexport interface UpstreamClaim {\n name: string;\n status: string;\n source?: string;\n}\n\nexport interface VerifyUpstream {\n provider?: string;\n modelId?: string;\n result?: string;\n tcbStatus?: string;\n /** The attested-session id (`as_…`) — resolve at GET /v1/aci/sessions/{id}. */\n sessionId?: string;\n /** Typed TCB claims (tee_attested, tcb_up_to_date, gpu_attested, …). */\n claims?: UpstreamClaim[];\n}\n\nexport interface VerifyResult {\n receiptId: string;\n /** True iff the receipt resolved AND its on-chain Sui anchor matches. */\n verified: boolean;\n /** The trustless core: an on-chain ReceiptAnchored event matches the receipt. */\n anchorVerified: boolean;\n checks: VerifyCheck[];\n wireHash?: string;\n workloadId?: string;\n upstream?: VerifyUpstream;\n anchor?: VerifyAnchor;\n}\n\nexport interface VerifyOptions {\n /** Override the API base (default `api.t2000.ai/v1`). */\n apiBase?: string;\n /** Sui network for the trustless anchor read (default `mainnet`). */\n network?: 'mainnet' | 'testnet';\n /** Confidential model id for fetching the attested receipt-signing key\n * (default `phala/glm-5.2`; the gateway key is workload-wide). */\n model?: string;\n /** Skip the local DCAP quote verification (the slower, network-bound check). */\n skipQuote?: boolean;\n}\n\ninterface AciReceiptSignature {\n algo?: string;\n key_id?: string;\n value?: string;\n}\n\ninterface AciReceipt {\n api_version?: string;\n receipt_id?: string;\n chat_id?: string | null;\n workload_id?: string;\n workload_keyset_digest?: string;\n endpoint?: string;\n method?: string;\n served_at?: number;\n signature?: AciReceiptSignature;\n event_log?: {\n type?: string;\n wire_hash?: string;\n result?: string;\n provider?: string;\n upstream_name?: string;\n model_id?: string;\n tcb_status?: string;\n session_id?: string;\n claims?:\n | Record<string, { status?: string; source?: string }>\n | { name?: string; status?: string; source?: string }[];\n }[];\n}\n\n/** Normalize ACI claims (object-map or array) into a typed list. */\nfunction normalizeClaims(\n claims:\n | Record<string, { status?: string; source?: string }>\n | { name?: string; status?: string; source?: string }[]\n | undefined\n): UpstreamClaim[] {\n if (!claims) {\n return [];\n }\n if (Array.isArray(claims)) {\n return claims\n .filter((c) => c.name)\n .map((c) => ({\n name: c.name as string,\n status: c.status ?? 'unknown',\n source: c.source,\n }));\n }\n return Object.entries(claims).map(([name, v]) => ({\n name,\n status: v?.status ?? 'unknown',\n source: v?.source,\n }));\n}\n\nfunction fullnodeUrl(network: 'mainnet' | 'testnet'): string {\n return network === 'testnet'\n ? 'https://fullnode.testnet.sui.io'\n : 'https://fullnode.mainnet.sui.io';\n}\n\ntype Jsonish = string | number | boolean | null | Jsonish[] | { [k: string]: Jsonish };\n\n// JCS (RFC 8785 subset) matching the dstack ACI gateway's `canonical.rs`:\n// object keys sorted by UTF-16 code units (JS default string order on the BMP),\n// integers only, no whitespace. JSON.stringify's string-escaping already matches\n// the gateway's (\\b \\t \\n \\f \\r, \\u00xx for other controls, non-ASCII verbatim).\nfunction jcs(value: Jsonish): string {\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n if (typeof value === 'number') {\n if (!Number.isInteger(value)) {\n throw new Error('JCS: non-integer number');\n }\n return String(value);\n }\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return `[${value.map(jcs).join(',')}]`;\n }\n const keys = Object.keys(value).sort();\n return `{${keys.map((k) => `${JSON.stringify(k)}:${jcs(value[k])}`).join(',')}}`;\n}\n\n// Verify the ACI receipt signature. The dstack gateway has shipped two schemes:\n//\n// • `ed25519` (current, key_id `dstack-kms-receipt-ed25519-v1`): a 64-byte\n// signature over the RAW JCS bytes of the receipt exactly as served — every\n// field present (incl. newer ones like `model`), with only `signature.value`\n// omitted. Verified against the attested 32-byte ed25519 key.\n// • `ecdsa-secp256k1` (legacy, §9.4): a 65-byte `r‖s‖v` signature over\n// `sha256(JCS(<the 10 protocol fields>))`; recover the public key and\n// require it to equal the attested key.\n//\n// Returns true only on a genuine match (any error → false).\n// (Module-level export for tests; the public SDK surface is `verifyReceipt`.)\nexport function verifyReceiptSignature(\n receipt: AciReceipt,\n signingKeyHex: string\n): boolean {\n try {\n const sig = receipt.signature;\n if (!sig?.value) {\n return false;\n }\n const endorsed = hexToBytes(signingKeyHex.replace(/^0x/, ''));\n const sigBytes = hexToBytes(sig.value);\n\n if (sig.algo === 'ed25519') {\n if (sigBytes.length !== 64 || endorsed.length !== 32) {\n return false;\n }\n // Canonicalise the receipt AS SERVED (untyped fields included) so the\n // check stays correct when the gateway adds receipt fields — only\n // `signature.value` is stripped.\n const { value: _omitted, ...sigRest } = sig;\n const canonical = {\n ...(receipt as unknown as { [k: string]: Jsonish }),\n signature: sigRest as unknown as Jsonish,\n };\n const msg = new TextEncoder().encode(jcs(canonical));\n return ed25519.verify(sigBytes, msg, endorsed);\n }\n\n if (sig.algo !== 'ecdsa-secp256k1') {\n return false;\n }\n // Legacy: reconstruct the exact canonical value — the 10 protocol fields,\n // with the signature object stripped of `value` (event_log entries are\n // already the flat {seq,type,...fields} shape the gateway canonicalises).\n const canonical: Jsonish = {\n api_version: receipt.api_version ?? '',\n receipt_id: receipt.receipt_id ?? '',\n chat_id: receipt.chat_id ?? null,\n workload_id: receipt.workload_id ?? '',\n workload_keyset_digest: receipt.workload_keyset_digest ?? '',\n endpoint: receipt.endpoint ?? '',\n method: receipt.method ?? '',\n served_at: receipt.served_at ?? 0,\n event_log: (receipt.event_log ?? []) as unknown as Jsonish,\n signature: { algo: sig.algo, key_id: sig.key_id ?? '' },\n };\n const prehash = sha256(new TextEncoder().encode(jcs(canonical)));\n\n if (sigBytes.length !== 65) {\n return false;\n }\n let v = sigBytes[64];\n if (v >= 27 && v <= 30) {\n v -= 27;\n }\n if (v > 3) {\n return false;\n }\n const recovered = secp256k1.Signature.fromCompact(sigBytes.slice(0, 64))\n .addRecoveryBit(v)\n .recoverPublicKey(prehash)\n .toHex(false);\n return recovered.toLowerCase() === bytesToHex(endorsed).toLowerCase();\n } catch {\n return false;\n }\n}\n\ninterface QuoteCheck {\n status: CheckStatus;\n detail: string;\n /** Definitively bad (verify the chain failed) — flips overall `verified`. */\n forged: boolean;\n tcbStatus?: string;\n}\n\n// TDX quote verification — TRUSTLESS, client-side (SPEC_CONFIDENTIAL_API Phase D\n// hardening). This is what removes the server-side-DCAP SPOF: instead of\n// trusting the gateway's `verified:true`, the client re-verifies the quote.\n// 1. @phala/dcap-qvl verifies the TDX quote, chaining to Intel's root CA via\n// PCCS collateral (Intel-signed, so the PCCS is a cache, not a trust point)\n// → genuine enclave + TCB status.\n// 2. confirm the genuine quote's `report_data` commits the report's\n// `signing_address` (the attested gateway identity) — so the report's TEE\n// binding is quote-backed, not fabricated — and that the quote is for the\n// same `workload_id` as the receipt.\n// (Tying the receipt-signing key to the identity key via keyset_endorsement is a\n// further hop; the receipt-signature check already proves the receipt is signed\n// by the published keyset key.)\ninterface AttReport {\n workload_id?: string;\n signing_address?: string;\n attestation?: { evidence?: { quote?: string } };\n}\n\nasync function verifyTdxQuote(\n base: string,\n model: string,\n receiptWorkloadId: string\n): Promise<QuoteCheck> {\n let nonce: string;\n try {\n nonce = bytesToHex(globalThis.crypto.getRandomValues(new Uint8Array(32)));\n } catch {\n return { status: 'skip', detail: 'no secure RNG available', forged: false };\n }\n\n let report: AttReport | undefined;\n try {\n const res = await fetch(\n `${base}/aci/attestation?model=${encodeURIComponent(model)}&nonce=${nonce}`\n );\n if (res.ok) {\n report = ((await res.json()) as { report?: AttReport }).report;\n }\n } catch {\n // network — fall through to skip\n }\n const quoteHex = report?.attestation?.evidence?.quote;\n if (!quoteHex) {\n return {\n status: 'skip',\n detail: 'attestation report (with quote) unavailable — pass --model?',\n forged: false,\n };\n }\n\n try {\n // `@phala/dcap-qvl` is CJS. When the SDK is bundled (e.g. into the CLI) and\n // hit via dynamic import, its named exports land under `.default`; unbundled\n // Node hoists them to the top level. Resolve both so it works either way.\n const dcap = await import('@phala/dcap-qvl');\n const getCollateralAndVerify =\n dcap.getCollateralAndVerify ?? dcap.default?.getCollateralAndVerify;\n if (typeof getCollateralAndVerify !== 'function') {\n return {\n status: 'fail',\n forged: false,\n detail: 'DCAP verifier unavailable in this build',\n };\n }\n const quoteBytes = hexToBytes(quoteHex.replace(/^0x/, ''));\n // Throws if the quote isn't a genuine TDX quote chaining to Intel's root.\n const vr = await getCollateralAndVerify(quoteBytes);\n const td = vr.report.asTd10() ?? vr.report.asTd15()?.base ?? null;\n const reportData = td?.reportData;\n const signingAddr = report?.signing_address?.replace(/^0x/, '').toLowerCase();\n const addrBound = Boolean(\n reportData &&\n signingAddr &&\n bytesToHex(reportData.slice(0, 20)) === signingAddr\n );\n const workloadMatch = report?.workload_id === receiptWorkloadId;\n const tcb = vr.status;\n const tcbBad = tcb === 'Revoked' || tcb === 'Unknown';\n const forged = !(addrBound && workloadMatch) || tcbBad;\n let detail: string;\n if (forged && tcbBad) {\n detail = `genuine TDX but TCB ${tcb}`;\n } else if (!addrBound) {\n detail = \"report_data does NOT commit the report's signing address\";\n } else if (!workloadMatch) {\n detail = \"quote workload_id does not match the receipt's\";\n } else {\n detail = `genuine Intel TDX (verified vs Intel collateral), TCB ${tcb}; report_data commits the attested signing address`;\n }\n return { status: forged ? 'fail' : 'pass', forged, tcbStatus: tcb, detail };\n } catch (e) {\n // A thrown verify is usually a PCCS/collateral/network issue, not a real\n // forgery from our own gateway — surface it but don't claim \"forged\".\n return {\n status: 'fail',\n forged: false,\n detail: `could not verify the quote: ${e instanceof Error ? e.message : 'error'}`,\n };\n }\n}\n\n/**\n * Verify a confidential response by its receipt id. Reads the signed receipt\n * (public), its on-chain Sui anchor (trustless), and reports a per-check result\n * that FAILS CLOSED on any forgery or mismatch.\n */\nexport async function verifyReceipt(\n receiptId: string,\n opts: VerifyOptions = {},\n): Promise<VerifyResult> {\n const base = opts.apiBase ?? DEFAULT_API_BASE;\n const network = opts.network ?? 'mainnet';\n const checks: VerifyCheck[] = [];\n\n // === 1. Receipt — fetch + structural soundness (public, no key) ===\n let receipt: AciReceipt | null = null;\n try {\n const res = await fetch(`${base}/aci/receipts/${encodeURIComponent(receiptId)}`);\n if (res.ok) {\n receipt = (await res.json()) as AciReceipt;\n }\n } catch {\n // network error → receipt stays null → fails closed below\n }\n if (!receipt?.event_log) {\n checks.push({\n name: 'Receipt',\n status: 'fail',\n detail: 'receipt not found or malformed',\n trust: 'receipt-asserted',\n });\n return { receiptId, verified: false, anchorVerified: false, checks };\n }\n const wireHash = receipt.event_log.find((e) => e.type === 'response.returned')\n ?.wire_hash;\n const workloadId = receipt.workload_id;\n checks.push({\n name: 'Receipt',\n status: wireHash && workloadId ? 'pass' : 'fail',\n detail: wireHash\n ? `well-formed (${receipt.event_log.length} log entries, workload ${workloadId})`\n : 'missing response wire_hash / workload_id',\n trust: 'receipt-asserted',\n });\n\n // === 2. Confidential upstream — attestation evidence in the signed receipt ===\n const upstreamEv = receipt.event_log.find((e) => e.type === 'upstream.verified');\n const upstreamOk = upstreamEv?.result === 'verified';\n const claims = normalizeClaims(upstreamEv?.claims);\n checks.push({\n name: 'Confidential upstream',\n status: upstreamEv ? (upstreamOk ? 'pass' : 'fail') : 'skip',\n detail: upstreamEv\n ? `${upstreamEv.provider ?? upstreamEv.upstream_name ?? 'upstream'}: ${upstreamEv.result ?? 'unknown'}${upstreamEv.tcb_status ? ` (TCB ${upstreamEv.tcb_status})` : ''}`\n : 'no upstream.verified event (routed/non-confidential?)',\n trust: 'receipt-asserted',\n });\n\n // === 3. Sui anchor — TRUSTLESS: read the on-chain event from a fullnode ===\n let anchorVerified = false;\n let anchor: VerifyAnchor | undefined;\n let digest: string | undefined;\n try {\n const res = await fetch(`${base}/aci/anchor/${encodeURIComponent(receiptId)}`);\n if (res.ok) {\n const j = (await res.json()) as { txDigest?: string };\n digest = j.txDigest;\n }\n } catch {\n // no anchor lookup → fails the anchor check below\n }\n if (!digest) {\n checks.push({\n name: 'Sui anchor',\n status: 'fail',\n detail: `no anchor on record — POST ${base}/aci/anchor/${receiptId} to create one`,\n trust: 'trustless',\n });\n } else {\n try {\n const client = new SuiGrpcClient({ baseUrl: fullnodeUrl(network), network });\n const tx = await client.core.getTransaction({\n digest,\n include: { events: true },\n });\n const txn = tx.$kind === 'Transaction' ? tx.Transaction : tx.FailedTransaction;\n const ev = (txn.events ?? []).find((e) =>\n e.eventType.endsWith(RECEIPT_ANCHORED_SUFFIX),\n );\n const data = (ev?.json ?? {}) as Record<string, unknown>;\n const onChainReceipt = String(data.receipt_id ?? '');\n const onChainWire = String(data.wire_hash ?? '');\n const onChainWorkload = String(data.workload_id ?? '');\n const matches =\n onChainReceipt === receiptId &&\n onChainWire === wireHash &&\n onChainWorkload === workloadId;\n anchorVerified = matches;\n anchor = {\n txDigest: digest,\n anchoredAtMs: data.anchored_at_ms ? String(data.anchored_at_ms) : undefined,\n anchoredBy: data.anchored_by ? String(data.anchored_by) : undefined,\n explorer: `https://suiscan.xyz/${network}/tx/${digest}`,\n };\n checks.push({\n name: 'Sui anchor',\n status: matches ? 'pass' : 'fail',\n detail: matches\n ? `on-chain ReceiptAnchored matches (wire_hash + workload_id), tx ${digest}`\n : `on-chain event does NOT match the receipt (wire ${onChainWire || 'absent'})`,\n trust: 'trustless',\n });\n } catch (e) {\n checks.push({\n name: 'Sui anchor',\n status: 'fail',\n detail: `could not read anchor tx ${digest}: ${e instanceof Error ? e.message : 'error'}`,\n trust: 'trustless',\n });\n }\n }\n\n // === 4. Receipt signature — recover the signer + match the attested key ===\n // The signing key (gateway receipt key) is workload-wide; fetch the attested\n // keyset and confirm its workload matches this receipt before trusting it.\n let sigStatus: CheckStatus = 'skip';\n let sigDetail = 'no signature on receipt';\n if (receipt.signature?.value) {\n try {\n const model = opts.model ?? 'phala/glm-5.2';\n const res = await fetch(\n `${base}/aci/attestation?model=${encodeURIComponent(model)}`,\n );\n const att = res.ok\n ? ((await res.json()) as { signingKey?: string; workloadId?: string })\n : null;\n if (!att?.signingKey) {\n sigDetail = 'could not fetch the attested keyset to check the signature';\n } else if (att.workloadId && att.workloadId !== workloadId) {\n sigDetail = `attested keyset is for a different workload — pass --model for ${workloadId}`;\n } else {\n const ok = verifyReceiptSignature(receipt, att.signingKey);\n sigStatus = ok ? 'pass' : 'fail';\n sigDetail = ok\n ? `signed by the attested receipt key (${receipt.signature.key_id ?? 'key'})`\n : 'signature does NOT recover the attested receipt key — forged/altered';\n }\n } catch {\n sigDetail = 'signature check errored';\n }\n }\n checks.push({\n name: 'Receipt signature',\n status: sigStatus,\n detail: sigDetail,\n trust: sigStatus === 'skip' ? 'roadmap' : 'trustless',\n });\n\n // === 5. TDX quote (DCAP) — verify the quote genuine + fresh, client-side ===\n if (opts.skipQuote) {\n checks.push({\n name: 'TDX quote (DCAP)',\n status: 'skip',\n detail: 'skipped (--quick)',\n trust: 'trustless',\n });\n } else {\n const q = await verifyTdxQuote(\n base,\n opts.model ?? 'phala/glm-5.2',\n workloadId ?? ''\n );\n checks.push({\n name: 'TDX quote (DCAP)',\n status: q.status,\n detail: q.detail,\n trust: 'trustless',\n });\n }\n\n // FAIL CLOSED: a sound receipt AND no trustless check left in `fail`. A DCAP\n // (or anchor/signature) check that errored counts as fail — \"couldn't prove\"\n // is \"not verified\"; we never report verified on an unchecked/failed quote.\n const trustlessFailed = checks.some(\n (c) => c.trust === 'trustless' && c.status === 'fail'\n );\n return {\n receiptId,\n verified: Boolean(wireHash && workloadId) && !trustlessFailed,\n anchorVerified,\n checks,\n wireHash,\n workloadId,\n upstream: upstreamEv\n ? {\n provider: upstreamEv.provider ?? upstreamEv.upstream_name,\n modelId: upstreamEv.model_id,\n result: upstreamEv.result,\n tcbStatus: upstreamEv.tcb_status,\n sessionId: upstreamEv.session_id,\n claims: claims.length > 0 ? claims : undefined,\n }\n : undefined,\n anchor,\n };\n}\n","// Unified spending-limit config store (`~/.t2000/config.json`). Moved here from\n// the CLI (`lib/config-store.ts`) + the SDK `SafeguardEnforcer` so ONE gate\n// serves CLI + MCP + programmatic writes (closes the H5 gap — R-0 Finding 1).\n//\n// Node-only (uses `node:fs`) — NOT re-exported from `browser.ts`. The browser\n// (Audric) write path skips client-side limits entirely; the server budget\n// ledger is the cap there.\n//\n// Schema (`~/.t2000/config.json`):\n// { \"limits\": { \"perTxUsd\": 25, \"dailyUsd\": 100 },\n// \"dailySpend\": { \"date\": \"2026-06-15\", \"usd\": 12.5 } }\n//\n// `daily` is CUMULATIVE across all outbound writes (send + swap + pay) since\n// midnight UTC — matches the engine's `autonomousDailyLimit` + the user mental\n// model (\"$100/day total\", not \"$100 per send\"). Locked S.424.\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport interface LimitsConfig {\n /** Caps any single outbound write (send | swap | pay) by USD value. */\n perTxUsd?: number;\n /** Caps CUMULATIVE outbound spend (all writes) per UTC day, by USD value. */\n dailyUsd?: number;\n}\n\nexport interface DailySpend {\n /** UTC date `YYYY-MM-DD` the running total applies to. */\n date: string;\n /** USD spent so far on `date`. */\n usd: number;\n}\n\nexport interface LimitsFile {\n limits?: LimitsConfig;\n dailySpend?: DailySpend;\n}\n\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.t2000');\n\nexport function resolveConfigPath(configDir?: string): string {\n return join(configDir ?? DEFAULT_CONFIG_DIR, 'config.json');\n}\n\n/** UTC date `YYYY-MM-DD`. */\nexport function todayUtc(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nexport function readLimitsFile(configDir?: string): LimitsFile {\n const path = resolveConfigPath(configDir);\n try {\n return sanitize(JSON.parse(readFileSync(path, 'utf-8')));\n } catch {\n return {};\n }\n}\n\n/**\n * Write the limits + dailySpend keys, PRESERVING any other keys already on\n * disk (a config file may carry unrelated data). Mode 0600.\n */\nexport function writeLimitsFile(file: LimitsFile, configDir?: string): string {\n const path = resolveConfigPath(configDir);\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n existing = {};\n }\n // Drop the dead v3 SafeguardEnforcer keys if present (maxPerTx/maxDailySend/\n // dailyUsed/dailyResetDate/locked) — they were never read by v4 and are\n // replaced by `limits` + `dailySpend`.\n for (const dead of ['maxPerTx', 'maxDailySend', 'dailyUsed', 'dailyResetDate', 'locked']) {\n delete existing[dead];\n }\n const merged: Record<string, unknown> = { ...existing };\n if (file.limits && (file.limits.perTxUsd !== undefined || file.limits.dailyUsd !== undefined)) {\n merged.limits = file.limits;\n } else {\n delete merged.limits;\n }\n if (file.dailySpend) merged.dailySpend = file.dailySpend;\n else delete merged.dailySpend;\n\n const dir = dirname(path);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(path, JSON.stringify(merged, null, 2) + '\\n', { mode: 0o600 });\n return path;\n}\n\nexport function getLimits(configDir?: string): LimitsConfig | undefined {\n return readLimitsFile(configDir).limits;\n}\n\nexport function hasLimits(configDir?: string): boolean {\n const l = readLimitsFile(configDir).limits;\n return !!l && (l.perTxUsd !== undefined || l.dailyUsd !== undefined);\n}\n\n/** Merge-set limits (only provided fields change). Returns the written path. */\nexport function setLimits(limits: LimitsConfig, configDir?: string): string {\n const file = readLimitsFile(configDir);\n const merged: LimitsConfig = { ...file.limits };\n if (limits.perTxUsd !== undefined) merged.perTxUsd = limits.perTxUsd;\n if (limits.dailyUsd !== undefined) merged.dailyUsd = limits.dailyUsd;\n return writeLimitsFile({ ...file, limits: merged }, configDir);\n}\n\n/** Remove all limits (keeps the dailySpend ledger). Returns the written path. */\nexport function clearLimits(configDir?: string): string {\n const file = readLimitsFile(configDir);\n return writeLimitsFile({ ...file, limits: undefined }, configDir);\n}\n\n/** Cumulative USD spent so far today (0 when the ledger is from a prior day). */\nexport function dailySpentToday(configDir?: string): number {\n const { dailySpend } = readLimitsFile(configDir);\n if (!dailySpend || dailySpend.date !== todayUtc()) return 0;\n return dailySpend.usd;\n}\n\n/** Add `usd` to today's running total (resets on UTC date rollover). */\nexport function recordDailySpend(usd: number, configDir?: string): void {\n if (!Number.isFinite(usd) || usd <= 0) return;\n const file = readLimitsFile(configDir);\n const today = todayUtc();\n const prior = file.dailySpend && file.dailySpend.date === today ? file.dailySpend.usd : 0;\n writeLimitsFile({ ...file, dailySpend: { date: today, usd: prior + usd } }, configDir);\n}\n\nfunction sanitize(raw: unknown): LimitsFile {\n if (typeof raw !== 'object' || raw === null) return {};\n const r = raw as Record<string, unknown>;\n const out: LimitsFile = {};\n\n if (typeof r.limits === 'object' && r.limits !== null) {\n const l = r.limits as Record<string, unknown>;\n const limits: LimitsConfig = {};\n if (typeof l.perTxUsd === 'number' && l.perTxUsd > 0) limits.perTxUsd = l.perTxUsd;\n // Migrate the legacy `dailySendUsd` (v4 CLI, per-send sub-cap) → `dailyUsd`\n // (cumulative all-writes). New canonical key wins if both are present.\n if (typeof l.dailyUsd === 'number' && l.dailyUsd > 0) limits.dailyUsd = l.dailyUsd;\n else if (typeof l.dailySendUsd === 'number' && l.dailySendUsd > 0) limits.dailyUsd = l.dailySendUsd;\n if (limits.perTxUsd !== undefined || limits.dailyUsd !== undefined) out.limits = limits;\n }\n\n if (typeof r.dailySpend === 'object' && r.dailySpend !== null) {\n const d = r.dailySpend as Record<string, unknown>;\n if (typeof d.date === 'string' && typeof d.usd === 'number' && d.usd >= 0) {\n out.dailySpend = { date: d.date, usd: d.usd };\n }\n }\n\n return out;\n}\n","// Spending-limit error — thrown by the unified limits gate (`@t2000/sdk/limits`)\n// when an outbound write exceeds an opted-in cap. Shared by CLI + MCP +\n// programmatic callers (the gate lives in the SDK write paths). Carries a\n// structured shape so the CLI can render `--json` output and the MCP can\n// surface a typed failure.\n\nexport type LimitKind = 'perTxUsd' | 'dailyUsd';\nexport type LimitOperation = 'send' | 'swap' | 'pay';\n\nexport class LimitExceededError extends Error {\n readonly code = 'LIMIT_EXCEEDED';\n readonly operation: LimitOperation;\n readonly limitKind: LimitKind;\n readonly limit: number;\n readonly attempted: number;\n\n constructor(params: {\n operation: LimitOperation;\n limitKind: LimitKind;\n limit: number;\n attempted: number;\n }) {\n const label = params.limitKind === 'perTxUsd' ? 'per-transaction limit' : 'daily spend limit';\n super(\n `Exceeds ${label} ($${params.limit}). Attempted $${params.attempted.toFixed(2)}. Use --force / force:true to override.`,\n );\n this.name = 'LimitExceededError';\n this.operation = params.operation;\n this.limitKind = params.limitKind;\n this.limit = params.limit;\n this.attempted = params.attempted;\n }\n\n toJSON(): unknown {\n return {\n error: this.code,\n message: this.message,\n operation: this.operation,\n limitKind: this.limitKind,\n limit: this.limit,\n attempted: this.attempted,\n };\n }\n}\n","// The unified spending-limit gate. ONE enforcer for CLI + MCP + programmatic\n// writes — wired into the T2000 write paths (send / swap / pay), so every\n// surface that calls those methods inherits the same cap (closes H5).\n//\n// USD-denominated. `perTxUsd` caps any single write; `dailyUsd` caps the\n// CUMULATIVE spend across all writes since UTC midnight (the running total\n// lives in the `dailySpend` ledger). `force` bypasses both — the caller owns\n// the prompt/consent.\n\nimport {\n type LimitsConfig,\n getLimits,\n setLimits,\n clearLimits,\n hasLimits,\n dailySpentToday,\n recordDailySpend,\n} from './config.js';\nimport { LimitExceededError, type LimitOperation } from './errors.js';\n\n/**\n * Best-effort USD value for an asset+amount pair, for the limit gate. Stables\n * are 1:1; SUI (and anything else) returns `null` — \"unknown, don't gate\".\n * The limits are USD-denominated; SUI-USD gating would need a price lookup and\n * is intentionally out of scope (matches the prior CLI behavior).\n */\nexport function approxUsdValue(asset: string, amount: number): number | null {\n const symbol = asset.toUpperCase();\n if (symbol === 'USDC' || symbol === 'USDSUI') return amount;\n return null;\n}\n\n/**\n * Pure gate — no I/O. Returns silently when allowed; throws\n * `LimitExceededError` when blocked.\n */\nexport function assertLimitConfig(input: {\n limits: LimitsConfig | undefined;\n spentTodayUsd: number;\n operation: LimitOperation;\n amountUsd: number;\n force?: boolean;\n}): void {\n if (input.force) return;\n if (!Number.isFinite(input.amountUsd) || input.amountUsd <= 0) return;\n const { limits } = input;\n if (!limits) return;\n\n if (limits.perTxUsd !== undefined && input.amountUsd > limits.perTxUsd) {\n throw new LimitExceededError({\n operation: input.operation,\n limitKind: 'perTxUsd',\n limit: limits.perTxUsd,\n attempted: input.amountUsd,\n });\n }\n\n if (limits.dailyUsd !== undefined && input.spentTodayUsd + input.amountUsd > limits.dailyUsd) {\n throw new LimitExceededError({\n operation: input.operation,\n limitKind: 'dailyUsd',\n // The cap is total/day; report the cap (attempted is THIS write's USD).\n limit: limits.dailyUsd,\n attempted: input.spentTodayUsd + input.amountUsd,\n });\n }\n}\n\nexport interface LimitAssertInput {\n operation: LimitOperation;\n /** This write's USD value. Pass 0 / non-positive to skip (e.g. SUI sends). */\n amountUsd: number;\n /** When true, skip the gate. */\n force?: boolean;\n}\n\n/**\n * The spending-limit enforcer — reads/writes `~/.t2000/config.json` (or a\n * `configDir` override for tests). Constructed once by the T2000 agent and\n * called around every outbound write; also drives the CLI `t2 limit` commands.\n */\nexport class LimitEnforcer {\n constructor(private readonly configDir?: string) {}\n\n /** Throws `LimitExceededError` when the write exceeds an opted-in cap. */\n assert(input: LimitAssertInput): void {\n assertLimitConfig({\n limits: getLimits(this.configDir),\n spentTodayUsd: dailySpentToday(this.configDir),\n operation: input.operation,\n amountUsd: input.amountUsd,\n force: input.force,\n });\n }\n\n /** Add a settled write's USD value to today's cumulative total. */\n record(amountUsd: number): void {\n recordDailySpend(amountUsd, this.configDir);\n }\n\n getLimits(): LimitsConfig | undefined {\n return getLimits(this.configDir);\n }\n\n hasLimits(): boolean {\n return hasLimits(this.configDir);\n }\n\n setLimits(limits: LimitsConfig): void {\n setLimits(limits, this.configDir);\n }\n\n clearLimits(): void {\n clearLimits(this.configDir);\n }\n\n dailySpentToday(): number {\n return dailySpentToday(this.configDir);\n }\n}\n","export { T2000 } from './t2000.js';\nexport type { TransactionSigner } from './signer.js';\nexport { KeypairSigner } from './wallet/keypairSigner.js';\nexport { ZkLoginSigner, type ZkLoginProof } from './wallet/zkLoginSigner.js';\nexport { payWithMpp, preflightPay, parseMppSuiChallenge } from './wallet/pay.js';\nexport {\n chatCompletion,\n chatCompletionStream,\n listModels,\n DEFAULT_API_BASE,\n} from './inference.js';\nexport type {\n ChatMessage,\n ChatParams,\n ChatResult,\n ChatUsage,\n ApiModel,\n} from './inference.js';\nexport { verifyReceipt } from './verify.js';\nexport type {\n VerifyResult,\n VerifyCheck,\n VerifyAnchor,\n VerifyUpstream,\n UpstreamClaim,\n VerifyOptions,\n CheckStatus,\n TrustMode,\n} from './verify.js';\nexport { executeTx } from './wallet/executeTx.js';\nexport { T2000Error, mapWalletError, mapMoveAbortCode } from './errors.js';\nexport type { T2000ErrorCode, T2000ErrorData } from './errors.js';\nexport type {\n T2000Options,\n BalanceResponse,\n SuiHolding,\n SendResult,\n DepositInfo,\n PaymentRequest,\n TransactionRecord,\n TransactionLeg,\n PayOptions,\n PayResult,\n SwapResult,\n SwapQuoteResult,\n} from './types.js';\nexport {\n MIST_PER_SUI,\n SUI_DECIMALS,\n USDC_DECIMALS,\n T2000_OVERLAY_FEE_WALLET,\n SUPPORTED_ASSETS,\n CLOCK_ID,\n DEFAULT_NETWORK,\n} from './constants.js';\nexport type { SupportedAsset, StableAsset, SendableAsset } from './constants.js';\nexport {\n STABLE_ASSETS,\n SENDABLE_ASSETS,\n GASLESS_MIN_STABLE_AMOUNT,\n GASLESS_STABLE_TYPES,\n DEFAULT_GRPC_URL,\n GAS_RESERVE_MIN,\n CETUS_USDC_SUI_POOL,\n OPERATION_ASSETS,\n isAllowedAsset,\n assertAllowedAsset,\n} from './constants.js';\nexport type { Operation } from './constants.js';\nexport {\n validateAddress,\n truncateAddress,\n normalizeCoinType,\n getSuiClient,\n getSuiGrpcClient,\n} from './utils/sui.js';\nexport {\n SUI_ADDRESS_REGEX,\n SUI_ADDRESS_STRICT_REGEX,\n SUINS_NAME_REGEX,\n InvalidAddressError,\n SuinsNotRegisteredError,\n SuinsRpcError,\n looksLikeSuiNs,\n resolveSuinsViaRpc,\n resolveAddressToSuinsViaRpc,\n normalizeAddressInput,\n} from './utils/suins.js';\nexport type { NormalizedAddress } from './utils/suins.js';\nexport {\n KNOWN_TARGETS,\n LABEL_PATTERNS,\n classifyAction,\n classifyLabel,\n fallbackLabel,\n refineLendingLabel,\n classifyTransaction,\n extractTransferDetails,\n extractAllUserLegs,\n} from './wallet/classify.js';\nexport type {\n ClassifyBalanceChange,\n ClassifyResult,\n ExtractedTransfer,\n TxDirection,\n} from './wallet/classify.js';\nexport {\n parseSuiRpcTx,\n extractTxSender,\n extractTxCommands,\n queryHistory,\n queryTransaction,\n} from './wallet/history.js';\nexport type { SuiRpcTxBlock } from './wallet/history.js';\nexport { queryBalance } from './wallet/balance.js';\nexport {\n mistToSui,\n suiToMist,\n usdcToRaw,\n rawToUsdc,\n stableToRaw,\n rawToStable,\n getDecimals,\n formatUsd,\n formatSui,\n formatAssetAmount,\n normalizeAsset,\n} from './utils/format.js';\nexport {\n generateKeypair,\n keypairFromPrivateKey,\n saveKey,\n saveBech32,\n loadKey,\n walletExists,\n exportPrivateKey,\n getAddress,\n} from './wallet/keyManager.js';\nexport { buildSendTx, addSendToTx, preflightSend } from './wallet/send.js';\nexport {\n A2A_ESCROW_PACKAGE_ID,\n A2A_ESCROW_FEE_CONFIG_ID,\n MAX_JOB_USDC,\n MAX_REVIEW_WINDOW_MS,\n MAX_DELIVER_HORIZON_MS,\n JOB_STATES,\n preflightCreateJob,\n buildCreateJobTx,\n buildDeliverJobTx,\n buildReleaseJobTx,\n buildRejectJobTx,\n buildRefundJobTx,\n getJob,\n jobActionsFor,\n verifyJobForSeller,\n} from './wallet/job.js';\nexport type { Job, JobState, JobTerms, JobVerification } from './wallet/job.js';\nexport {\n fetchAllCoins,\n selectAndSplitCoin,\n selectSuiCoin,\n} from './wallet/coinSelection.js';\nexport type { CoinPage, SelectAndSplitResult } from './wallet/coinSelection.js';\nexport {\n composeTx,\n deriveAllowedAddressesFromPtb,\n WRITE_APPENDER_REGISTRY,\n SPONSORED_PYTH_DEPENDENT_PROVIDERS,\n getSponsoredSwapProviders,\n} from './composeTx.js';\nexport type {\n WriteToolName,\n WriteStep,\n ComposeTxOptions,\n ComposeTxResult,\n AppenderContext,\n StepPreview,\n SendTransferInput,\n SwapExecuteInput,\n} from './composeTx.js';\nexport { simulateTransaction, throwIfSimulationFailed } from './utils/simulate.js';\nexport type { SimulationResult } from './utils/simulate.js';\nexport { getSwapQuote } from './swap-quote.js';\nexport {\n findSwapRoute,\n buildSwapTx,\n addSwapToTx,\n preflightSwap,\n OVERLAY_FEE_RATE,\n serializeCetusRoute,\n deserializeCetusRoute,\n verifyCetusRouteCoinMatch,\n isCetusRouteFresh,\n} from './protocols/cetus-swap.js';\nexport type {\n SwapRouteResult,\n OverlayFeeConfig,\n SerializedCetusRoute,\n SerializedRouterDataV3,\n SerializedCetusRoutePath,\n} from './protocols/cetus-swap.js';\nexport {\n COIN_REGISTRY,\n TOKEN_MAP,\n resolveTokenType,\n resolveSymbol,\n getDecimalsForCoinType,\n getCoinMeta,\n isInRegistry,\n SUI_TYPE,\n USDC_TYPE,\n USDT_TYPE,\n USDSUI_TYPE,\n USDE_TYPE,\n ETH_TYPE,\n WBTC_TYPE,\n WAL_TYPE,\n NAVX_TYPE,\n IKA_TYPE,\n LOFI_TYPE,\n MANIFEST_TYPE,\n} from './token-registry.js';\nexport type { CoinMeta } from './token-registry.js';\n// [S.323 / 2026-05-25] VOLO vSUI staking re-exports removed (full cut).\n// vSUI still exists in the codebase as a passive token (NAVI reward type\n// + Cetus swap target), but t2000 no longer exposes mint/redeem surfaces.\nexport {\n AGENT_ID_PARENT,\n AGENT_ID_PARENT_NAME,\n AGENT_ID_PARENT_NFT_ID,\n AUDRIC_PARENT,\n AUDRIC_PARENT_NAME,\n AUDRIC_PARENT_NFT_ID,\n buildAddLeafTx,\n buildRevokeLeafTx,\n displayHandle,\n fullHandle,\n validateLabel,\n} from './protocols/suins-leaf.js';\nexport type {\n BuildAddLeafParams,\n BuildRevokeLeafParams,\n LabelValidationResult,\n SuinsParent,\n} from './protocols/suins-leaf.js';\n// Unified spending limits (per-tx + cumulative daily, USD) — one gate for\n// CLI + MCP + programmatic writes (R-0 Finding 1; closes H5). Node-only.\nexport {\n LimitEnforcer,\n LimitExceededError,\n approxUsdValue,\n assertLimitConfig,\n getLimits,\n hasLimits,\n setLimits,\n clearLimits,\n dailySpentToday,\n recordDailySpend,\n readLimitsFile,\n writeLimitsFile,\n} from './limits/index.js';\nexport type { LimitsConfig, DailySpend, LimitsFile, LimitKind, LimitOperation, LimitAssertInput } from './limits/index.js';\n// Synchronous, network-free preflight (layer 2) — pure input validation the\n// v3 host runs before the LLM round-trip / tap-to-confirm. Per-builder\n// validators (`preflightSend`/`preflightPay`/`preflightSwap`) are exported\n// alongside their builders above; these are the shared primitives.\nexport {\n type PreflightResult,\n PREFLIGHT_MAX_AMOUNT,\n PREFLIGHT_OK,\n preflightFail,\n checkPositiveAmount,\n checkSuiAddress,\n} from './preflight.js';\n","import { Transaction } from '@mysten/sui/transactions';\nimport { T2000Error } from '../errors.js';\nimport { USDC_TYPE } from '../token-registry.js';\nimport { USDC_DECIMALS } from '../constants.js';\nimport {\n type PreflightResult,\n PREFLIGHT_OK,\n preflightFail,\n checkSuiAddress,\n} from '../preflight.js';\nimport { validateAddress, type SuiCoreClient } from '../utils/sui.js';\nimport { selectAndSplitCoin } from './coinSelection.js';\n\n/**\n * A2A Escrow — client for the `a2a_escrow::escrow` Move package\n * (SPEC_A2A_ESCROW, t2 Agents Phase 3).\n *\n * One shared `Job<USDC>` object per engagement; the escrow balance lives IN\n * the object (no treasury, no admin key). These builders construct UNSIGNED\n * transactions; the caller signs (buyer for create/release/reject, seller\n * for deliver, ANYONE for the two timeout cranks) and may sponsor gas — the\n * Move calls authorize on `ctx.sender()`, so sponsorship never weakens auth.\n *\n * Browser-safe (no fs / keyManager imports) so store surfaces can build the\n * buyer-side legs on a zkLogin session key.\n *\n * Deployed on Sui mainnet 2026-07-18 (fresh publish after the contract\n * review — 2.5% in-contract protocol fee (D-1, SPEC_ACP_SUI §7) snapshotted\n * onto the Job at create, FeeConfig versioning, bounded windows). Override\n * via env for testnet/dev.\n */\n\n/** The published `a2a_escrow` package id (mainnet). */\nexport const A2A_ESCROW_PACKAGE_ID =\n process.env.A2A_ESCROW_PACKAGE_ID ??\n '0x358a819c1c016e2cc84ef5fbea81cba90c31f7f8a62bf45cb5e5276acf198bdd';\n\n/** The shared `FeeConfig` object every escrow entry reads (mainnet). */\nexport const A2A_ESCROW_FEE_CONFIG_ID =\n process.env.A2A_ESCROW_FEE_CONFIG_ID ??\n '0xddaa25570950b7484dbf20797ebcf75707be9c87cd67bef2a06ed2e81d2c494b';\n\n/** `initial_shared_version` of the FeeConfig — lets builders reference the\n * shared object without a resolution round-trip (browser + PTB friendly). */\nexport const A2A_ESCROW_FEE_CONFIG_VERSION = Number(\n process.env.A2A_ESCROW_FEE_CONFIG_VERSION ?? 931861903,\n);\n\nconst CLOCK_ID = '0x6';\nconst MODULE = 'escrow';\n\n/** Immutable reference to the shared FeeConfig for the five escrow verbs. */\nfunction feeConfigArg(tx: Transaction) {\n return tx.sharedObjectRef({\n objectId: A2A_ESCROW_FEE_CONFIG_ID,\n initialSharedVersion: A2A_ESCROW_FEE_CONFIG_VERSION,\n mutable: false,\n });\n}\n\n/** v1 job-value cap in USDC — same instinct as the catalog price cap: the\n * no-arbitration reject-split is only fair at sizes where neither side is\n * incentivized to game it (SPEC_A2A_ESCROW §2). */\nexport const MAX_JOB_USDC = 50;\n\n/** Contract-enforced create bounds (mirror `escrow.move` — the caps that\n * close the v1 unbounded-window overflow lock). */\nexport const MAX_REVIEW_WINDOW_MS = 2_592_000_000; // 30 days\nexport const MAX_DELIVER_HORIZON_MS = 31_536_000_000; // 365 days\n\n/** Job lifecycle states, mirroring the Move constants. */\nexport const JOB_STATES = [\n 'funded',\n 'delivered',\n 'released',\n 'refunded',\n 'rejected',\n] as const;\nexport type JobState = (typeof JOB_STATES)[number];\n\nexport interface JobTerms {\n /** The seller's wallet (the listing's payTo / claimed Agent ID wallet). */\n seller: string;\n /** Job value in display USDC (e.g. `5` = 5 USDC). ≤ `MAX_JOB_USDC`. */\n amountUsdc: number;\n /** Hash/commitment of the job spec (hex string, `0x…` or bare). */\n specHash: string;\n /** Epoch-ms deadline the seller must deliver by. */\n deliverByMs: number;\n /** Buyer's accept/reject window (ms) after delivery; lapse = release. */\n reviewWindowMs: number;\n /** Buyer's share in basis points on reject (0–10000). Fixed at create. */\n rejectSplitBps: number;\n}\n\n/** Parsed on-chain `Job` object. */\nexport interface Job {\n id: string;\n buyer: string;\n seller: string;\n /** Locked amount in display USDC (immutable record). */\n amountUsdc: number;\n /** What's still in the object — 0 after settlement. */\n escrowUsdc: number;\n /** Protocol fee bps snapshotted at create (taken from seller-bound funds\n * at settlement; refunds are fee-free). */\n feeBps: number;\n specHash: string;\n deliverByMs: number;\n reviewWindowMs: number;\n rejectSplitBps: number;\n state: JobState;\n deliveryHash: string | null;\n deliveredAtMs: number | null;\n createdAtMs: number;\n}\n\n// ---------------------------------------------------------------------------\n// Hash plumbing — spec/delivery commitments travel as vector<u8>.\n// ---------------------------------------------------------------------------\n\nfunction hexToBytes(hex: string): number[] {\n const clean = hex.startsWith('0x') ? hex.slice(2) : hex;\n if (clean.length === 0 || clean.length % 2 !== 0 || /[^0-9a-fA-F]/.test(clean)) {\n throw new T2000Error(\n 'INVALID_AMOUNT',\n `Expected a hex hash (0x…), got \"${hex.slice(0, 32)}\"`,\n );\n }\n const out: number[] = [];\n for (let i = 0; i < clean.length; i += 2) {\n out.push(Number.parseInt(clean.slice(i, i + 2), 16));\n }\n return out;\n}\n\n/** gRPC's `json` include renders Move `vector<u8>` as a base64 STRING;\n * JSON-RPC (and tests) hand back number arrays. Accept both. */\nfunction bytesToHex(bytes: number[] | Uint8Array | string): string {\n const arr =\n typeof bytes === 'string'\n ? Array.from(atob(bytes), (c) => c.charCodeAt(0))\n : bytes;\n let s = '0x';\n for (const b of arr) s += b.toString(16).padStart(2, '0');\n return s;\n}\n\n// ---------------------------------------------------------------------------\n// Preflight\n// ---------------------------------------------------------------------------\n\n/**\n * Synchronous, network-free preflight for `create`. Terms sanity only —\n * the balance read happens in `buildCreateJobTx`.\n */\nexport function preflightCreateJob(terms: JobTerms): PreflightResult {\n const addressCheck = checkSuiAddress(terms.seller);\n if (!addressCheck.valid) return addressCheck;\n if (!Number.isFinite(terms.amountUsdc) || terms.amountUsdc <= 0) {\n return preflightFail('INVALID_AMOUNT', `Amount must be positive. Got ${terms.amountUsdc}.`);\n }\n if (terms.amountUsdc > MAX_JOB_USDC) {\n return preflightFail(\n 'INVALID_AMOUNT',\n `v1 caps escrow jobs at ${MAX_JOB_USDC} USDC (no-arbitration split only stays fair at small sizes). Got ${terms.amountUsdc}.`,\n );\n }\n if (terms.deliverByMs <= Date.now()) {\n return preflightFail('INVALID_AMOUNT', 'deliverByMs must be in the future.');\n }\n if (terms.deliverByMs > Date.now() + MAX_DELIVER_HORIZON_MS) {\n return preflightFail('INVALID_AMOUNT', 'deliverByMs is more than 365 days out.');\n }\n if (terms.reviewWindowMs < 0 || terms.reviewWindowMs > MAX_REVIEW_WINDOW_MS) {\n return preflightFail('INVALID_AMOUNT', 'reviewWindowMs must be 0–30 days.');\n }\n if (\n !Number.isInteger(terms.rejectSplitBps) ||\n terms.rejectSplitBps < 0 ||\n terms.rejectSplitBps > 10_000\n ) {\n return preflightFail('INVALID_AMOUNT', 'rejectSplitBps must be an integer 0–10000.');\n }\n try {\n hexToBytes(terms.specHash);\n } catch (e) {\n return preflightFail('INVALID_AMOUNT', (e as T2000Error).message);\n }\n return PREFLIGHT_OK;\n}\n\n// ---------------------------------------------------------------------------\n// Transaction builders (unsigned; caller signs + executes / sponsors)\n// ---------------------------------------------------------------------------\n\n/**\n * Buyer creates AND funds a job in one PTB — `escrow::create` consumes a\n * `Coin<USDC>` sourced from the buyer's coins + address balance.\n */\nexport async function buildCreateJobTx({\n client,\n buyer,\n terms,\n}: {\n client: SuiCoreClient;\n buyer: string;\n terms: JobTerms;\n}): Promise<Transaction> {\n const pf = preflightCreateJob(terms);\n if (!pf.valid) throw new T2000Error(pf.code, pf.error);\n\n const seller = validateAddress(terms.seller);\n if (seller === validateAddress(buyer)) {\n throw new T2000Error('INVALID_ADDRESS', 'Buyer and seller must be different wallets.');\n }\n // Floor, never round up — a rounded-up raw amount can exceed the on-chain\n // balance (financial-amounts discipline).\n const rawAmount = BigInt(Math.floor(terms.amountUsdc * 10 ** USDC_DECIMALS));\n\n const tx = new Transaction();\n const { coin } = await selectAndSplitCoin(tx, client, buyer, USDC_TYPE, rawAmount, {\n allowSwapAll: false,\n });\n tx.moveCall({\n target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::create`,\n typeArguments: [USDC_TYPE],\n arguments: [\n tx.pure.address(seller),\n coin,\n tx.pure.vector('u8', hexToBytes(terms.specHash)),\n tx.pure.u64(terms.deliverByMs),\n tx.pure.u64(terms.reviewWindowMs),\n tx.pure.u64(terms.rejectSplitBps),\n feeConfigArg(tx),\n tx.object(CLOCK_ID),\n ],\n });\n return tx;\n}\n\nfunction jobCall(jobId: string, fn: 'release' | 'refund' | 'reject'): Transaction {\n const tx = new Transaction();\n tx.moveCall({\n target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::${fn}`,\n typeArguments: [USDC_TYPE],\n arguments: [tx.object(jobId), feeConfigArg(tx), tx.object(CLOCK_ID)],\n });\n return tx;\n}\n\n/** Seller posts the delivery commitment (hex hash) before the deadline. */\nexport function buildDeliverJobTx(jobId: string, deliveryHash: string): Transaction {\n const tx = new Transaction();\n tx.moveCall({\n target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::deliver`,\n typeArguments: [USDC_TYPE],\n arguments: [\n tx.object(jobId),\n tx.pure.vector('u8', hexToBytes(deliveryHash)),\n feeConfigArg(tx),\n tx.object(CLOCK_ID),\n ],\n });\n return tx;\n}\n\n/** Buyer accepts (or anyone, once the review window lapsed) → funds to seller. */\nexport function buildReleaseJobTx(jobId: string): Transaction {\n return jobCall(jobId, 'release');\n}\n\n/** Buyer rejects within the review window → split per the create terms. */\nexport function buildRejectJobTx(jobId: string): Transaction {\n return jobCall(jobId, 'reject');\n}\n\n/** Anyone, after the deadline with no delivery → funds back to the buyer. */\nexport function buildRefundJobTx(jobId: string): Transaction {\n return jobCall(jobId, 'refund');\n}\n\n// ---------------------------------------------------------------------------\n// Reads\n// ---------------------------------------------------------------------------\n\n/** Fetch + parse a `Job` shared object. Throws `RPC_ERROR` when the id\n * doesn't resolve to an a2a_escrow Job. */\nexport async function getJob(client: SuiCoreClient, jobId: string): Promise<Job> {\n const resp = await client.core\n .getObject({ objectId: jobId, include: { json: true } })\n .catch((e: unknown) => {\n throw new T2000Error(\n 'RPC_ERROR',\n `Job ${jobId} not found: ${e instanceof Error ? e.message : String(e)}`,\n );\n });\n const objType = resp.object?.type ?? '';\n const json = resp.object?.json as Record<string, unknown> | null | undefined;\n if (!json || !objType.includes(`::${MODULE}::Job<`)) {\n throw new T2000Error('RPC_ERROR', `Object ${jobId} is not an a2a_escrow Job.`);\n }\n const stateNum = Number(json.state ?? -1);\n const state = JOB_STATES[stateNum];\n if (!state) {\n throw new T2000Error('RPC_ERROR', `Job ${jobId} has unknown state ${stateNum}.`);\n }\n const deliveredAtMs = Number(json.delivered_at_ms ?? 0);\n const deliveryBytes = (json.delivery_hash ?? []) as number[] | Uint8Array;\n const hasDelivery = deliveredAtMs > 0;\n return {\n id: jobId,\n buyer: String(json.buyer),\n seller: String(json.seller),\n amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,\n escrowUsdc: Number(json.escrow) / 10 ** USDC_DECIMALS,\n feeBps: Number(json.fee_bps ?? 0),\n specHash: bytesToHex((json.spec_hash ?? []) as number[] | Uint8Array),\n deliverByMs: Number(json.deliver_by_ms),\n reviewWindowMs: Number(json.review_window_ms),\n rejectSplitBps: Number(json.reject_split_bps),\n state,\n deliveryHash: hasDelivery ? bytesToHex(deliveryBytes) : null,\n deliveredAtMs: hasDelivery ? deliveredAtMs : null,\n createdAtMs: Number(json.created_at_ms),\n };\n}\n\n/** What `caller` can do to `job` right now — drives `t2 job watch` (the\n * ACP-style \"available action\" readout) and any host UI. */\nexport function jobActionsFor(\n job: Job,\n caller: string,\n nowMs = Date.now(),\n): string[] {\n const me = validateAddress(caller);\n const isBuyer = me === job.buyer;\n const isSeller = me === job.seller;\n const actions: string[] = [];\n if (job.state === 'funded') {\n if (isSeller && nowMs <= job.deliverByMs) actions.push('deliver');\n if (isBuyer) actions.push('release');\n if (nowMs > job.deliverByMs) actions.push('refund');\n } else if (job.state === 'delivered') {\n const windowClosesMs = (job.deliveredAtMs ?? 0) + job.reviewWindowMs;\n if (isBuyer && nowMs <= windowClosesMs) actions.push('release', 'reject');\n if (nowMs > windowClosesMs) actions.push('release');\n }\n return actions;\n}\n\nexport interface JobVerification {\n ok: boolean;\n job: Job;\n /** Human-readable reasons when `ok` is false. */\n problems: string[];\n}\n\n/**\n * Seller-side escrow verification — the x402 `intent: \"escrow\"` credential\n * check. Before starting work on a job id received in an `X-PAYMENT` header,\n * the seller confirms ON-CHAIN (works for every buyer signer, incl. zkLogin):\n * funded, pays ME, covers the price, and leaves enough runway to deliver.\n */\nexport async function verifyJobForSeller({\n client,\n jobId,\n seller,\n minAmountUsdc,\n minRunwayMs = 60_000,\n}: {\n client: SuiCoreClient;\n jobId: string;\n seller: string;\n /** The listing's price for this job class. */\n minAmountUsdc: number;\n /** Minimum time-to-deadline to accept the job (default 60s). */\n minRunwayMs?: number;\n}): Promise<JobVerification> {\n const job = await getJob(client, jobId);\n const problems: string[] = [];\n if (job.state !== 'funded') {\n problems.push(`state is \"${job.state}\", expected \"funded\"`);\n }\n if (job.seller !== validateAddress(seller)) {\n problems.push(`job pays ${job.seller}, not this seller`);\n }\n if (job.escrowUsdc < minAmountUsdc) {\n problems.push(`escrow holds ${job.escrowUsdc} USDC, price is ${minAmountUsdc}`);\n }\n if (job.deliverByMs - Date.now() < minRunwayMs) {\n problems.push('deadline too close to accept');\n }\n return { ok: problems.length === 0, job, problems };\n}\n","/**\n * SPEC 7 v0.4 § Layer 0 — Canonical Write Architecture.\n *\n * `composeTx({ steps })` is the single canonical entry-point for every\n * Audric Enoki-sponsored write. The fragment-appender pattern (Layer 1)\n * is the implementation; this primitive dispatches each step to its\n * registered appender from the typed `WRITE_APPENDER_REGISTRY`.\n *\n * Single-write and multi-write go through the same code path. A 1-step\n * `composeTx([{ toolName: 'send_transfer', input: {...} }])` produces\n * the same shape of result as a 3-step bundle.\n *\n * **Why this exists**\n *\n * Pre-Layer-0, four parallel write stacks lived across the audric host:\n * `transactions/prepare` (fat ~600-line route), `services/prepare`\n * (hand-rolled), `debug-swap` (diagnostic), and PayButton (dapp-kit).\n * Each one re-implemented merge/split/transfer + hand-maintained the\n * `allowedAddresses` array Enoki requires. Two production bugs in the\n * past 60 days came from drift between them — PR-H1 (claim-rewards\n * self-transfer missing from allowedAddresses) and PR-H4 (borrow/\n * withdraw self-transfer same bug).\n *\n * Layer 0 collapses 3 of those stacks into one canonical primitive.\n * PayButton stays out by design (different signer, different trust\n * model — see `audric-canonical-write.mdc` for the rationale and the\n * `// CANONICAL-BYPASS:` escape-hatch contract).\n *\n * **What composeTx owns**\n *\n * - PTB assembly via per-tool wallet-mode appenders (the\n * `WRITE_APPENDER_REGISTRY`).\n * - Pre-built `txKindBytes` (`tx.build({ onlyTransactionKind: true })`)\n * ready for Enoki's `createSponsoredTransaction`.\n * - Auto-derived `derivedAllowedAddresses` from the assembled PTB's\n * top-level `transferObjects` calls — eliminates the PR-H1/H4 bug\n * class permanently. Hand-maintained arrays are now unreachable.\n * - S.38 Pyth flag plumbing — `sponsoredContext: true` automatically\n * applies `skipPythUpdate` (borrow/withdraw) and `skipOracle` (repay)\n * to NAVI appenders so Enoki doesn't reject `tx.gas`-as-argument.\n *\n * **What composeTx does NOT own**\n *\n * - **Fees** — Audric concern, not @t2000/sdk concern (CLAUDE.md\n * rule #9). The SDK is fee-free by design as of @t2000/sdk@1.1.0\n * (B5 v2). Audric host wraps composeTx with fee insertion in P2.2c.\n * - **Sponsorship** — caller's job. composeTx returns `txKindBytes`\n * pre-built for Enoki; the caller calls `createSponsoredTransaction`\n * with their JWT.\n * - **Chain-mode coin handoff between steps** — Layer 2 (engine\n * bundling) ships this. P2.2b is wallet-mode-only: each step fetches\n * coins independently. Layer 2 will extend by introducing\n * `inputCoinFromStep: number` to thread upstream output coins.\n *\n * **Cross-references**\n *\n * - Spec → `spec/SPEC_7_MULTI_WRITE_PTB.md` § \"Layer 0: Canonical\n * Write Architecture\"\n * - Read-side companion → `t2000/.cursor/rules/single-source-of-truth.mdc`\n * + `audric/.cursor/rules/audric-canonical-portfolio.mdc`\n * - Write-side rule → `audric/.cursor/rules/audric-canonical-write.mdc`\n */\n\nimport type { SuiCoreClient } from './utils/sui.js';\nimport {\n Transaction,\n type TransactionObjectArgument,\n} from '@mysten/sui/transactions';\nimport type { OverlayFeeConfig } from './protocols/cetus-swap.js';\nimport { addSwapToTx, type SwapRouteResult } from './protocols/cetus-swap.js';\nimport { addSendToTx } from './wallet/send.js';\nimport {\n selectSuiCoin,\n type SponsoredCoinMergeCache,\n} from './wallet/coinSelection.js';\nimport { resolveTokenType, getDecimalsForCoinType, SUI_TYPE } from './token-registry.js';\nimport {\n GASLESS_MIN_STABLE_AMOUNT,\n GASLESS_STABLE_TYPES,\n SUPPORTED_ASSETS,\n assertAllowedAsset,\n type SendableAsset,\n type SupportedAsset,\n} from './constants.js';\nimport { T2000Error } from './errors.js';\nimport { validateAddress } from './utils/sui.js';\n\n/**\n * Canonical write tools. The 8 tools that can be composed into a PTB.\n *\n * History:\n * - 2026-05-08 (Track B): added `harvest_rewards` (compound macro).\n * - 2026-05-25 (S.323): removed `volo_stake` / `volo_unstake` — full Volo\n * cut across SDK/CLI/MCP after the engine cut Volo in S.277. vSUI\n * remains as a passive token (NAVI reward, Cetus swap target).\n *\n * Excluded by design:\n * - `save_contact` — no on-chain leg (Prisma-only).\n */\n// [S.444 — NAVI/DeFi removed] Canonical write tools narrowed to the two\n// surviving on-chain verbs: gasless send + Cetus swap. save/withdraw/borrow/\n// repay/claim/harvest were deleted with NAVI (v2 keeps them on @t2000/sdk@4.x).\nexport type WriteToolName =\n | 'send_transfer'\n | 'swap_execute';\n\n// Per-tool input contracts. Match the engine tool input schemas, not the\n// audric host's loosely-typed `params` blob — the registry is the typed\n// surface that lets the host shed the `any`-typed switch statement.\n\n/**\n * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]\n * `asset` is now REQUIRED (no more silent USDC default). The parameter\n * type is the wider `SupportedAsset` rather than the narrower\n * `SendableAsset` so callers that thread a wide-typed asset through\n * (primarily the engine LLM tool surface) compile without modification.\n * Runtime narrowing happens via `assertAllowedAsset('send', asset)`,\n * which throws `INVALID_ASSET` for anything outside the\n * `['USDC', 'USDsui', 'SUI']` whitelist. USDC + USDsui route through\n * the gasless `0x2::balance::send_funds` Move call; SUI uses the\n * standard `transferObjects` path.\n *\n * Audric hosts: the audric chat client (`audric-chat-client.tsx`)\n * already defaults asset to `'USDC'` at the marker layer before\n * calling `sponsoredTx({ type: 'send' })`, so this signature change\n * doesn't break the LLM flow. LLM intents like \"send 5 WAL\" now\n * surface a clear error instead of silently building a non-gasless\n * tx.\n */\nexport interface SendTransferInput {\n to: string;\n amount: number;\n asset: SupportedAsset;\n}\n\nexport interface SwapExecuteInput {\n from: string;\n to: string;\n amount: number;\n slippage?: number;\n byAmountIn?: boolean;\n /** Cetus provider allow-list. Sponsored callers MUST pass an exclusion list\n * to remove Pyth-dependent providers — see addSwapToTx JSDoc. composeTx\n * derives this automatically from `sponsoredContext` if omitted. */\n providers?: string[];\n /**\n * [SPEC 20.2 / D-1 (a)] Optional precomputed Cetus route discovered at\n * `swap_quote` time. Bypasses `findSwapRoute()` (-400-500ms) inside\n * `addSwapToTx`. Caller (audric prepare-route) is responsible for\n * coin-type verification (D-2) + freshness check (D-3) before passing.\n * `addSwapToTx` performs an additional sanity check on `amountIn` +\n * `byAmountIn` and falls back to fresh discovery on mismatch.\n */\n precomputedRoute?: SwapRouteResult;\n}\n\n/**\n * Discriminated union mapping `toolName` → `input`. Used to type\n * `WriteStep` so consumers get autocomplete + compile-time validation\n * that the input matches the tool.\n *\n * **[SPEC 13 Phase 1] `inputCoinFromStep`** — consumer steps may\n * reference an earlier step's output coin handle by index. When set,\n * `composeTx`'s orchestration loop threads the producer's\n * `outputCoin` into this step's appender as the `inputCoin` arg,\n * bypassing the wallet pre-fetch path. The producer's terminal\n * `tx.transferObjects([coin], sender)` is suppressed automatically so\n * the same handle isn't double-consumed.\n */\nexport type WriteStep =\n | { toolName: 'send_transfer'; input: SendTransferInput; inputCoinFromStep?: number }\n | { toolName: 'swap_execute'; input: SwapExecuteInput; inputCoinFromStep?: number };\n\nexport interface ComposeTxOptions {\n sender: string;\n steps: WriteStep[];\n client: SuiCoreClient;\n /**\n * S.38 Pyth flag (sponsorship-critical). When true:\n * - NAVI borrow/withdraw appenders apply `skipPythUpdate: true`\n * (preserves on-chain price-feed updates, skips the tx.gas-using\n * Pyth fee payment that Enoki rejects).\n * - NAVI repay appender applies `skipOracle: true` (debt reduction\n * has no health-factor risk, full oracle bypass is safe).\n * - Cetus swap appender applies `getProvidersExcluding([HAEDALPMM,\n * METASTABLE, OBRIC, STEAMM_OMM, STEAMM_OMM_V2, SEVENK,\n * HAEDALHMMV2])` — Pyth-dependent providers reference `tx.gas` for\n * oracle fees, also rejected by Enoki.\n * - SUI sends fetch coins via `getCoins` (tx.gas belongs to sponsor,\n * not user) instead of splitting from `tx.gas`.\n *\n * Self-funded callers (CLI, MCP, server tasks) leave this `false` /\n * omit — they pay all oracle/Pyth fees from their own SUI gas.\n */\n sponsoredContext?: boolean;\n /**\n * Per-call overlay fee config for Cetus swaps. Audric host passes\n * `{ rate: 0.001, receiver: T2000_OVERLAY_FEE_WALLET }` to charge the\n * 0.1% swap overlay. CLI / direct SDK callers omit. Forwarded to\n * `addSwapToTx`'s `input.overlayFee`.\n */\n overlayFee?: OverlayFeeConfig;\n}\n\n/** Per-step preview returned by each registry appender. Tool-specific shape. */\nexport type StepPreview =\n | { toolName: 'send_transfer'; effectiveAmount: number; recipient: string; asset: SendableAsset }\n | { toolName: 'swap_execute'; effectiveAmountIn: number; expectedAmountOut: number; route: SwapRouteResult };\n\nexport interface ComposeTxResult {\n tx: Transaction;\n /**\n * Pre-built bytes for Enoki's `createSponsoredTransaction`. Built\n * with `onlyTransactionKind: true` so the gas coin can be supplied\n * by the sponsor.\n */\n txKindBytes: Uint8Array;\n /**\n * Auto-derived from the assembled PTB's top-level `transferObjects`\n * commands. Replaces hand-maintained `allowedAddresses` arrays in\n * audric host's `transactions/prepare` + `services/prepare` —\n * eliminates the PR-H1/H4 bug class permanently.\n */\n derivedAllowedAddresses: string[];\n perStepPreviews: StepPreview[];\n}\n\n/**\n * Per-appender context passed into every registry entry. Carries the\n * RPC client, sender, sponsorship flag, optional per-call overlay\n * fee config (Cetus swaps), and SPEC 13 Phase 1 chain-mode fields.\n */\nexport interface AppenderContext {\n client: SuiCoreClient;\n sender: string;\n sponsoredContext: boolean;\n overlayFee?: OverlayFeeConfig;\n /**\n * [SPEC 13 Phase 1] When set, the consumer appender consumes this\n * coin handle directly instead of pre-fetching from the wallet via\n * `selectAndSplitCoin` / `selectSuiCoin`. Provided by the\n * orchestration loop when the step has `inputCoinFromStep` set; the\n * loop looks up `priorOutputs[step.inputCoinFromStep]` and threads\n * it through here.\n *\n * In chain mode, the consumer consumes the handle IN FULL — the\n * `input.amount` field is treated as informational (used for preview\n * math). This matches Cetus's `routerSwap`, NAVI's `deposit`/`repay`,\n * and the Sui `transferObjects` semantics: each takes a coin object\n * and consumes its entire balance.\n */\n chainedCoin?: TransactionObjectArgument;\n /**\n * [SPEC 13 Phase 1] True when this step's output coin will be\n * consumed by a downstream step (some later step has\n * `inputCoinFromStep === currentStepIndex`). Producer appenders MUST\n * skip their terminal `tx.transferObjects([coin], ctx.sender)` call\n * when this is true — otherwise the same `TransactionObjectArgument`\n * gets used twice (once by the consumer, once by the transfer) and\n * the PTB build fails or the on-chain leg reverts.\n */\n isOutputConsumed?: boolean;\n /**\n * Per-PTB merge cache for sponsored coin-object sourcing, shared across\n * every appender in a single `composeTx` run. Lets multiple legs that\n * source the same coin type (two SUI swaps, swap USDC + save USDC, etc.)\n * reuse a single merged primary coin instead of each re-fetching +\n * re-merging the same coin objects (the second merge of which references\n * already-consumed coins → Enoki dry-run `ArgumentWithoutValue`). Applies\n * to ALL coin types, not just SUI. See `SponsoredCoinMergeCache` JSDoc.\n */\n coinMergeCache?: SponsoredCoinMergeCache;\n}\n\n/**\n * [SPEC 13 Phase 1] Appender return shape. Producers populate\n * `outputCoin` so the orchestration loop can thread it into a\n * downstream consumer's `chainedCoin`. The terminal consumer\n * (`send_transfer`) omits it.\n *\n * `swap_execute` is the only dual-mode tool — it accepts `chainedCoin`\n * AND populates `outputCoin`. (Pre-S.444 the DeFi tools\n * save/withdraw/borrow/repay were also producers/consumers; removed with NAVI.)\n */\nexport interface AppenderResult<TPreview extends StepPreview> {\n preview: TPreview;\n outputCoin?: TransactionObjectArgument;\n}\n\ntype AppenderFn<TInput, TPreview extends StepPreview> = (\n tx: Transaction,\n input: TInput,\n ctx: AppenderContext,\n) => Promise<AppenderResult<TPreview>>;\n\n/**\n * Cetus provider exclusion list for sponsored flows. Mirrors the\n * audric host's `SPONSORED_TX_PROVIDERS` constant — these 7 providers\n * reference `tx.gas` for Pyth oracle fee payments, which Enoki rejects.\n *\n * NOTE: keeping this hardcoded means `findSwapRoute` doesn't need a\n * dependency on `@cetusprotocol/aggregator-sdk`'s `getProvidersExcluding`\n * helper — composeTx forwards the literal list to Cetus, Cetus does the\n * inverse lookup. Result is identical.\n */\nexport const SPONSORED_PYTH_DEPENDENT_PROVIDERS = [\n 'HAEDALPMM',\n 'METASTABLE',\n 'OBRIC',\n 'STEAMM_OMM',\n 'STEAMM_OMM_V2',\n 'SEVENK',\n 'HAEDALHMMV2',\n] as const;\n\n/**\n * Get all eligible Cetus provider names except the Pyth-dependent ones,\n * for sponsored swap context. Computed from the Cetus SDK's\n * `getAllProviders()` minus the exclusion list.\n *\n * [Bug A fix / 2026-05-10] Exported so the engine's `swap_quote` tool can\n * call this when discovering routes for sponsored hosts. Previously the\n * engine only exclude these providers at COMPOSE time; now it excludes\n * at QUOTE time too, so the precomputed route stashed on\n * `pending_action.cetusRoute` is always sponsor-safe.\n */\nexport async function getSponsoredSwapProviders(): Promise<string[]> {\n const { getProvidersExcluding } = await import('@cetusprotocol/aggregator-sdk');\n return getProvidersExcluding([...SPONSORED_PYTH_DEPENDENT_PROVIDERS]);\n}\n\n/**\n * The typed registry. Each entry is a wallet-mode dispatcher that takes\n * (tx, input, ctx) and returns a per-step preview. Compile-time check\n * that all `WriteToolName` values have an entry — TypeScript will\n * fail the build if a tool is missing.\n *\n * [S.444] Narrowed to send_transfer + swap_execute after the NAVI/DeFi cut.\n */\nexport const WRITE_APPENDER_REGISTRY: {\n send_transfer: AppenderFn<SendTransferInput, Extract<StepPreview, { toolName: 'send_transfer' }>>;\n swap_execute: AppenderFn<SwapExecuteInput, Extract<StepPreview, { toolName: 'swap_execute' }>>;\n} = {\n send_transfer: async (tx, input, ctx) => {\n const recipient = validateAddress(input.to);\n // [v4.0 Phase A Day 2] Asset is required (no `?? 'USDC'` default).\n // assertAllowedAsset narrows the runtime value to\n // `'USDC' | 'USDsui' | 'SUI'` and throws INVALID_ASSET otherwise.\n // The TypeScript shape is `SupportedAsset` (wider, accommodates\n // engine LLM tool callers that pass wide-typed assets through);\n // the runtime assertion is the canonical gate.\n if (!input.asset) {\n throw new T2000Error(\n 'INVALID_ASSET',\n \"send_transfer requires an explicit asset. Use one of: USDC, USDsui, SUI.\",\n );\n }\n assertAllowedAsset('send', input.asset);\n const asset: SendableAsset = input.asset as SendableAsset;\n const assetInfo = SUPPORTED_ASSETS[asset];\n if (input.amount <= 0) {\n throw new T2000Error('INVALID_AMOUNT', 'Send amount must be greater than zero');\n }\n\n const rawAmount = BigInt(Math.floor(input.amount * 10 ** assetInfo.decimals));\n\n // [v4.0 Phase A Day 2] Chain-mode (`chainedCoin` from a previous\n // appender) ALWAYS uses the legacy `transferObjects` path —\n // bundles never qualify for gasless because the protocol allowlist\n // only accepts PTBs whose ops are `balance::send_funds` /\n // `balance::redeem_funds` / `coin::send_funds` etc. A withdraw →\n // send bundle has the withdraw Move call, so the whole tx pays gas.\n if (ctx.chainedCoin) {\n addSendToTx(tx, ctx.chainedCoin, recipient);\n return {\n preview: {\n toolName: 'send_transfer',\n effectiveAmount: Number(rawAmount) / 10 ** assetInfo.decimals,\n recipient,\n asset,\n },\n };\n }\n\n if (asset === 'SUI') {\n // Standard gas-native SUI transfer — NOT gasless (SUI is not on\n // the protocol `balance::send_funds` allowlist).\n const result = await selectSuiCoin(\n tx,\n ctx.client,\n ctx.sender,\n rawAmount,\n ctx.sponsoredContext,\n ctx.coinMergeCache,\n );\n addSendToTx(tx, result.coin, recipient);\n return {\n preview: {\n toolName: 'send_transfer',\n effectiveAmount: Number(result.effectiveAmount) / 10 ** assetInfo.decimals,\n recipient,\n asset,\n },\n };\n }\n\n // USDC / USDsui — gasless single-step send via `0x2::balance::send_funds`.\n // Surfaces the protocol's 0.01 minimum BEFORE building so we don't\n // burn a sponsorship slot on a tx that will revert on-chain.\n if (input.amount < GASLESS_MIN_STABLE_AMOUNT) {\n throw new T2000Error(\n 'INVALID_AMOUNT',\n `Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${asset}. Got ${input.amount}.`,\n );\n }\n // Pre-flight balance check (composeTx's selectAndSplitCoin used to\n // do this; we lose the coin-selection but keep the balance gate so\n // build-time errors stay actionable for audric's prepare route).\n const balanceResp = await ctx.client.core.getBalance({ owner: ctx.sender, coinType: assetInfo.type });\n if (BigInt(balanceResp.balance.balance) < rawAmount) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${asset} balance`, {\n available: Number(balanceResp.balance.balance) / 10 ** assetInfo.decimals,\n required: input.amount,\n });\n }\n const coinType = GASLESS_STABLE_TYPES[asset];\n tx.moveCall({\n target: '0x2::balance::send_funds',\n typeArguments: [coinType],\n arguments: [\n tx.balance({ type: coinType, balance: rawAmount }),\n tx.pure.address(recipient),\n ],\n });\n return {\n preview: {\n toolName: 'send_transfer',\n effectiveAmount: Number(rawAmount) / 10 ** assetInfo.decimals,\n recipient,\n asset,\n },\n };\n },\n\n swap_execute: async (tx, input, ctx) => {\n const fromType = resolveTokenType(input.from);\n const toType = resolveTokenType(input.to);\n if (!fromType || !toType) {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n `Unknown token in swap: from=${input.from}, to=${input.to}`,\n );\n }\n\n const providers = input.providers\n ?? (ctx.sponsoredContext ? await getSponsoredSwapProviders() : undefined);\n\n const result = await addSwapToTx(tx, ctx.client, ctx.sender, {\n from: input.from,\n to: input.to,\n amount: input.amount,\n slippage: input.slippage,\n byAmountIn: input.byAmountIn,\n overlayFee: ctx.overlayFee,\n providers,\n inputCoin: ctx.chainedCoin,\n precomputedRoute: input.precomputedRoute,\n sponsoredContext: ctx.sponsoredContext,\n coinMergeCache: ctx.coinMergeCache,\n });\n if (!ctx.isOutputConsumed) {\n tx.transferObjects([result.coin], ctx.sender);\n }\n return {\n preview: {\n toolName: 'swap_execute',\n effectiveAmountIn: result.effectiveAmountIn,\n expectedAmountOut: result.expectedAmountOut,\n route: result.route,\n },\n outputCoin: result.coin,\n };\n },\n\n // [S.444] claim_rewards / harvest_rewards appenders removed with NAVI.\n // [S.323] volo_stake / volo_unstake appenders removed earlier.\n};\n\n// Reference unused import to suppress noUnusedLocals; SUI_TYPE is used\n// by selectSuiCoin internally and re-export from index.ts.\nvoid SUI_TYPE;\nvoid getDecimalsForCoinType;\n\n/**\n * Walks the assembled PTB's command list and extracts every recipient\n * address from top-level `TransferObjects` commands. Top-level only —\n * recipients inside nested Move calls are NOT inspected (Enoki only\n * cross-checks top-level commands).\n *\n * Replaces hand-maintained `allowedAddresses` arrays. Two production\n * bugs in 60 days came from drift between the array and the actual\n * PTB recipients (PR-H1 + PR-H4). Computing this from the PTB makes\n * drift impossible by construction.\n */\nexport function deriveAllowedAddressesFromPtb(tx: Transaction): string[] {\n const addresses = new Set<string>();\n const data = tx.getData();\n\n const addAddressFromInput = (inputIndex: number | undefined): void => {\n if (inputIndex === undefined) return;\n const input = data.inputs[inputIndex];\n if (!input) return;\n const pureBytes = (input as { Pure?: { bytes?: string } }).Pure?.bytes;\n if (!pureBytes) return;\n // Pure bytes are base64-encoded BCS for Sui addresses (32 bytes →\n // 44-char base64). Decode + format as 0x-prefixed hex.\n try {\n const bytes = base64ToBytes(pureBytes);\n if (bytes.length !== 32) return; // not an address\n const hex = '0x' + Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');\n addresses.add(hex);\n } catch {\n // not a parseable address — skip\n }\n };\n\n for (const cmd of data.commands) {\n // Path 1 — `TransferObjects.address` (the legacy send/withdraw/\n // claim/fee-transfer recipient surface). The Sui transaction-builder\n // stores each top-level command as a tagged object:\n // { TransferObjects: { objects, address: { Input: <index> } } }.\n const transferCmd = (cmd as { TransferObjects?: unknown }).TransferObjects;\n if (transferCmd) {\n const addressArg = (transferCmd as { address?: unknown }).address;\n const addressInputIndex = (addressArg as { Input?: number } | undefined)?.Input;\n addAddressFromInput(addressInputIndex);\n continue;\n }\n\n // Path 2 — `0x2::balance::send_funds(balance, recipient)` (gasless\n // stablecoin transfer, v4.0 Phase A Day 2). Recipient is arg[1],\n // not a TransferObjects.address. The Move call shape:\n // { MoveCall: { package, module, function, arguments: [...] } }\n // target = `0x2::balance::send_funds`, arguments[1] = recipient.\n const moveCall = (cmd as { MoveCall?: unknown }).MoveCall;\n if (moveCall) {\n const mc = moveCall as {\n package?: string;\n module?: string;\n function?: string;\n arguments?: Array<{ Input?: number } | unknown>;\n };\n // The `package` field is the normalized framework address. For\n // `0x2::balance::send_funds` it's `0x0000…0002` (`SUI_FRAMEWORK_ADDRESS`).\n // Match on module + function defensively; the recipient extraction\n // only fires when the signature matches.\n const isBalanceSendFunds =\n mc.module === 'balance' && mc.function === 'send_funds';\n const isCoinSendFunds =\n mc.module === 'coin' && mc.function === 'send_funds';\n if (isBalanceSendFunds || isCoinSendFunds) {\n const args = mc.arguments ?? [];\n const recipientArg = args[1] as { Input?: number } | undefined;\n addAddressFromInput(recipientArg?.Input);\n }\n continue;\n }\n }\n\n return Array.from(addresses);\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(b64, 'base64'));\n }\n // Browser fallback (in case this ever runs in a worker)\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\n/**\n * Compose a PTB from a list of canonical write steps. Each step\n * dispatches to its registered fragment-appender; the assembled PTB is\n * returned alongside pre-built `txKindBytes` ready for Enoki sponsorship\n * + auto-derived `derivedAllowedAddresses`.\n *\n * Single-step: `composeTx({ steps: [{ toolName: 'send_transfer', input: {...} }], ... })`\n * Multi-step (Layer 2): `composeTx({ steps: [{...}, {...}, {...}], ... })`\n *\n * Throws:\n * - `T2000Error('NO_APPENDER')` — unknown `toolName`\n * - Any error thrown by the per-step appender (insufficient balance,\n * asset not supported, route not found, etc.) — propagates as-is.\n */\nexport async function composeTx(opts: ComposeTxOptions): Promise<ComposeTxResult> {\n const tx = new Transaction();\n tx.setSender(opts.sender);\n\n const baseCtx = {\n client: opts.client,\n sender: opts.sender,\n sponsoredContext: opts.sponsoredContext ?? false,\n overlayFee: opts.overlayFee,\n // One cache per compose run — shared across all legs (any coin type)\n // so multi-leg sponsored bundles that source the same coin (two SUI\n // swaps, swap USDC + save USDC, ...) merge that coin's objects once.\n coinMergeCache: new Map() as SponsoredCoinMergeCache,\n };\n\n // [SPEC 13 Phase 1] First pass: validate every `inputCoinFromStep`\n // reference and build the `consumedSteps` set. Forward-only\n // references; producer-only tools can't be consumers.\n const consumedSteps = new Set<number>();\n for (let i = 0; i < opts.steps.length; i++) {\n const step = opts.steps[i];\n const stepWithChain = step as { inputCoinFromStep?: number };\n const idx = stepWithChain.inputCoinFromStep;\n if (idx === undefined) continue;\n\n if (!Number.isInteger(idx) || idx < 0 || idx >= i) {\n throw new T2000Error(\n 'CHAIN_MODE_INVALID',\n `Step ${i} (${step.toolName}) has inputCoinFromStep=${idx}, ` +\n `which must be a non-negative integer < ${i} (forward-only references).`,\n );\n }\n\n const producer = opts.steps[idx];\n if (producer.toolName === 'send_transfer') {\n throw new T2000Error(\n 'CHAIN_MODE_INVALID',\n `Step ${i} (${step.toolName}) references step ${idx} (${producer.toolName}) as ` +\n `producer, but 'send_transfer' is a terminal consumer that does not ` +\n `produce a chainable coin handle. Allowed producers: swap_execute.`,\n );\n }\n\n consumedSteps.add(idx);\n }\n\n // [SPEC 13 Phase 1] Second pass: dispatch each step in order,\n // capturing producers' output handles in `priorOutputs` and threading\n // them into consumers' `chainedCoin`.\n const priorOutputs: (TransactionObjectArgument | null)[] = [];\n const previews: StepPreview[] = [];\n for (let i = 0; i < opts.steps.length; i++) {\n const step = opts.steps[i];\n const appender = (WRITE_APPENDER_REGISTRY as Record<string, AppenderFn<unknown, StepPreview>>)[step.toolName];\n if (!appender) {\n throw new T2000Error(\n 'UNKNOWN',\n `No fragment appender registered for tool '${step.toolName}'. ` +\n `Allowed: ${(Object.keys(WRITE_APPENDER_REGISTRY) as WriteToolName[]).join(', ')}`,\n );\n }\n\n const stepWithChain = step as { inputCoinFromStep?: number };\n let chainedCoin: TransactionObjectArgument | undefined;\n if (stepWithChain.inputCoinFromStep !== undefined) {\n const upstream = priorOutputs[stepWithChain.inputCoinFromStep];\n if (!upstream) {\n // Producer didn't return an outputCoin (shouldn't happen given the\n // first-pass guard, but defends against future appender bugs).\n throw new T2000Error(\n 'CHAIN_MODE_INVALID',\n `Step ${i} (${step.toolName}) expected a coin handle from step ` +\n `${stepWithChain.inputCoinFromStep}, but the producer did not return one.`,\n );\n }\n chainedCoin = upstream;\n }\n\n const stepCtx: AppenderContext = {\n ...baseCtx,\n chainedCoin,\n isOutputConsumed: consumedSteps.has(i),\n };\n\n const result = await appender(tx, step.input, stepCtx);\n priorOutputs.push(result.outputCoin ?? null);\n previews.push(result.preview);\n }\n\n const txKindBytes = await tx.build({ client: opts.client, onlyTransactionKind: true });\n const derivedAllowedAddresses = deriveAllowedAddressesFromPtb(tx);\n\n return {\n tx,\n txKindBytes,\n derivedAllowedAddresses,\n perStepPreviews: previews,\n };\n}\n","import { Transaction } from '@mysten/sui/transactions';\nimport { T2000Error } from '../errors.js';\nimport { mapMoveAbortCode } from '../errors.js';\nimport type { SuiCoreClient } from './sui.js';\n\nexport interface SimulationResult {\n success: boolean;\n gasEstimateSui: number;\n error?: {\n moveAbortCode?: number;\n moveModule?: string;\n reason: string;\n rawError: string;\n };\n}\n\nexport async function simulateTransaction(\n client: SuiCoreClient,\n tx: Transaction,\n sender: string,\n): Promise<SimulationResult> {\n tx.setSender(sender);\n\n try {\n // [gRPC migration] `core.simulateTransaction` replaces `dryRunTransactionBlock`.\n // It returns a discriminated union; effects.status is `{ success, error }`\n // where `error` is a structured `ExecutionError` (not the legacy raw string).\n const txBytes = await tx.build({ client });\n const sim = await client.core.simulateTransaction({\n transaction: txBytes,\n include: { effects: true },\n });\n const txn = sim.$kind === 'Transaction' ? sim.Transaction : sim.FailedTransaction;\n const effects = txn.effects;\n const gasUsed = effects?.gasUsed;\n\n const gasEstimateSui = gasUsed\n ? (Number(gasUsed.computationCost) +\n Number(gasUsed.storageCost) -\n Number(gasUsed.storageRebate)) / 1e9\n : 0;\n\n const errObj = effects && !effects.status.success ? effects.status.error : undefined;\n if (sim.$kind === 'FailedTransaction' || errObj) {\n const rawError = errObj?.message ?? 'Unknown simulation error';\n // Prefer the structured MoveAbort code; fall back to regex-parsing the\n // message for non-abort errors / pre-structured formats.\n const structuredAbort =\n errObj?.$kind === 'MoveAbort' ? Number(errObj.MoveAbort.abortCode) : undefined;\n const parsed = parseMoveAbort(rawError);\n const abortCode = structuredAbort ?? parsed.abortCode;\n\n return {\n success: false,\n gasEstimateSui,\n error: {\n moveAbortCode: abortCode,\n moveModule: parsed.module,\n reason: abortCode != null ? mapMoveAbortCode(abortCode) : parsed.reason,\n rawError,\n },\n };\n }\n\n return { success: true, gasEstimateSui };\n } catch (err) {\n const rawError = err instanceof Error ? err.message : String(err);\n return {\n success: false,\n gasEstimateSui: 0,\n error: {\n reason: 'Simulation failed: ' + rawError,\n rawError,\n },\n };\n }\n}\n\nexport function throwIfSimulationFailed(sim: SimulationResult): void {\n if (sim.success) return;\n\n throw new T2000Error(\n 'SIMULATION_FAILED',\n sim.error?.reason ?? 'Transaction simulation failed',\n {\n moveAbortCode: sim.error?.moveAbortCode,\n moveModule: sim.error?.moveModule,\n reason: sim.error?.reason,\n rawError: sim.error?.rawError,\n },\n );\n}\n\nfunction parseMoveAbort(errorStr: string): {\n abortCode?: number;\n module?: string;\n reason: string;\n} {\n // Pattern: MoveAbort(MoveLocation { module: ModuleId { ... name: \"module\" }, ... }, code)\n const abortMatch = errorStr.match(/MoveAbort\\([^,]*,\\s*(\\d+)\\)/);\n const moduleMatch = errorStr.match(/name:\\s*Identifier\\(\"([^\"]+)\"\\)/);\n\n if (abortMatch) {\n const code = parseInt(abortMatch[1], 10);\n const module = moduleMatch?.[1];\n const reason = mapMoveAbortCode(code);\n return { abortCode: code, module, reason };\n }\n\n // Pattern: MovePrimitiveRuntimeError\n if (errorStr.includes('MovePrimitiveRuntimeError')) {\n const module = moduleMatch?.[1];\n return {\n module,\n reason: `Move runtime error in ${module ?? 'unknown'} module`,\n };\n }\n\n return { reason: errorStr };\n}\n","/**\n * SuiNS leaf-subname builders for the `audric.sui` parent NFT.\n *\n * Used by SPEC 10 v0.2.1 Phase A.1 — Audric Passport Identity. Lets the audric host\n * mint and revoke `username.audric.sui` leaves under the parent NFT held by the\n * dedicated custody address (`0xaca29165…23d11`).\n *\n * **Why a dedicated SDK module (not inline in the audric route):**\n * - Consumers (audric/web's `/api/identity/{reserve,change,release}` routes) can import\n * the canonical builder shape without re-discovering the `SuinsTransaction` API.\n * - Single source of truth for the parent NFT ID + parent name.\n * - Single source of truth for label validation (length / charset / hyphen rules).\n *\n * **Signer model — read this before wiring into a route:**\n * These builders are signed by the **service account** (the parent NFT custody address),\n * NOT by the user's zkLogin key. Per `audric/.cursor/rules/audric-canonical-write.mdc`,\n * the SPEC 10 leaf-mint API routes are explicitly documented as a CANONICAL-BYPASS of\n * the `composeTx` write contract — they are server-to-server, the user's key is never\n * in the loop, and Enoki sponsors the gas. PTB atomicity requires single-signer, so\n * leaf mints cannot be bundled with chat-agent writes via composeTx.\n *\n * **Reference:** `spec/runbooks/RUNBOOK_audric_sui_parent.md` §1 (parent NFT ID) +\n * §3 (validated SDK reference shape) + §4 (mainnet smoke test 2026-05-01).\n */\n\nimport { Transaction } from '@mysten/sui/transactions';\nimport { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport { SuinsTransaction, type SuinsClient } from '@mysten/suins';\n\n/**\n * Parent name registered on SuiNS mainnet. Audric's identity namespace anchor.\n *\n * Every leaf created via `buildAddLeafTx` becomes `<label>.audric.sui` and resolves\n * via the standard SuiNS resolver (`suix_resolveNameServiceAddress`).\n */\nexport const AUDRIC_PARENT_NAME = 'audric.sui';\n\n/**\n * On-chain object ID of the `audric.sui` parent NFT (a `SuinsRegistration`).\n *\n * Owned by the dedicated custody address `0xaca29165188f10136073788f648e1186dd25100100146186ebecedaf94b23d11`\n * (per `RUNBOOK_audric_sui_parent.md` §1). Every leaf mint / revoke MUST be signed\n * by the address that owns this NFT. Mainnet only.\n */\nexport const AUDRIC_PARENT_NFT_ID =\n '0x070456e283ec988b6302bdd6cc5172bbdcb709998cf116586fb98d19b0870198';\n\n/**\n * A SuiNS parent under which leaf subnames are minted: the registered SLD name\n * + the on-chain `SuinsRegistration` NFT id the minting service must own/sign.\n *\n * Added 2026-06-29 (Agent ID Phase B, gate 2) to let the same leaf machinery\n * serve a SECOND namespace — `agent-id.sui` for Agent ID handles — without\n * forking it. Audric stays the default so every existing caller is unchanged.\n */\nexport interface SuinsParent {\n name: string;\n nftId: string;\n}\n\n/** The Audric consumer-handle parent (`<label>.audric.sui` → `@audric`). */\nexport const AUDRIC_PARENT: SuinsParent = {\n name: AUDRIC_PARENT_NAME,\n nftId: AUDRIC_PARENT_NFT_ID,\n};\n\n/** The Agent ID parent (`<label>.agent-id.sui` → `@agent-id`). Distinct from\n * audric.sui on purpose (infra/agent registry vs consumer brand).\n *\n * Registered on SuiNS mainnet 2026-06-29; the `SuinsRegistration` NFT\n * (`0xc8c1…d5d1f`) is held by the custody address\n * `0x6988a92d…30e4532`, which signs leaf mints + pays their gas. Override via\n * `AGENT_ID_PARENT_NFT_ID` for testnet/dev. */\nexport const AGENT_ID_PARENT_NAME = 'agent-id.sui';\nexport const AGENT_ID_PARENT_NFT_ID =\n process.env.AGENT_ID_PARENT_NFT_ID ??\n '0xc8c13f5b5a6d4c47c04877014794f65e67e2745d3bfa089b736eb54b0ebd5d1f';\nexport const AGENT_ID_PARENT: SuinsParent = {\n name: AGENT_ID_PARENT_NAME,\n nftId: AGENT_ID_PARENT_NFT_ID,\n};\n\nexport interface BuildAddLeafParams {\n /** Bare label, e.g. `'alice'` — NOT the full `'alice.audric.sui'` path. */\n label: string;\n /** Sui address the leaf will resolve to (typically the user's zkLogin wallet). */\n targetAddress: string;\n /** Parent to mint under. Defaults to Audric (back-compat). */\n parent?: SuinsParent;\n}\n\nexport interface BuildRevokeLeafParams {\n /** Bare label of the leaf to revoke. */\n label: string;\n /** Parent the leaf lives under. Defaults to Audric (back-compat). */\n parent?: SuinsParent;\n}\n\nexport type LabelValidationResult = { valid: true } | { valid: false; reason: string };\n\n/**\n * SuiNS labels accept lowercase ASCII letters, digits, and hyphens. Hyphens cannot\n * lead or trail. The 3–63 char window matches SuiNS protocol rules and the SuiNS\n * dashboard's own `Register` form.\n *\n * The regex permits a single character only when it is alphanumeric (rejected by\n * the length check below for being < 3, but the pattern itself stays internally\n * consistent with DNS conventions).\n *\n * SUINS-LABEL-RULE — paired with `audric/apps/web/lib/identity/validate-label.ts`.\n * The audric host duplicates these rules inline to avoid pulling the full SDK\n * (and its server-side transitive deps) into the client bundle. If SuiNS ever\n * label rules, BOTH this file and the audric copy need updating.\n */\nconst LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\n/**\n * Validate a leaf label against SuiNS protocol rules. Pure function; no I/O.\n *\n * Pre-call this before `buildAddLeafTx` / `buildRevokeLeafTx` if you want a\n * structured error (the builder functions throw on invalid labels). The audric\n * `/api/identity/check` endpoint uses this to drive the picker's real-time\n * availability indicator.\n *\n * Reserved-name policy (specific Audric handles like `support`, `admin`,\n * `official`) is NOT enforced here — that's a UI / route-level concern owned\n * by the audric host, not a protocol-level rule. See SPEC 10 D3.\n */\nexport function validateLabel(label: unknown): LabelValidationResult {\n if (typeof label !== 'string') {\n return { valid: false, reason: 'label must be a string' };\n }\n if (label.length < 3) {\n return { valid: false, reason: 'label must be at least 3 characters' };\n }\n if (label.length > 63) {\n return { valid: false, reason: 'label must be at most 63 characters' };\n }\n if (!LABEL_PATTERN.test(label)) {\n return {\n valid: false,\n reason:\n 'label may only contain lowercase letters, digits, and hyphens, and may not start or end with a hyphen',\n };\n }\n if (label.includes('--')) {\n return { valid: false, reason: 'label may not contain consecutive hyphens' };\n }\n return { valid: true };\n}\n\n/**\n * Build an unsigned PTB that creates a `<label>.audric.sui` leaf subname pointing\n * to `targetAddress`.\n *\n * The returned `Transaction` has neither sender nor gas configured — the caller\n * (audric's `/api/identity/reserve` route) sets the sender to the parent NFT\n * custody address and submits via Enoki sponsorship. See `audric-transaction-flow.mdc`\n * for the sponsored-tx wrapper pattern; note SPEC 10 leaf-mint is a documented\n * CANONICAL-BYPASS of `composeTx` because the signer is the service account, not\n * the user's zkLogin key.\n *\n * Throws synchronously if `label` violates protocol rules or `targetAddress` is\n * not a valid Sui address — fail-closed before bytes are built.\n */\nexport function buildAddLeafTx(\n suinsClient: SuinsClient,\n { label, targetAddress, parent = AUDRIC_PARENT }: BuildAddLeafParams,\n): Transaction {\n const labelCheck = validateLabel(label);\n if (!labelCheck.valid) {\n throw new Error(`buildAddLeafTx: invalid label \"${label}\" — ${labelCheck.reason}`);\n }\n if (typeof targetAddress !== 'string' || !isValidSuiAddress(normalizeSuiAddress(targetAddress))) {\n throw new Error(`buildAddLeafTx: invalid targetAddress \"${targetAddress}\"`);\n }\n if (!parent.nftId) {\n throw new Error(`buildAddLeafTx: parent NFT id not configured for \"${parent.name}\"`);\n }\n\n const tx = new Transaction();\n const suinsTx = new SuinsTransaction(suinsClient, tx);\n suinsTx.createLeafSubName({\n parentNft: parent.nftId,\n name: `${label}.${parent.name}`,\n targetAddress: normalizeSuiAddress(targetAddress),\n });\n return tx;\n}\n\n/**\n * Build an unsigned PTB that revokes a `<label>.audric.sui` leaf subname.\n *\n * Used by:\n * 1. The change-username flow (`/api/identity/change`): revoke old leaf inside\n * the same PTB as the new leaf creation, atomically.\n * 2. The release-username flow (`/api/admin/identity/release`): admin recovery\n * of squatted / impersonating handles.\n * 3. Account-deletion flow (future): revoke leaf when user deletes their account.\n *\n * The mainnet smoke test (2026-05-01) confirmed revocation gas cost is roughly\n * negative net (storage rebate exceeds computation) — see RUNBOOK §4.\n */\nexport function buildRevokeLeafTx(\n suinsClient: SuinsClient,\n { label, parent = AUDRIC_PARENT }: BuildRevokeLeafParams,\n): Transaction {\n const labelCheck = validateLabel(label);\n if (!labelCheck.valid) {\n throw new Error(`buildRevokeLeafTx: invalid label \"${label}\" — ${labelCheck.reason}`);\n }\n if (!parent.nftId) {\n throw new Error(`buildRevokeLeafTx: parent NFT id not configured for \"${parent.name}\"`);\n }\n\n const tx = new Transaction();\n const suinsTx = new SuinsTransaction(suinsClient, tx);\n suinsTx.removeLeafSubName({\n parentNft: parent.nftId,\n name: `${label}.${parent.name}`,\n });\n return tx;\n}\n\n/**\n * Convenience: turn a bare label into the full `<label>.audric.sui` path.\n *\n * **Use this for ON-CHAIN operations** — SuiNS leaf NFT `name` field, the\n * `createLeafSubName` / `removeLeafSubName` move calls, and any RPC call\n * that returns/expects the canonical name string. The `<label>.audric.sui`\n * form is what the SuiNS protocol writes into the NFT `name` field.\n *\n * **Do NOT use this for UI rendering** — that's `displayHandle()`'s job\n * (S.118 reversal of SPEC 10 D10, see audric-build-tracker). Pre-S.118\n * we surfaced the full `.sui` form everywhere; we now use the SuiNS V2\n * `@` form (`alice@audric`) for display because it's shorter, fits the\n * agent harness mono aesthetic, and matches SuiNS's own V2 standard.\n *\n * Both forms resolve to the same address via SuiNS RPC (verified\n * mainnet 2026-05-08 PF1) — `displayHandle()` is purely a render-layer\n * choice, not a backend storage change.\n */\nexport function fullHandle(\n label: string,\n parentName: string = AUDRIC_PARENT_NAME,\n): string {\n return `${label}.${parentName}`;\n}\n\n/**\n * SuiNS V2 short-form display alias. `displayHandle('alice')` →\n * `'alice@audric'`. Use for chat narration, permission cards, receipts,\n * profile pages, share-to-X copy, OG metadata, and lookup_user output.\n *\n * **Why a separate function from `fullHandle`:**\n * - `fullHandle('alice')` → `'alice.audric.sui'` is the **on-chain**\n * NFT name field; SuiNS's `createLeafSubName` writes exactly this\n * string and `suix_resolveNameServiceAddress` accepts it.\n * - `displayHandle('alice')` → `'alice@audric'` is the **UI** form\n * that users see and share. SuiNS RPC also accepts this form\n * (verified mainnet 2026-05-08 PF1 — both forms return the same\n * address), so we have one storage form (`<label>.audric.sui`) and\n * two interchangeable input forms (the user can paste either).\n *\n * Reverses SPEC 10 D10 (\"full handle ALWAYS\"). See audric-build-tracker\n * S.118 for the rationale; see also `audric/apps/web/lib/identity/`\n * for canonicalization in the input parser (which is a no-op since\n * SuiNS RPC accepts both — kept available for future-proofing).\n */\nexport function displayHandle(\n label: string,\n parentName: string = AUDRIC_PARENT_NAME,\n): string {\n // Strip the trailing `.sui` TLD for the `@` display form.\n // `displayHandle('alice')` → `'alice@audric'`; for Agent ID,\n // `displayHandle('bot', AGENT_ID_PARENT_NAME)` → `'bot@agent-id'`.\n const parentDisplay = parentName.replace(/\\.sui$/, '');\n return `${label}@${parentDisplay}`;\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/preflight.ts","../src/token-registry.ts","../src/wallet/coinSelection.ts","../src/protocols/cetus-swap.ts","../src/swap-quote.ts","../src/constants.ts","../src/utils/sui.ts","../src/wallet/keyManager.ts","../src/wallet/keypairSigner.ts","../src/wallet/executeTx.ts","../src/wallet/pay.ts","../src/mpp-cost.ts","../src/wallet/zkLoginSigner.ts","../src/wallet/send.ts","../src/utils/format.ts","../src/wallet/balance.ts","../src/wallet/classify.ts","../src/wallet/history.ts","../src/t2000.ts","../src/utils/suins.ts","../src/inference.ts","../src/verify.ts","../src/limits/config.ts","../src/limits/errors.ts","../src/limits/enforce.ts","../src/index.ts","../src/wallet/job.ts","../src/commerce.ts","../src/composeTx.ts","../src/utils/simulate.ts","../src/protocols/suins-leaf.ts"],"names":["isValidSuiAddress","normalizeSuiAddress","requested","swapAll","effectiveAmount","coin","SUI_TYPE","T2000Error","selectSuiCoin","selectAndSplitCoin","findSwapRoute","resolveTokenType","serializeCetusRoute","body","result","buildCoinToAddressBalanceMigration","SuiGrpcClient","getDecimalsForCoinType","Transaction","canonical","homedir","dirname","DEFAULT_CONFIG_DIR","join","buildSwapTx","preflightSwap","coinWithBalance","getSwapQuote","CLOCK_ID","hexToBytes","bytesToHex"],"mappings":"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","file":"index.js","sourcesContent":["export type T2000ErrorCode =\n | 'INSUFFICIENT_BALANCE'\n | 'ADDRESS_BALANCE_UNSPONSORABLE'\n | 'INSUFFICIENT_GAS'\n | 'INVALID_ADDRESS'\n | 'INVALID_AMOUNT'\n | 'WALLET_NOT_FOUND'\n | 'WALLET_LOCKED'\n | 'WALLET_EXISTS'\n | 'WALLET_CORRUPT'\n | 'INVALID_KEY'\n | 'SIMULATION_FAILED'\n | 'TRANSACTION_FAILED'\n | 'ASSET_NOT_SUPPORTED'\n | 'INVALID_ASSET'\n | 'PROTOCOL_UNAVAILABLE'\n | 'RPC_ERROR'\n | 'RPC_UNREACHABLE'\n | 'PRICE_EXCEEDS_LIMIT'\n | 'UNSUPPORTED_NETWORK'\n | 'PAYMENT_EXPIRED'\n | 'DUPLICATE_PAYMENT'\n | 'FACILITATOR_REJECTION'\n | 'CONTACT_NOT_FOUND'\n | 'INVALID_CONTACT_NAME'\n | 'SUINS_NOT_REGISTERED'\n | 'FACILITATOR_TIMEOUT'\n | 'SAFEGUARD_BLOCKED'\n | 'SWAP_NO_ROUTE'\n | 'SWAP_FAILED'\n | 'DIALECT_UNSUPPORTED'\n | 'ESCROW_REQUIRED'\n | 'CHAIN_MODE_INVALID'\n | 'INFERENCE_FAILED'\n | 'UNKNOWN';\n\nexport interface T2000ErrorData {\n reason?: string;\n [key: string]: unknown;\n}\n\nexport class T2000Error extends Error {\n readonly code: T2000ErrorCode;\n readonly data?: T2000ErrorData;\n readonly retryable: boolean;\n\n constructor(code: T2000ErrorCode, message: string, data?: T2000ErrorData, retryable = false) {\n super(message);\n this.name = 'T2000Error';\n this.code = code;\n this.data = data;\n this.retryable = retryable;\n }\n\n toJSON() {\n return {\n error: this.code,\n message: this.message,\n ...(this.data && { data: this.data }),\n retryable: this.retryable,\n };\n }\n}\n\nexport function mapWalletError(error: unknown): T2000Error {\n const msg = error instanceof Error ? error.message : String(error);\n\n if (msg.includes('rejected') || msg.includes('cancelled')) {\n return new T2000Error('TRANSACTION_FAILED', 'Transaction cancelled');\n }\n if (msg.includes('Insufficient') || msg.includes('insufficient')) {\n return new T2000Error('INSUFFICIENT_BALANCE', 'Insufficient balance');\n }\n\n return new T2000Error('UNKNOWN', msg, undefined, true);\n}\n\nexport function mapMoveAbortCode(code: number): string {\n const abortMessages: Record<number, string> = {\n 1: 'Protocol is temporarily paused',\n 2: 'Amount must be greater than zero',\n 3: 'Invalid operation type',\n 4: 'Fee rate exceeds maximum',\n 5: 'Insufficient treasury balance',\n 6: 'Not authorized',\n 7: 'Package version mismatch — upgrade required',\n 8: 'Timelock is active — wait for expiry',\n 9: 'No pending change to execute',\n 10: 'Already at current version',\n // NAVI Protocol abort codes\n 1502: 'Oracle price is stale — try again in a moment',\n 1503: 'Withdrawal amount is invalid (zero or dust) — try a specific amount instead of \"all\"',\n 1600: 'Health factor too low — withdrawal would risk liquidation',\n 1605: 'Asset borrowing is disabled or at capacity on this protocol',\n // NAVI utils abort codes\n 46000: 'Insufficient balance to repay — withdraw some savings first to get cash',\n };\n return abortMessages[code] ?? `Move abort code: ${code}`;\n}\n\n/**\n * Check if an error message contains a MoveAbort — these are on-chain\n * failures that will fail no matter how many times you retry.\n */\nexport function isMoveAbort(msg: string): boolean {\n return msg.includes('MoveAbort') || msg.includes('MovePrimitiveRuntimeError');\n}\n\nexport function parseMoveAbortMessage(msg: string): string {\n const abortMatch = msg.match(/abort code:\\s*(\\d+)/i) ?? msg.match(/MoveAbort[^,]*,\\s*(\\d+)/);\n if (abortMatch) {\n const code = parseInt(abortMatch[1], 10);\n\n const moduleMatch = msg.match(/Identifier\\(\"([^\"]+)\"\\)/) ?? msg.match(/in '([^']+)'/);\n const fnMatch = msg.match(/function_name:\\s*Some\\(\"([^\"]+)\"\\)/);\n const context = `${moduleMatch?.[1] ?? ''}${fnMatch ? `::${fnMatch[1]}` : ''}`.toLowerCase();\n const suffix = moduleMatch\n ? ` [${moduleMatch[1]}${fnMatch ? `::${fnMatch[1]}` : ''}]`\n : '';\n\n if (context.includes('slippage')) {\n return `Slippage too high — price moved during execution${suffix}`;\n }\n if (context.includes('balance::split') || context.includes('balance::ENotEnough')) {\n return `Insufficient on-chain balance${suffix}`;\n }\n\n const mapped = mapMoveAbortCode(code);\n return `${mapped}${suffix}`;\n }\n return msg;\n}\n","// Builder-appropriate safety, layer 2 (SPEC_AUDRIC_V3 §7 / safeguards-defense-\n// in-depth.mdc). `preflight()` is CHEAP, PURE, SYNCHRONOUS input validation —\n// no network, no I/O, no context lookup. It runs BEFORE the LLM round-trip /\n// before the tap-to-confirm card, so a malformed intent is rejected without\n// the user ever seeing a confirm for it.\n//\n// Each write builder co-locates its own `preflight*` validator (send.ts →\n// `preflightSend`, pay.ts → `preflightPay`, cetus-swap.ts → `preflightSwap`).\n// This module owns ONLY the shared result type + the two pure primitives those\n// validators compose (amount sanity + sync address validity). The agent-loop\n// guards that read conversation/session state stay in the v3 HOST (they are\n// NOT builder-appropriate, S.442/S.443).\n\nimport { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport type { T2000ErrorCode } from './errors.js';\n\n/**\n * The result of a synchronous preflight check. `valid: false` carries a\n * `T2000ErrorCode` + human message so the host can surface a precise reason\n * (and the builder can rethrow it as a `T2000Error` verbatim).\n */\nexport type PreflightResult =\n | { valid: true }\n | { valid: false; code: T2000ErrorCode; error: string };\n\n/**\n * Fat-finger / overflow ceiling for an asset amount. NOT a spending policy\n * (that's the `@t2000/sdk/limits` module — USD-denominated, opt-in, stateful);\n * this is the \"obviously wrong number\" guard the safeguards rule prescribes\n * (`amount > 1_000_000` → unreasonable).\n */\nexport const PREFLIGHT_MAX_AMOUNT = 1_000_000;\n\nexport const PREFLIGHT_OK: PreflightResult = { valid: true };\n\nexport function preflightFail(code: T2000ErrorCode, error: string): PreflightResult {\n return { valid: false, code, error };\n}\n\n/**\n * Pure positive-finite-amount sanity check (no network). Rejects NaN/Infinity\n * and non-positive values. The absurd-value ceiling defaults to\n * {@link PREFLIGHT_MAX_AMOUNT} but callers can raise it — pass\n * `max: Number.POSITIVE_INFINITY` for swaps of low-unit-value tokens\n * (memecoins legitimately trade in millions/billions of units), where a fixed\n * display-amount ceiling would be a false positive.\n */\nexport function checkPositiveAmount(\n amount: number,\n label = 'Amount',\n max: number = PREFLIGHT_MAX_AMOUNT,\n): PreflightResult {\n if (typeof amount !== 'number' || !Number.isFinite(amount)) {\n return preflightFail('INVALID_AMOUNT', `${label} must be a finite number`);\n }\n if (amount <= 0) {\n return preflightFail('INVALID_AMOUNT', `${label} must be greater than zero`);\n }\n if (amount > max) {\n return preflightFail('INVALID_AMOUNT', `${label} ${amount} exceeds the sane maximum (${max})`);\n }\n return PREFLIGHT_OK;\n}\n\n/**\n * Pure, synchronous Sui-address validity (no throw, no network) — the\n * non-throwing sibling of `validateAddress`. Use in preflight; use\n * `validateAddress` when you need the normalized form.\n */\nexport function checkSuiAddress(address: string, label = 'recipient'): PreflightResult {\n try {\n // `normalizeSuiAddress('')` pads to the zero address (which is \"valid\"), so\n // guard empty / whitespace-only input before normalizing.\n if (typeof address === 'string' && address.trim() !== '' &&\n isValidSuiAddress(normalizeSuiAddress(address))) {\n return PREFLIGHT_OK;\n }\n } catch {\n // normalizeSuiAddress throws on malformed input → fall through to the fail.\n }\n return preflightFail('INVALID_ADDRESS', `Invalid ${label} address: ${address}`);\n}\n","/**\n * Unified token registry — single source of truth for coin types, decimals,\n * and symbols. ZERO heavy dependencies; safe to import anywhere (server,\n * browser, Edge).\n *\n * Used for swap-by-symbol resolution, amount formatting (decimals), and\n * history/balance display. USDC is the settlement stable (send / receive /\n * x402 pay); everything else is holdable / swappable. There is no curated\n * \"tier\" gate — swaps accept any coin type (Cetus routes); the registry just\n * makes the common tokens ergonomic to reference by symbol.\n *\n * To add a token: add ONE entry to COIN_REGISTRY below — everything derives\n * from it.\n */\n\nexport interface CoinMeta {\n type: string;\n decimals: number;\n symbol: string;\n}\n\n/**\n * Canonical coin registry.\n * Key = user-friendly name (used in swap, CLI, prompts).\n */\nexport const COIN_REGISTRY: Record<string, CoinMeta> = {\n // ── Settlement stable ─────────────────────────────────────────────────\n USDC: { type: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC', decimals: 6, symbol: 'USDC' },\n\n // ── Common swap assets (symbol ergonomics — any coin type still swaps) ─\n SUI: { type: '0x2::sui::SUI', decimals: 9, symbol: 'SUI' },\n wBTC: { type: '0x0041f9f9344cac094454cd574e333c4fdb132d7bcc9379bcd4aab485b2a63942::wbtc::WBTC', decimals: 8, symbol: 'wBTC' },\n ETH: { type: '0xd0e89b2af5e4910726fbcd8b8dd37bb79b29e5f83f7491bca830e94f7f226d29::eth::ETH', decimals: 8, symbol: 'ETH' },\n GOLD: { type: '0x9d297676e7a4b771ab023291377b2adfaa4938fb9080b8d12430e4b108b836a9::xaum::XAUM', decimals: 9, symbol: 'GOLD' },\n DEEP: { type: '0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP', decimals: 6, symbol: 'DEEP' },\n WAL: { type: '0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL', decimals: 9, symbol: 'WAL' },\n NS: { type: '0x5145494a5f5100e645e4b0aa950fa6b68f614e8c59e17bc5ded3495123a79178::ns::NS', decimals: 6, symbol: 'NS' },\n IKA: { type: '0x7262fb2f7a3a14c888c438a3cd9b912469a58cf60f367352c46584262e8299aa::ika::IKA', decimals: 9, symbol: 'IKA' },\n CETUS: { type: '0x06864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b::cetus::CETUS', decimals: 9, symbol: 'CETUS' },\n NAVX: { type: '0xa99b8952d4f7d947ea77fe0ecdcc9e5fc0bcab2841d6e2a5aa00c3044e5544b5::navx::NAVX', decimals: 9, symbol: 'NAVX' },\n vSUI: { type: '0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT', decimals: 9, symbol: 'vSUI' },\n haSUI: { type: '0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d::hasui::HASUI', decimals: 9, symbol: 'haSUI' },\n afSUI: { type: '0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc::afsui::AFSUI', decimals: 9, symbol: 'afSUI' },\n LOFI: { type: '0xf22da9a24ad027cccb5f2d496cbe91de953d363513db08a3a734d361c7c17503::LOFI::LOFI', decimals: 9, symbol: 'LOFI' },\n MANIFEST: { type: '0xc466c28d87b3d5cd34f3d5c088751532d71a38d93a8aae4551dd56272cfb4355::manifest::MANIFEST', decimals: 9, symbol: 'MANIFEST' },\n\n // ── Other stables (display / classification) ──────────────────────────\n USDT: { type: '0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT', decimals: 6, symbol: 'USDT' },\n USDe: { type: '0x41d587e5336f1c86cad50d38a7136db99333bb9bda91cea4ba69115defeb1402::sui_usde::SUI_USDE', decimals: 6, symbol: 'USDe' },\n USDSUI: { type: '0x44f838219cf67b058f3b37907b655f226153c18e33dfcd0da559a844fea9b1c1::usdsui::USDSUI', decimals: 6, symbol: 'USDsui' },\n};\n\n/** Reverse lookup: coin type → CoinMeta. Built once at import time. */\nconst BY_TYPE = new Map<string, CoinMeta>();\nfor (const meta of Object.values(COIN_REGISTRY)) {\n BY_TYPE.set(meta.type, meta);\n}\n\n// ── Lookup helpers ───────────────────────────────────────────────────────\n\n/**\n * Returns the registry metadata for a coin type, or `undefined` if the coin\n * is not in the registry. Used for canonical-symbol + decimal resolution.\n */\nexport function getCoinMeta(coinType: string): CoinMeta | undefined {\n return BY_TYPE.get(coinType);\n}\n\n/**\n * Returns true if the coin type appears in COIN_REGISTRY. Useful as a\n * canonical-symbol gate — e.g. so the registry's mixed-case `USDsui` wins\n * over a vendor feed's uppercase `USDSUI`.\n */\nexport function isInRegistry(coinType: string): boolean {\n return BY_TYPE.has(coinType);\n}\n\n// ── Lookup helpers ───────────────────────────────────────────────────────\n\n/**\n * Get decimals for any coin type. Checks full type match, then suffix match,\n * then defaults to 9. Works for any token, registered or not.\n */\nexport function getDecimalsForCoinType(coinType: string): number {\n const direct = BY_TYPE.get(coinType);\n if (direct) return direct.decimals;\n\n const suffix = coinType.split('::').slice(1).join('::').toUpperCase();\n if (suffix) {\n for (const meta of BY_TYPE.values()) {\n const metaSuffix = meta.type.split('::').slice(1).join('::').toUpperCase();\n if (metaSuffix === suffix) return meta.decimals;\n }\n }\n\n return 9;\n}\n\n/** Minimal structural client — just the coin-metadata read this needs. */\ninterface CoinMetadataClient {\n core: { getCoinMetadata: (opts: { coinType: string }) => Promise<unknown> };\n}\n\n/**\n * [2.11] Decimals for any coin type, resolved correctly for arbitrary tokens.\n * Registry tokens return their known decimals (no network). A coin type NOT in\n * the registry is read ON-CHAIN via coin metadata — never the 9-default guess,\n * because a wrong `from` decimal would corrupt a swap's input amount\n * (financial-amounts rule). Falls back to the registry heuristic only if the\n * on-chain read fails or returns no usable decimals.\n */\nexport async function resolveCoinDecimals(\n client: CoinMetadataClient,\n coinType: string,\n): Promise<number> {\n if (isInRegistry(coinType)) return getDecimalsForCoinType(coinType);\n try {\n const res = (await client.core.getCoinMetadata({ coinType })) as {\n metadata?: { decimals?: number };\n decimals?: number;\n };\n const d = res?.metadata?.decimals ?? res?.decimals;\n if (typeof d === 'number' && Number.isFinite(d)) return d;\n } catch {\n /* on-chain read failed — fall through to the registry heuristic */\n }\n return getDecimalsForCoinType(coinType);\n}\n\n/**\n * Resolve a full coin type to a user-friendly symbol.\n * Returns the last `::` segment if not in the registry.\n */\nexport function resolveSymbol(coinType: string): string {\n const direct = BY_TYPE.get(coinType);\n if (direct) return direct.symbol;\n\n const suffix = coinType.split('::').slice(1).join('::').toUpperCase();\n if (suffix) {\n for (const meta of BY_TYPE.values()) {\n const metaSuffix = meta.type.split('::').slice(1).join('::').toUpperCase();\n if (metaSuffix === suffix) return meta.symbol;\n }\n }\n\n return coinType.split('::').pop() ?? coinType;\n}\n\n/**\n * Name → type map for swap resolution. Derived from COIN_REGISTRY.\n * Contains BOTH original-case and UPPERCASE keys for case-insensitive lookup.\n */\nexport const TOKEN_MAP: Record<string, string> = (() => {\n const map: Record<string, string> = {};\n for (const [name, meta] of Object.entries(COIN_REGISTRY)) {\n map[name] = meta.type;\n map[name.toUpperCase()] = meta.type;\n }\n return map;\n})();\n\n/**\n * Resolve a user-friendly token name to its full coin type.\n * Returns the input unchanged if already a full coin type (contains \"::\").\n * Case-insensitive: 'usde', 'USDe', 'USDE' all resolve correctly.\n */\nexport function resolveTokenType(nameOrType: string): string | null {\n if (nameOrType.includes('::')) return nameOrType;\n return TOKEN_MAP[nameOrType] ?? TOKEN_MAP[nameOrType.toUpperCase()] ?? null;\n}\n\n/** Common type constants for direct import. */\nexport const SUI_TYPE = COIN_REGISTRY.SUI.type;\nexport const USDC_TYPE = COIN_REGISTRY.USDC.type;\nexport const USDT_TYPE = COIN_REGISTRY.USDT.type;\nexport const USDSUI_TYPE = COIN_REGISTRY.USDSUI.type;\nexport const USDE_TYPE = COIN_REGISTRY.USDe.type;\nexport const ETH_TYPE = COIN_REGISTRY.ETH.type;\nexport const WBTC_TYPE = COIN_REGISTRY.wBTC.type;\nexport const WAL_TYPE = COIN_REGISTRY.WAL.type;\nexport const NAVX_TYPE = COIN_REGISTRY.NAVX.type;\nexport const IKA_TYPE = COIN_REGISTRY.IKA.type;\nexport const LOFI_TYPE = COIN_REGISTRY.LOFI.type;\nexport const MANIFEST_TYPE = COIN_REGISTRY.MANIFEST.type;\n","/**\n * Wallet-side coin selection helpers — single source of truth for the\n * \"produce a `Coin<T>` argument holding `amount` raw units of `coinType`,\n * owned by `address`\" pattern. Used by every wallet-mode appender that\n * needs a coin input (save, send, swap, repay, stake, etc.).\n *\n * **2026-05-22 — address-balance migration.** Sui mainnet's address-balance\n * feature ships funds account-style instead of as discrete `Coin<T>` objects.\n * After a payment via `0x2::balance::send_funds`, the leftover lands in the\n * sender's address balance with a synthetic \"coin reservation\" representing\n * the deposit. `client.getCoins()` correctly filters those reservations out\n * (they aren't real owned objects), so the old fetch+merge+split pattern\n * threw `INSUFFICIENT_BALANCE` for users whose stables had drifted into\n * address balance — even when `getBalance().totalBalance` showed plenty.\n *\n * The fix is structural: hand the work to `coinWithBalance({ type, balance })`\n * from `@mysten/sui/transactions`. Its build-time resolver inspects coins +\n * address balance together (`getBalance` + `listCoins`), then emits the\n * right shape — direct `redeem_funds` from address balance when AB ≥\n * required, or merge-and-split across coins + AB withdrawal when not. Multi\n * intents per coin type get batched into a single merge in one PTB, so the\n * old per-PTB merge cache is no longer needed.\n *\n * Pre-flight uses `client.getBalance().totalBalance` (sums coins + AB)\n * instead of summing the paginated `getCoins` page. That's the OTHER half\n * of the migration — the legacy path could see `0` from `getCoins` and\n * mistakenly throw before `coinWithBalance` ever ran.\n */\nimport {\n Transaction,\n coinWithBalance,\n type TransactionObjectArgument,\n} from '@mysten/sui/transactions';\nimport type { SuiCoreClient } from '../utils/sui.js';\nimport { T2000Error } from '../errors.js';\n\nexport interface CoinPage {\n ids: string[];\n totalBalance: bigint;\n}\n\n/**\n * Sum every coin of `coinType` owned by `owner`, INCLUDING address balance.\n * Returns the IDs of any discrete coin objects that exist (callers\n * occasionally need this for non-`coinWithBalance` paths, e.g. SUIns name\n * registration which expects raw object IDs).\n *\n * Pre-2026-05-22 this function paginated `client.getCoins` and summed\n * the page balances. That misses address-balance funds (the SDK filters\n * them out of `getCoins` for back-compat). The new implementation calls\n * `getBalance` for the canonical total and `getCoins` for the optional\n * ID list — both round-trips, but they happen in parallel.\n */\nexport async function fetchAllCoins(\n client: SuiCoreClient,\n owner: string,\n coinType: string,\n): Promise<CoinPage> {\n const [balance, ids] = await Promise.all([\n client.core.getBalance({ owner, coinType }),\n (async () => {\n const out: string[] = [];\n let cursor: string | null | undefined;\n let hasNext = true;\n while (hasNext) {\n const page = await client.core.listCoins({ owner, coinType, cursor: cursor ?? undefined });\n for (const c of page.objects) out.push(c.objectId);\n cursor = page.cursor;\n hasNext = page.hasNextPage;\n }\n return out;\n })(),\n ]);\n return { ids, totalBalance: BigInt(balance.balance.balance) };\n}\n\nexport interface SelectAndSplitResult {\n /** TransactionObjectArgument for a coin holding `effectiveAmount` raw units. */\n coin: TransactionObjectArgument;\n /** Actual raw amount the returned coin holds. May be < requested if `swapAll` is true. */\n effectiveAmount: bigint;\n /** True iff the request consumed the entire wallet balance (no split needed). */\n swapAll: boolean;\n}\n\n/**\n * Wallet-mode coin selection prelude. Pre-flights against\n * `getBalance().totalBalance` (coins + address balance combined), then\n * returns a `coinWithBalance({ type, balance })` argument that the\n * `@mysten/sui` resolver fulfills at build time.\n *\n * Throws `T2000Error` (`INSUFFICIENT_BALANCE`) when:\n * - `amount` is bigger than the total balance AND the caller did NOT\n * opt into `swapAll: true` clipping.\n * - `amount === 'all'` AND total balance is zero.\n *\n * @param tx — PTB to register the `coinWithBalance` intent against.\n * @param client — Sui RPC client for the pre-flight `getBalance` lookup.\n * @param owner — wallet address whose coins to source from.\n * @param coinType — fully-qualified Sui coin type (e.g. `\"0x...::usdc::USDC\"`).\n * @param amount — raw amount to source (in MIST / smallest unit). Pass\n * `'all'` to consume the entire balance.\n * @param options.allowSwapAll — if true (default), `amount` >= totalBalance\n * auto-clips to total. If false, throws when the request would over-consume.\n * @param options.sponsoredContext — when true, source ONLY from discrete coin\n * objects (never the address balance). See the long note below — this exists\n * because Enoki's gas station can't yet deserialize a `TransactionData` that\n * contains the address-balance `FundsWithdrawal` reservation that\n * `coinWithBalance` emits. Self-funded callers leave this false: the fullnode\n * handles `FundsWithdrawal` fine, so the address-balance path is preferred\n * (it can reach funds that aren't held as coin objects).\n *\n * @returns\n * - `coin` — `TransactionObjectArgument` ready for downstream consumption.\n * - `effectiveAmount` — the raw amount the returned coin holds (handles\n * swapAll clipping).\n * - `swapAll` — true iff the entire balance was consumed.\n */\nexport async function selectAndSplitCoin(\n tx: Transaction,\n client: SuiCoreClient,\n owner: string,\n coinType: string,\n amount: bigint | 'all',\n options: {\n allowSwapAll?: boolean;\n sponsoredContext?: boolean;\n mergeCache?: SponsoredCoinMergeCache;\n } = {},\n): Promise<SelectAndSplitResult> {\n // [2026-05-30] Sponsored Enoki path — coin objects only. `coinWithBalance`\n // reaches into the address balance (mysten Address Balances feature) when\n // `addressBalance >= required`, emitting `0x2::coin::redeem_funds` + a\n // `FundsWithdrawal` reservation input. That input is a newer `TransactionData`\n // field; Enoki's sponsor endpoint accepts the kind bytes (200) but its gas\n // station rejects the assembled `TransactionData` at execute with\n // \"Invalid bcs bytes for TransactionData\". The fullnode parses it fine — only\n // Enoki can't (yet). So under sponsorship we source from discrete coin objects\n // and surface a clear error when the user's funds are address-balance-only.\n // See github.com/mission69b/t2000 issue #93.\n if (options.sponsoredContext) {\n return selectCoinObjectsOnly(\n tx,\n client,\n owner,\n coinType,\n amount,\n options.allowSwapAll ?? true,\n options.mergeCache,\n );\n }\n\n const balanceResp = await client.core.getBalance({ owner, coinType });\n const totalBalance = BigInt(balanceResp.balance.balance);\n\n if (totalBalance === 0n) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `No balance found for ${coinType}`);\n }\n\n const allowSwapAll = options.allowSwapAll ?? true;\n\n if (amount !== 'all' && amount > totalBalance && !allowSwapAll) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient balance for ${coinType}`, {\n available: totalBalance.toString(),\n required: amount.toString(),\n });\n }\n\n const requested = amount === 'all' ? totalBalance : amount;\n const swapAll = amount === 'all' || requested >= totalBalance;\n const effectiveAmount = swapAll ? totalBalance : requested;\n\n const coin = coinWithBalance({ type: coinType, balance: effectiveAmount })(tx);\n\n return { coin, effectiveAmount, swapAll };\n}\n\n/**\n * Coin-object-only selection for sponsored (Enoki) transactions. Fetches the\n * owner's discrete `Coin<T>` objects (NOT the address balance — `getCoins`\n * excludes it), merges them, and splits the requested amount. Never emits a\n * `FundsWithdrawal` reservation, so the resulting `TransactionData` stays on\n * the shape Enoki's gas station can serialize.\n *\n * Throws `ADDRESS_BALANCE_UNSPONSORABLE` when the coin objects don't cover the\n * request — which, for a user whose `getBalance().totalBalance` shows funds,\n * means those funds live in the address balance (e.g. received via a gasless\n * stablecoin transfer) and can't be moved through a sponsored transaction yet.\n */\n/**\n * Per-PTB cache of merged sponsored coin-object primaries, keyed by coin\n * type. The FIRST `selectCoinObjectsOnly` call for a given coin type in a\n * PTB fetches the owner's discrete `Coin<T>` objects, merges them into one\n * `primary`, and records it here alongside the remaining (unspent) balance.\n * EVERY subsequent leg sourcing the same coin type splits from that cached\n * `primary` instead of re-fetching + re-merging.\n *\n * Why this exists (S.xxx, 2026-06-02): a sponsored bundle with 2+ legs\n * sourcing the same coin (e.g. `SUI→WAL` + `SUI→DEEP`, or `swap USDC` +\n * `save USDC`) called `selectCoinObjectsOnly` once per leg. Each call\n * emitted its own `mergeCoins` over the SAME coin objects, so the second\n * leg's merge referenced coins the first leg already consumed → Enoki\n * dry-run failed with `CommandArgumentError { ArgumentWithoutValue }`.\n *\n * This is NOT SUI-specific. Under sponsorship, `selectAndSplitCoin` routes\n * EVERY asset through `selectCoinObjectsOnly` (the `coinWithBalance`\n * batching that would otherwise dedup these merges only runs for\n * non-sponsored CLI/direct flows — its address-balance `FundsWithdrawal`\n * reservation is what Enoki can't deserialize, issue #93). So the cache is\n * the dedup layer for ALL coin types in a sponsored multi-leg PTB, keyed\n * by coin type. SUI was simply the first asset observed failing in the\n * wild because it's the most common swap source.\n */\nexport type SponsoredCoinMergeCache = Map<\n string,\n { primary: TransactionObjectArgument; remaining: bigint }\n>;\n\nasync function selectCoinObjectsOnly(\n tx: Transaction,\n client: SuiCoreClient,\n owner: string,\n coinType: string,\n amount: bigint | 'all',\n allowSwapAll: boolean,\n mergeCache?: SponsoredCoinMergeCache,\n): Promise<SelectAndSplitResult> {\n // Cache hit — a prior leg in THIS PTB already merged this coin type's\n // objects into `cached.primary`. Re-running the fetch+merge below would\n // emit a second `mergeCoins` over already-consumed coins → dry-run\n // `ArgumentWithoutValue`. Split from the cached primary instead.\n const cached = mergeCache?.get(coinType);\n if (cached) {\n const requested = amount === 'all' ? cached.remaining : amount;\n if (cached.remaining === 0n || requested > cached.remaining) {\n throw new T2000Error(\n 'ADDRESS_BALANCE_UNSPONSORABLE',\n `Not enough ${coinType} in coin objects to cover all legs of this ` +\n `sponsored bundle. The remaining funds are in your address balance, ` +\n `which sponsored transactions can't access yet.`,\n { remaining: cached.remaining.toString(), requested: requested.toString(), coinType },\n );\n }\n const swapAll = amount === 'all' || requested >= cached.remaining;\n const effectiveAmount = swapAll ? cached.remaining : requested;\n const coin = swapAll\n ? cached.primary\n : tx.splitCoins(cached.primary, [effectiveAmount])[0];\n cached.remaining -= effectiveAmount;\n return { coin, effectiveAmount, swapAll };\n }\n\n const objects: { objectId: string; balance: bigint }[] = [];\n let coinObjectTotal = 0n;\n let cursor: string | null | undefined;\n let hasNext = true;\n while (hasNext) {\n const page = await client.core.listCoins({ owner, coinType, cursor: cursor ?? undefined });\n for (const c of page.objects) {\n objects.push({ objectId: c.objectId, balance: BigInt(c.balance) });\n coinObjectTotal += BigInt(c.balance);\n }\n cursor = page.cursor;\n hasNext = page.hasNextPage;\n }\n\n const unsponsorable = (): T2000Error =>\n new T2000Error(\n 'ADDRESS_BALANCE_UNSPONSORABLE',\n `These funds are in your address balance, which sponsored transactions ` +\n `can't access yet. (Funds received via gasless transfers land there.) ` +\n `This will work once the gas sponsor adds address-balance support.`,\n { coinObjectTotal: coinObjectTotal.toString(), coinType },\n );\n\n if (coinObjectTotal === 0n) {\n throw unsponsorable();\n }\n\n const requested = amount === 'all' ? coinObjectTotal : amount;\n if (requested > coinObjectTotal) {\n // Not enough in coin objects. If the caller allows clipping to the\n // available coin-object total (\"swap all\"), do so; otherwise the shortfall\n // is sitting in the address balance → unsponsorable.\n if (allowSwapAll && amount === 'all') {\n // unreachable (requested === coinObjectTotal here) — kept for clarity.\n } else {\n throw unsponsorable();\n }\n }\n\n const swapAll = amount === 'all' || requested >= coinObjectTotal;\n const effectiveAmount = swapAll ? coinObjectTotal : requested;\n\n const [first, ...rest] = objects;\n const primary = tx.object(first.objectId);\n if (rest.length > 0) {\n tx.mergeCoins(\n primary,\n rest.map((o) => tx.object(o.objectId)),\n );\n }\n\n // Consume the whole merged coin when taking everything; otherwise split the\n // exact amount and leave the remainder on the (sender-owned) primary coin.\n const coin = swapAll ? primary : tx.splitCoins(primary, [effectiveAmount])[0];\n\n // Record the merged primary so later legs in the same PTB reuse it\n // rather than re-fetching + re-merging the same (now-consumed) coins.\n // When `swapAll`, the primary was consumed (remaining 0) — a later leg\n // hitting the cache then throws the unsponsorable shortfall above.\n mergeCache?.set(coinType, {\n primary,\n remaining: coinObjectTotal - effectiveAmount,\n });\n\n return { coin, effectiveAmount, swapAll };\n}\n\n/**\n * Build a GASLESS coin→address-balance migration.\n *\n * Sends WHOLE `Coin<T>` objects to `owner`'s OWN SIP-58 address balance via\n * `0x2::coin::send_funds(coin, owner)` — one allowlisted framework MoveCall\n * per coin, with NO native `SplitCoins` / `MergeCoins` commands. That shape is\n * what makes it gasless: the gRPC build resolver only zeros gas for PTBs whose\n * every command is a MoveCall into the `0x2` gasless allowlist (`send_funds` /\n * `redeem_funds` / `withdrawal_split` / `into_balance`). The same eligibility\n * the gasless `balance::send_funds` send + the x402 `redeem_funds`+`send_funds`\n * withdrawal rely on. (The old migration merged+split first → native commands →\n * fell outside the allowlist → needed SUI. See `pay.ts ensureAddressBalanceCovers`.)\n *\n * Selects the FEWEST coins (largest first) whose combined balance covers\n * `minAmount`, minimizing the MoveCall count. Over-migration is harmless — the\n * surplus just lands in the address balance. Pure / network-free: callers pass\n * coins they've already fetched, so this is unit-testable offline.\n *\n * Throws `INSUFFICIENT_BALANCE` when the supplied coin objects can't cover\n * `minAmount`.\n */\nexport function buildCoinToAddressBalanceMigration(args: {\n coins: { objectId: string; balance: bigint }[];\n coinType: string;\n owner: string;\n minAmount: bigint;\n}): { tx: Transaction; migratedRaw: bigint } {\n const { coins, coinType, owner, minAmount } = args;\n\n // Largest first → fewest whole-coin sends to cover the shortfall.\n const sorted = [...coins]\n .filter((c) => c.balance > 0n)\n .sort((a, b) => (b.balance > a.balance ? 1 : b.balance < a.balance ? -1 : 0));\n\n const selected: { objectId: string; balance: bigint }[] = [];\n let migratedRaw = 0n;\n for (const c of sorted) {\n if (migratedRaw >= minAmount) break;\n selected.push(c);\n migratedRaw += c.balance;\n }\n\n if (migratedRaw < minAmount) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${coinType} coin objects to migrate`, {\n available: migratedRaw.toString(),\n required: minAmount.toString(),\n });\n }\n\n const tx = new Transaction();\n for (const c of selected) {\n tx.moveCall({\n target: '0x2::coin::send_funds',\n typeArguments: [coinType],\n arguments: [tx.object(c.objectId), tx.pure.address(owner)],\n });\n }\n return { tx, migratedRaw };\n}\n\n/**\n * SUI-specific coin selection. Branches on sponsorship context:\n *\n * - **Self-funded (`sponsoredContext: false`)** — splits from `tx.gas`\n * directly (the user's gas coin IS their SUI). More efficient — no\n * `getBalance` RTT.\n *\n * - **Sponsored (`sponsoredContext: true`)** — sources from the user's\n * discrete SUI coin objects (`selectCoinObjectsOnly`). This both (a) avoids\n * `tx.gas`, which belongs to the Enoki sponsor — NOT the user — under\n * sponsored flows (the original S.260 reason for `useGasCoin: false`), AND\n * (b) avoids `coinWithBalance`'s address-balance `FundsWithdrawal`, which\n * Enoki's gas station can't deserialize (issue #93). If the user's SUI is\n * address-balance-only, it raises `ADDRESS_BALANCE_UNSPONSORABLE`.\n */\nexport async function selectSuiCoin(\n tx: Transaction,\n client: SuiCoreClient,\n owner: string,\n amountMist: bigint,\n sponsoredContext: boolean,\n mergeCache?: SponsoredCoinMergeCache,\n): Promise<SelectAndSplitResult> {\n if (sponsoredContext) {\n const { SUI_TYPE } = await import('../token-registry.js');\n return selectCoinObjectsOnly(tx, client, owner, SUI_TYPE, amountMist, false, mergeCache);\n }\n\n const [coin] = tx.splitCoins(tx.gas, [amountMist]);\n return { coin, effectiveAmount: amountMist, swapAll: false };\n}\n","/**\n * Cetus Aggregator V3 SDK wrapper — the ONLY file that imports @cetusprotocol/aggregator-sdk.\n * Documented CLAUDE.md exception: multi-DEX routing cannot be feasibly replaced by thin tx builders.\n *\n * [B5 v2 / @t2000/sdk@1.1.0 / 2026-04-30]\n * Overlay fee config is now per-call instead of a module-level singleton. CLI / direct\n * SDK callers (`T2000.swap()`) DON'T pass `overlayFee` → fee-free swap. Audric's\n * prepare/route.ts ALWAYS passes `overlayFee = { rate: OVERLAY_FEE_RATE, receiver:\n * T2000_OVERLAY_FEE_WALLET }` → fee charged. Structural inclusion (Audric's code can't\n * forget to pass it because it IS the code), not a toggle that defaults to safe.\n *\n * Pre-1.1.0: a module-level `OVERLAY_FEE_RECEIVER` constant defaulted to a Move object\n * ID. USDC sent there became OwnedObjects keyed to the object and was inaccessible.\n * Fixed by making the receiver a regular wallet address (T2000_OVERLAY_FEE_WALLET) AND\n * by removing the singleton pattern that hid the misconfig.\n */\nimport { AggregatorClient, Env, type FindRouterParams, type RouterDataV3 } from '@cetusprotocol/aggregator-sdk';\nimport { Transaction, type TransactionObjectArgument } from '@mysten/sui/transactions';\nimport BN from 'bn.js';\nimport { resolveTokenType, getDecimalsForCoinType } from '../token-registry.js';\nimport type { SuiCoreClient } from '../utils/sui.js';\nimport type { SponsoredCoinMergeCache } from '../wallet/coinSelection.js';\nimport {\n type PreflightResult,\n PREFLIGHT_OK,\n preflightFail,\n checkPositiveAmount,\n} from '../preflight.js';\n\n/**\n * Synchronous, network-free preflight for `swap`. Validates the from/to token\n * args + amount sanity, and rejects an identity swap — the cheap checks the\n * host runs before routing. Returns a `PreflightResult`; never throws.\n * Route-finding, liquidity, slippage + decimals resolution stay in the async\n * path (`findSwapRoute`/`buildSwapTx`/`getSwapQuote`).\n *\n * v3 drops the swap *tool*, but `swap` survives as an SDK/CLI builder (§8) so\n * it gets the same builder-appropriate preflight as send/pay.\n */\nexport function preflightSwap(input: {\n from: string;\n to: string;\n amount: number;\n}): PreflightResult {\n if (typeof input.from !== 'string' || input.from.trim() === '') {\n return preflightFail('INVALID_ASSET', 'A `from` token is required to swap');\n }\n if (typeof input.to !== 'string' || input.to.trim() === '') {\n return preflightFail('INVALID_ASSET', 'A `to` token is required to swap');\n }\n\n // No upper ceiling — swaps route arbitrary tokens, and low-unit-value tokens\n // legitimately trade in millions/billions of units.\n const amountCheck = checkPositiveAmount(input.amount, 'Amount', Number.POSITIVE_INFINITY);\n if (!amountCheck.valid) return amountCheck;\n\n // Identity swap is a no-op the router can't route — catch it cheaply.\n // Resolve symbol → coin type so \"USDC\" and the USDC coin type compare equal.\n // Guard the null===null case (two unknown symbols both resolve to null) by\n // also requiring the resolved value to be non-null, falling back to a raw\n // string compare.\n const resolvedFrom = resolveTokenType(input.from);\n const resolvedTo = resolveTokenType(input.to);\n const sameToken =\n input.from.trim() === input.to.trim() ||\n (resolvedFrom !== null && resolvedFrom === resolvedTo);\n if (sameToken) {\n return preflightFail('INVALID_ASSET', `Cannot swap ${input.from} to itself`);\n }\n\n return PREFLIGHT_OK;\n}\n\nexport interface OverlayFeeConfig {\n /** Fee rate as a fraction (e.g. 0.001 = 0.1%). Pass 0 to disable. */\n rate: number;\n /** Wallet address that receives the overlay fee. */\n receiver: string;\n}\n\nexport interface SwapRouteResult {\n routerData: RouterDataV3;\n amountIn: string;\n amountOut: string;\n byAmountIn: boolean;\n priceImpact: number;\n insufficientLiquidity: boolean;\n}\n\n// [SPEC 20.2 / D-1 (a)] Typed JSON-friendly representation of a Cetus\n// `RouterDataV3` for cross-process / cross-network transport. The native\n// shape contains `BN` instances (`bn.js`) and a `Map<string, string>`\n// (`packages`) that don't survive JSON.stringify / JSON.parse cleanly:\n// - `BN.toJSON()` returns the internal `{negative,words,length,red}` blob\n// - `Map.toJSON()` returns `{}`\n// Round-tripping via `serializeCetusRoute` + `deserializeCetusRoute`\n// converts BN ↔ decimal string and Map ↔ Record. Engine + audric both\n// reference fields by path (`route.routerData.paths[i].provider`) without\n// needing to know about the underlying BN/Map types.\nexport interface SerializedCetusRoutePath {\n id: string;\n direction: boolean;\n provider: string;\n from: string;\n target: string;\n feeRate: number;\n amountIn: string;\n amountOut: string;\n version?: string;\n publishedAt?: string;\n extendedDetails?: Record<string, unknown>;\n}\n\nexport interface SerializedRouterDataV3 {\n quoteID?: string;\n /** RouterDataV3.amountIn (BN) → decimal string */\n amountIn: string;\n /** RouterDataV3.amountOut (BN) → decimal string */\n amountOut: string;\n byAmountIn: boolean;\n paths: SerializedCetusRoutePath[];\n insufficientLiquidity: boolean;\n deviationRatio: number;\n /** RouterDataV3.packages (Map) → Record */\n packages?: Record<string, string>;\n totalDeepFee?: number;\n error?: { code: number; msg: string };\n overlayFee?: number;\n}\n\nexport interface SerializedCetusRoute {\n routerData: SerializedRouterDataV3;\n amountIn: string;\n amountOut: string;\n byAmountIn: boolean;\n priceImpact: number;\n insufficientLiquidity: boolean;\n /**\n * Wall-clock timestamp (ms since epoch) at which the route was discovered.\n * Used by audric's prepare-route for SPEC 20.2 D-3 TTL re-validation: if\n * the route is older than the threshold AND price impact has shifted\n * beyond tolerance, fall back to a fresh `findSwapRoute()` call.\n */\n discoveredAt: number;\n /**\n * Snapshot of the input/output coin types the route was discovered for.\n * SPEC 20.2 D-2 (b) structural verification: prepare-route asserts\n * input/output coins match before using the fast-path; mismatch falls\n * back to fresh discovery (defense against client-side tampering and\n * against legitimate token-type drift in the request).\n */\n fromCoinType: string;\n toCoinType: string;\n}\n\nexport function serializeCetusRoute(\n route: SwapRouteResult,\n context: { fromCoinType: string; toCoinType: string },\n): SerializedCetusRoute {\n return {\n routerData: serializeRouterDataV3(route.routerData),\n amountIn: route.amountIn,\n amountOut: route.amountOut,\n byAmountIn: route.byAmountIn,\n priceImpact: route.priceImpact,\n insufficientLiquidity: route.insufficientLiquidity,\n discoveredAt: Date.now(),\n fromCoinType: context.fromCoinType,\n toCoinType: context.toCoinType,\n };\n}\n\nexport function deserializeCetusRoute(serialized: SerializedCetusRoute): SwapRouteResult {\n return {\n routerData: deserializeRouterDataV3(serialized.routerData),\n amountIn: serialized.amountIn,\n amountOut: serialized.amountOut,\n byAmountIn: serialized.byAmountIn,\n priceImpact: serialized.priceImpact,\n insufficientLiquidity: serialized.insufficientLiquidity,\n };\n}\n\nfunction serializeRouterDataV3(rd: RouterDataV3): SerializedRouterDataV3 {\n const out: SerializedRouterDataV3 = {\n amountIn: rd.amountIn.toString(),\n amountOut: rd.amountOut.toString(),\n byAmountIn: rd.byAmountIn,\n paths: rd.paths.map(serializeCetusRoutePath),\n insufficientLiquidity: rd.insufficientLiquidity,\n deviationRatio: rd.deviationRatio,\n };\n if (rd.quoteID !== undefined) out.quoteID = rd.quoteID;\n if (rd.packages) {\n const obj: Record<string, string> = {};\n for (const [k, v] of rd.packages) obj[k] = v;\n out.packages = obj;\n }\n if (rd.totalDeepFee !== undefined) out.totalDeepFee = rd.totalDeepFee;\n if (rd.error) out.error = { code: rd.error.code, msg: rd.error.msg };\n if (rd.overlayFee !== undefined) out.overlayFee = rd.overlayFee;\n return out;\n}\n\nfunction deserializeRouterDataV3(s: SerializedRouterDataV3): RouterDataV3 {\n const out: RouterDataV3 = {\n amountIn: new BN(s.amountIn),\n amountOut: new BN(s.amountOut),\n byAmountIn: s.byAmountIn,\n paths: s.paths.map(deserializeCetusRoutePath),\n insufficientLiquidity: s.insufficientLiquidity,\n deviationRatio: s.deviationRatio,\n };\n if (s.quoteID !== undefined) out.quoteID = s.quoteID;\n if (s.packages) out.packages = new Map(Object.entries(s.packages));\n if (s.totalDeepFee !== undefined) out.totalDeepFee = s.totalDeepFee;\n if (s.error) out.error = { code: s.error.code, msg: s.error.msg };\n if (s.overlayFee !== undefined) out.overlayFee = s.overlayFee;\n return out;\n}\n\nfunction serializeCetusRoutePath(p: RouterDataV3['paths'][number]): SerializedCetusRoutePath {\n const out: SerializedCetusRoutePath = {\n id: p.id,\n direction: p.direction,\n provider: p.provider,\n from: p.from,\n target: p.target,\n feeRate: p.feeRate,\n amountIn: p.amountIn,\n amountOut: p.amountOut,\n };\n if (p.version !== undefined) out.version = p.version;\n if (p.publishedAt !== undefined) out.publishedAt = p.publishedAt;\n if (p.extendedDetails) out.extendedDetails = { ...p.extendedDetails };\n return out;\n}\n\nfunction deserializeCetusRoutePath(p: SerializedCetusRoutePath): RouterDataV3['paths'][number] {\n const out: RouterDataV3['paths'][number] = {\n id: p.id,\n direction: p.direction,\n provider: p.provider,\n from: p.from,\n target: p.target,\n feeRate: p.feeRate,\n amountIn: p.amountIn,\n amountOut: p.amountOut,\n };\n if (p.version !== undefined) out.version = p.version;\n if (p.publishedAt !== undefined) out.publishedAt = p.publishedAt;\n if (p.extendedDetails) out.extendedDetails = { ...p.extendedDetails };\n return out;\n}\n\n/**\n * SPEC 20.2 D-2 (b) structural verification helper. Returns true when the\n * serialized route matches the requested coin types (i.e. it's safe to use\n * as the prepare-route fast-path), false otherwise (tampered, or input\n * mismatch from a legitimate but stale pending action). Caller falls back\n * to a fresh `findSwapRoute()` call when verification fails.\n */\nexport function verifyCetusRouteCoinMatch(\n serialized: SerializedCetusRoute,\n expected: { fromCoinType: string; toCoinType: string },\n): boolean {\n return serialized.fromCoinType === expected.fromCoinType && serialized.toCoinType === expected.toCoinType;\n}\n\n/**\n * SPEC 20.2 D-3 (b) TTL helper. Returns true when the serialized route is\n * fresh enough to use as the fast-path (< `maxAgeMs` old). Returns false\n * for stale routes — caller falls back to fresh `findSwapRoute()` to pick\n * up any pool-price drift since route discovery.\n *\n * Default 30s aligns with the existing quote-freshness contract surfaced\n * to users via `pending_action.quoteAge` (the PermissionCard \"QUOTE Ns OLD\"\n * badge starts warning the user past 30s).\n */\nexport function isCetusRouteFresh(serialized: SerializedCetusRoute, maxAgeMs: number = 30_000): boolean {\n return Date.now() - serialized.discoveredAt < maxAgeMs;\n}\n\n/**\n * Default Audric swap overlay fee — 0.1%. Exported for consumers that want to use\n * the canonical Audric rate (the Audric prepare-route does this). Changing this\n * rate requires a coordinated SDK + audric release.\n */\nexport const OVERLAY_FEE_RATE = 0.001;\n\n/**\n * Cache `AggregatorClient` instances by `(signer + overlay rate + overlay receiver)`.\n * Per-call instantiation is cheap (the client is mostly config), but caching avoids\n * pointless re-allocation when the same caller swaps multiple times in a loop.\n */\nconst clientCache = new Map<string, AggregatorClient>();\n\nfunction getClient(walletAddress: string, overlayFee?: OverlayFeeConfig): AggregatorClient {\n const rate = overlayFee?.rate ?? 0;\n const receiver = overlayFee?.receiver ?? '';\n const key = `${walletAddress}|${rate}|${receiver}`;\n\n const cached = clientCache.get(key);\n if (cached) return cached;\n\n const client = new AggregatorClient({\n signer: walletAddress,\n env: Env.Mainnet,\n ...(rate > 0 && receiver\n ? { overlayFeeRate: rate, overlayFeeReceiver: receiver }\n : {}),\n });\n clientCache.set(key, client);\n return client;\n}\n\n/**\n * [Bug A defense-in-depth / 2026-05-10] Returns true when every path\n * provider in `route.routerData.paths` is present in the active\n * `providers` allow-list. Cetus's `getProvidersExcluding(...)` returns\n * an inclusion list (the complement of the exclusion), so when a caller\n * passes `providers`, every walked provider must be IN that list to be\n * compatible.\n *\n * When `providers` is undefined (non-sponsored caller, e.g. CLI) every\n * route is compatible — same semantics as `findSwapRoute` itself.\n *\n * Why per-path: a Cetus aggregator route can split across multiple DEXes\n * (e.g. 60% Cetus + 40% Bluefin). A single excluded provider in any path\n * triggers `tx.gas` usage in `routerSwap`. Reject the whole route if any\n * leg is excluded.\n */\nexport function isPrecomputedRouteCompatibleWithProviders(\n route: SwapRouteResult,\n providers: string[] | undefined,\n): boolean {\n if (!providers || providers.length === 0) return true;\n const allowed = new Set(providers);\n for (const path of route.routerData.paths) {\n if (!allowed.has(path.provider)) return false;\n }\n return true;\n}\n\n/**\n * Find the optimal swap route via Cetus Aggregator REST API.\n *\n * Pass `overlayFee` to charge an overlay fee on the output (Audric's pattern).\n * Omit it for a fee-free swap (CLI / direct SDK pattern).\n */\nexport async function findSwapRoute(params: {\n walletAddress: string;\n from: string;\n to: string;\n amount: bigint;\n byAmountIn: boolean;\n overlayFee?: OverlayFeeConfig;\n /**\n * Optional Cetus provider allow-list. When omitted, all 30+ DEXes\n * are eligible. Sponsored flows (Enoki) MUST pass an exclusion list\n * computed via `getProvidersExcluding([...])` from the Cetus SDK to\n * remove Pyth-dependent providers (HAEDALPMM, METASTABLE, OBRIC,\n * STEAMM_OMM, STEAMM_OMM_V2, SEVENK, HAEDALHMMV2) — those reference\n * `tx.gas` for oracle fees, which Enoki rejects in sponsored txs.\n * Non-sponsored callers (CLI, direct SDK) leave this undefined.\n */\n providers?: string[];\n}): Promise<SwapRouteResult | null> {\n const client = getClient(params.walletAddress, params.overlayFee);\n\n const findParams: FindRouterParams = {\n from: params.from,\n target: params.to,\n amount: params.amount.toString(),\n byAmountIn: params.byAmountIn,\n ...(params.providers ? { providers: params.providers } : {}),\n };\n\n const routerData = await client.findRouters(findParams);\n if (!routerData) return null;\n\n if (routerData.insufficientLiquidity) {\n return {\n routerData,\n amountIn: routerData.amountIn.toString(),\n amountOut: routerData.amountOut.toString(),\n byAmountIn: params.byAmountIn,\n priceImpact: normalizePriceImpact(routerData.deviationRatio),\n insufficientLiquidity: true,\n };\n }\n\n if (routerData.error) {\n const { T2000Error } = await import('../errors.js');\n throw new T2000Error('SWAP_FAILED', `Cetus routing error: ${routerData.error.msg} (code ${routerData.error.code})`);\n }\n\n return {\n routerData,\n amountIn: routerData.amountIn.toString(),\n amountOut: routerData.amountOut.toString(),\n byAmountIn: params.byAmountIn,\n priceImpact: normalizePriceImpact(routerData.deviationRatio),\n insufficientLiquidity: false,\n };\n}\n\n/**\n * Cetus' aggregator types `deviationRatio` as `number`, but in some routes\n * the router actually returns a string (\"0.001234\"). The SDK type lies, so we\n * always coerce to a finite number here (NaN/null/undefined → 0). Without\n * this every downstream consumer that calls `priceImpact.toFixed(...)` will\n * crash at runtime — including the Audric SwapQuoteCard, which takes the\n * whole chat UI down through its error boundary.\n */\nfunction normalizePriceImpact(value: unknown): number {\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : 0;\n}\n\n/**\n * Build a swap PTB from a route result. The caller must provide an input coin\n * obtained by splitting/merging wallet coins.\n *\n * **Important:** Cetus's `routerSwap` reads the overlay-fee config from the\n * AggregatorClient instance. The `overlayFee` param here MUST match the one\n * passed to `findSwapRoute` for the same swap (otherwise you'll hit the cache\n * boundary and get a different client with different overlay config).\n */\nexport async function buildSwapTx(params: {\n walletAddress: string;\n route: SwapRouteResult;\n tx: Transaction;\n inputCoin: TransactionObjectArgument;\n slippage: number;\n overlayFee?: OverlayFeeConfig;\n}): Promise<TransactionObjectArgument> {\n const client = getClient(params.walletAddress, params.overlayFee);\n const clampedSlippage = Math.max(0.001, Math.min(params.slippage, 0.05));\n\n const outputCoin = await client.routerSwap({\n router: params.route.routerData,\n inputCoin: params.inputCoin,\n slippage: clampedSlippage,\n txb: params.tx,\n });\n\n return outputCoin;\n}\n\n/**\n * Append a swap fragment to an existing PTB. SPEC 7 § \"Layer 1\" Cetus\n * appender. Two modes, dispatched by the presence of `input.inputCoin`:\n *\n * - **Wallet mode** (`inputCoin` omitted) — sources `from`-asset funds\n * via `coinWithBalance({ type, balance })` (resolves coin objects +\n * address balance at build time), runs the swap. Mirrors the audric\n * host's `transactions/prepare/route.ts` swap branch (P2.2c will\n * retire that branch in favor of this appender via `composeTx`).\n *\n * - **Chain mode** (`inputCoin` provided) — consumes the passed-in coin\n * reference (typically produced by an upstream appender like\n * `addWithdrawToTx`) directly, no wallet fetch / no merge / no\n * split. This is the SPEC 7 multi-write enabler (\"withdraw → swap →\n * save\" without intermediate wallet materialization).\n *\n * **SUI in wallet mode:** ALWAYS sources through `selectSuiCoin` (which\n * routes via `coinWithBalance({ type: SUI, useGasCoin: false })` under\n * sponsored flows, OR `tx.splitCoins(tx.gas, ...)` under self-funded\n * flows). The caller MUST set `sponsoredContext` correctly — otherwise\n * sponsored swaps with SUI source fail with `Cannot use GasCoin as a\n * transaction argument` (Enoki owns `tx.gas`, the PTB body referencing\n * it as an argument is invalid for sponsorship). 2.14.0 shipped without\n * this branch and broke audric/web-v2 SUI→USDC swaps; restored in 2.14.1\n * (S.260). For non-sponsored flows (CLI), `T2000.swap()` pre-builds the\n * inputCoin via `tx.splitCoins(tx.gas, [rawAmount])[0]` and uses chain\n * mode, sidestepping wallet-mode entirely — this branch is a defensive\n * safety net for future direct SDK users who pass SUI in wallet mode.\n *\n * **`swapAll` semantics (wallet mode):** if the requested raw amount\n * is >= the wallet's total `from` balance, the appender consumes the\n * entire merged primary coin (not a split), matching audric's host\n * route's `swapAll` clipping. The returned `effectiveAmountIn` reflects\n * the actual consumed amount in display units.\n *\n * **Slippage:** clamped to [0.001, 0.05] (0.1% – 5%). Defaults to 0.01.\n *\n * @returns\n * - `coin` — output coin reference, ready for downstream consumption\n * (e.g. `addSaveToTx`) or wallet transfer (`tx.transferObjects`).\n * - `effectiveAmountIn` — display-units input amount the swap actually\n * consumes (handles `swapAll` clipping in wallet mode; in chain mode\n * echoes the requested `input.amount`).\n * - `expectedAmountOut` — display-units output amount per the route\n * quote. Actual on-chain output may differ within slippage.\n * - `route` — raw `SwapRouteResult` for downstream telemetry / logging.\n */\nexport async function addSwapToTx(\n tx: Transaction,\n client: SuiCoreClient,\n address: string,\n input: {\n from: string;\n to: string;\n amount: number;\n slippage?: number;\n byAmountIn?: boolean;\n overlayFee?: OverlayFeeConfig;\n inputCoin?: TransactionObjectArgument;\n /**\n * Optional Cetus provider allow-list. Forwarded to `findSwapRoute`.\n * Sponsored flows (Enoki) MUST pass `getProvidersExcluding([...])`\n * to remove Pyth-dependent providers — see `findSwapRoute`'s JSDoc\n * for the exclusion list. Non-sponsored callers omit this.\n */\n providers?: string[];\n /**\n * [SPEC 20.2 D-3 (b)] Precomputed route from a prior `findSwapRoute()`\n * call (typically captured by `swap_quote` and threaded through\n * `pending_action.cetusRoute`). When present AND not stale (per\n * `isCetusRouteFresh`) AND the input/output coins match, this skips\n * the ~400-500ms `findSwapRoute()` discovery call. Stale routes are\n * silently ignored (caller falls back to fresh discovery).\n *\n * Caller responsibility: pass the SAME `overlayFee` / `providers` /\n * `byAmountIn` that produced the precomputed route. Mismatch will\n * still produce a working swap but may use the wrong overlay-fee\n * config (the route data already encodes the chosen DEX path).\n */\n precomputedRoute?: SwapRouteResult;\n /**\n * Whether this swap is being built inside a sponsored-tx flow (Enoki)\n * vs self-funded (CLI / direct sign). Load-bearing for SUI-source\n * swaps in wallet mode: under sponsored flows, `tx.gas` belongs to\n * the sponsor and CANNOT be referenced as a transaction argument\n * (Sui protocol rejects with `Cannot use GasCoin as a transaction\n * argument`). When `true`, SUI source routes through `selectSuiCoin`\n * with `useGasCoin: false` so the resolver sources from the user's\n * SUI coin objects + address balance instead. Defaults to `false`\n * (back-compat — pre-2.14.1 behavior). Audric/web-v2's compose path\n * threads this through via `composeTx({ sponsoredContext: true })`.\n */\n sponsoredContext?: boolean;\n /**\n * Per-PTB merge cache for sponsored coin-object sourcing (any coin\n * type — SUI in the dedicated branch, USDC/USDsui/etc. in the wallet\n * branch). Provided by `composeTx`'s orchestration loop so multiple\n * legs sourcing the same coin in one bundle share a single merged\n * primary coin instead of each emitting its own `mergeCoins` (the\n * second of which references already-consumed coins → Enoki dry-run\n * `ArgumentWithoutValue`). Single swaps don't need it; omit. See\n * `SponsoredCoinMergeCache` JSDoc.\n */\n coinMergeCache?: SponsoredCoinMergeCache;\n },\n): Promise<{\n coin: TransactionObjectArgument;\n effectiveAmountIn: number;\n expectedAmountOut: number;\n route: SwapRouteResult;\n /** True when `precomputedRoute` was used (no `findSwapRoute()` call). */\n usedPrecomputedRoute: boolean;\n}> {\n const { T2000Error } = await import('../errors.js');\n\n const fromType = resolveTokenType(input.from);\n const toType = resolveTokenType(input.to);\n if (!fromType) throw new T2000Error('ASSET_NOT_SUPPORTED', `Unknown token: ${input.from}. Provide the symbol (USDC, SUI, ...) or full coin type.`);\n if (!toType) throw new T2000Error('ASSET_NOT_SUPPORTED', `Unknown token: ${input.to}. Provide the symbol (USDC, SUI, ...) or full coin type.`);\n if (fromType === toType) throw new T2000Error('SWAP_FAILED', 'Cannot swap a token to itself');\n if (!Number.isFinite(input.amount) || input.amount <= 0) {\n throw new T2000Error('INVALID_AMOUNT', 'Amount must be greater than zero');\n }\n\n const fromDecimals = getDecimalsForCoinType(fromType);\n const toDecimals = getDecimalsForCoinType(toType);\n const requestedRaw = BigInt(Math.floor(input.amount * 10 ** fromDecimals));\n\n const slippage = Math.max(0.001, Math.min(input.slippage ?? 0.01, 0.05));\n const byAmountIn = input.byAmountIn ?? true;\n\n let inputCoin: TransactionObjectArgument;\n let effectiveRaw: bigint;\n\n if (input.inputCoin) {\n inputCoin = input.inputCoin;\n effectiveRaw = requestedRaw;\n } else if (fromType === '0x2::sui::SUI') {\n // SUI source needs special handling: under sponsored flows (Enoki),\n // referencing `tx.gas` as a transaction argument is forbidden (sponsor\n // owns the gas coin). `selectSuiCoin` does the right thing for both\n // sponsored (uses `coinWithBalance({ useGasCoin: false })`) and\n // self-funded (splits from `tx.gas` directly). The 2.14.0 release\n // shipped without this branch and broke audric/web-v2 SUI→USDC swaps\n // (\"Cannot use GasCoin as a transaction argument\" from Enoki); fixed\n // in 2.14.1 (S.260).\n const { selectSuiCoin } = await import('../wallet/coinSelection.js');\n const result = await selectSuiCoin(\n tx,\n client,\n address,\n requestedRaw,\n input.sponsoredContext ?? false,\n input.coinMergeCache,\n );\n inputCoin = result.coin;\n effectiveRaw = result.effectiveAmount;\n } else {\n // Non-SUI wallet-mode source — delegate to the canonical prelude.\n // NON-sponsored: pre-flights against `getBalance().totalBalance` and\n // returns a `coinWithBalance({ type, balance })` arg, whose `@mysten/sui`\n // resolver batches all intents for a coin type into a single build-time\n // merge — so same-asset multi-leg bundles dedup automatically.\n //\n // SPONSORED: routes through `selectCoinObjectsOnly` instead (coinWithBalance's\n // address-balance `FundsWithdrawal` reservation is what Enoki can't\n // deserialize, issue #93). That manual path has NO build-time batching, so\n // two legs sourcing the same coin would each emit their own `mergeCoins`\n // over the SAME objects → second merge references consumed coins → Enoki\n // dry-run `ArgumentWithoutValue`. The `coinMergeCache` supplies the dedup:\n // first leg merges once + caches the primary, later legs split from it.\n const { selectAndSplitCoin } = await import('../wallet/coinSelection.js');\n const result = await selectAndSplitCoin(tx, client, address, fromType, requestedRaw, {\n sponsoredContext: input.sponsoredContext ?? false,\n mergeCache: input.coinMergeCache,\n });\n inputCoin = result.coin;\n effectiveRaw = result.effectiveAmount;\n }\n\n // [SPEC 20.2 D-3 (b)] Use the precomputed route when available + valid.\n // Validity = same input/output coin types AND the requested raw amount\n // matches what the route was discovered for (mismatch indicates the user\n // edited the amount post-quote, in which case we must re-discover at the\n // new amount because price impact is amount-dependent). The caller\n // (`audric prepare-route`) owns the staleness check (`isCetusRouteFresh`)\n // and only forwards `precomputedRoute` when fresh.\n //\n // [Bug A defense-in-depth / 2026-05-10] Even with the engine fix that\n // makes `swap_quote` discover sponsor-safe routes, this layer also\n // validates the precomputed route against the active providers\n // allow-list. If the route walks any excluded provider (e.g. a stale\n // `pending_action.cetusRoute` from before the engine fix shipped, or a\n // provider list that drifted between quote and execute), fall back to\n // fresh discovery. Better to eat 400ms than to let a Pyth-dependent\n // route reach Enoki and revert with HTTP 400.\n let route: SwapRouteResult | null;\n let usedPrecomputedRoute = false;\n if (\n input.precomputedRoute &&\n input.precomputedRoute.amountIn === effectiveRaw.toString() &&\n input.precomputedRoute.byAmountIn === byAmountIn &&\n isPrecomputedRouteCompatibleWithProviders(input.precomputedRoute, input.providers)\n ) {\n route = input.precomputedRoute;\n usedPrecomputedRoute = true;\n } else {\n route = await findSwapRoute({\n walletAddress: address,\n from: fromType,\n to: toType,\n amount: effectiveRaw,\n byAmountIn,\n overlayFee: input.overlayFee,\n providers: input.providers,\n });\n }\n\n if (!route) {\n throw new T2000Error('SWAP_NO_ROUTE', `No swap route found for ${input.from} → ${input.to}`);\n }\n if (route.insufficientLiquidity) {\n throw new T2000Error('SWAP_NO_ROUTE', `Insufficient liquidity for ${input.from} → ${input.to}`);\n }\n\n const outputCoin = await buildSwapTx({\n walletAddress: address,\n route,\n tx,\n inputCoin,\n slippage,\n overlayFee: input.overlayFee,\n });\n\n return {\n coin: outputCoin,\n effectiveAmountIn: Number(effectiveRaw) / 10 ** fromDecimals,\n expectedAmountOut: Number(route.amountOut) / 10 ** toDecimals,\n route,\n usedPrecomputedRoute,\n };\n}\n\n// Re-export from the canonical token registry for backward-compat.\nexport { TOKEN_MAP, resolveTokenType } from '../token-registry.js';\n","/**\n * Standalone swap quote — no T2000 agent instance required.\n * Only needs a wallet address for Cetus Aggregator routing.\n */\nimport { T2000Error } from './errors.js';\nimport { getDecimalsForCoinType } from './token-registry.js';\nimport type { SwapQuoteResult } from './types.js';\n\nexport async function getSwapQuote(params: {\n walletAddress: string;\n from: string;\n to: string;\n amount: number;\n byAmountIn?: boolean;\n /**\n * [Bug A fix / 2026-05-10] Optional Cetus provider allow-list, forwarded to\n * `findSwapRoute`. Sponsored callers (Enoki) MUST pass\n * `getSponsoredSwapProviders()` to remove Pyth-dependent providers\n * (HAEDALPMM, METASTABLE, OBRIC, STEAMM_OMM/_V2, SEVENK, HAEDALHMMV2).\n * Those providers cause the Cetus aggregator's internal `routerSwap` to\n * insert a `tx.splitCoins(tx.gas, ...)` call for the Pyth update fee,\n * which Enoki rejects with HTTP 400 \"Cannot use GasCoin as a transaction\n * argument\" (3-step bundle smoke 2026-05-10).\n *\n * Pre-fix: `getSwapQuote` discovered routes against the FULL provider set,\n * stashed Pyth-dependent routes onto `pending_action.cetusRoute` (SPEC\n * 20.2 fast-path), and the audric `prepare` route's `swap_execute`\n * appender used the precomputed route AS-IS — bypassing the providers\n * filter that `composeTx` correctly applied. Result: every swap whose\n * best route happened to include a Pyth-dependent provider failed at\n * Enoki sponsorship.\n *\n * Non-sponsored callers (e.g. CLI direct swap) leave this undefined to\n * keep access to the full provider set including Pyth-dependent pools.\n */\n providers?: string[];\n /**\n * [2.11] On-chain-resolved decimals for `from` / `to`, supplied by callers\n * that hold a client (e.g. `T2000.swapQuote`). When omitted (standalone /\n * sponsored callers), falls back to the registry — correct for registry\n * tokens, a 9-decimal guess for an unknown coin type.\n */\n fromDecimals?: number;\n toDecimals?: number;\n}): Promise<SwapQuoteResult> {\n const { findSwapRoute, resolveTokenType } = await import('./protocols/cetus-swap.js');\n\n const fromType = resolveTokenType(params.from);\n const toType = resolveTokenType(params.to);\n // [S.123 v1.24.7] Use T2000Error('ASSET_NOT_SUPPORTED') consistently with the\n // other 4 throw sites in t2000.ts / cetus-swap.ts. Allows tools to branch\n // on `err.code === 'ASSET_NOT_SUPPORTED'` and return a structured recovery\n // hint to the LLM instead of re-throwing a generic error string.\n if (!fromType) {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n `Unknown token: ${params.from}. Provide the symbol (USDC, SUI, ...) or full coin type.`,\n );\n }\n if (!toType) {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n `Unknown token: ${params.to}. Provide the symbol (USDC, SUI, ...) or full coin type.`,\n );\n }\n\n const byAmountIn = params.byAmountIn ?? true;\n\n const fromDecimals = params.fromDecimals ?? getDecimalsForCoinType(fromType);\n const rawAmount = BigInt(Math.floor(params.amount * 10 ** fromDecimals));\n\n const route = await findSwapRoute({\n walletAddress: params.walletAddress,\n from: fromType,\n to: toType,\n amount: rawAmount,\n byAmountIn,\n providers: params.providers,\n });\n\n if (!route) throw new T2000Error('SWAP_FAILED', `No swap route found for ${params.from} -> ${params.to}.`);\n if (route.insufficientLiquidity) {\n throw new T2000Error('SWAP_FAILED', `Insufficient liquidity for ${params.from} -> ${params.to}.`);\n }\n\n const toDecimals = params.toDecimals ?? getDecimalsForCoinType(toType);\n const fromAmount = Number(route.amountIn) / 10 ** fromDecimals;\n const toAmount = Number(route.amountOut) / 10 ** toDecimals;\n\n const routeDesc = route.routerData.paths\n ?.map((p: { provider?: string }) => p.provider)\n .filter(Boolean)\n .slice(0, 3)\n .join(' + ') ?? 'Cetus Aggregator';\n\n // [SPEC 20.2 / D-1 (a)] Serialize the Cetus route at quote time so the\n // engine can attach it to `pending_action.cetusRoute`. The serialized\n // form survives the SSE → client → POST → prepare-route hop without losing\n // BN/Map fidelity (raw RouterDataV3 doesn't JSON-stringify cleanly).\n const { serializeCetusRoute } = await import('./protocols/cetus-swap.js');\n const serializedRoute = serializeCetusRoute(route, { fromCoinType: fromType, toCoinType: toType });\n\n return {\n fromToken: params.from,\n toToken: params.to,\n fromAmount,\n toAmount,\n priceImpact: route.priceImpact,\n route: routeDesc,\n serializedRoute,\n };\n}\n","import { T2000Error } from './errors.js';\n\nexport const MIST_PER_SUI = 1_000_000_000n;\nexport const SUI_DECIMALS = 9;\nexport const USDC_DECIMALS = 6;\n\nexport const PRECISION = 1_000_000_000_000_000_000n;\n\nexport const MIN_DEPOSIT = 1_000_000n; // 1 USDC (6 decimals)\n\nexport const CLOCK_ID = '0x6';\n\nexport const SUPPORTED_ASSETS = {\n USDC: {\n type: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n symbol: 'USDC',\n displayName: 'USDC',\n },\n USDT: {\n type: '0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT',\n decimals: 6,\n symbol: 'USDT',\n displayName: 'suiUSDT',\n },\n USDe: {\n type: '0x41d587e5336f1c86cad50d38a7136db99333bb9bda91cea4ba69115defeb1402::sui_usde::SUI_USDE',\n decimals: 6,\n symbol: 'USDe',\n displayName: 'suiUSDe',\n },\n USDsui: {\n type: '0x44f838219cf67b058f3b37907b655f226153c18e33dfcd0da559a844fea9b1c1::usdsui::USDSUI',\n decimals: 6,\n symbol: 'USDsui',\n displayName: 'USDsui',\n },\n SUI: {\n type: '0x2::sui::SUI',\n decimals: 9,\n symbol: 'SUI',\n displayName: 'SUI',\n },\n WAL: {\n type: '0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL',\n decimals: 9,\n symbol: 'WAL',\n displayName: 'WAL',\n },\n ETH: {\n type: '0xd0e89b2af5e4910726fbcd8b8dd37bb79b29e5f83f7491bca830e94f7f226d29::eth::ETH',\n decimals: 8,\n symbol: 'ETH',\n displayName: 'suiETH',\n },\n NAVX: {\n type: '0xa99b8952d4f7d947ea77fe0ecdcc9e5fc0bcab2841d6e2a5aa00c3044e5544b5::navx::NAVX',\n decimals: 9,\n symbol: 'NAVX',\n displayName: 'NAVX',\n },\n GOLD: {\n type: '0x9d297676e7a4b771ab023291377b2adfaa4938fb9080b8d12430e4b108b836a9::xaum::XAUM',\n decimals: 6,\n symbol: 'GOLD',\n displayName: 'XAUM',\n },\n} as const;\n\nexport type SupportedAsset = keyof typeof SUPPORTED_ASSETS;\n\n// [SPEC_AGENTIC_STACK P1 / SDK F3 — 2026-05-25]\n// `StableAsset` = \"what we treat as worth $1 for wallet pricing and balance roll-up\".\n// Pre-Phase 1: USDC only — left USDsui wallet holdings invisible to balance.ts.\n// Phase 1: widened to USDC + USDsui (both are NAVI-native stables with $1 peg).\n// USDT / USDe stay OUT of this set deliberately — they are stables, but the\n// codebase has never priced them at $1, and adding them here would require\n// auditing balance.ts callers downstream. Keep the carve minimal.\nexport type StableAsset = 'USDC' | 'USDsui';\nexport const STABLE_ASSETS: readonly StableAsset[] = ['USDC', 'USDsui'] as const;\n\n// ---------------------------------------------------------------------------\n// Operation → allowed asset rules (single source of truth)\n// ---------------------------------------------------------------------------\n\n// [v4.0 Phase A Day 2 — 2026-05-26] `send` is constrained to\n// `['USDC', 'USDsui', 'SUI']`. Rationale (SPEC_AGENT_WALLET_GREENFIELD §A):\n// - USDC + USDsui are gasless via `0x2::balance::send_funds` (Sui mainnet\n// protocol allowlist) — the two foundation stables.\n// - SUI is the only non-stable kept on the allowlist so users with no\n// stablecoin balance can still pay gas-native SUI transfers.\n// - USDT, USDe, WAL, ETH, NAVX, GOLD are NOT sendable — users must swap to\n// USDC/USDsui first (one-step) or hold SUI and use a manual Move call.\n// `swap` is unrestricted (Cetus routes any pair). The DeFi operations\n// (save/borrow/withdraw/repay) were removed with NAVI.\nexport const OPERATION_ASSETS = {\n send: ['USDC', 'USDsui', 'SUI'],\n swap: '*',\n} as const;\n\nexport type Operation = keyof typeof OPERATION_ASSETS;\n\nexport function isAllowedAsset(op: Operation, asset: string): boolean {\n const allowed = OPERATION_ASSETS[op];\n if (allowed === '*') return true;\n // [v0.51.0] Mixed-case canonical keys (USDsui, suiUSDT) need case-insensitive\n // membership. Pre-v0.51 we only had USDC ↔ USDC (uppercase identity), so\n // a one-sided uppercase compare looked correct. Now that USDsui is in the\n // set, normalize both sides.\n const target = asset.toLowerCase();\n return (allowed as readonly string[]).some((a) => a.toLowerCase() === target);\n}\n\n/**\n * Throws if the asset is not permitted for the given operation.\n *\n * [v4.0 Phase A Day 2] Pre-v4 this allowed `undefined` as a silent default\n * to USDC. Removed because every write path now requires explicit asset\n * (see `T2000.send` + `buildSendTx` + `composeTx.send_transfer`). The\n * `undefined → no-op` branch is kept defensively; the `send_transfer` flow\n * validates non-undefined.\n */\nexport function assertAllowedAsset(op: Operation, asset: string | undefined): void {\n if (!asset) return;\n if (!isAllowedAsset(op, asset)) {\n const allowed = OPERATION_ASSETS[op];\n const list = Array.isArray(allowed) ? allowed.join(', ') : 'any';\n const swapHint =\n op === 'send' ? ' Swap to USDC or USDsui first, or send SUI.' : '';\n throw new T2000Error(\n 'INVALID_ASSET',\n `${op} only supports ${list}. Cannot use ${asset}.${swapHint}`,\n );\n }\n}\n\n/**\n * [v4.0 Phase A Day 2] Narrow type alias for assets sendable through the\n * Agent Wallet. Matches `OPERATION_ASSETS.send` exactly. Exported so the\n * CLI / SDK / composeTx can share one type without re-declaring it.\n */\nexport type SendableAsset = 'USDC' | 'USDsui' | 'SUI';\nexport const SENDABLE_ASSETS: readonly SendableAsset[] = ['USDC', 'USDsui', 'SUI'] as const;\n\n/**\n * [v4.0 Phase A Day 2] Coin types for the two gasless-allowlisted stables.\n * Used by `wallet/send.ts` + `composeTx.send_transfer` to construct the\n * `0x2::balance::send_funds` Move call's `typeArguments`. SUI is excluded\n * because SUI transfers are NOT gasless (gas-native, uses `tx.gas` split +\n * `transferObjects` per the existing path).\n */\nexport const GASLESS_STABLE_TYPES: Record<'USDC' | 'USDsui', string> = {\n USDC: SUPPORTED_ASSETS.USDC.type,\n USDsui: SUPPORTED_ASSETS.USDsui.type,\n};\n\n// Swap overlay fees route here. Audric's prepare/route.ts passes\n// `overlayFee.receiver = T2000_OVERLAY_FEE_WALLET` to the Cetus aggregator. The\n// CLI/SDK never charge fees — this constant is exported for consumer apps only.\n//\n// Address corresponds to the treasury admin wallet. Override via env for local dev /\n// testnet only — production must use the canonical mainnet address below.\nexport const T2000_OVERLAY_FEE_WALLET = process.env.T2000_OVERLAY_FEE_WALLET\n ?? '0x5366efbf2b4fe5767fe2e78eb197aa5f5d138d88ac3333fbf3f80a1927da473a';\n\nexport const DEFAULT_NETWORK = 'mainnet' as const;\n// gRPC fullnode endpoint. Post-flip this is the canonical transport for the\n// whole SDK: `getSuiClient()` (reads + execution) AND `getSuiGrpcClient()`\n// (gasless stablecoin build detection) both target it. Override the read/exec\n// client with T2000_RPC_URL and the build client with T2000_GRPC_URL.\nexport const DEFAULT_RPC_URL = 'https://fullnode.mainnet.sui.io:443';\nexport const DEFAULT_GRPC_URL = 'https://fullnode.mainnet.sui.io:443';\n// [gRPC migration] GraphQL endpoint for the query surface that has NO gRPC\n// `core` equivalent — `transactionBlocks` (history). Used by\n// `getSuiGraphQLClient()`. The canonical mainnet host is `graphql.mainnet.sui.io`\n// (parallel to the gRPC fullnode); the older `sui-mainnet.mystenlabs.com/graphql`\n// host was dropped 2026-06-15 after it began resetting TLS connections (live\n// smoke). Public endpoint is rate-limited — production hosts override with\n// T2000_GRAPHQL_URL to a dedicated provider.\nexport const DEFAULT_GRAPHQL_URL = 'https://graphql.mainnet.sui.io/graphql';\nexport const DEFAULT_KEY_PATH = '~/.t2000/wallet.key';\nexport const DEFAULT_CONFIG_PATH = '~/.t2000/config.json';\n\n// [v4.0 Phase A Day 2] Minimum stablecoin amount for protocol-level gasless\n// transfers via `0x2::balance::send_funds`. The Sui mainnet allowlist enforces\n// this floor at the protocol level to prevent dust spam; we surface a clear\n// error before signing rather than letting the tx revert on-chain.\nexport const GASLESS_MIN_STABLE_AMOUNT = 0.01;\n\n// Cetus USDC/SUI pool — read-only for SUI price oracle (no SDK dependency)\nexport const CETUS_USDC_SUI_POOL = '0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab';\n\nexport const GAS_RESERVE_MIN = 0.05; // minimum SUI to keep for gas\n","import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';\nimport { SuiGrpcClient } from '@mysten/sui/grpc';\nimport { SuiGraphQLClient } from '@mysten/sui/graphql';\nimport { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport { DEFAULT_GRAPHQL_URL, DEFAULT_GRPC_URL, DEFAULT_RPC_URL } from '../constants.js';\nimport { T2000Error } from '../errors.js';\n\n/**\n * [gRPC migration / S.438] Transport-agnostic client type for the migration.\n *\n * Both `SuiJsonRpcClient` and `SuiGrpcClient` extend `BaseClient` and expose\n * an identical `.core.*` API. During the migration, call sites are rewritten\n * from legacy methods (`getBalance`, `getObject`, `executeTransactionBlock`)\n * to the unified `client.core.*` API and typed against this union — so the\n * rewrite is behavior-preserving while still on JSON-RPC, and the final\n * transport flip (gRPC) is a one-line change in `getSuiClient()`.\n *\n * The query surface that has no gRPC `core` equivalent (`queryTransactionBlocks`\n * / `queryEvents`, Stage 0 finding A) uses `getSuiGraphQLClient()` instead.\n */\nexport type SuiCoreClient = SuiJsonRpcClient | SuiGrpcClient;\n\n/**\n * Resolve the effective JSON-RPC URL: explicit arg > env var > default.\n * `T2000_RPC_URL` is an OPTIONAL override per the Greenfield SPEC's env\n * contract — no required vars, so we read inline (allowed by\n * `env-validation-gate.mdc` carve-out for packages with zero required\n * env vars).\n */\nfunction resolveRpcUrl(rpcUrl?: string): string {\n if (rpcUrl) return rpcUrl;\n const envUrl = process.env.T2000_RPC_URL?.trim();\n if (envUrl) return envUrl;\n return DEFAULT_RPC_URL;\n}\n\n/**\n * Same shape as `resolveRpcUrl` for the gRPC endpoint.\n */\nfunction resolveGrpcUrl(grpcUrl?: string): string {\n if (grpcUrl) return grpcUrl;\n const envUrl = process.env.T2000_GRPC_URL?.trim();\n if (envUrl) return envUrl;\n return DEFAULT_GRPC_URL;\n}\n\n/**\n * Same shape as `resolveRpcUrl` for the GraphQL endpoint.\n */\nfunction resolveGraphqlUrl(graphqlUrl?: string): string {\n if (graphqlUrl) return graphqlUrl;\n const envUrl = process.env.T2000_GRAPHQL_URL?.trim();\n if (envUrl) return envUrl;\n return DEFAULT_GRAPHQL_URL;\n}\n\n/**\n * Canonical agent client cache, keyed by URL. The earlier impl cached\n * unconditionally and ignored URL changes after the first call —\n * brittle for testnet smokes and custom-RPC test setups.\n */\nconst rpcClientCache = new Map<string, SuiGrpcClient>();\n\n/**\n * [gRPC cutover] The canonical agent client is now gRPC. Mysten deactivates\n * the JSON-RPC fullnode interface on 2026-07-31, so reads (`.core.*`) and\n * execution route over gRPC — transaction *builds* already do\n * (`getSuiGrpcClient`). The whole SDK was first refactored onto the unified\n * `.core` API (behavior-preserving on JSON-RPC), then flipped here. The\n * `rpcUrl` arg / `T2000_RPC_URL` override now resolve a gRPC `baseUrl`\n * (`DEFAULT_RPC_URL` is the same host as `DEFAULT_GRPC_URL`). The historical\n * query surface stays on `getSuiGraphQLClient()`.\n */\nexport function getSuiClient(rpcUrl?: string): SuiGrpcClient {\n const url = resolveRpcUrl(rpcUrl);\n const cached = rpcClientCache.get(url);\n if (cached) return cached;\n const client = new SuiGrpcClient({ baseUrl: url, network: 'mainnet' });\n rpcClientCache.set(url, client);\n return client;\n}\n\n/**\n * gRPC client cache, keyed by URL. Same rationale as the JSON-RPC cache:\n * different URLs must produce different clients.\n */\nconst grpcClientCache = new Map<string, SuiGrpcClient>();\n\n/**\n * Cached `SuiGrpcClient` for gasless stablecoin transfer builds.\n *\n * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]\n *\n * Why this exists: Sui mainnet's protocol-level gasless stablecoin transfers\n * (`0x2::balance::send_funds` on the USDC + USDsui allowlist) are detected\n * ONLY when the transaction is built through a `SuiGrpcClient`. The gRPC\n * client's build resolver inspects the PTB at `tx.build()` time and, if it\n * matches the gasless pattern, sets `gasPrice=0` + `gasBudget=0` automatically.\n * Building the SAME PTB through `SuiJsonRpcClient` produces the same bytes\n * but with non-zero gas — the tx still works, but the user pays SUI gas.\n *\n * Execution stays on JSON-RPC (`SuiJsonRpcClient.executeTransactionBlock`)\n * because (a) the rest of the SDK expects JSON-RPC and (b) Sui's docs\n * explicitly support a \"build via gRPC, execute via JSON-RPC\" hybrid:\n * https://docs.sui.io/develop/transaction-payment/gasless-stablecoin-transfers\n *\n * Override the endpoint with the `T2000_GRPC_URL` env var or the\n * `grpcUrl` arg. Cache is keyed by URL so multiple endpoints can\n * co-exist (e.g., the rare testnet smoke + production usage from the\n * same process).\n */\nexport function getSuiGrpcClient(grpcUrl?: string): SuiGrpcClient {\n const baseUrl = resolveGrpcUrl(grpcUrl);\n const cached = grpcClientCache.get(baseUrl);\n if (cached) return cached;\n const client = new SuiGrpcClient({ baseUrl, network: 'mainnet' });\n grpcClientCache.set(baseUrl, client);\n return client;\n}\n\n/**\n * GraphQL client cache, keyed by URL. Same rationale as the other caches.\n */\nconst graphqlClientCache = new Map<string, SuiGraphQLClient>();\n\n/**\n * Cached `SuiGraphQLClient` for the query surface that has NO gRPC `core`\n * equivalent: `queryTransactionBlocks` + `queryEvents` (Stage 0 finding A —\n * `SPEC_FULL_GRPC_MIGRATION.md`). Mysten's gRPC successor doesn't cover the\n * historical query/event API; GraphQL is its documented home. Consumers:\n * `wallet/history.ts` + the swap-event read in `protocols/cetus-swap.ts`.\n *\n * Override the endpoint with `T2000_GRAPHQL_URL` or the `graphqlUrl` arg.\n */\nexport function getSuiGraphQLClient(graphqlUrl?: string): SuiGraphQLClient {\n const url = resolveGraphqlUrl(graphqlUrl);\n const cached = graphqlClientCache.get(url);\n if (cached) return cached;\n const client = new SuiGraphQLClient({ url, network: 'mainnet' });\n graphqlClientCache.set(url, client);\n return client;\n}\n\nexport function validateAddress(address: string): string {\n const normalized = normalizeSuiAddress(address);\n if (!isValidSuiAddress(normalized)) {\n throw new T2000Error('INVALID_ADDRESS', `Invalid Sui address: ${address}`);\n }\n return normalized;\n}\n\nexport function truncateAddress(address: string): string {\n if (address.length <= 10) return address;\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n\n/**\n * Normalize a Sui coin type to its canonical long-form 64-hex address.\n * `0x2::sui::SUI` → `0x0000…0002::sui::SUI`. Idempotent on already-long\n * forms. Returns the input unchanged if it doesn't look like a coin type\n * (`<address>::<module>::<name>`) so callers can pass arbitrary strings\n * without crashing.\n *\n * Why this exists: BlockVision's `/v2/sui/coin/price/list` endpoint\n * silently returns an empty `prices` map for short-form coin types\n * (notably `0x2::sui::SUI` — the native gas coin). Internal callers must\n * pass the long form, but external callers (LLM tool args, cached\n * coin-type strings, audit logs) commonly use the short form. Normalize\n * before the network call, denormalize back to the caller's input shape\n * after, and short/long become interchangeable.\n */\nexport function normalizeCoinType(coinType: string): string {\n const parts = coinType.split('::');\n if (parts.length !== 3) return coinType;\n const [addr, mod, name] = parts;\n if (!addr.startsWith('0x')) return coinType;\n return `${normalizeSuiAddress(addr)}::${mod}::${name}`;\n}\n","// v4.0 wallet auth model: plain Bech32 secret in a versioned JSON file,\n// 0o600 perms. Matches the Sui CLI convention. No AES, no PIN, no scrypt.\n// Anything that isn't `{ version: 2, secret: \"suiprivkey1...\" }` throws\n// `WALLET_CORRUPT` — the user moves/deletes the file and runs `t2 init`.\n\nimport { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { decodeSuiPrivateKey } from '@mysten/sui/cryptography';\nimport { readFile, writeFile, mkdir, access } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { T2000Error } from '../errors.js';\nimport { DEFAULT_KEY_PATH } from '../constants.js';\n\ninterface PlainKey {\n version: 2;\n secret: string;\n}\n\nfunction expandPath(p: string): string {\n if (p.startsWith('~')) return resolve(homedir(), p.slice(2));\n return resolve(p);\n}\n\nexport function generateKeypair(): Ed25519Keypair {\n return Ed25519Keypair.generate();\n}\n\nexport function keypairFromPrivateKey(privateKey: string): Ed25519Keypair {\n if (privateKey.startsWith('suiprivkey')) {\n const decoded = decodeSuiPrivateKey(privateKey);\n return Ed25519Keypair.fromSecretKey(decoded.secretKey);\n }\n const bytes = Buffer.from(privateKey.replace(/^0x/, ''), 'hex');\n return Ed25519Keypair.fromSecretKey(bytes);\n}\n\n/**\n * Save a keypair as a v2 plain Bech32 JSON file with `0o600` perms.\n *\n * `_passphrase` is accepted but IGNORED — kept in the signature for\n * back-compat with v3.x callers. Will be removed when all callers\n * are off PIN (Phase A Day 5+).\n */\nexport async function saveKey(\n keypair: Ed25519Keypair,\n _passphrase: string | undefined,\n keyPath?: string,\n): Promise<string> {\n const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);\n\n try {\n await access(filePath);\n throw new T2000Error('WALLET_EXISTS', `Wallet already exists at ${filePath}`);\n } catch (error) {\n if (error instanceof T2000Error) throw error;\n }\n\n await mkdir(dirname(filePath), { recursive: true });\n\n const payload: PlainKey = {\n version: 2,\n secret: keypair.getSecretKey(),\n };\n\n await writeFile(filePath, JSON.stringify(payload, null, 2), { mode: 0o600 });\n\n return filePath;\n}\n\n/**\n * Save a Bech32 secret directly as a v2 plain wallet file. Used by any\n * path where the secret is supplied externally rather than freshly\n * generated. Kept exported because external tooling may still want it\n * even though the CLI no longer ships an `--import` flag.\n */\nexport async function saveBech32(secret: string, keyPath?: string): Promise<string> {\n if (!secret.startsWith('suiprivkey')) {\n throw new T2000Error(\n 'INVALID_KEY',\n `Secret must be a Bech32 suiprivkey1... string. Got: ${secret.slice(0, 12)}...`,\n );\n }\n decodeSuiPrivateKey(secret);\n\n const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);\n\n try {\n await access(filePath);\n throw new T2000Error('WALLET_EXISTS', `Wallet already exists at ${filePath}`);\n } catch (error) {\n if (error instanceof T2000Error) throw error;\n }\n\n await mkdir(dirname(filePath), { recursive: true });\n\n const payload: PlainKey = { version: 2, secret };\n\n await writeFile(filePath, JSON.stringify(payload, null, 2), { mode: 0o600 });\n\n return filePath;\n}\n\n/**\n * Load a keypair from disk.\n *\n * `_passphrase` is accepted but IGNORED — kept for back-compat. The\n * actual file format determines the load path:\n *\n * - **v2 plain JSON** (`{ version: 2, secret: \"suiprivkey1...\" }`) →\n * decode + return keypair.\n * - **Anything else** → throw `WALLET_CORRUPT`. The user moves or\n * deletes the file and runs `t2 init` to create a fresh wallet.\n */\nexport async function loadKey(\n _passphrase?: string,\n keyPath?: string,\n): Promise<Ed25519Keypair> {\n const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);\n\n let content: string;\n try {\n content = await readFile(filePath, 'utf-8');\n } catch {\n throw new T2000Error('WALLET_NOT_FOUND', `No wallet found at ${filePath}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n throw new T2000Error(\n 'WALLET_CORRUPT',\n `Wallet file at ${filePath} is not a valid v4 wallet. Move or delete the file, then run \\`t2 init\\`.`,\n );\n }\n\n if (!isPlainKey(parsed)) {\n throw new T2000Error(\n 'WALLET_CORRUPT',\n `Wallet file at ${filePath} is not a valid v4 wallet. Expected { version: 2, secret: \"suiprivkey1...\" }. Move or delete the file, then run \\`t2 init\\`.`,\n );\n }\n\n const decoded = decodeSuiPrivateKey(parsed.secret);\n return Ed25519Keypair.fromSecretKey(decoded.secretKey);\n}\n\nexport async function walletExists(keyPath?: string): Promise<boolean> {\n const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function exportPrivateKey(keypair: Ed25519Keypair): string {\n return keypair.getSecretKey();\n}\n\nexport function getAddress(keypair: Ed25519Keypair): string {\n return keypair.getPublicKey().toSuiAddress();\n}\n\nfunction isPlainKey(value: unknown): value is PlainKey {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { version?: unknown }).version === 2 &&\n typeof (value as { secret?: unknown }).secret === 'string'\n );\n}\n","import type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport type { TransactionSigner } from '../signer.js';\n\nexport class KeypairSigner implements TransactionSigner {\n readonly kind = 'keypair' as const;\n\n constructor(private readonly keypair: Ed25519Keypair) {}\n\n getAddress(): string {\n return this.keypair.getPublicKey().toSuiAddress();\n }\n\n async signTransaction(txBytes: Uint8Array): Promise<{ signature: string }> {\n return this.keypair.signTransaction(txBytes);\n }\n\n async signPersonalMessage(messageBytes: Uint8Array): Promise<{ signature: string; bytes: string }> {\n return this.keypair.signPersonalMessage(messageBytes);\n }\n\n /** Access the underlying keypair for APIs that still require it directly. */\n getKeypair(): Ed25519Keypair {\n return this.keypair;\n }\n}\n","import type { SuiClientTypes } from '@mysten/sui/client';\nimport type { Transaction } from '@mysten/sui/transactions';\nimport type { TransactionSigner } from '../signer.js';\nimport type { SuiCoreClient } from '../utils/sui.js';\n\n// ---------------------------------------------------------------------------\n// executeTx — build + sign + submit + wait, the SDK's one tx-execution helper.\n//\n// Browser-safe (no fs / keyManager imports) so it can back\n// both the Node-side `T2000` methods AND the browser-side `payWithMpp`\n// (gasless MPP runs client-side on the zkLogin session key). Moved out of\n// `t2000.ts` so `wallet/pay.ts` can share it without pulling the Node-only\n// `T2000` module graph into the browser bundle.\n//\n// [gRPC migration] Submit + wait go through the unified `client.core.*`\n// API (`executeTransaction` + `waitForTransaction`), which is transport-\n// agnostic across the JSON-RPC and gRPC clients.\n// ---------------------------------------------------------------------------\n\nexport type SuiTransactionEffects = SuiClientTypes.TransactionEffects;\nexport type BuildClient = NonNullable<Parameters<Transaction['build']>[0]>['client'];\n\nexport async function executeTx(\n client: SuiCoreClient,\n signer: TransactionSigner,\n buildTx: () => Promise<Transaction> | Transaction,\n options: { buildClient?: BuildClient } = {},\n): Promise<{ digest: string; gasCostSui: number; effects: SuiTransactionEffects | undefined }> {\n const tx = await buildTx();\n tx.setSender(signer.getAddress());\n // [2026-05-22] Optional buildClient. When set, `tx.build()` uses it to\n // resolve the PTB — relevant for gasless stablecoin transfers where the\n // SuiGrpcClient build path auto-detects allowlisted ops and zeros out\n // gasPrice/gasBudget/gasPayment. See `payWithMpp`.\n const txBytes = await tx.build({ client: options.buildClient ?? client });\n const { signature } = await signer.signTransaction(txBytes);\n const result = await client.core.executeTransaction({\n transaction: txBytes,\n signatures: [signature],\n include: { effects: true },\n });\n const txn = result.$kind === 'Transaction' ? result.Transaction : result.FailedTransaction;\n try {\n await client.core.waitForTransaction({ digest: txn.digest });\n } catch (err) {\n // A successful executeTransaction already returned the certified effects —\n // the wait only provides read-your-write index visibility. On a lagging\n // fullnode it can time out AFTER the tx landed; propagating that turns a\n // SUCCESSFUL on-chain payment into a reported failure, which bait-invites\n // a double-pay retry (S.453 JMPR e2e: two 0.02 USDC charges for one call).\n // Effects in hand = executed + certified → proceed. No effects = nothing\n // proves execution → rethrow.\n if (!txn.effects) throw err;\n }\n const effects = txn.effects ?? undefined;\n const gasUsed = effects?.gasUsed;\n let gasCostSui = 0;\n if (gasUsed) {\n const total = BigInt(gasUsed.computationCost) + BigInt(gasUsed.storageCost) - BigInt(gasUsed.storageRebate);\n gasCostSui = Number(total) / 1e9;\n }\n return { digest: txn.digest, gasCostSui, effects };\n}\n","import type { SuiGrpcClient } from '@mysten/sui/grpc';\nimport { fromBase64 } from '@mysten/sui/utils';\nimport type { X402Requirements } from '@suimpp/mpp/x402';\nimport type { TransactionSigner } from '../signer.js';\nimport type { PayOptions, PayResult } from '../types.js';\nimport { T2000Error } from '../errors.js';\nimport { parseChallengeAmount } from '../mpp-cost.js';\nimport { executeTx } from './executeTx.js';\nimport {\n type PreflightResult,\n PREFLIGHT_OK,\n preflightFail,\n checkPositiveAmount,\n} from '../preflight.js';\n\n/**\n * Synchronous, network-free preflight for `pay` (x402 Service call). Validates\n * the target URL shape and the `maxPrice` ceiling when present — the cheap\n * checks the v3 host runs before dispatching the paid tool / showing the\n * tap-to-confirm card. Returns a `PreflightResult`; never throws. The probe +\n * 402 handshake + balance migration stay in `payWithMpp` (network).\n */\nexport function preflightPay(input: { url: string; maxPrice?: number }): PreflightResult {\n if (typeof input.url !== 'string' || input.url.trim() === '') {\n return preflightFail('FACILITATOR_REJECTION', 'A target URL is required to pay');\n }\n let parsed: URL;\n try {\n parsed = new URL(input.url);\n } catch {\n return preflightFail('FACILITATOR_REJECTION', `Invalid URL: ${input.url}`);\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return preflightFail(\n 'FACILITATOR_REJECTION',\n `URL must be http(s): got ${parsed.protocol}//`,\n );\n }\n // `maxPrice` is optional (no ceiling = pay whatever the 402 asks). Validate\n // only when the caller set one — a malformed ceiling is a fat-finger.\n if (input.maxPrice !== undefined) {\n const priceCheck = checkPositiveAmount(input.maxPrice, 'maxPrice');\n if (!priceCheck.valid) return priceCheck;\n }\n return PREFLIGHT_OK;\n}\n\n// ---------------------------------------------------------------------------\n// payWithMpp — the SDK's single source of truth for the pay loop. Browser-safe\n// (no fs / keyManager / SafeguardEnforcer), so the Audric client can run it\n// in-browser on the zkLogin session key. `T2000.pay()` delegates here.\n//\n// TWO dialects, ONE preference order (both ride the SAME gasless\n// `send_funds<USDC>` rail; the only difference is who submits):\n//\n// 1. x402 `sui-exact` (preferred — SPEC_AGENT_PAYMENTS_X402 1.2; scheme =\n// SUIMPP_X402_SCHEME.md v0.3): the 402 body carries `accepts[]`; the\n// client signs an authorization, the SERVER settles (settle-then-serve,\n// so a failed upstream is never charged). The withdrawal form draws from\n// the SIP-58 address balance, so coin-object funds are migrated in first\n// when needed (S.414 finding).\n//\n// 2. MPP header dialect (fallback — suimpp.dev/spec): the 402 carries only a\n// `WWW-Authenticate: Payment … method=\"sui\"` challenge, no x402 body. The\n// CLIENT broadcasts the gasless USDC transfer and retries with the digest\n// credential. S.452 retired this path assuming all sellers were our\n// gateway (which dual-serves); the first EXTERNAL seller (JMPR, S.453)\n// shipped header-only — the client must speak everything the gateway and\n// suimpp spec serve, so the fallback is back. Trade-off vs x402: the\n// client pays BEFORE the server proves it can deliver, so a broken seller\n// can charge without serving — x402 stays preferred whenever offered.\n// ---------------------------------------------------------------------------\n\nexport async function payWithMpp(args: {\n signer: TransactionSigner;\n client: SuiGrpcClient;\n options: PayOptions;\n}): Promise<PayResult> {\n const { signer, client } = args;\n let options = args.options;\n\n // Layer 2 — cheap synchronous preflight (URL shape + maxPrice sanity) before\n // any network round-trip. Rethrow the precise code+message verbatim.\n const pf = preflightPay({ url: options.url, maxPrice: options.maxPrice });\n if (!pf.valid) throw new T2000Error(pf.code, pf.error);\n\n const method = (options.method ?? 'GET').toUpperCase();\n const canHaveBody = method !== 'GET' && method !== 'HEAD';\n\n // Default `content-type: application/json` when the body IS JSON and the\n // caller didn't say otherwise. Without it, fetch stamps `text/plain` and\n // strict servers (FastAPI et al.) receive the body as a string — a 422\n // before the 402 ever fires (live finding vs JMPR, the first external\n // seller). Every retry below reads from the normalized `options`.\n if (\n canHaveBody &&\n typeof options.body === 'string' &&\n isJsonText(options.body) &&\n !hasContentType(options.headers)\n ) {\n options = {\n ...options,\n headers: { ...(options.headers ?? {}), 'content-type': 'application/json' },\n };\n }\n\n const reqInit: RequestInit = {\n method,\n headers: options.headers,\n body: canHaveBody ? options.body : undefined,\n };\n\n // Probe (no payment). A paid endpoint answers 402; a free/cached one serves.\n const probe = await fetch(options.url, reqInit);\n if (probe.status !== 402) {\n return finalize(probe, { paid: false });\n }\n\n const requirements = await pickSuiExactRequirements(probe, client.network);\n if (requirements) {\n // Job-class (escrow-intent) 402 — SPEC_A2A_ESCROW slice 2. The entry\n // advertises escrow TERMS, not an instant settlement challenge: paying\n // it with a signed transfer would move money with no delivery contract.\n // Fail closed and route the caller to the escrow flow.\n const { isX402EscrowRequirements } = await import('@suimpp/mpp/x402');\n if (isX402EscrowRequirements(requirements)) {\n const escrow = requirements.extra.escrow;\n const price = atomicToHuman(\n BigInt(requirements.maxAmountRequired),\n await assetDecimals(requirements.asset),\n );\n throw new T2000Error(\n 'ESCROW_REQUIRED',\n 'This endpoint sells deliverable work through on-chain escrow, not an instant call. ' +\n `Create a job instead: t2 job create ${price} ${requirements.payTo} --spec <your-brief> ` +\n '— funds lock in a Job object and release on delivery. No payment was made.',\n { payTo: requirements.payTo, priceUsdc: price, escrow },\n );\n }\n const result = await payViaX402({ signer, client, options, reqInit, requirements });\n await reportDirectPayment(result, options.url);\n return result;\n }\n\n // No x402 envelope — fall back to the MPP header dialect when the 402\n // advertises a `sui` method challenge.\n const headerChallenge = await parseMppSuiChallenge(probe);\n if (headerChallenge) {\n // Fail CLOSED before any money moves: the header dialect pays first and\n // proves identity with a personal-message signature the SELLER verifies.\n // zkLogin signatures are ZK constructs external sellers can't check —\n // the payment settles on-chain, then the retry 402s and the buyer ate\n // the charge (live: JMPR × Audric Passport, 2026-07-17). x402 is immune\n // (the tx itself carries the zkLogin sig; the CHAIN verifies it), so\n // zkLogin payers require sellers that offer x402.\n if (signer.kind === 'zklogin') {\n throw new T2000Error(\n 'DIALECT_UNSUPPORTED',\n 'This seller only offers the MPP header dialect, which zkLogin (Passport) wallets ' +\n 'cannot safely pay: the seller cannot verify zkLogin signatures, so the payment ' +\n 'would settle on-chain without the service delivering. No payment was made. ' +\n 'Use an x402-capable service, or pay from a keypair wallet (t2 CLI / MCP).',\n { dialect: 'mpp-header', signerKind: 'zklogin' },\n );\n }\n const result = await payViaMppHeader({ signer, client, options });\n await reportDirectPayment(result, options.url);\n return result;\n }\n\n throw new T2000Error(\n 'FACILITATOR_REJECTION',\n `Endpoint returned 402 without an x402 'exact' / sui:${client.network} requirement in the body ` +\n `or an MPP 'sui' challenge in WWW-Authenticate. Nothing this SDK can pay.`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// Direct-seller activity reporting (S.743). Gateway-proxied payments are\n// logged server-side by the gateway itself; DIRECT payments (catalog\n// federation — seller's own origin) never touch it, leaving the activity\n// feed blind. After a paid call to a non-gateway origin, tell the gateway\n// \"look at this digest for this url\" — it verifies on-chain (USDC inflow to\n// the cataloged seller's pinned payTo) before recording, so the report\n// carries no trusted data. Best-effort by construction: timeout-capped and\n// error-swallowed, a lost report never fails or delays the payment. Awaited\n// (not fire-and-forget) so short-lived CLI processes don't drop it on exit.\n// ---------------------------------------------------------------------------\n\nconst MPP_REPORT_URL = 'https://mpp.t2000.ai/api/mpp/report';\nconst REPORT_TIMEOUT_MS = 2_000;\n\nasync function reportDirectPayment(result: PayResult, url: string): Promise<void> {\n if (!result.paid || !result.receipt?.reference) return;\n try {\n if (new URL(url).origin === new URL(MPP_REPORT_URL).origin) return;\n await fetch(MPP_REPORT_URL, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ digest: result.receipt.reference, url }),\n signal: AbortSignal.timeout(REPORT_TIMEOUT_MS),\n });\n } catch {\n // Best-effort: the payment already succeeded; the feed row is analytics.\n }\n}\n\n/**\n * Parse the MPP header dialect from a 402 response: the\n * `WWW-Authenticate: Payment …` challenge(s), looking for `method=\"sui\"`.\n * Returns the decoded `{ amount, currency, recipient }` request (amount is a\n * decimal string, e.g. \"0.02\") or `undefined` when the response carries no\n * sui challenge. Exported for the CLI's `t2 pay --estimate`.\n */\nexport async function parseMppSuiChallenge(\n response: Response,\n): Promise<{ amount: string; currency: string; recipient: string; description?: string } | undefined> {\n try {\n const { Challenge } = await import('mppx');\n const challenges = Challenge.fromResponseList(response);\n const suiChallenge = challenges.find((c) => c.method === 'sui' && c.intent === 'charge');\n if (!suiChallenge) return undefined;\n const req = suiChallenge.request as Record<string, unknown>;\n if (typeof req?.amount !== 'string' || typeof req?.recipient !== 'string') return undefined;\n return {\n amount: req.amount,\n currency: typeof req.currency === 'string' ? req.currency : '',\n recipient: req.recipient,\n description: suiChallenge.description,\n };\n } catch {\n return undefined;\n }\n}\n\n// ---------------------------------------------------------------------------\n// x402 `sui-exact` — sign-then-settle\n// ---------------------------------------------------------------------------\n\nasync function pickSuiExactRequirements(\n response: Response,\n network: string,\n): Promise<X402Requirements | undefined> {\n try {\n const body = (await response.clone().json()) as { accepts?: X402Requirements[] };\n const want = `sui:${network === 'testnet' ? 'testnet' : 'mainnet'}`;\n return body.accepts?.find((a) => a.scheme === 'exact' && a.network === want);\n } catch {\n return undefined;\n }\n}\n\nasync function payViaX402(args: {\n signer: TransactionSigner;\n client: SuiGrpcClient;\n options: PayOptions;\n reqInit: RequestInit;\n requirements: X402Requirements;\n}): Promise<PayResult> {\n const { signer, client, options, reqInit, requirements } = args;\n const { buildX402SignedPayment, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER } = await import(\n '@suimpp/mpp/x402'\n );\n\n const amountRaw = BigInt(requirements.maxAmountRequired);\n assertWithinMaxPrice(atomicToHuman(amountRaw, await assetDecimals(requirements.asset)), options.maxPrice);\n\n // The x402 withdrawal form spends ONLY the SIP-58 address balance. A wallet\n // funded by ordinary coin transfers (or swap output) holds Coin<USDC>\n // objects → migrate enough in first (S.414 finding; SUIMPP_X402_SCHEME §4).\n const migrationGasSui = await ensureAddressBalanceCovers({\n signer,\n client,\n asset: requirements.asset,\n amountRaw,\n });\n\n // Build + sign — NEVER submitted client-side; the gateway settles. The\n // builder only reads toSuiAddress() + signTransaction(), both of which every\n // TransactionSigner (keypair AND zkLogin) provides.\n const signerAdapter = {\n toSuiAddress: () => signer.getAddress(),\n signTransaction: (bytes: Uint8Array) => signer.signTransaction(bytes),\n } as unknown as Parameters<typeof buildX402SignedPayment>[0]['signer'];\n\n const { header } = await buildX402SignedPayment({ requirements, signer: signerAdapter });\n\n const res = await fetch(options.url, {\n ...reqInit,\n headers: { ...(options.headers ?? {}), [X402_PAYMENT_HEADER]: header },\n });\n\n // Settled iff the gateway returned the x402 receipt header.\n const settleHeader = res.headers.get(X402_PAYMENT_RESPONSE_HEADER);\n const paid = !!settleHeader;\n let digest: string | undefined;\n if (settleHeader) {\n try {\n digest = (JSON.parse(new TextDecoder().decode(fromBase64(settleHeader))) as { transaction?: string })\n .transaction;\n } catch {\n digest = undefined;\n }\n }\n\n const result = await finalize(res, { paid });\n if (!paid) return { ...result, dialect: 'x402' };\n return {\n ...result,\n dialect: 'x402',\n cost: atomicToHuman(amountRaw, await assetDecimals(requirements.asset)),\n gasCostSui: migrationGasSui,\n receipt: digest\n ? { reference: digest, timestamp: new Date().toISOString() }\n : result.receipt,\n };\n}\n\n// ---------------------------------------------------------------------------\n// MPP header dialect — client broadcasts, retries with the digest credential.\n// The pre-S.452 `payViaLegacy`, restored (S.453) for header-only external\n// sellers. mppx's client handles the 402 → pay → retry loop; we plug in the\n// Sui charge method with an `execute` override that routes the on-chain leg\n// through `executeTx` (gRPC build → gasless resolver → the same\n// `send_funds<USDC>` rail as x402).\n// ---------------------------------------------------------------------------\n\nasync function payViaMppHeader(args: {\n signer: TransactionSigner;\n client: SuiGrpcClient;\n options: PayOptions;\n}): Promise<PayResult> {\n const { signer, client, options } = args;\n\n const { Mppx } = await import('mppx/client');\n const { sui, USDC, USDC_TESTNET } = await import('@suimpp/mpp/client');\n\n const signerAddress = signer.getAddress();\n const network: 'mainnet' | 'testnet' = client.network === 'testnet' ? 'testnet' : 'mainnet';\n const grpcClient = await makeGrpcBuildClient(client);\n\n let paymentDigest: string | undefined;\n let gasCostSui = 0;\n // The real amount charged on-chain is the 402 challenge price (a decimal\n // USDC string like \"0.01\"), NOT the caller's `maxPrice` ceiling (Bug 1,\n // dogfood 2026-05-31). Capture it in `onChallenge` — and enforce the\n // ceiling THERE, before any credential is created: the header dialect pays\n // client-side, so this hook is the last stop before money moves.\n let chargedAmount: number | undefined;\n\n const mppx = Mppx.create({\n polyfill: false,\n onChallenge: async (challenge: { request?: { amount?: unknown } }) => {\n const parsed = parseChallengeAmount(challenge);\n if (parsed !== undefined) {\n chargedAmount = parsed;\n assertWithinMaxPrice(parsed, options.maxPrice);\n }\n return undefined;\n },\n methods: [\n sui({\n client,\n currency: network === 'testnet' ? USDC_TESTNET : USDC,\n signer: {\n toSuiAddress: () => signerAddress,\n signPersonalMessage: (bytes: Uint8Array) => signer.signPersonalMessage(bytes),\n } as unknown as Parameters<typeof sui>[0]['signer'],\n execute: async (tx) => {\n const result = await executeTx(client, signer, () => tx, { buildClient: grpcClient });\n paymentDigest = result.digest;\n gasCostSui = result.gasCostSui;\n return { digest: result.digest };\n },\n }),\n ],\n });\n\n const method = (options.method ?? 'GET').toUpperCase();\n const canHaveBody = method !== 'GET' && method !== 'HEAD';\n\n const response = await mppx.fetch(options.url, {\n method,\n headers: options.headers,\n body: canHaveBody ? options.body : undefined,\n });\n\n const paid = !!paymentDigest;\n const result = await finalize(response, { paid });\n if (!paid) return { ...result, dialect: 'legacy' };\n return {\n ...result,\n dialect: 'legacy',\n cost: chargedAmount ?? options.maxPrice ?? undefined,\n gasCostSui,\n receipt: paymentDigest\n ? { reference: paymentDigest, timestamp: new Date().toISOString() }\n : undefined,\n };\n}\n\n/** Throw `PRICE_EXCEEDS_LIMIT` when the challenge price exceeds the caller's\n * `maxPrice` ceiling (no ceiling = pay whatever the 402 asks). */\nfunction assertWithinMaxPrice(price: number, maxPrice: number | undefined): void {\n if (maxPrice !== undefined && price > maxPrice) {\n throw new T2000Error(\n 'PRICE_EXCEEDS_LIMIT',\n `Service price $${price} exceeds maxPrice ceiling $${maxPrice}`,\n { price, maxPrice },\n );\n }\n}\n\n/**\n * Ensure the sender's SIP-58 address balance covers `amountRaw` of `asset`.\n * Returns the SUI gas spent migrating (0 when no migration was needed or the\n * migration was gasless). Throws `INSUFFICIENT_BALANCE` when the wallet\n * doesn't hold enough of the asset at all (coins + address balance combined).\n */\nasync function ensureAddressBalanceCovers(args: {\n signer: TransactionSigner;\n client: SuiGrpcClient;\n asset: string;\n amountRaw: bigint;\n}): Promise<number> {\n const { signer, client, asset, amountRaw } = args;\n const owner = signer.getAddress();\n\n // total = coins + address balance (the canonical combined read)\n const balanceResp = await client.core.getBalance({ owner, coinType: asset });\n const total = BigInt(balanceResp.balance.balance);\n if (total < amountRaw) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${asset} to pay`, {\n available: total.toString(),\n required: amountRaw.toString(),\n });\n }\n\n // address balance = total − discrete coin-object sum (listCoins excludes AB).\n // Collect the coin objects too — we reuse them to build the migration.\n const coins: { objectId: string; balance: bigint }[] = [];\n let coinSum = 0n;\n let cursor: string | null | undefined;\n let hasNext = true;\n while (hasNext) {\n const page = await client.core.listCoins({ owner, coinType: asset, cursor: cursor ?? undefined });\n for (const c of page.objects) {\n coins.push({ objectId: c.objectId, balance: BigInt(c.balance) });\n coinSum += BigInt(c.balance);\n }\n cursor = page.cursor;\n hasNext = page.hasNextPage;\n }\n const addressBalance = total - coinSum;\n if (addressBalance >= amountRaw) return 0; // address balance already covers it\n\n // Move the shortfall from coin objects into the address balance by sending\n // WHOLE coin objects to self via `0x2::coin::send_funds` — one allowlisted\n // framework MoveCall per coin, NO native merge/split. Built on the gRPC\n // client so its resolver detects the all-allowlisted-MoveCall shape and zeros\n // gas: the migration itself is gasless (the same eligibility the x402\n // withdrawal + the gasless send rely on). The old merge+split+send shape had\n // native `SplitCoins`/`MergeCoins` commands → fell outside the allowlist →\n // forced SUI gas, breaking coin-object holders with 0 SUI.\n const shortfall = amountRaw - addressBalance;\n const { buildCoinToAddressBalanceMigration } = await import('./coinSelection.js');\n const grpcClient = await makeGrpcBuildClient(client);\n const { tx } = buildCoinToAddressBalanceMigration({ coins, coinType: asset, owner, minAmount: shortfall });\n const migration = await executeTx(client, signer, () => tx, { buildClient: grpcClient });\n return migration.gasCostSui;\n}\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\n/** Cheap \"is this JSON?\" check — parse, don't guess from the first char. */\nfunction isJsonText(text: string): boolean {\n try {\n JSON.parse(text);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Case-insensitive content-type presence check on a plain header record. */\nfunction hasContentType(headers: Record<string, string> | undefined): boolean {\n if (!headers) return false;\n return Object.keys(headers).some((k) => k.toLowerCase() === 'content-type');\n}\n\n/** Read the response body (json or text) and assemble the base PayResult. */\nasync function finalize(response: Response, opts: { paid: boolean }): Promise<PayResult> {\n const contentType = response.headers.get('content-type') ?? '';\n let body: unknown;\n try {\n body = contentType.includes('application/json') ? await response.json() : await response.text();\n } catch {\n body = null;\n }\n return { status: response.status, body, paid: opts.paid };\n}\n\n/** A gRPC client for tx BUILD — its resolver auto-detects the gasless\n * stablecoin shape (gasPrice/gasBudget/gasPayment zeroed). */\nasync function makeGrpcBuildClient(client: SuiGrpcClient): Promise<SuiGrpcClient> {\n const { SuiGrpcClient } = await import('@mysten/sui/grpc');\n const network: 'mainnet' | 'testnet' = client.network === 'testnet' ? 'testnet' : 'mainnet';\n const baseUrl =\n network === 'testnet' ? 'https://fullnode.testnet.sui.io' : 'https://fullnode.mainnet.sui.io';\n return new SuiGrpcClient({ baseUrl, network });\n}\n\nfunction atomicToHuman(raw: bigint, decimals: number): number {\n return Number(raw) / 10 ** decimals;\n}\n\nasync function assetDecimals(coinType: string): Promise<number> {\n try {\n const { getDecimalsForCoinType } = await import('../token-registry.js');\n const d = getDecimalsForCoinType(coinType);\n return typeof d === 'number' ? d : 6;\n } catch {\n return 6;\n }\n}\n","/**\n * MPP cost extraction — the truthful-`cost` fix (Bug 1, dogfood 2026-05-31).\n *\n * `T2000.pay()` used to report `options.maxPrice` (the caller's ceiling, default\n * 1.0 in MCP) as the `cost`, wildly overstating the real charge. The real\n * amount is the 402 challenge price, a decimal USDC string like \"0.01\" carried\n * on `challenge.request.amount`. mppx surfaces the parsed challenge via its\n * `onChallenge` hook; this pure helper pulls the amount out so the extraction\n * is unit-testable in isolation (the ordering/format invariant can't silently\n * regress).\n */\n\n/** Minimal structural view of an mppx payment challenge. */\nexport type MppChallenge = { request?: { amount?: unknown } } | null | undefined;\n\n/**\n * Parse the charged amount (USD) from a payment challenge. Returns `undefined`\n * when the challenge has no usable numeric amount, so callers can fall back to\n * the `maxPrice` ceiling rather than reporting a wrong number.\n */\nexport function parseChallengeAmount(challenge: MppChallenge): number | undefined {\n const raw = challenge?.request?.amount;\n const n =\n typeof raw === 'string' ? Number(raw) : typeof raw === 'number' ? raw : Number.NaN;\n return Number.isFinite(n) ? n : undefined;\n}\n","import type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport type { TransactionSigner } from '../signer.js';\n\nexport interface ZkLoginProof {\n proofPoints: {\n a: string[];\n b: string[][];\n c: string[];\n };\n issBase64Details: {\n indexMod4: number;\n value: string;\n };\n headerBase64: string;\n addressSeed: string;\n}\n\nexport class ZkLoginSigner implements TransactionSigner {\n readonly kind = 'zklogin' as const;\n\n constructor(\n private readonly ephemeralKeypair: Ed25519Keypair,\n private readonly zkProof: ZkLoginProof,\n private readonly userAddress: string,\n private readonly maxEpoch: number,\n ) {}\n\n getAddress(): string {\n return this.userAddress;\n }\n\n async signTransaction(txBytes: Uint8Array): Promise<{ signature: string }> {\n const { getZkLoginSignature } = await import('@mysten/zklogin');\n const ephSig = await this.ephemeralKeypair.signTransaction(txBytes);\n return {\n signature: getZkLoginSignature({\n inputs: this.zkProof,\n maxEpoch: this.maxEpoch,\n userSignature: ephSig.signature,\n }),\n };\n }\n\n async signPersonalMessage(messageBytes: Uint8Array): Promise<{ signature: string; bytes: string }> {\n const { getZkLoginSignature } = await import('@mysten/zklogin');\n const { signature: ephSig, bytes } = await this.ephemeralKeypair.signPersonalMessage(messageBytes);\n return {\n signature: getZkLoginSignature({\n inputs: this.zkProof,\n maxEpoch: this.maxEpoch,\n userSignature: ephSig,\n }),\n bytes,\n };\n }\n\n isExpired(currentEpoch: number): boolean {\n return currentEpoch >= this.maxEpoch;\n }\n}\n","import {\n Transaction,\n type TransactionObjectArgument,\n} from '@mysten/sui/transactions';\nimport {\n GASLESS_MIN_STABLE_AMOUNT,\n GASLESS_STABLE_TYPES,\n SUPPORTED_ASSETS,\n assertAllowedAsset,\n type SendableAsset,\n} from '../constants.js';\nimport { T2000Error } from '../errors.js';\nimport { validateAddress, type SuiCoreClient } from '../utils/sui.js';\nimport { displayToRaw } from '../utils/format.js';\nimport {\n type PreflightResult,\n PREFLIGHT_OK,\n preflightFail,\n checkPositiveAmount,\n checkSuiAddress,\n} from '../preflight.js';\n\n/**\n * Synchronous, network-free preflight for `send`. Validates asset membership,\n * amount sanity, the gasless stable floor, and recipient address shape — the\n * cheap checks the v3 host runs before the LLM round-trip / tap-to-confirm.\n * Returns a `PreflightResult`; never throws. `buildSendTx` calls this first,\n * then layers the network balance read on top.\n */\nexport function preflightSend(input: {\n to: string;\n amount: number;\n asset: string;\n}): PreflightResult {\n // Asset membership — reuse the canonical message (single source of truth).\n try {\n assertAllowedAsset('send', input.asset);\n } catch (e) {\n return preflightFail('INVALID_ASSET', (e as T2000Error).message);\n }\n\n const amountCheck = checkPositiveAmount(input.amount);\n if (!amountCheck.valid) return amountCheck;\n\n // Gasless protocol allowlist enforces a 0.01 minimum on the stables.\n if (\n (input.asset === 'USDC' || input.asset === 'USDsui') &&\n input.amount < GASLESS_MIN_STABLE_AMOUNT\n ) {\n return preflightFail(\n 'INVALID_AMOUNT',\n `Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${input.asset}. Got ${input.amount}.`,\n );\n }\n\n const addressCheck = checkSuiAddress(input.to);\n if (!addressCheck.valid) return addressCheck;\n\n return PREFLIGHT_OK;\n}\n\n/**\n * Build a PTB that sends `amount` of `asset` from `address` to `to`.\n *\n * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]\n *\n * Asset constraint: `'USDC' | 'USDsui' | 'SUI'` only. Other assets throw\n * `INVALID_ASSET` via `assertAllowedAsset('send', asset)`. The constrained\n * set matches Sui mainnet's gasless allowlist (USDC + USDsui) plus SUI\n * for users who want a gas-native transfer.\n *\n * Build paths:\n * - **USDC / USDsui** — `0x2::balance::send_funds` Move call with a\n * `tx.balance({ type, balance })` input. When built via `SuiGrpcClient`,\n * the gRPC resolver auto-detects gasless eligibility and zeros gas.\n * When built via `SuiJsonRpcClient`, the same PTB still executes but\n * the caller pays normal gas. Minimum 0.01 (protocol allowlist floor).\n * - **SUI** — `tx.splitCoins(tx.gas, [amount]) → tx.transferObjects()`.\n * Standard gas-native transfer. No minimum.\n *\n * Pre-flight balance check stays on JSON-RPC (`client.getBalance`) — it\n * sums coin objects + address balance so the legacy `getCoins` page miss\n * doesn't break for users whose stables landed via gasless deposits.\n *\n * `asset` is REQUIRED (no implicit USDC default — pre-v4 hid LLM intent\n * errors). Callers passing the wrong asset get an explicit error rather\n * than a silent currency substitution.\n */\nexport async function buildSendTx({\n client,\n address,\n to,\n amount,\n asset,\n}: {\n client: SuiCoreClient;\n address: string;\n to: string;\n amount: number;\n asset: SendableAsset;\n}): Promise<Transaction> {\n // Layer 2 — cheap synchronous preflight (asset / amount / gasless floor /\n // recipient shape). Rethrow the precise code+message verbatim.\n const pf = preflightSend({ to, amount, asset });\n if (!pf.valid) throw new T2000Error(pf.code, pf.error);\n\n const recipient = validateAddress(to);\n const assetInfo = SUPPORTED_ASSETS[asset];\n if (!assetInfo) throw new T2000Error('ASSET_NOT_SUPPORTED', `Asset ${asset} is not supported`);\n\n const rawAmount = displayToRaw(amount, assetInfo.decimals);\n const tx = new Transaction();\n tx.setSender(address);\n\n // Balance pre-flight against `core.getBalance().balance.balance` (sums\n // coins + address balance). The legacy `getCoins` page miss broke for\n // users whose stables had drifted into address balance via @suimpp/mpp 0.7+.\n const balanceResp = await client.core.getBalance({ owner: address, coinType: assetInfo.type });\n const totalBalance = BigInt(balanceResp.balance.balance);\n if (totalBalance < rawAmount) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${asset} balance`, {\n available: Number(totalBalance) / 10 ** assetInfo.decimals,\n required: amount,\n });\n }\n\n // Gasless dust floor — the protocol validator rejects a gasless stable\n // withdrawal that leaves a remainder BELOW the 0.01 floor (it must either\n // consume the entire balance or leave >= 0.01). Without this check the\n // build surfaces a cryptic node error (\"Invalid withdraw reservation\" /\n // \"Unable to perform gas selection\") — verified live 2026-07-19. Auto-clip\n // is intentionally NOT done here: silently sending more than asked is\n // worse than a clear error (financial-amounts discipline).\n if (asset === 'USDC' || asset === 'USDsui') {\n const rawFloor = displayToRaw(GASLESS_MIN_STABLE_AMOUNT, assetInfo.decimals);\n const remainder = totalBalance - rawAmount;\n if (remainder > 0n && remainder < rawFloor) {\n const total = Number(totalBalance) / 10 ** assetInfo.decimals;\n throw new T2000Error(\n 'INVALID_AMOUNT',\n `Gasless ${asset} transfers must send the entire balance or leave at least ${GASLESS_MIN_STABLE_AMOUNT} ${asset}. ` +\n `Sending ${amount} of ${total} leaves ${(total - amount).toFixed(assetInfo.decimals)}. ` +\n `Send ${total} (everything) or at most ${(total - GASLESS_MIN_STABLE_AMOUNT).toFixed(assetInfo.decimals)}.`,\n { available: total, required: amount },\n );\n }\n }\n\n if (asset === 'SUI') {\n // Standard gas-native transfer — split from the gas coin, transfer\n // the resulting object. NOT gasless (SUI is not on the protocol\n // allowlist for `balance::send_funds`).\n const [sendCoin] = tx.splitCoins(tx.gas, [rawAmount]);\n tx.transferObjects([sendCoin], recipient);\n return tx;\n }\n\n // USDC / USDsui — gasless via `0x2::balance::send_funds`. The gRPC\n // build resolver inspects this PTB shape at `tx.build()` time and,\n // when it matches the protocol allowlist, sets gasPrice=0/gasBudget=0\n // automatically. The Move signature is:\n // public fun send_funds<T>(balance: Balance<T>, recipient: address)\n // `tx.balance({ type, balance })` produces a Balance<T> input sourced\n // from the sender's address balance + coin objects (auto-merged).\n const coinType = GASLESS_STABLE_TYPES[asset];\n tx.moveCall({\n target: '0x2::balance::send_funds',\n typeArguments: [coinType],\n arguments: [\n tx.balance({ type: coinType, balance: rawAmount }),\n tx.pure.address(recipient),\n ],\n });\n return tx;\n}\n\n/**\n * Fragment-appender for the chain-mode send leg of SPEC 7 multi-write\n * Payment Intents. Consumes a coin reference produced by a previous\n * appender (e.g. `addWithdrawToTx`, `addSwapToTx`) and transfers it to\n * `recipient` within the same Payment Intent — no intermediate wallet\n * materialization.\n *\n * Codifies the hand-built send leg from\n * `scripts/smoke-spec7-withdraw-then-send.ts` (P2.1) into a typed\n * appender. SPEC 7 § \"Layer 1\" — P2.2b will register this in the\n * `WRITE_APPENDER_REGISTRY` under `send_transfer` for chain-mode\n * dispatch; the registry adapter will handle the wallet-fetch fallback\n * by delegating to `buildSendTx` when no upstream coin is available.\n *\n * For single-step send_transfer flows (no chained predecessor), use\n * `buildSendTx` directly — it builds a complete tx including the\n * wallet-coin selection / merge / split prelude.\n *\n * [v4.0 Phase A Day 2] Stays on the legacy `transferObjects` path\n * because chain-mode bundles are NEVER gasless — by definition they\n * combine multiple Move calls (`withdraw → send`, `swap → send`) which\n * fail the protocol allowlist check (only `balance::send_funds` and\n * a few related helpers are eligible). The bundled flow still works,\n * the user just pays gas (or has it sponsored by audric via Enoki).\n *\n * @returns void — the coin is consumed by `tx.transferObjects`. Callers\n * that need the post-transfer \"effective amount\" should rely on the\n * upstream appender's `effectiveAmount` (e.g. `addWithdrawToTx`'s\n * return), not on this appender.\n */\nexport function addSendToTx(\n tx: Transaction,\n coin: TransactionObjectArgument,\n recipient: string,\n): void {\n const validRecipient = validateAddress(recipient);\n tx.transferObjects([coin], validRecipient);\n}\n","import { MIST_PER_SUI, USDC_DECIMALS, SUPPORTED_ASSETS } from '../constants.js';\nimport type { SupportedAsset } from '../constants.js';\n\nexport function mistToSui(mist: bigint): number {\n return Number(mist) / Number(MIST_PER_SUI);\n}\n\nexport function suiToMist(sui: number): bigint {\n return BigInt(Math.round(sui * Number(MIST_PER_SUI)));\n}\n\nexport function usdcToRaw(amount: number): bigint {\n return BigInt(Math.round(amount * 10 ** USDC_DECIMALS));\n}\n\nexport function rawToUsdc(raw: bigint): number {\n return Number(raw) / 10 ** USDC_DECIMALS;\n}\n\nexport function stableToRaw(amount: number, decimals: number): bigint {\n return BigInt(Math.round(amount * 10 ** decimals));\n}\n\nexport function rawToStable(raw: bigint, decimals: number): number {\n return Number(raw) / 10 ** decimals;\n}\n\nexport function getDecimals(asset: SupportedAsset): number {\n return SUPPORTED_ASSETS[asset].decimals;\n}\n\nexport function rawToDisplay(raw: bigint, decimals: number): number {\n return Number(raw) / 10 ** decimals;\n}\n\nexport function displayToRaw(amount: number, decimals: number): bigint {\n return BigInt(Math.round(amount * 10 ** decimals));\n}\n\nexport function formatUsd(amount: number): string {\n return `$${amount.toFixed(2)}`;\n}\n\nexport function formatSui(amount: number): string {\n if (amount < 0.001) return `${amount.toFixed(6)} SUI`;\n return `${amount.toFixed(3)} SUI`;\n}\n\nexport function formatLargeNumber(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return n.toFixed(2);\n}\n\nexport function formatAssetAmount(amount: number, asset: string): string {\n if (asset === 'BTC') return amount.toFixed(8);\n if (asset === 'GOLD') return amount.toFixed(6);\n if (asset === 'ETH') return amount.toFixed(6);\n return amount.toFixed(4);\n}\n\nconst ASSET_LOOKUP: Map<string, string> = new Map();\nfor (const [key, info] of Object.entries(SUPPORTED_ASSETS)) {\n ASSET_LOOKUP.set(key.toUpperCase(), key);\n if (info.displayName && info.displayName.toUpperCase() !== key.toUpperCase()) {\n ASSET_LOOKUP.set(info.displayName.toUpperCase(), key);\n }\n}\n\n/**\n * Case-insensitive lookup against SUPPORTED_ASSETS keys AND display names.\n * 'usde' → 'USDe', 'suiusde' → 'USDe', 'suiusdt' → 'USDT', 'usdsui' → 'USDsui'.\n * Returns the original input if not found so downstream validation can reject it.\n */\nexport function normalizeAsset(input: string): string {\n return ASSET_LOOKUP.get(input.toUpperCase()) ?? input;\n}\n","import { normalizeStructTag } from '@mysten/sui/utils';\nimport { SUPPORTED_ASSETS, STABLE_ASSETS, MIST_PER_SUI, CETUS_USDC_SUI_POOL } from '../constants.js';\nimport type { StableAsset } from '../constants.js';\nimport { resolveSymbol, resolveCoinDecimals } from '../token-registry.js';\nimport type { SuiCoreClient } from '../utils/sui.js';\nimport type { BalanceResponse, TokenHolding } from '../types.js';\n\nconst SUI_PRICE_FALLBACK = 1.0;\nlet _cachedSuiPrice = 0;\nlet _priceLastFetched = 0;\nconst PRICE_CACHE_TTL_MS = 60_000;\n\n/**\n * Fetch SUI price in USD from the Cetus USDC/SUI pool's sqrt_price.\n *\n * Pool is Pool<USDC, SUI> so coin_a = USDC (6 dec), coin_b = SUI (9 dec).\n * current_sqrt_price (Q64 fixed-point) encodes sqrt(raw_price) where\n * raw_price = SUI_raw / USDC_raw.\n *\n * USDC per SUI = 10^(decimals_a - decimals_b) / raw_price\n * = 10^(6-9) / raw_price\n * = 1 / (raw_price * 1000)\n *\n * Equivalently: 1000 / raw_price\n */\nasync function fetchSuiPrice(client: SuiCoreClient): Promise<number> {\n const now = Date.now();\n if (_cachedSuiPrice > 0 && now - _priceLastFetched < PRICE_CACHE_TTL_MS) {\n return _cachedSuiPrice;\n }\n\n try {\n // [gRPC migration] `core.getObject` returns BCS content; request `json`\n // to read parsed Move fields (the legacy `content.fields` path is gone).\n const pool = await client.core.getObject({\n objectId: CETUS_USDC_SUI_POOL,\n include: { json: true },\n });\n\n const fields = pool.object?.json as Record<string, unknown> | null | undefined;\n if (fields) {\n const currentSqrtPrice = BigInt(String(fields.current_sqrt_price ?? '0'));\n\n if (currentSqrtPrice > 0n) {\n const Q64 = 2n ** 64n;\n const sqrtPriceFloat = Number(currentSqrtPrice) / Number(Q64);\n const rawPrice = sqrtPriceFloat * sqrtPriceFloat;\n const price = 1000 / rawPrice;\n if (price > 0.01 && price < 1000) {\n _cachedSuiPrice = price;\n _priceLastFetched = now;\n }\n }\n }\n } catch {\n // Use cached/fallback price\n }\n\n return _cachedSuiPrice || SUI_PRICE_FALLBACK;\n}\n\nfunction safeNorm(coinType: string): string {\n try {\n return normalizeStructTag(coinType);\n } catch {\n return coinType;\n }\n}\n\nconst SUI_TYPE_NORM = safeNorm(SUPPORTED_ASSETS.SUI.type);\nconst STABLE_BY_NORM: Record<string, StableAsset> = (() => {\n const m: Record<string, StableAsset> = {};\n for (const asset of STABLE_ASSETS) m[safeNorm(SUPPORTED_ASSETS[asset].type)] = asset;\n return m;\n})();\n\n/**\n * Full wallet balance: **every** held coin, not just the curated stables + SUI.\n *\n * Uses one `listBalances` (paginated) instead of N `getBalance` calls, then\n * partitions: stables → priced $1, SUI → Cetus-oracle priced, **everything else\n * → `tokens[]` amount-only** (`usdValue: null` — no price oracle for arbitrary\n * tokens; we don't guess). Decimals for non-registry tokens are read on-chain\n * (the only added call, and only for tokens you actually hold — necessary for a\n * correct amount). `totalUsd` sums **priced holdings only** so it never\n * overstates; `tokens` surfaces the rest honestly.\n */\nexport async function queryBalance(\n client: SuiCoreClient,\n address: string,\n): Promise<BalanceResponse> {\n const held: Array<{ coinType: string; raw: bigint }> = [];\n let cursor: string | null | undefined;\n do {\n const page = await client.core.listBalances({ owner: address, cursor: cursor ?? undefined });\n for (const b of page.balances) {\n const raw = BigInt(b.balance);\n if (raw > 0n) held.push({ coinType: b.coinType, raw });\n }\n cursor = page.hasNextPage ? page.cursor : null;\n } while (cursor);\n\n const suiPriceUsd = await fetchSuiPrice(client);\n\n const stables = {} as Record<StableAsset, number>;\n for (const asset of STABLE_ASSETS) stables[asset] = 0;\n let totalStables = 0;\n let suiAmount = 0;\n const otherCoins: Array<{ coinType: string; raw: bigint }> = [];\n\n for (const { coinType, raw } of held) {\n const norm = safeNorm(coinType);\n if (norm === SUI_TYPE_NORM) {\n suiAmount = Number(raw) / Number(MIST_PER_SUI);\n } else if (STABLE_BY_NORM[norm]) {\n const asset = STABLE_BY_NORM[norm];\n const amount = Number(raw) / 10 ** SUPPORTED_ASSETS[asset].decimals;\n stables[asset] = amount;\n totalStables += amount;\n } else {\n otherCoins.push({ coinType, raw });\n }\n }\n\n // Non-stable, non-SUI holdings — amount-only (no price oracle). Decimals come\n // from the registry (no call) or on-chain coin metadata (unknown tokens only).\n const tokens: TokenHolding[] = await Promise.all(\n otherCoins.map(async ({ coinType, raw }) => {\n const decimals = await resolveCoinDecimals(client, coinType);\n return {\n coinType,\n symbol: resolveSymbol(coinType),\n amount: Number(raw) / 10 ** decimals,\n usdValue: null,\n };\n }),\n );\n tokens.sort((a, b) => a.symbol.localeCompare(b.symbol));\n\n const suiUsdValue = suiAmount * suiPriceUsd;\n\n return {\n stables,\n available: totalStables,\n sui: { amount: suiAmount, usdValue: suiUsdValue },\n tokens,\n totalUsd: totalStables + suiUsdValue,\n };\n}\n","/**\n * Shared transaction classifier.\n *\n * Consumed by both the SDK's `parseTxRecord` (production agent path) and\n * the engine's `transaction_history` tool (cold-start RPC path). Keeping\n * a single source of truth here prevents the two paths from drifting —\n * see v1.5.3 regression where the SDK path was emitting `action:\n * 'transaction'` (rendered as \"On-chain\") while the engine path was\n * already producing fine-grained labels.\n */\n\nimport { getDecimalsForCoinType, resolveSymbol, SUI_TYPE } from '../token-registry.js';\n\n/**\n * Coarse action bucket — one of `'send' | 'lending' | 'swap' |\n * 'transaction'`. Used by the ACI `action` filter on the\n * `transaction_history` tool. STABLE: downstream queries depend on\n * exactly these values.\n *\n * Order matters: more specific buckets first. Lending patterns precede\n * swap patterns so a NAVI `::swap` helper (if one ever existed) would\n * still bucket as lending.\n */\nexport const KNOWN_TARGETS: readonly [RegExp, string][] = [\n [/::suilend|::obligation/, 'lending'],\n [/::navi|::lending_core|::incentive_v\\d+|::oracle_pro/, 'lending'],\n /**\n * DEX modules — both direct calls and aggregator legs. The Cetus\n * aggregator dispatches through a per-DEX module (e.g.\n * `cetus::swap`, `flowx_amm::swap`, `aftermath::swap`, …) plus\n * router glue functions. We list every DEX module the aggregator\n * supports today so a single-DEX call still classifies cleanly.\n */\n [/::cetus(?:_dlmm)?::|::pool::|::deepbook|::flowx_(?:amm|clmm)::|::kriya_(?:amm|clmm)::|::turbos::|::aftermath::|::afsui::|::bluefin::|::bluemove::|::ferra_(?:clmm|dlmm)::|::haedal_hmm::|::hasui::|::hawal::|::magma::|::momentum::|::obric::|::springsui::|::steamm_cpmm::|::fullsail::|::alphafi::|::volo_swap::/, 'swap'],\n /**\n * Cetus aggregator router glue. These are the swap-context and\n * balance-handling helpers the aggregator emits around per-DEX\n * legs. Without this entry a tx that ONLY had router calls\n * (theoretically possible for setup/cleanup) would slip through;\n * in practice these always coexist with a DEX leg, but the entry\n * is cheap insurance.\n */\n [/::router::(?:new_swap_context(?:_v)?|confirm_swap|transfer_balance|take_balance|transfer_or_destroy_coin)/, 'swap'],\n [/::transfer::public_transfer/, 'send'],\n];\n\n/**\n * Finer-grained display labels — derived from MoveCall function names.\n * The card renders `label ?? action`, so when this map matches we get\n * \"Deposit\" / \"Withdraw\" / \"Borrow\" / \"Repay\" / \"Payment link\" instead\n * of the generic \"Lending\" or \"Transaction\".\n *\n * Order matters: more specific patterns first. Each entry is\n * (regex, label) where the regex is matched against the\n * fully-qualified MoveCall target `pkg::module::function`.\n */\nexport const LABEL_PATTERNS: readonly [RegExp, string][] = [\n [/::pay(?:ment_kit|_kit)?::|::create_payment_link|::pay_link/, 'payment_link'],\n [/::create_invoice|::invoice::/, 'invoice'],\n [/::deposit|::supply|::mint_ctokens/, 'deposit'],\n [/::withdraw|::redeem|::redeem_ctokens/, 'withdraw'],\n [/::borrow/, 'borrow'],\n [/::repay/, 'repay'],\n [/::claim_reward|::claim::|::claim_incentive/, 'claim'],\n [/::stake/, 'stake'],\n [/::unstake|::burn::/, 'unstake'],\n [/::liquidate/, 'liquidate'],\n];\n\nexport interface ClassifyBalanceChange {\n owner: { AddressOwner?: string } | string;\n coinType: string;\n amount: string;\n}\n\nfunction resolveOwner(owner: ClassifyBalanceChange['owner']): string | null {\n if (typeof owner === 'object' && owner.AddressOwner) return owner.AddressOwner;\n if (typeof owner === 'string') return owner;\n return null;\n}\n\nexport function classifyAction(targets: string[], commandTypes: string[]): string {\n for (const target of targets) {\n for (const [pattern, label] of KNOWN_TARGETS) {\n if (pattern.test(target)) return label;\n }\n }\n if (commandTypes.includes('TransferObjects') && !commandTypes.includes('MoveCall')) return 'send';\n return 'transaction';\n}\n\n/**\n * Last-resort fallback when neither `LABEL_PATTERNS` nor the action\n * bucket produces something useful.\n *\n * Returns the first MoveCall's *module* name (e.g. \"navi\", \"spam\") so\n * the card shows something better than the literal word \"transaction\".\n * When no MoveCall exists, returns 'on-chain'.\n *\n * Note: callers should prefer `classifyLabel` which now layers\n * pattern-match → coarse action → module name (see commentary there).\n */\nexport function fallbackLabel(targets: string[]): string {\n if (!targets.length) return 'on-chain';\n const first = targets[0];\n const parts = first.split('::');\n if (parts.length >= 2 && parts[1]) return parts[1].toLowerCase();\n return 'on-chain';\n}\n\n/**\n * Three-tier label resolution for the transaction history card:\n * 1. Specific keyword match in `LABEL_PATTERNS` (\"deposit\",\n * \"payment_link\", …).\n * 2. Coarse action bucket from `classifyAction` (\"swap\", \"send\",\n * \"lending\") — prevents leaking opaque internal module names like\n * \"router\" (Cetus aggregator) or \"cross_swap\" (third-party DEX\n * aggregators) for txs that we already classified as a swap.\n * 3. Module name from the first MoveCall (`fallbackLabel`) — only\n * used when the action bucket itself is the generic \"transaction\".\n *\n * Pre-v0.46.2 we skipped tier 2, so swaps showed labels like \"router\",\n * \"cross_swap\", \"scallop_router\", etc. instead of the clean \"swap\".\n */\nexport function classifyLabel(targets: string[], commandTypes: string[]): string {\n for (const target of targets) {\n for (const [pattern, label] of LABEL_PATTERNS) {\n if (pattern.test(target)) return label;\n }\n }\n if (commandTypes.includes('TransferObjects') && !commandTypes.includes('MoveCall')) return 'send';\n const action = classifyAction(targets, commandTypes);\n if (action !== 'transaction') return action;\n return fallbackLabel(targets);\n}\n\n/**\n * Balance-direction tiebreaker for ambiguous lending calls.\n *\n * Many lending modules expose generic entry points (NAVI's bundled\n * flash actions, `lending_core::*::entry_*`, etc.) that don't carry\n * a `deposit`/`withdraw`/`borrow`/`repay` keyword in the function\n * name. When `classifyLabel` falls back to a bare module name like\n * `\"lending\"` for a known lending tx, infer direction from the user's\n * non-SUI balance change:\n * - net outflow of the supplied asset → deposit (also covers repay,\n * but repay-without-keyword is essentially never emitted).\n * - net inflow of the supplied asset → withdraw (also covers borrow).\n * SUI is excluded so gas-only transactions don't get mislabeled.\n *\n * If `LABEL_PATTERNS` matched a specific keyword, the existing label is\n * returned unchanged.\n */\nexport function refineLendingLabel(\n currentAction: string,\n currentLabel: string,\n moveCallTargets: string[],\n changes: ClassifyBalanceChange[],\n address: string,\n): string {\n if (currentAction !== 'lending') return currentLabel;\n const labelMatchedSpecific = LABEL_PATTERNS.some(([p]) =>\n moveCallTargets.some((t) => p.test(t)),\n );\n if (labelMatchedSpecific) return currentLabel;\n\n const userNonSuiOutflow = changes.find(\n (c) => resolveOwner(c.owner) === address && c.coinType !== SUI_TYPE && BigInt(c.amount) < 0n,\n );\n if (userNonSuiOutflow) return 'deposit';\n\n const userNonSuiInflow = changes.find(\n (c) => resolveOwner(c.owner) === address && c.coinType !== SUI_TYPE && BigInt(c.amount) > 0n,\n );\n if (userNonSuiInflow) return 'withdraw';\n\n return currentLabel;\n}\n\nexport interface ClassifyResult {\n action: string;\n label: string;\n}\n\nexport function classifyTransaction(\n moveCallTargets: string[],\n commandTypes: string[],\n balanceChanges: ClassifyBalanceChange[],\n address: string,\n): ClassifyResult {\n const action = classifyAction(moveCallTargets, commandTypes);\n const baseLabel = classifyLabel(moveCallTargets, commandTypes);\n const label = refineLendingLabel(action, baseLabel, moveCallTargets, balanceChanges, address);\n return { action, label };\n}\n\n/**\n * Direction of the user's net non-gas movement for this transaction.\n *\n * - `'out'` — the user spent the asset (sends, deposits, repays,\n * swap-in, payment-link payouts).\n * - `'in'` — the user received the asset (withdraws, borrows,\n * swap-out, claims, deposits credited from another wallet).\n *\n * Used by the `TransactionHistoryCard` to choose the `+`/`−` sign and\n * color. Direction is computed from the actual on-chain balance change\n * — never from the textual label — so opaque action types (`'router'`,\n * `'cross_swap'`, …) still render the correct sign.\n */\nexport type TxDirection = 'in' | 'out';\n\nexport interface ExtractedTransfer {\n amount?: number;\n asset?: string;\n recipient?: string;\n direction?: TxDirection;\n}\n\n/**\n * Extracts the principal amount/asset/direction for a transaction\n * from its `balanceChanges`.\n *\n * Algorithm:\n * 1. Restrict to the user's *own* balance changes.\n * 2. Prefer non-SUI changes (gas-only SUI deltas are noise).\n * 3. Pick the change with the largest absolute value — the \"principal\".\n * 4. If no non-SUI change exists, fall back to the largest SUI change\n * so pure-SUI transfers (stake/unstake/native send) still render.\n * 5. Direction follows the sign of the principal.\n * 6. Recipient is set only on outflows, by finding a matching inflow\n * on a *non-user* address with the same coinType.\n *\n * Pre-v0.46.2 this function only inspected outflows, so withdraws,\n * borrows, claims, swap-receives and payment-link receives all\n * rendered with no amount on the rich card (and with a wrong sign,\n * because the card guessed direction from the label string).\n */\nexport function extractTransferDetails(\n changes: ClassifyBalanceChange[] | undefined,\n sender: string,\n): ExtractedTransfer {\n if (!changes || changes.length === 0) return {};\n\n const userChanges = changes.filter((c) => resolveOwner(c.owner) === sender);\n if (userChanges.length === 0) return {};\n\n const userNonSui = userChanges.filter((c) => c.coinType !== SUI_TYPE);\n const pool = userNonSui.length > 0 ? userNonSui : userChanges;\n\n let primary = pool[0];\n let primaryAbs = bigintAbs(BigInt(primary.amount));\n for (let i = 1; i < pool.length; i++) {\n const abs = bigintAbs(BigInt(pool[i].amount));\n if (abs > primaryAbs) {\n primary = pool[i];\n primaryAbs = abs;\n }\n }\n\n const raw = BigInt(primary.amount);\n if (raw === 0n) return {};\n\n const decimals = getDecimalsForCoinType(primary.coinType);\n const amount = Number(primaryAbs) / 10 ** decimals;\n const asset = resolveSymbol(primary.coinType);\n const direction: TxDirection = raw < 0n ? 'out' : 'in';\n\n let recipient: string | undefined;\n if (direction === 'out') {\n const recipientChange = changes.find(\n (c) =>\n resolveOwner(c.owner) !== sender &&\n c.coinType === primary.coinType &&\n BigInt(c.amount) > 0n,\n );\n recipient = recipientChange ? resolveOwner(recipientChange.owner) ?? undefined : undefined;\n }\n\n return { amount, asset, recipient, direction };\n}\n\nfunction bigintAbs(n: bigint): bigint {\n return n < 0n ? -n : n;\n}\n\n/**\n * Extract every non-zero user balance leg for a transaction — not\n * just the largest one. Order is RPC order; callers responsible for\n * any sorting (e.g. audric sorts by USD value once it's priced).\n *\n * Sui collapses balance changes by coin type, so a 3-step bundle\n * touching USDC three times surfaces as ONE leg of net USDC delta.\n * Distinguishing per-step legs would require parsing the PTB's\n * commands; this helper deliberately stops at the balance-change\n * granularity because that's what's reliably available across all\n * Sui RPC versions.\n *\n * Pre-v1.27.2 the only public API was `extractTransferDetails`,\n * which returned a single \"primary\" leg and made swap rows\n * unrenderable (showed `Swapped 987.60 MANIFEST` because MANIFEST\n * was the largest raw delta even though USDC was the value side).\n */\nexport function extractAllUserLegs(\n changes: ClassifyBalanceChange[] | undefined,\n sender: string,\n): import('../types.js').TransactionLeg[] {\n if (!changes || changes.length === 0) return [];\n\n const legs: import('../types.js').TransactionLeg[] = [];\n for (const c of changes) {\n if (resolveOwner(c.owner) !== sender) continue;\n const raw = BigInt(c.amount);\n if (raw === 0n) continue;\n const decimals = getDecimalsForCoinType(c.coinType);\n const absAmount = bigintAbs(raw);\n legs.push({\n coinType: c.coinType,\n asset: resolveSymbol(c.coinType),\n decimals,\n amount: Number(absAmount) / 10 ** decimals,\n rawAmount: raw.toString(),\n direction: raw < 0n ? 'out' : 'in',\n });\n }\n\n return legs;\n}\n","import type { TransactionRecord } from '../types.js';\nimport { getSuiGraphQLClient } from '../utils/sui.js';\nimport {\n classifyTransaction,\n extractAllUserLegs,\n extractTransferDetails,\n type ClassifyBalanceChange,\n} from './classify.js';\n\n// ---------------------------------------------------------------------------\n// [gRPC migration / S.447 + S.450] Transaction history is the one surface with\n// NO gRPC `core.*` equivalent (Stage 0 finding A): list-by-affected-address +\n// per-tx-by-digest live in the GraphQL RPC, not gRPC. Both go through the\n// Sui GraphQL endpoint (`getSuiGraphQLClient()`), share one node fragment +\n// one mapper, and feed the existing (tested) classifier in `classify.ts`.\n//\n// LIVE-VERIFIED 2026-06-15 (S.450) against `graphql.mainnet.sui.io` with a\n// real sender (send + Cetus swap digests). The live schema differs from the\n// older `transactionBlocks` one: the query is `transactions` / `transaction`\n// (filter `affectedAddress` — sender, sponsor, or recipient), the programmable kind is `ProgrammableTransaction`\n// (was `ProgrammableTransactionBlock`) with `commands { nodes }` (was\n// `transactions`), and a move call is `MoveCallCommand` with a nested\n// `function { name module { name package { address } } }` (was a flat\n// `MoveCallTransaction { package module functionName }`). GraphQL errors are\n// now SURFACED, not swallowed (the old `?? []` hid this schema drift as an\n// empty history for a whole session). Schema ref: https://docs.sui.io/references/sui-graphql\n// ---------------------------------------------------------------------------\n\nconst TX_NODE_FRAGMENT = `\n digest\n effects {\n timestamp\n gasEffects { gasSummary { computationCost storageCost storageRebate } }\n balanceChanges { nodes { amount coinType { repr } owner { address } } }\n }\n kind {\n __typename\n ... on ProgrammableTransaction {\n commands {\n nodes {\n __typename\n ... on MoveCallCommand { function { name module { name package { address } } } }\n }\n }\n }\n }\n`;\n\n// `affectedAddress` (not `sentAddress`) so history includes INCOMING transactions\n// — received payments, x402/MPP refunds, airdrops — not just ones the agent\n// signed. Per the Sui GraphQL schema: \"transactions that interacted with the\n// given address … as a sender, sponsor, or recipient.\" The shared classifier\n// already labels each leg's direction ('in' / 'out'), so inbound txns render\n// correctly downstream.\nconst HISTORY_QUERY = `query History($address: SuiAddress!, $last: Int!) {\n transactions(last: $last, filter: { affectedAddress: $address }) {\n nodes {${TX_NODE_FRAGMENT}}\n }\n}`;\n\nconst TX_BY_DIGEST_QUERY = `query TxByDigest($digest: String!) {\n transaction(digest: $digest) {${TX_NODE_FRAGMENT}}\n}`;\n\n/** Minimal shape of a Sui GraphQL transaction node we consume. */\ninterface GqlTxNode {\n digest?: string;\n effects?: {\n timestamp?: string;\n // Live schema returns gas as numbers; `Number()` in the mapper tolerates both.\n gasEffects?: { gasSummary?: { computationCost?: string | number; storageCost?: string | number; storageRebate?: string | number } };\n balanceChanges?: { nodes?: Array<{ amount?: string; coinType?: { repr?: string }; owner?: { address?: string } }> };\n };\n kind?: {\n __typename?: string;\n commands?: {\n nodes?: Array<{\n __typename?: string;\n function?: { name?: string; module?: { name?: string; package?: { address?: string } } };\n }>;\n };\n };\n}\n\n/** GraphQL transport result with the optional `errors` array surfaced. */\ninterface GqlResult<T> {\n data?: T;\n errors?: Array<{ message?: string }>;\n}\n\nfunction assertNoGqlErrors(res: GqlResult<unknown>, what: string): void {\n if (res.errors?.length) {\n throw new Error(\n `Sui GraphQL ${what} failed: ${res.errors.map((e) => e.message ?? 'unknown error').join('; ')}`,\n );\n }\n}\n\nexport async function queryHistory(\n address: string,\n limit = 20,\n): Promise<TransactionRecord[]> {\n const gql = getSuiGraphQLClient();\n const res = (await gql.query({ query: HISTORY_QUERY, variables: { address, last: limit } })) as GqlResult<{\n transactions?: { nodes?: GqlTxNode[] };\n }>;\n assertNoGqlErrors(res, 'history query');\n const nodes = res.data?.transactions?.nodes ?? [];\n // GraphQL `last` returns ascending; the legacy JSON-RPC path returned\n // descending (newest first) — reverse to preserve caller expectations.\n return nodes.map((n) => recordFromGqlNode(n, address)).reverse();\n}\n\nexport async function queryTransaction(\n digest: string,\n senderAddress: string,\n): Promise<TransactionRecord | null> {\n const gql = getSuiGraphQLClient();\n const res = (await gql.query({ query: TX_BY_DIGEST_QUERY, variables: { digest } })) as GqlResult<{\n transaction?: GqlTxNode | null;\n }>;\n assertNoGqlErrors(res, 'transaction query');\n const node = res.data?.transaction;\n if (!node) return null; // genuine not-found (distinct from a query error, which throws above)\n return recordFromGqlNode(node, senderAddress);\n}\n\n/**\n * Map a Sui GraphQL transactionBlock node → the primitives the shared\n * classifier consumes, then build the record. Isolated so the legacy\n * JSON-RPC `parseTxRecord` (back-compat, below) and this GraphQL path\n * converge on one classification routine.\n */\nfunction recordFromGqlNode(node: GqlTxNode, address: string): TransactionRecord {\n const gs = node.effects?.gasEffects?.gasSummary;\n const gasCost = gs\n ? (Number(gs.computationCost ?? 0) + Number(gs.storageCost ?? 0) - Number(gs.storageRebate ?? 0)) / 1e9\n : undefined;\n\n const balanceChanges: ClassifyBalanceChange[] = (node.effects?.balanceChanges?.nodes ?? [])\n .filter((b) => b.coinType?.repr && b.amount != null)\n .map((b) => ({ coinType: b.coinType!.repr!, amount: String(b.amount), owner: b.owner?.address ?? '' }));\n\n const moveCallTargets: string[] = [];\n const commandTypes: string[] = [];\n if (node.kind?.__typename === 'ProgrammableTransaction') {\n for (const cmd of node.kind.commands?.nodes ?? []) {\n if (cmd.__typename === 'MoveCallCommand') {\n commandTypes.push('MoveCall');\n const fn = cmd.function;\n const pkg = fn?.module?.package?.address;\n const mod = fn?.module?.name;\n const name = fn?.name;\n if (pkg && mod && name) {\n moveCallTargets.push(`${pkg}::${mod}::${name}`);\n }\n } else if (cmd.__typename === 'TransferObjectsCommand') {\n commandTypes.push('TransferObjects');\n }\n }\n }\n\n // GraphQL effects.timestamp is an ISO datetime; the record wants ms.\n const ts = node.effects?.timestamp ? Date.parse(node.effects.timestamp) : 0;\n\n return buildRecord({\n digest: node.digest ?? '',\n moveCallTargets,\n commandTypes,\n balanceChanges,\n timestampMs: Number.isFinite(ts) ? ts : 0,\n gasCost,\n address,\n });\n}\n\n/** Shared record builder — classification + leg/transfer extraction. */\nfunction buildRecord(args: {\n digest: string;\n moveCallTargets: string[];\n commandTypes: string[];\n balanceChanges: ClassifyBalanceChange[];\n timestampMs: number;\n gasCost: number | undefined;\n address: string;\n}): TransactionRecord {\n const { digest, moveCallTargets, commandTypes, balanceChanges, timestampMs, gasCost, address } = args;\n const legs = extractAllUserLegs(balanceChanges, address);\n const { amount, asset, recipient, direction } = extractTransferDetails(balanceChanges, address);\n const { action, label } = classifyTransaction(moveCallTargets, commandTypes, balanceChanges, address);\n return { digest, action, label, legs, amount, asset, recipient, direction, timestamp: timestampMs, gasCost };\n}\n\n/**\n * Shape of a transaction block as returned by `suix_queryTransactionBlocks`\n * with `showEffects | showInput | showBalanceChanges` enabled. Exported so\n * downstream consumers (audric dashboard `/api/history`, `/api/activity`,\n * etc.) can type their RPC calls without redeclaring the structure.\n */\nexport interface SuiRpcTxBlock {\n digest: string;\n timestampMs?: string;\n transaction?: unknown;\n effects?: { gasUsed?: { computationCost: string; storageCost: string; storageRebate: string } };\n balanceChanges?: ClassifyBalanceChange[];\n}\n\n/**\n * Convert a single Sui RPC transaction block to a {@link TransactionRecord}\n * using the canonical (shared) classifier and balance-change extractor.\n *\n * This is the single source of truth for transaction parsing across the\n * agent-tool path AND the dashboard-API path. Use it instead of writing\n * a bespoke parser per surface.\n *\n * @param tx Raw RPC tx block (must include `effects`, `input`, `balanceChanges`).\n * @param address Wallet address whose perspective we're parsing from.\n */\nexport function parseSuiRpcTx(tx: SuiRpcTxBlock, address: string): TransactionRecord {\n return parseTxRecord(tx, address);\n}\n\n/**\n * Extract the sender (signer) address from a raw RPC tx block.\n * Returns `null` if the block shape is unexpected.\n */\nexport function extractTxSender(txBlock: unknown): string | null {\n try {\n if (!txBlock || typeof txBlock !== 'object') return null;\n const data = 'data' in txBlock ? (txBlock as Record<string, unknown>).data : undefined;\n if (!data || typeof data !== 'object') return null;\n return ((data as Record<string, unknown>).sender as string) ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract MoveCall targets (`<pkg>::<module>::<function>`) and the\n * sequence of programmable-transaction command types (e.g. `MoveCall`,\n * `TransferObjects`) from a raw RPC tx block. Tolerates both the\n * legacy `inner.transactions` field and the newer `inner.commands`\n * field.\n */\nexport function extractTxCommands(txBlock: unknown): {\n moveCallTargets: string[];\n commandTypes: string[];\n} {\n return extractCommands(txBlock);\n}\n\n// [back-compat] Legacy JSON-RPC-shape parser. The live history path is now\n// GraphQL (above); this stays for external consumers that already hold a\n// JSON-RPC tx block (e.g. via `parseSuiRpcTx`). Routes through `buildRecord`\n// so classification is identical to the GraphQL path.\nfunction parseTxRecord(tx: SuiRpcTxBlock, address: string): TransactionRecord {\n const gasUsed = tx.effects?.gasUsed;\n const gasCost = gasUsed\n ? (Number(gasUsed.computationCost) +\n Number(gasUsed.storageCost) -\n Number(gasUsed.storageRebate)) /\n 1e9\n : undefined;\n\n const { moveCallTargets, commandTypes } = extractCommands(tx.transaction);\n return buildRecord({\n digest: tx.digest,\n moveCallTargets,\n commandTypes,\n balanceChanges: tx.balanceChanges ?? [],\n timestampMs: Number(tx.timestampMs ?? 0),\n gasCost,\n address,\n });\n}\n\ninterface CommandInfo {\n moveCallTargets: string[];\n commandTypes: string[];\n}\n\nfunction extractCommands(txBlock: unknown): CommandInfo {\n const result: CommandInfo = { moveCallTargets: [], commandTypes: [] };\n try {\n if (!txBlock || typeof txBlock !== 'object') return result;\n const data = 'data' in txBlock ? (txBlock as Record<string, unknown>).data : undefined;\n if (!data || typeof data !== 'object') return result;\n const inner = 'transaction' in (data as Record<string, unknown>)\n ? (data as Record<string, unknown>).transaction\n : undefined;\n if (!inner || typeof inner !== 'object') return result;\n const commands = 'commands' in (inner as Record<string, unknown>)\n ? (inner as Record<string, unknown>).commands\n : 'transactions' in (inner as Record<string, unknown>)\n ? (inner as Record<string, unknown>).transactions\n : undefined;\n if (!Array.isArray(commands)) return result;\n\n for (const cmd of commands as Record<string, unknown>[]) {\n if (cmd.MoveCall) {\n const mc = cmd.MoveCall as { package: string; module: string; function: string };\n result.moveCallTargets.push(`${mc.package}::${mc.module}::${mc.function}`);\n result.commandTypes.push('MoveCall');\n } else if (cmd.TransferObjects) {\n result.commandTypes.push('TransferObjects');\n }\n }\n } catch { /* best effort */ }\n return result;\n}\n","import { EventEmitter } from 'eventemitter3';\nimport type { SuiGrpcClient } from '@mysten/sui/grpc';\nimport type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction, coinWithBalance, type TransactionObjectArgument } from '@mysten/sui/transactions';\nimport { createPaymentTransactionUri } from '@mysten/payment-kit';\nimport { getSuiClient, getSuiGrpcClient } from './utils/sui.js';\nimport {\n generateKeypair,\n keypairFromPrivateKey,\n saveKey,\n loadKey,\n walletExists,\n exportPrivateKey,\n getAddress,\n} from './wallet/keyManager.js';\nimport type { TransactionSigner } from './signer.js';\nimport { KeypairSigner } from './wallet/keypairSigner.js';\nimport { executeTx } from './wallet/executeTx.js';\nimport { payWithMpp } from './wallet/pay.js';\nimport { ZkLoginSigner, type ZkLoginProof } from './wallet/zkLoginSigner.js';\nimport { buildSendTx } from './wallet/send.js';\nimport { queryBalance } from './wallet/balance.js';\nimport { queryHistory, queryTransaction } from './wallet/history.js';\nimport { resolveSymbol, resolveCoinDecimals } from './token-registry.js';\nimport {\n SUI_ADDRESS_REGEX,\n SuinsNotRegisteredError,\n looksLikeSuiNs,\n resolveSuinsViaRpc,\n} from './utils/suins.js';\n// [B5 v2 / 2026-04-30] No fee imports — CLI / direct SDK is fee-free. Consumer\n// apps (Audric) own fee policy (Cetus `overlayFee` on swaps → T2000_OVERLAY_FEE_WALLET).\nimport type {\n T2000Options,\n BalanceResponse,\n SendResult,\n TransactionRecord,\n DepositInfo,\n PaymentRequest,\n PayOptions,\n PayResult,\n SwapResult,\n SwapQuoteResult,\n} from './types.js';\nimport { T2000Error } from './errors.js';\nimport {\n chatCompletion,\n chatCompletionStream,\n listModels,\n type ApiModel,\n type ChatParams,\n type ChatResult,\n} from './inference.js';\nimport { verifyReceipt, type VerifyOptions, type VerifyResult } from './verify.js';\nimport { SUPPORTED_ASSETS, assertAllowedAsset, type SendableAsset, type SupportedAsset } from './constants.js';\n\nimport { truncateAddress } from './utils/sui.js';\nimport { LimitEnforcer, approxUsdValue } from './limits/index.js';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.t2000');\n\ninterface T2000Events {\n balanceChange: (event: { asset: string; previous: number; current: number; cause: string; tx?: string }) => void;\n healthWarning: (event: { healthFactor: number; threshold: number; severity: 'warning' }) => void;\n healthCritical: (event: { healthFactor: number; threshold: number; severity: 'critical' }) => void;\n yield: (event: { earned: number; total: number; apy: number; timestamp: number }) => void;\n error: (error: T2000Error) => void;\n}\n\n// Sign + execute a transaction with the agent's signer. Replaces the pre-v2 gas\n// manager — every transaction is now self-funded by the agent's wallet.\nexport class T2000 extends EventEmitter<T2000Events> {\n private readonly _signer: TransactionSigner;\n private readonly _keypair?: Ed25519Keypair;\n private readonly client: SuiGrpcClient;\n private readonly _address: string;\n /** Unified spending-limit gate (per-tx + cumulative daily, USD). Shared by\n * CLI + MCP + programmatic writes — one gate, no bypass (R-0 Finding 1). */\n readonly limits: LimitEnforcer;\n\n private constructor(keypair: Ed25519Keypair, client: SuiGrpcClient, configDir?: string);\n private constructor(signer: TransactionSigner, client: SuiGrpcClient, configDir: string | undefined, isSignerMode: true);\n private constructor(\n keypairOrSigner: Ed25519Keypair | TransactionSigner,\n client: SuiGrpcClient,\n configDir?: string,\n isSignerMode?: boolean,\n ) {\n super();\n if (isSignerMode) {\n this._signer = keypairOrSigner as TransactionSigner;\n this._keypair = undefined;\n this._address = this._signer.getAddress();\n } else {\n const kp = keypairOrSigner as Ed25519Keypair;\n this._keypair = kp;\n this._signer = new KeypairSigner(kp);\n this._address = getAddress(kp);\n }\n this.client = client;\n this.limits = new LimitEnforcer(configDir);\n }\n\n static async create(options: T2000Options = {}): Promise<T2000> {\n const { keyPath, rpcUrl } = options;\n\n const client = getSuiClient(rpcUrl);\n\n const exists = await walletExists(keyPath);\n if (!exists) {\n throw new T2000Error(\n 'WALLET_NOT_FOUND',\n 'No wallet found. Run `t2 init` to create one.',\n );\n }\n\n // [v4.0] loadKey reads v2 plain Bech32 JSON. Anything else throws\n // WALLET_CORRUPT. PIN/passphrase fields on T2000Options are accepted\n // for back-compat but IGNORED.\n const keypair = await loadKey(undefined, keyPath);\n return new T2000(keypair, client, DEFAULT_CONFIG_DIR);\n }\n\n static fromPrivateKey(privateKey: string, options: { network?: 'mainnet' | 'testnet'; rpcUrl?: string } = {}): T2000 {\n const keypair = keypairFromPrivateKey(privateKey);\n const client = getSuiClient(options.rpcUrl);\n return new T2000(keypair, client);\n }\n\n static async init(options: { pin?: string; passphrase?: string; keyPath?: string; name?: string } = {}): Promise<{ agent: T2000; address: string }> {\n // [v4.0] pin/passphrase accepted for back-compat but IGNORED.\n const keypair = generateKeypair();\n await saveKey(keypair, undefined, options.keyPath);\n\n const client = getSuiClient();\n const agent = new T2000(keypair, client, DEFAULT_CONFIG_DIR);\n const address = agent.address();\n\n return { agent, address };\n }\n\n // -- Gas --\n\n /** SuiGrpcClient used by this agent — exposed for integrations. */\n get suiClient(): SuiGrpcClient {\n return this.client;\n }\n\n /** Ed25519Keypair used by this agent — exposed for CLI/MCP integrations. */\n get keypair(): Ed25519Keypair {\n if (!this._keypair) {\n throw new T2000Error('WALLET_NOT_FOUND', 'Keypair not available — this instance uses zkLogin');\n }\n return this._keypair;\n }\n\n /** Transaction signer (works for both keypair and zkLogin). */\n get signer(): TransactionSigner {\n return this._signer;\n }\n\n // -- MPP Payments --\n\n async pay(options: PayOptions): Promise<PayResult> {\n // Gate on the maxPrice ceiling pre-flight (USD); record the ACTUAL cost\n // post-settle. `force` bypasses (caller owns consent).\n this.limits.assert({ operation: 'pay', amountUsd: options.maxPrice ?? 0, force: options.force });\n\n // Canonical gasless MPP pay loop lives in `wallet/pay.ts` (browser-safe,\n // shared with the Audric client's unified gasless write path). T2000\n // owns only the limit book-ends; the server budget ledger is the cap on\n // the browser side, so the browser caller skips the SDK limit gate.\n const result = await payWithMpp({ signer: this._signer, client: this.client, options });\n\n if (result.paid) {\n this.limits.record(result.cost ?? options.maxPrice ?? 0);\n }\n\n return result;\n }\n\n // [S.323 / 2026-05-25] VOLO vSUI staking surfaces removed (full cut).\n // Engine cut Volo in S.277; SDK + CLI + MCP followed in S.323 because the\n // product surface (five products: Passport / Intelligence / Finance / Pay\n // / Store) doesn't include a staking primitive. vSUI still appears in the\n // codebase as a passive token (NAVI reward rewards, Cetus swap routing),\n // but there is no longer any way to MINT or REDEEM vSUI through t2000.\n // History: see spec/archive/v07e/AUDIT_V07E_EARNS_ITS_KEEP_2026-05-23.md\n // and the S.323 build-tracker entry.\n\n // -- Private Inference API (SPEC_AUDRIC_API, S.575) --\n //\n // Inference as a wallet verb — the agent's brain + wallet in one package.\n // Key-based today (`apiKey` / `T2000_API_KEY`); the x402 no-key pay-per-call\n // path is a later add. The model runs on t2000 Private Inference (ZDR; a\n // `phala/*` confidential tier runs in a GPU-TEE).\n\n /** Non-streaming chat completion against Private Inference. */\n async chat(params: ChatParams): Promise<ChatResult> {\n return chatCompletion(params);\n }\n\n /** Streaming chat completion — async-iterate the assistant text deltas;\n * the generator returns `{ receiptId }` (confidential attestation) at the end. */\n chatStream(\n params: ChatParams\n ): AsyncGenerator<string, { receiptId?: string }, unknown> {\n return chatCompletionStream(params);\n }\n\n /** The Private Inference model catalog (`GET /v1/models`). */\n async models(opts?: { apiKey?: string; apiBase?: string }): Promise<ApiModel[]> {\n return listModels(opts);\n }\n\n /** Verify a confidential response by receipt id — checks the signed receipt\n * + its trustless on-chain Sui anchor. Fails closed on any mismatch. */\n async verify(receiptId: string, opts?: VerifyOptions): Promise<VerifyResult> {\n return verifyReceipt(receiptId, opts);\n }\n\n // -- Swap --\n\n async swap(params: {\n from: string;\n to: string;\n amount: number;\n byAmountIn?: boolean;\n slippage?: number;\n force?: boolean;\n }): Promise<SwapResult> {\n // Gate on the input-side USD value (stables 1:1; SUI/other → ungated).\n this.limits.assert({\n operation: 'swap',\n amountUsd: approxUsdValue(params.from, params.amount) ?? 0,\n force: params.force,\n });\n\n const { findSwapRoute, buildSwapTx, resolveTokenType, preflightSwap } = await import('./protocols/cetus-swap.js');\n\n // Layer 2 — cheap synchronous preflight (from/to/amount sanity, identity\n // swap). Runs before any route-finding network call.\n const pf = preflightSwap({ from: params.from, to: params.to, amount: params.amount });\n if (!pf.valid) throw new T2000Error(pf.code, pf.error);\n\n const fromType = resolveTokenType(params.from);\n const toType = resolveTokenType(params.to);\n if (!fromType) throw new T2000Error('ASSET_NOT_SUPPORTED', `Unknown token: ${params.from}. Provide the full coin type.`);\n if (!toType) throw new T2000Error('ASSET_NOT_SUPPORTED', `Unknown token: ${params.to}. Provide the full coin type.`);\n\n const byAmountIn = params.byAmountIn ?? true;\n const slippage = Math.min(params.slippage ?? 0.01, 0.05);\n\n const fromDecimals = await resolveCoinDecimals(this.client, fromType);\n const rawAmount = BigInt(Math.floor(params.amount * 10 ** fromDecimals));\n\n const route = await findSwapRoute({\n walletAddress: this._address,\n from: fromType,\n to: toType,\n amount: rawAmount,\n byAmountIn,\n });\n\n if (!route) throw new T2000Error('SWAP_NO_ROUTE', `No swap route found for ${params.from} -> ${params.to}.`);\n if (route.insufficientLiquidity) throw new T2000Error('SWAP_NO_ROUTE', `Insufficient liquidity for ${params.from} -> ${params.to}.`);\n if (route.priceImpact > 0.05) {\n console.warn(`[swap] High price impact: ${(route.priceImpact * 100).toFixed(2)}%`);\n }\n\n const toDecimals = await resolveCoinDecimals(this.client, toType);\n\n // Snapshot pre-swap balance for fallback diff calculation\n let preBalRaw = 0n;\n try {\n const preBal = await this.client.core.getBalance({ owner: this._address, coinType: toType });\n preBalRaw = BigInt(preBal.balance.balance);\n } catch { /* first time holding this token — balance is 0 */ }\n\n const gasResult = await executeTx(this.client, this._signer, async () => {\n const tx = new Transaction();\n tx.setSender(this._address);\n\n let inputCoin: TransactionObjectArgument;\n if (fromType === '0x2::sui::SUI') {\n [inputCoin] = tx.splitCoins(tx.gas, [rawAmount]);\n } else {\n const bal = await this.client.core.getBalance({ owner: this._address, coinType: fromType });\n if (BigInt(bal.balance.balance) < rawAmount) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${params.from} balance.`, {\n available: Number(bal.balance.balance) / 10 ** fromDecimals,\n required: params.amount,\n });\n }\n inputCoin = coinWithBalance({ type: fromType, balance: rawAmount })(tx);\n }\n\n const outputCoin = await buildSwapTx({\n walletAddress: this._address,\n route,\n tx,\n inputCoin,\n slippage,\n });\n\n tx.transferObjects([outputCoin], this._address);\n return tx;\n });\n\n const fromAmount = Number(route.amountIn) / 10 ** fromDecimals;\n let toAmount = Number(route.amountOut) / 10 ** toDecimals;\n\n // --- Primary: parse balance changes from the finalized transaction ---\n const toTypeSuffix = toType.split('::').slice(1).join('::');\n try {\n // [gRPC migration] core.waitForTransaction returns a discriminated union;\n // balanceChanges are `{ coinType, address, amount }` (signed string),\n // not the legacy `{ owner: { AddressOwner } }` shape.\n const fullTx = await this.client.core.waitForTransaction({\n digest: gasResult.digest,\n include: { balanceChanges: true },\n timeout: 8_000,\n });\n const txn = fullTx.$kind === 'Transaction' ? fullTx.Transaction : fullTx.FailedTransaction;\n const changes = txn.balanceChanges ?? [];\n const received = changes.find((c) => {\n if (BigInt(c.amount) <= 0n) return false;\n if (!c.address || c.address.toLowerCase() !== this._address.toLowerCase()) return false;\n if (c.coinType === toType) return true;\n return c.coinType.endsWith(toTypeSuffix);\n });\n if (received) {\n const actual = Number(BigInt(received.amount)) / 10 ** toDecimals;\n if (actual > 0) toAmount = actual;\n }\n } catch {\n // waitForTransaction timeout — fall through to balance diff\n }\n\n // --- Fallback: pre/post getBalance diff ---\n const cetusEstimate = Number(route.amountOut) / 10 ** toDecimals;\n if (Math.abs(toAmount - cetusEstimate) < 0.001) {\n try {\n await new Promise((r) => setTimeout(r, 2000));\n const postBal = await this.client.core.getBalance({ owner: this._address, coinType: toType });\n const postRaw = BigInt(postBal.balance.balance);\n const delta = Number(postRaw - preBalRaw) / 10 ** toDecimals;\n if (delta > 0) toAmount = delta;\n } catch {\n // Balance diff fallback failed — use Cetus estimate\n }\n }\n\n // Resolve full coin types to user-friendly token names\n const fromName = resolveSymbol(fromType);\n const toName = resolveSymbol(toType);\n\n const routeDesc = route.routerData.paths\n ?.map((p) => p.provider)\n .filter(Boolean)\n .slice(0, 3)\n .join(' + ') ?? 'Cetus Aggregator';\n\n // Record the settled input-side USD against the cumulative daily total.\n this.limits.record(approxUsdValue(params.from, params.amount) ?? 0);\n\n return {\n success: true,\n tx: gasResult.digest,\n fromToken: fromName,\n toToken: toName,\n fromAmount,\n toAmount,\n priceImpact: route.priceImpact,\n route: routeDesc,\n gasCost: gasResult.gasCostSui,\n };\n }\n\n /**\n * [SPEC_AGENTIC_STACK P1 / SDK F2 — 2026-05-25]\n * Thin wrapper around the standalone `getSwapQuote()`. Pre-Phase 1 this method\n * was ~50 LoC duplicating `swap-quote.ts` — missing `serializedRoute` (SPEC 20.2\n * fast-path) and the `providers` allow-list (Bug A fix / Pyth-dependent\n * provider filter for sponsored callers). Routing both API surfaces through\n * one implementation ensures fixes land for both.\n */\n async swapQuote(params: {\n from: string;\n to: string;\n amount: number;\n byAmountIn?: boolean;\n providers?: string[];\n }): Promise<SwapQuoteResult> {\n const { getSwapQuote } = await import('./swap-quote.js');\n const { resolveTokenType } = await import('./protocols/cetus-swap.js');\n // [2.11] Resolve decimals on-chain for non-registry coin types so the quote\n // matches what a real swap would compute (the standalone getSwapQuote can't\n // — it has no client). Falls back to its registry default if unresolved.\n const fromType = resolveTokenType(params.from);\n const toType = resolveTokenType(params.to);\n return getSwapQuote({\n walletAddress: this._address,\n from: params.from,\n to: params.to,\n amount: params.amount,\n byAmountIn: params.byAmountIn,\n providers: params.providers,\n fromDecimals: fromType ? await resolveCoinDecimals(this.client, fromType) : undefined,\n toDecimals: toType ? await resolveCoinDecimals(this.client, toType) : undefined,\n });\n }\n\n // -- Wallet --\n\n address(): string {\n return this._address;\n }\n\n /**\n * Send `amount` of `asset` to `to` (hex address or SuiNS name).\n *\n * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]\n *\n * **Breaking changes from v3.x:**\n * - `asset` is now REQUIRED (no implicit `?? 'USDC'` default). Callers\n * must specify `'USDC' | 'USDsui' | 'SUI'`. Sending `'USDT'` /\n * `'USDe'` / `'WAL'` / `'ETH'` / `'NAVX'` / `'GOLD'` now errors\n * with `INVALID_ASSET` — swap to a stable first.\n * - USDC + USDsui builds go through `SuiGrpcClient` so the gRPC build\n * resolver auto-detects `0x2::balance::send_funds` eligibility and\n * zeros gas at simulate time. Result: **gasless USDC / USDsui sends\n * from a zero-SUI wallet.** SUI sends stay on the standard gas-paid\n * path.\n *\n * Submission stays on the JSON-RPC client (the rest of the SDK\n * expects JSON-RPC for read paths, and Sui's docs explicitly support\n * the \"build via gRPC, execute via JSON-RPC\" hybrid).\n */\n async send(params: { to: string; amount: number; asset: SupportedAsset; force?: boolean }): Promise<SendResult> {\n // [v4.0 Phase A Day 2] Asset is REQUIRED at runtime (no more silent\n // USDC default). The parameter type is `SupportedAsset` (the wider\n // SDK surface) rather than `SendableAsset` so callers that still\n // hand a wide-typed asset through — primarily the engine LLM tool\n // surface — compile without modification. Runtime narrowing happens\n // via `assertAllowedAsset('send', asset)`, which throws\n // `INVALID_ASSET` for anything outside `['USDC', 'USDsui', 'SUI']`.\n // This matches the SPEC verification gate `asset: 'USDY'` →\n // `INVALID_ASSET` (runtime check, not compile check).\n const asset = params.asset;\n if (!asset) {\n throw new T2000Error(\n 'INVALID_ASSET',\n \"send() requires an explicit asset. Use one of: USDC, USDsui, SUI.\",\n );\n }\n assertAllowedAsset('send', asset);\n // `assertAllowedAsset('send', asset)` narrows the runtime value to\n // one of `SendableAsset` (USDC / USDsui / SUI). Cast statically.\n const sendableAsset = asset as SendableAsset;\n\n // Spending-limit gate (USD; stables 1:1, SUI ungated). `force` bypasses.\n this.limits.assert({\n operation: 'send',\n amountUsd: approxUsdValue(sendableAsset, params.amount) ?? 0,\n force: params.force,\n });\n\n const resolved = await this.resolveRecipient(params.to);\n const sendAmount = params.amount;\n const sendTo = resolved.address;\n\n // Gasless-eligible stables (USDC / USDsui) build via the dedicated gRPC\n // client so the resolver can zero gas at simulate. SUI is not on the\n // `balance::send_funds` allowlist, so it builds via the default client\n // (also gRPC post-cutover) with normal gas — no separate build client.\n const useGrpc = sendableAsset === 'USDC' || sendableAsset === 'USDsui';\n const buildClient = useGrpc ? getSuiGrpcClient() : undefined;\n\n const gasResult = await executeTx(\n this.client,\n this._signer,\n () => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset: sendableAsset }),\n { buildClient },\n );\n\n this.limits.record(approxUsdValue(sendableAsset, sendAmount) ?? 0);\n const balance = await this.balance();\n\n this.emitBalanceChange(sendableAsset, sendAmount, 'send', gasResult.digest);\n\n return {\n success: true,\n tx: gasResult.digest,\n amount: sendAmount,\n to: resolved.address,\n suinsName: resolved.suinsName,\n gasCost: gasResult.gasCostSui,\n gasCostUnit: 'SUI',\n balance,\n };\n }\n\n /**\n * Resolve a recipient string into a canonical 0x address:\n * 1. **hex** — `0x…` is used directly (no RPC round-trip).\n * 2. **SuiNS** — `alex.sui` resolves via `suix_resolveNameServiceAddress`.\n *\n * Anything else is rejected. (The legacy `contacts.json` alias map was\n * removed — SuiNS supersedes local contacts.)\n *\n * Returns `{ address, suinsName? }` so `send()` can stamp the name source\n * on the receipt without re-resolving. Throws\n * `T2000Error('SUINS_NOT_REGISTERED', …)` for well-formed but unregistered\n * SuiNS names, keeping the SDK error surface `T2000Error`-only.\n *\n * Public so MCP's `t2000_send` dryRun preview shares one resolution path\n * with the live execute path (never resolve the same input two ways).\n */\n async resolveRecipient(\n input: string,\n ): Promise<{ address: string; suinsName?: string }> {\n const trimmed = input.trim();\n if (SUI_ADDRESS_REGEX.test(trimmed)) {\n return { address: trimmed.toLowerCase() };\n }\n if (looksLikeSuiNs(trimmed)) {\n try {\n const name = trimmed.toLowerCase();\n const address = await resolveSuinsViaRpc(name);\n if (!address) {\n throw new SuinsNotRegisteredError(name);\n }\n return { address: address.toLowerCase(), suinsName: name };\n } catch (err) {\n if (err instanceof SuinsNotRegisteredError) {\n throw new T2000Error(\n 'SUINS_NOT_REGISTERED',\n err.message,\n );\n }\n throw err;\n }\n }\n throw new T2000Error(\n 'INVALID_ADDRESS',\n `Cannot resolve recipient \"${input}\". Provide a 0x address or a .sui name.`,\n );\n }\n\n async balance(): Promise<BalanceResponse> {\n // [NAVI removed] Wallet-only balance: spendable stables + SUI gas reserve.\n return queryBalance(this.client, this._address);\n }\n\n async history(params?: { limit?: number }): Promise<TransactionRecord[]> {\n return queryHistory(this._address, params?.limit);\n }\n\n async transactionDetail(digest: string): Promise<TransactionRecord | null> {\n return queryTransaction(digest, this._address);\n }\n\n async deposit(): Promise<DepositInfo> {\n return {\n address: this._address,\n network: 'mainnet',\n supportedAssets: ['USDC', 'USDT', 'SUI'],\n instructions: [\n `Send USDC to: ${this._address}`,\n `Network: Sui Mainnet`,\n `Or buy USDC on an exchange and withdraw to this address.`,\n `USDC contract: ${SUPPORTED_ASSETS.USDC.type}`,\n ].join('\\n'),\n };\n }\n\n /**\n * [SPEC_AGENTIC_STACK P1 / SDK F2 — 2026-05-25; refreshed S.342 / 2026-05-26]\n * Preferred alias of `deposit()`. Was introduced to mirror the v3 `t2000 fund`\n * CLI command; the v4 CLI surface is `t2 fund` (renamed back from the\n * interim `t2 receive` in S.464). `deposit()` stays as the canonical method name for\n * back-compat; `fund()` stays as a programmatic alias for audric + other\n * SDK consumers that prefer the verb.\n */\n async fund(): Promise<DepositInfo> {\n return this.deposit();\n }\n\n receive(params?: { amount?: number; currency?: string; memo?: string; label?: string }): PaymentRequest {\n const amount = params?.amount ?? null;\n const currency = params?.currency ?? 'USDC';\n const memo = params?.memo ?? null;\n const label = params?.label ?? null;\n const nonce = crypto.randomUUID();\n\n let qrUri: string;\n if (amount != null && amount > 0) {\n const decimals = currency === 'SUI' ? 9 : 6;\n const coinType = currency === 'SUI'\n ? '0x2::sui::SUI'\n : SUPPORTED_ASSETS.USDC.type;\n const rawAmount = BigInt(Math.floor(amount * 10 ** decimals));\n qrUri = createPaymentTransactionUri({\n receiverAddress: this._address,\n amount: rawAmount,\n coinType,\n nonce,\n ...(label ? { label } : {}),\n ...(memo ? { message: memo } : {}),\n });\n } else {\n const qrParts = [`sui:${this._address}`];\n const queryParams: string[] = [];\n if (currency !== 'SUI') queryParams.push(`currency=${currency}`);\n if (memo) queryParams.push(`memo=${encodeURIComponent(memo)}`);\n if (label) queryParams.push(`label=${encodeURIComponent(label)}`);\n qrUri = queryParams.length > 0 ? `${qrParts[0]}?${queryParams.join('&')}` : qrParts[0];\n }\n\n const amountStr = amount != null ? `$${amount.toFixed(2)} ` : '';\n const displayParts = [`Send ${amountStr}${currency} to ${truncateAddress(this._address)}`];\n if (memo) displayParts.push(`Memo: ${memo}`);\n\n return {\n address: this._address,\n network: 'mainnet',\n amount,\n currency,\n memo,\n label,\n nonce,\n qrUri,\n displayText: displayParts.join('\\n'),\n };\n }\n\n exportKey(): string {\n return exportPrivateKey(this.keypair);\n }\n\n static fromZkLogin(opts: {\n ephemeralKeypair: Ed25519Keypair;\n zkProof: ZkLoginProof;\n userAddress: string;\n maxEpoch: number;\n rpcUrl?: string;\n }): T2000 {\n const signer = new ZkLoginSigner(opts.ephemeralKeypair, opts.zkProof, opts.userAddress, opts.maxEpoch);\n const client = getSuiClient(opts.rpcUrl);\n return new T2000(signer, client, undefined, true);\n }\n\n private emitBalanceChange(asset: string, amount: number, cause: string, tx?: string): void {\n this.emit('balanceChange', { asset, previous: 0, current: 0, cause, tx });\n }\n}\n\n","// ---------------------------------------------------------------------------\n// Sui address + SuiNS normalization — single source of truth.\n//\n// [S.279 / CLI-CONTACTS-CLEANUP — 2026-05-23] Promoted from the deleted\n// `@t2000/engine` package to the SDK so the CLI's `T2000.send()` can accept\n// SuiNS names (`alex.sui`) alongside hex addresses — one canonical resolver.\n//\n// Background. Host read tools accept an optional `address` parameter so the\n// LLM can inspect any public Sui wallet. Each calls `normalizeAddressInput()`\n// to accept either `0x...` or `alex.sui` and returns a structured\n// `{ address, suinsName, raw }` triple. The SDK's `T2000.send()` uses the\n// same primitive, so a CLI user can run\n// `t2000 send alex.sui 10 USDC` without looking up the hex address first.\n//\n// Single source of truth — see `.cursor/rules/single-source-of-truth.mdc`\n// and `.cursor/rules/engineering-principles.mdc` Principle 2.\n// ---------------------------------------------------------------------------\n\nimport { getSuiGraphQLClient } from './sui.js';\n\n// [gRPC migration] SuiNS resolution moved off JSON-RPC\n// (`suix_resolveNameServiceAddress` / `suix_resolveNameServiceNames`) onto the\n// Sui GraphQL endpoint — the last JSON-RPC caller in the SDK. Both directions\n// use the unified `address(...)` query: `address(name:)` for forward\n// (name → address) and `address(address:){ defaultNameRecord { domain } }` for\n// reverse (address → primary name).\nconst RESOLVE_NAME_QUERY = `query ResolveSuins($name: String!) {\n address(name: $name) { address }\n}`;\n\nconst REVERSE_NAME_QUERY = `query ReverseSuins($address: SuiAddress!) {\n address(address: $address) { defaultNameRecord { domain } }\n}`;\n\ninterface GqlResult<T> {\n data?: T;\n errors?: Array<{ message?: string }>;\n}\n\n/**\n * Canonical 0x-address shape. Loose lower bound (>= 1 hex char) so\n * pre-v1.0 short addresses still validate; tools that need a full 64-hex\n * address can additionally check `length === 66`. Case-insensitive on\n * the `0x` prefix because some upstream callers (and historic tests)\n * uppercase the prefix as part of address normalization tests; the\n * normalizer always returns the lowercased canonical form regardless.\n */\nexport const SUI_ADDRESS_REGEX = /^0x[a-fA-F0-9]{1,64}$/i;\n\n/**\n * Strict canonical 0x-address shape (66 chars total). Used by the\n * resolver's \"looks like\" check to disambiguate \"user pasted an\n * address\" vs \"user typed a SuiNS name\".\n */\nexport const SUI_ADDRESS_STRICT_REGEX = /^0x[a-fA-F0-9]{64}$/i;\n\n/**\n * Mirrors the pattern in `audric/apps/web-v2/lib/suins-cache.ts` so the\n * host-side send executor and the engine-side read normalizer agree on\n * what counts as a SuiNS name. SuiNS allows nested labels (`team.alex.sui`)\n * but every label must use only `[a-z0-9-]`.\n */\nexport const SUINS_NAME_REGEX = /^[a-z0-9-]+(\\.[a-z0-9-]+)*\\.sui$/;\n\nexport class InvalidAddressError extends Error {\n constructor(public readonly raw: string) {\n super(\n `\"${raw}\" isn't a valid Sui address or SuiNS name. ` +\n `Pass a 0x-prefixed hex address (e.g. 0x40cd…3e62) or a SuiNS name ending in .sui (e.g. alex.sui).`,\n );\n this.name = 'InvalidAddressError';\n }\n}\n\nexport class SuinsNotRegisteredError extends Error {\n constructor(public readonly name_: string) {\n super(\n `\"${name_}\" isn't a registered SuiNS name. Double-check the spelling, ` +\n `or paste the full Sui address (0x… 64 hex characters).`,\n );\n this.name = 'SuinsNotRegisteredError';\n }\n}\n\nexport class SuinsRpcError extends Error {\n constructor(public readonly name_: string, detail: string) {\n super(`SuiNS lookup failed for \"${name_}\" (${detail}). Try again, or paste the full Sui address.`);\n this.name = 'SuinsRpcError';\n }\n}\n\n/**\n * Returns true if `value` looks like a SuiNS name (case-insensitive).\n * Cheap synchronous check — use to avoid an unnecessary RPC round-trip\n * for inputs that obviously aren't names (0x addresses, contact handles).\n */\nexport function looksLikeSuiNs(value: string): boolean {\n if (!value) return false;\n return SUINS_NAME_REGEX.test(value.trim().toLowerCase());\n}\n\n/**\n * Resolve a SuiNS name to its on-chain Sui address via the Sui GraphQL\n * `address(name:)` query. Returns `null` if the name resolves to no address\n * (= not registered or expired). Throws `SuinsRpcError` on transport failure.\n *\n * `ctx.signal` is honored for cancellation. (`ctx.suiRpcUrl` is retained for\n * call-site back-compat but no longer used — resolution runs against the\n * canonical GraphQL endpoint via `getSuiGraphQLClient()`.)\n */\nexport async function resolveSuinsViaRpc(\n rawName: string,\n ctx: { suiRpcUrl?: string; signal?: AbortSignal } = {},\n): Promise<string | null> {\n const name = rawName.trim().toLowerCase();\n if (!SUINS_NAME_REGEX.test(name)) {\n throw new InvalidAddressError(rawName);\n }\n\n const gql = getSuiGraphQLClient();\n let res: GqlResult<{ address?: { address?: string } | null }>;\n try {\n res = (await gql.query({\n query: RESOLVE_NAME_QUERY,\n variables: { name },\n signal: ctx.signal,\n })) as typeof res;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new SuinsRpcError(name, msg);\n }\n\n if (res.errors?.length) {\n throw new SuinsRpcError(name, res.errors.map((e) => e.message ?? 'unknown error').join('; '));\n }\n\n // `address(name:)` returns the Address the name points to, or null when the\n // name has never been registered (or has expired and the record was reaped).\n return res.data?.address?.address ?? null;\n}\n\n/**\n * Reverse-resolve a 0x address to its SuiNS name via the Sui GraphQL\n * `address(address:){ defaultNameRecord { domain } }` query. Returns a\n * single-element array with the address's **default (primary)** name, or\n * `[]` when it has none. Throws `SuinsRpcError` on transport failure.\n *\n * Behavior note: the legacy JSON-RPC path returned *all* names for the\n * address; GraphQL exposes the explicitly-configured default record, which is\n * the one every consumer here actually uses (the LLM `resolve_suins` tool +\n * card titles only ever render the primary). Returning `[primary]` keeps the\n * `string[]` contract intact.\n *\n * Why this is its own helper (not folded into `normalizeAddressInput`): a\n * reverse lookup adds a second round-trip per tool call. We don't want every\n * read tool that takes an `address` to silently double its latency. The lookup\n * primitive is opt-in via the `resolve_suins` tool; normalizers stay\n * forward-only.\n */\nexport async function resolveAddressToSuinsViaRpc(\n rawAddress: string,\n ctx: { suiRpcUrl?: string; signal?: AbortSignal } = {},\n): Promise<string[]> {\n const address = rawAddress.trim().toLowerCase();\n if (!SUI_ADDRESS_REGEX.test(address)) {\n throw new InvalidAddressError(rawAddress);\n }\n\n const gql = getSuiGraphQLClient();\n let res: GqlResult<{ address?: { defaultNameRecord?: { domain?: string } | null } | null }>;\n try {\n res = (await gql.query({\n query: REVERSE_NAME_QUERY,\n variables: { address },\n signal: ctx.signal,\n })) as typeof res;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new SuinsRpcError(address, msg);\n }\n\n if (res.errors?.length) {\n throw new SuinsRpcError(address, res.errors.map((e) => e.message ?? 'unknown error').join('; '));\n }\n\n const domain = res.data?.address?.defaultNameRecord?.domain;\n return domain ? [domain] : [];\n}\n\nexport interface NormalizedAddress {\n /**\n * Canonical 0x-prefixed lowercase hex address. Always set on success.\n * Tools should use this for any downstream query (BlockVision, NAVI,\n * positionFetcher, etc.) and for cache keys.\n */\n address: string;\n /**\n * The user-facing name when the input was resolved via SuiNS, otherwise\n * `null`. Tools should stamp this on result data so card titles can\n * render \"Balance · obehi.sui\" instead of \"Balance · 0x1234…abcd\".\n */\n suinsName: string | null;\n /**\n * The original input (pre-normalization). Useful for error narration —\n * \"I tried to resolve `Obehi.Sui` and …\" reads better than the\n * post-trim/lowercase form.\n */\n raw: string;\n}\n\n/**\n * Canonical normalizer. Accepts a 0x address OR a SuiNS name; returns\n * a structured `NormalizedAddress`. Throws:\n * - `InvalidAddressError` if the input matches neither shape.\n * - `SuinsNotRegisteredError` if the SuiNS name is well-formed but\n * resolves to null (= not registered).\n * - `SuinsRpcError` if the RPC fails.\n *\n * Every read tool (engine) and write helper (SDK `T2000.send()`) that\n * accepts a user-supplied recipient MUST call this helper before any\n * downstream lookup. Doing the check inline (1) duplicates the regex,\n * (2) silently rejects SuiNS names, (3) makes cache keys inconsistent\n * across tools.\n */\nexport async function normalizeAddressInput(\n value: string,\n ctx: { suiRpcUrl?: string; signal?: AbortSignal } = {},\n): Promise<NormalizedAddress> {\n const trimmed = value.trim();\n if (SUI_ADDRESS_REGEX.test(trimmed)) {\n return { address: trimmed.toLowerCase(), suinsName: null, raw: value };\n }\n if (looksLikeSuiNs(trimmed)) {\n const name = trimmed.toLowerCase();\n const address = await resolveSuinsViaRpc(name, ctx);\n if (!address) {\n throw new SuinsNotRegisteredError(name);\n }\n return { address: address.toLowerCase(), suinsName: name, raw: value };\n }\n throw new InvalidAddressError(value);\n}\n","import { T2000Error } from './errors.js';\n\n// Private Inference API client (SPEC_AUDRIC_API — agent-native layer, S.575).\n// Key-based access to t2000 Private Inference (OpenAI-compatible) at\n// `api.t2000.ai/v1`. The x402 pay-per-call (no-key) path is a later add; this\n// is the key-based distribution surface used by `t2 chat` + the MCP `t2000_chat`\n// tool. Browser-safe (fetch + ReadableStream only — no wallet/Node deps).\n\nexport const DEFAULT_API_BASE = 'https://api.t2000.ai/v1';\n\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface ChatParams {\n model: string;\n messages: ChatMessage[];\n /** Private Inference key (`sk-…`). Falls back to `T2000_API_KEY` env. */\n apiKey?: string;\n /** Override the API base (default `api.t2000.ai/v1`; e.g. for testing). */\n apiBase?: string;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface ChatUsage {\n promptTokens?: number;\n completionTokens?: number;\n totalTokens?: number;\n}\n\nexport interface ChatResult {\n content: string;\n model: string;\n usage?: ChatUsage;\n /** Confidential calls (`phala/*`) return a TEE attestation receipt id —\n * fetch + verify it at `/v1/aci/receipts/{id}`. Absent for ZDR models. */\n receiptId?: string;\n /** The verbatim OpenAI-shaped response body. */\n raw: unknown;\n}\n\nexport interface ApiModel {\n id: string;\n contextWindow?: number;\n inputPer1M?: number;\n outputPer1M?: number;\n /** Privacy tier surfaced by the API (e.g. `zdr`, `confidential`). */\n privacy?: string;\n /** True for reasoning models — deeper but slower (a hidden reasoning trace\n * before the answer). Surfaced so callers pick the speed/depth tradeoff. */\n reasoning?: boolean;\n}\n\nfunction envApiKey(): string | undefined {\n return typeof process !== 'undefined' ? process.env?.T2000_API_KEY : undefined;\n}\n\nfunction resolveApiKey(apiKey?: string): string {\n const key = apiKey ?? envApiKey();\n if (!key) {\n throw new T2000Error(\n 'INVALID_KEY',\n 'No Private Inference key. Pass `apiKey` or set T2000_API_KEY. Generate one at agents.t2000.ai/manage.',\n );\n }\n return key;\n}\n\nasync function failBody(res: Response): Promise<never> {\n const text = await res.text().catch(() => '');\n let msg = text.slice(0, 300);\n try {\n const j = JSON.parse(text) as { error?: { message?: string } | string };\n msg =\n (typeof j.error === 'object' ? j.error?.message : j.error) ?? msg;\n } catch {\n // keep the raw text\n }\n throw new T2000Error(\n 'INFERENCE_FAILED',\n `Inference request failed (${res.status}): ${msg}`,\n { status: res.status },\n res.status >= 500,\n );\n}\n\nfunction usageOf(raw: unknown): ChatUsage | undefined {\n const u = (raw as { usage?: Record<string, number> })?.usage;\n if (!u) {\n return;\n }\n return {\n promptTokens: u.prompt_tokens,\n completionTokens: u.completion_tokens,\n totalTokens: u.total_tokens,\n };\n}\n\nfunction body(params: ChatParams, stream: boolean): string {\n return JSON.stringify({\n model: params.model,\n messages: params.messages,\n // include_usage → the final stream chunk carries usage + x_receipt_id\n // (the confidential attestation receipt) so we can surface it after a stream.\n ...(stream ? { stream: true, stream_options: { include_usage: true } } : {}),\n ...(params.maxTokens != null ? { max_tokens: params.maxTokens } : {}),\n ...(params.temperature != null ? { temperature: params.temperature } : {}),\n });\n}\n\n/** Non-streaming chat completion. Returns the assistant text + usage + the\n * verbatim OpenAI response body. */\nexport async function chatCompletion(params: ChatParams): Promise<ChatResult> {\n const key = resolveApiKey(params.apiKey);\n const base = params.apiBase ?? DEFAULT_API_BASE;\n const res = await fetch(`${base}/chat/completions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${key}` },\n body: body(params, false),\n });\n if (!res.ok) {\n await failBody(res);\n }\n const receiptId = res.headers.get('x-receipt-id') ?? undefined;\n const raw = await res.json();\n const content =\n (raw as { choices?: { message?: { content?: string } }[] })?.choices?.[0]\n ?.message?.content ?? '';\n return {\n content,\n model: (raw as { model?: string })?.model ?? params.model,\n usage: usageOf(raw),\n receiptId,\n raw,\n };\n}\n\n/** Streaming chat completion — yields assistant text deltas as they arrive\n * (parses the OpenAI SSE `data:` frames). */\nexport async function* chatCompletionStream(\n params: ChatParams,\n): AsyncGenerator<string, { receiptId?: string }, unknown> {\n const key = resolveApiKey(params.apiKey);\n const base = params.apiBase ?? DEFAULT_API_BASE;\n const res = await fetch(`${base}/chat/completions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${key}` },\n body: body(params, true),\n });\n if (!(res.ok && res.body)) {\n await failBody(res);\n return {};\n }\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let receiptId: string | undefined;\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith('data:')) {\n continue;\n }\n const data = trimmed.slice(5).trim();\n if (data === '[DONE]') {\n return { receiptId };\n }\n try {\n const json = JSON.parse(data) as {\n choices?: { delta?: { content?: string } }[];\n x_receipt_id?: string;\n };\n // The confidential TEE receipt rides the final usage chunk.\n if (json.x_receipt_id) {\n receiptId = json.x_receipt_id;\n }\n const delta = json.choices?.[0]?.delta?.content;\n if (typeof delta === 'string' && delta) {\n yield delta;\n }\n } catch {\n // keep-alive or partial frame — ignore\n }\n }\n }\n return { receiptId };\n}\n\n/** List Private Inference model catalog (`GET /v1/models`). The key is sent when\n * available but not required (the catalog may be public). */\nexport async function listModels(opts?: {\n apiKey?: string;\n apiBase?: string;\n}): Promise<ApiModel[]> {\n const base = opts?.apiBase ?? DEFAULT_API_BASE;\n const key = opts?.apiKey ?? envApiKey();\n const res = await fetch(`${base}/models`, {\n headers: key ? { authorization: `Bearer ${key}` } : {},\n });\n if (!res.ok) {\n await failBody(res);\n }\n const json = (await res.json()) as {\n data?: {\n id: string;\n context_window?: number;\n context_length?: number;\n privacy?: string;\n privacy_tier?: string;\n reasoning?: boolean;\n pricing?: {\n input_per_1m?: number;\n output_per_1m?: number;\n prompt?: number;\n completion?: number;\n };\n }[];\n };\n const data = Array.isArray(json.data) ? json.data : [];\n return data.map((m) => ({\n id: m.id,\n contextWindow: m.context_window ?? m.context_length,\n inputPer1M: m.pricing?.input_per_1m ?? m.pricing?.prompt,\n outputPer1M: m.pricing?.output_per_1m ?? m.pricing?.completion,\n privacy: m.privacy ?? m.privacy_tier,\n reasoning: m.reasoning,\n }));\n}\n","import { SuiGrpcClient } from '@mysten/sui/grpc';\nimport { ed25519 } from '@noble/curves/ed25519';\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex, hexToBytes } from '@noble/hashes/utils';\nimport { DEFAULT_API_BASE } from './inference.js';\n\n// Confidential receipt verifier (SPEC_CONFIDENTIAL_API v3.0, Phase D).\n//\n// Lets anyone CHECK — not just trust — a t2000 confidential response, by\n// receipt id. The Sui-anchor check is FULLY TRUSTLESS: it reads the on-chain\n// `ReceiptAnchored` event straight from a public Sui fullnode and confirms the\n// committed `wire_hash` + `workload_id` match the signed receipt — t2000 can't\n// forge that (a wrong/missing anchor → fails closed). The confidential-upstream\n// check reads the attestation evidence embedded in the signed receipt\n// (`upstream.verified`).\n//\n// All three core checks are trustless client-side: the Sui anchor (read from a\n// fullnode), the receipt signature (recompute dstack ACI canonical bytes per\n// `canonical.rs` + verify against the attested key — ed25519 current,\n// secp256k1-recover legacy), and the TDX quote\n// (@phala/dcap-qvl chains to Intel's root — removing the server-side-DCAP SPOF).\n// The remaining hop is keyset_endorsement (tying the receipt key to the quote's\n// identity key); the receipt-sig check already proves the receipt is signed by\n// the published keyset key. Per the spec: a wrong \"verifiable\" claim is worse\n// than honest ZDR — so each check states exactly what it proves.\n\nconst RECEIPT_ANCHORED_SUFFIX = '::anchor::ReceiptAnchored';\n\nexport type CheckStatus = 'pass' | 'fail' | 'skip';\nexport type TrustMode = 'trustless' | 'receipt-asserted' | 'roadmap';\n\nexport interface VerifyCheck {\n name: string;\n status: CheckStatus;\n detail: string;\n trust: TrustMode;\n}\n\nexport interface VerifyAnchor {\n txDigest: string;\n anchoredAtMs?: string;\n anchoredBy?: string;\n explorer: string;\n}\n\n/** A typed TCB claim from the attested upstream (dstack ACI §tcb-and-claims). */\nexport interface UpstreamClaim {\n name: string;\n status: string;\n source?: string;\n}\n\nexport interface VerifyUpstream {\n provider?: string;\n modelId?: string;\n result?: string;\n tcbStatus?: string;\n /** The attested-session id (`as_…`) — resolve at GET /v1/aci/sessions/{id}. */\n sessionId?: string;\n /** Typed TCB claims (tee_attested, tcb_up_to_date, gpu_attested, …). */\n claims?: UpstreamClaim[];\n}\n\nexport interface VerifyResult {\n receiptId: string;\n /** True iff the receipt resolved AND its on-chain Sui anchor matches. */\n verified: boolean;\n /** The trustless core: an on-chain ReceiptAnchored event matches the receipt. */\n anchorVerified: boolean;\n checks: VerifyCheck[];\n wireHash?: string;\n workloadId?: string;\n upstream?: VerifyUpstream;\n anchor?: VerifyAnchor;\n}\n\nexport interface VerifyOptions {\n /** Override the API base (default `api.t2000.ai/v1`). */\n apiBase?: string;\n /** Sui network for the trustless anchor read (default `mainnet`). */\n network?: 'mainnet' | 'testnet';\n /** Confidential model id for fetching the attested receipt-signing key\n * (default `phala/glm-5.2`; the gateway key is workload-wide). */\n model?: string;\n /** Skip the local DCAP quote verification (the slower, network-bound check). */\n skipQuote?: boolean;\n}\n\ninterface AciReceiptSignature {\n algo?: string;\n key_id?: string;\n value?: string;\n}\n\ninterface AciReceipt {\n api_version?: string;\n receipt_id?: string;\n chat_id?: string | null;\n workload_id?: string;\n workload_keyset_digest?: string;\n endpoint?: string;\n method?: string;\n served_at?: number;\n signature?: AciReceiptSignature;\n event_log?: {\n type?: string;\n wire_hash?: string;\n result?: string;\n provider?: string;\n upstream_name?: string;\n model_id?: string;\n tcb_status?: string;\n session_id?: string;\n claims?:\n | Record<string, { status?: string; source?: string }>\n | { name?: string; status?: string; source?: string }[];\n }[];\n}\n\n/** Normalize ACI claims (object-map or array) into a typed list. */\nfunction normalizeClaims(\n claims:\n | Record<string, { status?: string; source?: string }>\n | { name?: string; status?: string; source?: string }[]\n | undefined\n): UpstreamClaim[] {\n if (!claims) {\n return [];\n }\n if (Array.isArray(claims)) {\n return claims\n .filter((c) => c.name)\n .map((c) => ({\n name: c.name as string,\n status: c.status ?? 'unknown',\n source: c.source,\n }));\n }\n return Object.entries(claims).map(([name, v]) => ({\n name,\n status: v?.status ?? 'unknown',\n source: v?.source,\n }));\n}\n\nfunction fullnodeUrl(network: 'mainnet' | 'testnet'): string {\n return network === 'testnet'\n ? 'https://fullnode.testnet.sui.io'\n : 'https://fullnode.mainnet.sui.io';\n}\n\ntype Jsonish = string | number | boolean | null | Jsonish[] | { [k: string]: Jsonish };\n\n// JCS (RFC 8785 subset) matching the dstack ACI gateway's `canonical.rs`:\n// object keys sorted by UTF-16 code units (JS default string order on the BMP),\n// integers only, no whitespace. JSON.stringify's string-escaping already matches\n// the gateway's (\\b \\t \\n \\f \\r, \\u00xx for other controls, non-ASCII verbatim).\nfunction jcs(value: Jsonish): string {\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false';\n }\n if (typeof value === 'number') {\n if (!Number.isInteger(value)) {\n throw new Error('JCS: non-integer number');\n }\n return String(value);\n }\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return `[${value.map(jcs).join(',')}]`;\n }\n const keys = Object.keys(value).sort();\n return `{${keys.map((k) => `${JSON.stringify(k)}:${jcs(value[k])}`).join(',')}}`;\n}\n\n// Verify the ACI receipt signature. The dstack gateway has shipped two schemes:\n//\n// • `ed25519` (current, key_id `dstack-kms-receipt-ed25519-v1`): a 64-byte\n// signature over the RAW JCS bytes of the receipt exactly as served — every\n// field present (incl. newer ones like `model`), with only `signature.value`\n// omitted. Verified against the attested 32-byte ed25519 key.\n// • `ecdsa-secp256k1` (legacy, §9.4): a 65-byte `r‖s‖v` signature over\n// `sha256(JCS(<the 10 protocol fields>))`; recover the public key and\n// require it to equal the attested key.\n//\n// Returns true only on a genuine match (any error → false).\n// (Module-level export for tests; the public SDK surface is `verifyReceipt`.)\nexport function verifyReceiptSignature(\n receipt: AciReceipt,\n signingKeyHex: string\n): boolean {\n try {\n const sig = receipt.signature;\n if (!sig?.value) {\n return false;\n }\n const endorsed = hexToBytes(signingKeyHex.replace(/^0x/, ''));\n const sigBytes = hexToBytes(sig.value);\n\n if (sig.algo === 'ed25519') {\n if (sigBytes.length !== 64 || endorsed.length !== 32) {\n return false;\n }\n // Canonicalise the receipt AS SERVED (untyped fields included) so the\n // check stays correct when the gateway adds receipt fields — only\n // `signature.value` is stripped.\n const { value: _omitted, ...sigRest } = sig;\n const canonical = {\n ...(receipt as unknown as { [k: string]: Jsonish }),\n signature: sigRest as unknown as Jsonish,\n };\n const msg = new TextEncoder().encode(jcs(canonical));\n return ed25519.verify(sigBytes, msg, endorsed);\n }\n\n if (sig.algo !== 'ecdsa-secp256k1') {\n return false;\n }\n // Legacy: reconstruct the exact canonical value — the 10 protocol fields,\n // with the signature object stripped of `value` (event_log entries are\n // already the flat {seq,type,...fields} shape the gateway canonicalises).\n const canonical: Jsonish = {\n api_version: receipt.api_version ?? '',\n receipt_id: receipt.receipt_id ?? '',\n chat_id: receipt.chat_id ?? null,\n workload_id: receipt.workload_id ?? '',\n workload_keyset_digest: receipt.workload_keyset_digest ?? '',\n endpoint: receipt.endpoint ?? '',\n method: receipt.method ?? '',\n served_at: receipt.served_at ?? 0,\n event_log: (receipt.event_log ?? []) as unknown as Jsonish,\n signature: { algo: sig.algo, key_id: sig.key_id ?? '' },\n };\n const prehash = sha256(new TextEncoder().encode(jcs(canonical)));\n\n if (sigBytes.length !== 65) {\n return false;\n }\n let v = sigBytes[64];\n if (v >= 27 && v <= 30) {\n v -= 27;\n }\n if (v > 3) {\n return false;\n }\n const recovered = secp256k1.Signature.fromCompact(sigBytes.slice(0, 64))\n .addRecoveryBit(v)\n .recoverPublicKey(prehash)\n .toHex(false);\n return recovered.toLowerCase() === bytesToHex(endorsed).toLowerCase();\n } catch {\n return false;\n }\n}\n\ninterface QuoteCheck {\n status: CheckStatus;\n detail: string;\n /** Definitively bad (verify the chain failed) — flips overall `verified`. */\n forged: boolean;\n tcbStatus?: string;\n}\n\n// TDX quote verification — TRUSTLESS, client-side (SPEC_CONFIDENTIAL_API Phase D\n// hardening). This is what removes the server-side-DCAP SPOF: instead of\n// trusting the gateway's `verified:true`, the client re-verifies the quote.\n// 1. @phala/dcap-qvl verifies the TDX quote, chaining to Intel's root CA via\n// PCCS collateral (Intel-signed, so the PCCS is a cache, not a trust point)\n// → genuine enclave + TCB status.\n// 2. confirm the genuine quote's `report_data` commits the report's\n// `signing_address` (the attested gateway identity) — so the report's TEE\n// binding is quote-backed, not fabricated — and that the quote is for the\n// same `workload_id` as the receipt.\n// (Tying the receipt-signing key to the identity key via keyset_endorsement is a\n// further hop; the receipt-signature check already proves the receipt is signed\n// by the published keyset key.)\ninterface AttReport {\n workload_id?: string;\n signing_address?: string;\n attestation?: { evidence?: { quote?: string } };\n}\n\nasync function verifyTdxQuote(\n base: string,\n model: string,\n receiptWorkloadId: string\n): Promise<QuoteCheck> {\n let nonce: string;\n try {\n nonce = bytesToHex(globalThis.crypto.getRandomValues(new Uint8Array(32)));\n } catch {\n return { status: 'skip', detail: 'no secure RNG available', forged: false };\n }\n\n let report: AttReport | undefined;\n try {\n const res = await fetch(\n `${base}/aci/attestation?model=${encodeURIComponent(model)}&nonce=${nonce}`\n );\n if (res.ok) {\n report = ((await res.json()) as { report?: AttReport }).report;\n }\n } catch {\n // network — fall through to skip\n }\n const quoteHex = report?.attestation?.evidence?.quote;\n if (!quoteHex) {\n return {\n status: 'skip',\n detail: 'attestation report (with quote) unavailable — pass --model?',\n forged: false,\n };\n }\n\n try {\n // `@phala/dcap-qvl` is CJS. When the SDK is bundled (e.g. into the CLI) and\n // hit via dynamic import, its named exports land under `.default`; unbundled\n // Node hoists them to the top level. Resolve both so it works either way.\n const dcap = await import('@phala/dcap-qvl');\n const getCollateralAndVerify =\n dcap.getCollateralAndVerify ?? dcap.default?.getCollateralAndVerify;\n if (typeof getCollateralAndVerify !== 'function') {\n return {\n status: 'fail',\n forged: false,\n detail: 'DCAP verifier unavailable in this build',\n };\n }\n const quoteBytes = hexToBytes(quoteHex.replace(/^0x/, ''));\n // Throws if the quote isn't a genuine TDX quote chaining to Intel's root.\n const vr = await getCollateralAndVerify(quoteBytes);\n const td = vr.report.asTd10() ?? vr.report.asTd15()?.base ?? null;\n const reportData = td?.reportData;\n const signingAddr = report?.signing_address?.replace(/^0x/, '').toLowerCase();\n const addrBound = Boolean(\n reportData &&\n signingAddr &&\n bytesToHex(reportData.slice(0, 20)) === signingAddr\n );\n const workloadMatch = report?.workload_id === receiptWorkloadId;\n const tcb = vr.status;\n const tcbBad = tcb === 'Revoked' || tcb === 'Unknown';\n const forged = !(addrBound && workloadMatch) || tcbBad;\n let detail: string;\n if (forged && tcbBad) {\n detail = `genuine TDX but TCB ${tcb}`;\n } else if (!addrBound) {\n detail = \"report_data does NOT commit the report's signing address\";\n } else if (!workloadMatch) {\n detail = \"quote workload_id does not match the receipt's\";\n } else {\n detail = `genuine Intel TDX (verified vs Intel collateral), TCB ${tcb}; report_data commits the attested signing address`;\n }\n return { status: forged ? 'fail' : 'pass', forged, tcbStatus: tcb, detail };\n } catch (e) {\n // A thrown verify is usually a PCCS/collateral/network issue, not a real\n // forgery from our own gateway — surface it but don't claim \"forged\".\n return {\n status: 'fail',\n forged: false,\n detail: `could not verify the quote: ${e instanceof Error ? e.message : 'error'}`,\n };\n }\n}\n\n/**\n * Verify a confidential response by its receipt id. Reads the signed receipt\n * (public), its on-chain Sui anchor (trustless), and reports a per-check result\n * that FAILS CLOSED on any forgery or mismatch.\n */\nexport async function verifyReceipt(\n receiptId: string,\n opts: VerifyOptions = {},\n): Promise<VerifyResult> {\n const base = opts.apiBase ?? DEFAULT_API_BASE;\n const network = opts.network ?? 'mainnet';\n const checks: VerifyCheck[] = [];\n\n // === 1. Receipt — fetch + structural soundness (public, no key) ===\n let receipt: AciReceipt | null = null;\n try {\n const res = await fetch(`${base}/aci/receipts/${encodeURIComponent(receiptId)}`);\n if (res.ok) {\n receipt = (await res.json()) as AciReceipt;\n }\n } catch {\n // network error → receipt stays null → fails closed below\n }\n if (!receipt?.event_log) {\n checks.push({\n name: 'Receipt',\n status: 'fail',\n detail: 'receipt not found or malformed',\n trust: 'receipt-asserted',\n });\n return { receiptId, verified: false, anchorVerified: false, checks };\n }\n const wireHash = receipt.event_log.find((e) => e.type === 'response.returned')\n ?.wire_hash;\n const workloadId = receipt.workload_id;\n checks.push({\n name: 'Receipt',\n status: wireHash && workloadId ? 'pass' : 'fail',\n detail: wireHash\n ? `well-formed (${receipt.event_log.length} log entries, workload ${workloadId})`\n : 'missing response wire_hash / workload_id',\n trust: 'receipt-asserted',\n });\n\n // === 2. Confidential upstream — attestation evidence in the signed receipt ===\n const upstreamEv = receipt.event_log.find((e) => e.type === 'upstream.verified');\n const upstreamOk = upstreamEv?.result === 'verified';\n const claims = normalizeClaims(upstreamEv?.claims);\n checks.push({\n name: 'Confidential upstream',\n status: upstreamEv ? (upstreamOk ? 'pass' : 'fail') : 'skip',\n detail: upstreamEv\n ? `${upstreamEv.provider ?? upstreamEv.upstream_name ?? 'upstream'}: ${upstreamEv.result ?? 'unknown'}${upstreamEv.tcb_status ? ` (TCB ${upstreamEv.tcb_status})` : ''}`\n : 'no upstream.verified event (routed/non-confidential?)',\n trust: 'receipt-asserted',\n });\n\n // === 3. Sui anchor — TRUSTLESS: read the on-chain event from a fullnode ===\n let anchorVerified = false;\n let anchor: VerifyAnchor | undefined;\n let digest: string | undefined;\n try {\n const res = await fetch(`${base}/aci/anchor/${encodeURIComponent(receiptId)}`);\n if (res.ok) {\n const j = (await res.json()) as { txDigest?: string };\n digest = j.txDigest;\n }\n } catch {\n // no anchor lookup → fails the anchor check below\n }\n if (!digest) {\n checks.push({\n name: 'Sui anchor',\n status: 'fail',\n detail: `no anchor on record — POST ${base}/aci/anchor/${receiptId} to create one`,\n trust: 'trustless',\n });\n } else {\n try {\n const client = new SuiGrpcClient({ baseUrl: fullnodeUrl(network), network });\n const tx = await client.core.getTransaction({\n digest,\n include: { events: true },\n });\n const txn = tx.$kind === 'Transaction' ? tx.Transaction : tx.FailedTransaction;\n const ev = (txn.events ?? []).find((e) =>\n e.eventType.endsWith(RECEIPT_ANCHORED_SUFFIX),\n );\n const data = (ev?.json ?? {}) as Record<string, unknown>;\n const onChainReceipt = String(data.receipt_id ?? '');\n const onChainWire = String(data.wire_hash ?? '');\n const onChainWorkload = String(data.workload_id ?? '');\n const matches =\n onChainReceipt === receiptId &&\n onChainWire === wireHash &&\n onChainWorkload === workloadId;\n anchorVerified = matches;\n anchor = {\n txDigest: digest,\n anchoredAtMs: data.anchored_at_ms ? String(data.anchored_at_ms) : undefined,\n anchoredBy: data.anchored_by ? String(data.anchored_by) : undefined,\n explorer: `https://suiscan.xyz/${network}/tx/${digest}`,\n };\n checks.push({\n name: 'Sui anchor',\n status: matches ? 'pass' : 'fail',\n detail: matches\n ? `on-chain ReceiptAnchored matches (wire_hash + workload_id), tx ${digest}`\n : `on-chain event does NOT match the receipt (wire ${onChainWire || 'absent'})`,\n trust: 'trustless',\n });\n } catch (e) {\n checks.push({\n name: 'Sui anchor',\n status: 'fail',\n detail: `could not read anchor tx ${digest}: ${e instanceof Error ? e.message : 'error'}`,\n trust: 'trustless',\n });\n }\n }\n\n // === 4. Receipt signature — recover the signer + match the attested key ===\n // The signing key (gateway receipt key) is workload-wide; fetch the attested\n // keyset and confirm its workload matches this receipt before trusting it.\n let sigStatus: CheckStatus = 'skip';\n let sigDetail = 'no signature on receipt';\n if (receipt.signature?.value) {\n try {\n const model = opts.model ?? 'phala/glm-5.2';\n const res = await fetch(\n `${base}/aci/attestation?model=${encodeURIComponent(model)}`,\n );\n const att = res.ok\n ? ((await res.json()) as { signingKey?: string; workloadId?: string })\n : null;\n if (!att?.signingKey) {\n sigDetail = 'could not fetch the attested keyset to check the signature';\n } else if (att.workloadId && att.workloadId !== workloadId) {\n sigDetail = `attested keyset is for a different workload — pass --model for ${workloadId}`;\n } else {\n const ok = verifyReceiptSignature(receipt, att.signingKey);\n sigStatus = ok ? 'pass' : 'fail';\n sigDetail = ok\n ? `signed by the attested receipt key (${receipt.signature.key_id ?? 'key'})`\n : 'signature does NOT recover the attested receipt key — forged/altered';\n }\n } catch {\n sigDetail = 'signature check errored';\n }\n }\n checks.push({\n name: 'Receipt signature',\n status: sigStatus,\n detail: sigDetail,\n trust: sigStatus === 'skip' ? 'roadmap' : 'trustless',\n });\n\n // === 5. TDX quote (DCAP) — verify the quote genuine + fresh, client-side ===\n if (opts.skipQuote) {\n checks.push({\n name: 'TDX quote (DCAP)',\n status: 'skip',\n detail: 'skipped (--quick)',\n trust: 'trustless',\n });\n } else {\n const q = await verifyTdxQuote(\n base,\n opts.model ?? 'phala/glm-5.2',\n workloadId ?? ''\n );\n checks.push({\n name: 'TDX quote (DCAP)',\n status: q.status,\n detail: q.detail,\n trust: 'trustless',\n });\n }\n\n // FAIL CLOSED: a sound receipt AND no trustless check left in `fail`. A DCAP\n // (or anchor/signature) check that errored counts as fail — \"couldn't prove\"\n // is \"not verified\"; we never report verified on an unchecked/failed quote.\n const trustlessFailed = checks.some(\n (c) => c.trust === 'trustless' && c.status === 'fail'\n );\n return {\n receiptId,\n verified: Boolean(wireHash && workloadId) && !trustlessFailed,\n anchorVerified,\n checks,\n wireHash,\n workloadId,\n upstream: upstreamEv\n ? {\n provider: upstreamEv.provider ?? upstreamEv.upstream_name,\n modelId: upstreamEv.model_id,\n result: upstreamEv.result,\n tcbStatus: upstreamEv.tcb_status,\n sessionId: upstreamEv.session_id,\n claims: claims.length > 0 ? claims : undefined,\n }\n : undefined,\n anchor,\n };\n}\n","// Unified spending-limit config store (`~/.t2000/config.json`). Moved here from\n// the CLI (`lib/config-store.ts`) + the SDK `SafeguardEnforcer` so ONE gate\n// serves CLI + MCP + programmatic writes (closes the H5 gap — R-0 Finding 1).\n//\n// Node-only (uses `node:fs`) — NOT re-exported from `browser.ts`. The browser\n// (Audric) write path skips client-side limits entirely; the server budget\n// ledger is the cap there.\n//\n// Schema (`~/.t2000/config.json`):\n// { \"limits\": { \"perTxUsd\": 25, \"dailyUsd\": 100 },\n// \"dailySpend\": { \"date\": \"2026-06-15\", \"usd\": 12.5 } }\n//\n// `daily` is CUMULATIVE across all outbound writes (send + swap + pay) since\n// midnight UTC — matches the engine's `autonomousDailyLimit` + the user mental\n// model (\"$100/day total\", not \"$100 per send\"). Locked S.424.\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport interface LimitsConfig {\n /** Caps any single outbound write (send | swap | pay) by USD value. */\n perTxUsd?: number;\n /** Caps CUMULATIVE outbound spend (all writes) per UTC day, by USD value. */\n dailyUsd?: number;\n}\n\nexport interface DailySpend {\n /** UTC date `YYYY-MM-DD` the running total applies to. */\n date: string;\n /** USD spent so far on `date`. */\n usd: number;\n}\n\nexport interface LimitsFile {\n limits?: LimitsConfig;\n dailySpend?: DailySpend;\n}\n\nconst DEFAULT_CONFIG_DIR = join(homedir(), '.t2000');\n\nexport function resolveConfigPath(configDir?: string): string {\n return join(configDir ?? DEFAULT_CONFIG_DIR, 'config.json');\n}\n\n/** UTC date `YYYY-MM-DD`. */\nexport function todayUtc(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nexport function readLimitsFile(configDir?: string): LimitsFile {\n const path = resolveConfigPath(configDir);\n try {\n return sanitize(JSON.parse(readFileSync(path, 'utf-8')));\n } catch {\n return {};\n }\n}\n\n/**\n * Write the limits + dailySpend keys, PRESERVING any other keys already on\n * disk (a config file may carry unrelated data). Mode 0600.\n */\nexport function writeLimitsFile(file: LimitsFile, configDir?: string): string {\n const path = resolveConfigPath(configDir);\n let existing: Record<string, unknown> = {};\n try {\n existing = JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n existing = {};\n }\n // Drop the dead v3 SafeguardEnforcer keys if present (maxPerTx/maxDailySend/\n // dailyUsed/dailyResetDate/locked) — they were never read by v4 and are\n // replaced by `limits` + `dailySpend`.\n for (const dead of ['maxPerTx', 'maxDailySend', 'dailyUsed', 'dailyResetDate', 'locked']) {\n delete existing[dead];\n }\n const merged: Record<string, unknown> = { ...existing };\n if (file.limits && (file.limits.perTxUsd !== undefined || file.limits.dailyUsd !== undefined)) {\n merged.limits = file.limits;\n } else {\n delete merged.limits;\n }\n if (file.dailySpend) merged.dailySpend = file.dailySpend;\n else delete merged.dailySpend;\n\n const dir = dirname(path);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(path, JSON.stringify(merged, null, 2) + '\\n', { mode: 0o600 });\n return path;\n}\n\nexport function getLimits(configDir?: string): LimitsConfig | undefined {\n return readLimitsFile(configDir).limits;\n}\n\nexport function hasLimits(configDir?: string): boolean {\n const l = readLimitsFile(configDir).limits;\n return !!l && (l.perTxUsd !== undefined || l.dailyUsd !== undefined);\n}\n\n/** Merge-set limits (only provided fields change). Returns the written path. */\nexport function setLimits(limits: LimitsConfig, configDir?: string): string {\n const file = readLimitsFile(configDir);\n const merged: LimitsConfig = { ...file.limits };\n if (limits.perTxUsd !== undefined) merged.perTxUsd = limits.perTxUsd;\n if (limits.dailyUsd !== undefined) merged.dailyUsd = limits.dailyUsd;\n return writeLimitsFile({ ...file, limits: merged }, configDir);\n}\n\n/** Remove all limits (keeps the dailySpend ledger). Returns the written path. */\nexport function clearLimits(configDir?: string): string {\n const file = readLimitsFile(configDir);\n return writeLimitsFile({ ...file, limits: undefined }, configDir);\n}\n\n/** Cumulative USD spent so far today (0 when the ledger is from a prior day). */\nexport function dailySpentToday(configDir?: string): number {\n const { dailySpend } = readLimitsFile(configDir);\n if (!dailySpend || dailySpend.date !== todayUtc()) return 0;\n return dailySpend.usd;\n}\n\n/** Add `usd` to today's running total (resets on UTC date rollover). */\nexport function recordDailySpend(usd: number, configDir?: string): void {\n if (!Number.isFinite(usd) || usd <= 0) return;\n const file = readLimitsFile(configDir);\n const today = todayUtc();\n const prior = file.dailySpend && file.dailySpend.date === today ? file.dailySpend.usd : 0;\n writeLimitsFile({ ...file, dailySpend: { date: today, usd: prior + usd } }, configDir);\n}\n\nfunction sanitize(raw: unknown): LimitsFile {\n if (typeof raw !== 'object' || raw === null) return {};\n const r = raw as Record<string, unknown>;\n const out: LimitsFile = {};\n\n if (typeof r.limits === 'object' && r.limits !== null) {\n const l = r.limits as Record<string, unknown>;\n const limits: LimitsConfig = {};\n if (typeof l.perTxUsd === 'number' && l.perTxUsd > 0) limits.perTxUsd = l.perTxUsd;\n // Migrate the legacy `dailySendUsd` (v4 CLI, per-send sub-cap) → `dailyUsd`\n // (cumulative all-writes). New canonical key wins if both are present.\n if (typeof l.dailyUsd === 'number' && l.dailyUsd > 0) limits.dailyUsd = l.dailyUsd;\n else if (typeof l.dailySendUsd === 'number' && l.dailySendUsd > 0) limits.dailyUsd = l.dailySendUsd;\n if (limits.perTxUsd !== undefined || limits.dailyUsd !== undefined) out.limits = limits;\n }\n\n if (typeof r.dailySpend === 'object' && r.dailySpend !== null) {\n const d = r.dailySpend as Record<string, unknown>;\n if (typeof d.date === 'string' && typeof d.usd === 'number' && d.usd >= 0) {\n out.dailySpend = { date: d.date, usd: d.usd };\n }\n }\n\n return out;\n}\n","// Spending-limit error — thrown by the unified limits gate (`@t2000/sdk/limits`)\n// when an outbound write exceeds an opted-in cap. Shared by CLI + MCP +\n// programmatic callers (the gate lives in the SDK write paths). Carries a\n// structured shape so the CLI can render `--json` output and the MCP can\n// surface a typed failure.\n\nexport type LimitKind = 'perTxUsd' | 'dailyUsd';\nexport type LimitOperation = 'send' | 'swap' | 'pay';\n\nexport class LimitExceededError extends Error {\n readonly code = 'LIMIT_EXCEEDED';\n readonly operation: LimitOperation;\n readonly limitKind: LimitKind;\n readonly limit: number;\n readonly attempted: number;\n\n constructor(params: {\n operation: LimitOperation;\n limitKind: LimitKind;\n limit: number;\n attempted: number;\n }) {\n const label = params.limitKind === 'perTxUsd' ? 'per-transaction limit' : 'daily spend limit';\n super(\n `Exceeds ${label} ($${params.limit}). Attempted $${params.attempted.toFixed(2)}. Use --force / force:true to override.`,\n );\n this.name = 'LimitExceededError';\n this.operation = params.operation;\n this.limitKind = params.limitKind;\n this.limit = params.limit;\n this.attempted = params.attempted;\n }\n\n toJSON(): unknown {\n return {\n error: this.code,\n message: this.message,\n operation: this.operation,\n limitKind: this.limitKind,\n limit: this.limit,\n attempted: this.attempted,\n };\n }\n}\n","// The unified spending-limit gate. ONE enforcer for CLI + MCP + programmatic\n// writes — wired into the T2000 write paths (send / swap / pay), so every\n// surface that calls those methods inherits the same cap (closes H5).\n//\n// USD-denominated. `perTxUsd` caps any single write; `dailyUsd` caps the\n// CUMULATIVE spend across all writes since UTC midnight (the running total\n// lives in the `dailySpend` ledger). `force` bypasses both — the caller owns\n// the prompt/consent.\n\nimport {\n type LimitsConfig,\n getLimits,\n setLimits,\n clearLimits,\n hasLimits,\n dailySpentToday,\n recordDailySpend,\n} from './config.js';\nimport { LimitExceededError, type LimitOperation } from './errors.js';\n\n/**\n * Best-effort USD value for an asset+amount pair, for the limit gate. Stables\n * are 1:1; SUI (and anything else) returns `null` — \"unknown, don't gate\".\n * The limits are USD-denominated; SUI-USD gating would need a price lookup and\n * is intentionally out of scope (matches the prior CLI behavior).\n */\nexport function approxUsdValue(asset: string, amount: number): number | null {\n const symbol = asset.toUpperCase();\n if (symbol === 'USDC' || symbol === 'USDSUI') return amount;\n return null;\n}\n\n/**\n * Pure gate — no I/O. Returns silently when allowed; throws\n * `LimitExceededError` when blocked.\n */\nexport function assertLimitConfig(input: {\n limits: LimitsConfig | undefined;\n spentTodayUsd: number;\n operation: LimitOperation;\n amountUsd: number;\n force?: boolean;\n}): void {\n if (input.force) return;\n if (!Number.isFinite(input.amountUsd) || input.amountUsd <= 0) return;\n const { limits } = input;\n if (!limits) return;\n\n if (limits.perTxUsd !== undefined && input.amountUsd > limits.perTxUsd) {\n throw new LimitExceededError({\n operation: input.operation,\n limitKind: 'perTxUsd',\n limit: limits.perTxUsd,\n attempted: input.amountUsd,\n });\n }\n\n if (limits.dailyUsd !== undefined && input.spentTodayUsd + input.amountUsd > limits.dailyUsd) {\n throw new LimitExceededError({\n operation: input.operation,\n limitKind: 'dailyUsd',\n // The cap is total/day; report the cap (attempted is THIS write's USD).\n limit: limits.dailyUsd,\n attempted: input.spentTodayUsd + input.amountUsd,\n });\n }\n}\n\nexport interface LimitAssertInput {\n operation: LimitOperation;\n /** This write's USD value. Pass 0 / non-positive to skip (e.g. SUI sends). */\n amountUsd: number;\n /** When true, skip the gate. */\n force?: boolean;\n}\n\n/**\n * The spending-limit enforcer — reads/writes `~/.t2000/config.json` (or a\n * `configDir` override for tests). Constructed once by the T2000 agent and\n * called around every outbound write; also drives the CLI `t2 limit` commands.\n */\nexport class LimitEnforcer {\n constructor(private readonly configDir?: string) {}\n\n /** Throws `LimitExceededError` when the write exceeds an opted-in cap. */\n assert(input: LimitAssertInput): void {\n assertLimitConfig({\n limits: getLimits(this.configDir),\n spentTodayUsd: dailySpentToday(this.configDir),\n operation: input.operation,\n amountUsd: input.amountUsd,\n force: input.force,\n });\n }\n\n /** Add a settled write's USD value to today's cumulative total. */\n record(amountUsd: number): void {\n recordDailySpend(amountUsd, this.configDir);\n }\n\n getLimits(): LimitsConfig | undefined {\n return getLimits(this.configDir);\n }\n\n hasLimits(): boolean {\n return hasLimits(this.configDir);\n }\n\n setLimits(limits: LimitsConfig): void {\n setLimits(limits, this.configDir);\n }\n\n clearLimits(): void {\n clearLimits(this.configDir);\n }\n\n dailySpentToday(): number {\n return dailySpentToday(this.configDir);\n }\n}\n","export { T2000 } from './t2000.js';\nexport type { TransactionSigner } from './signer.js';\nexport { KeypairSigner } from './wallet/keypairSigner.js';\nexport { ZkLoginSigner, type ZkLoginProof } from './wallet/zkLoginSigner.js';\nexport { payWithMpp, preflightPay, parseMppSuiChallenge } from './wallet/pay.js';\nexport {\n chatCompletion,\n chatCompletionStream,\n listModels,\n DEFAULT_API_BASE,\n} from './inference.js';\nexport type {\n ChatMessage,\n ChatParams,\n ChatResult,\n ChatUsage,\n ApiModel,\n} from './inference.js';\nexport { verifyReceipt } from './verify.js';\nexport type {\n VerifyResult,\n VerifyCheck,\n VerifyAnchor,\n VerifyUpstream,\n UpstreamClaim,\n VerifyOptions,\n CheckStatus,\n TrustMode,\n} from './verify.js';\nexport { executeTx } from './wallet/executeTx.js';\nexport { T2000Error, mapWalletError, mapMoveAbortCode } from './errors.js';\nexport type { T2000ErrorCode, T2000ErrorData } from './errors.js';\nexport type {\n T2000Options,\n BalanceResponse,\n SuiHolding,\n SendResult,\n DepositInfo,\n PaymentRequest,\n TransactionRecord,\n TransactionLeg,\n PayOptions,\n PayResult,\n SwapResult,\n SwapQuoteResult,\n} from './types.js';\nexport {\n MIST_PER_SUI,\n SUI_DECIMALS,\n USDC_DECIMALS,\n T2000_OVERLAY_FEE_WALLET,\n SUPPORTED_ASSETS,\n CLOCK_ID,\n DEFAULT_NETWORK,\n} from './constants.js';\nexport type { SupportedAsset, StableAsset, SendableAsset } from './constants.js';\nexport {\n STABLE_ASSETS,\n SENDABLE_ASSETS,\n GASLESS_MIN_STABLE_AMOUNT,\n GASLESS_STABLE_TYPES,\n DEFAULT_GRPC_URL,\n GAS_RESERVE_MIN,\n CETUS_USDC_SUI_POOL,\n OPERATION_ASSETS,\n isAllowedAsset,\n assertAllowedAsset,\n} from './constants.js';\nexport type { Operation } from './constants.js';\nexport {\n validateAddress,\n truncateAddress,\n normalizeCoinType,\n getSuiClient,\n getSuiGrpcClient,\n} from './utils/sui.js';\nexport {\n SUI_ADDRESS_REGEX,\n SUI_ADDRESS_STRICT_REGEX,\n SUINS_NAME_REGEX,\n InvalidAddressError,\n SuinsNotRegisteredError,\n SuinsRpcError,\n looksLikeSuiNs,\n resolveSuinsViaRpc,\n resolveAddressToSuinsViaRpc,\n normalizeAddressInput,\n} from './utils/suins.js';\nexport type { NormalizedAddress } from './utils/suins.js';\nexport {\n KNOWN_TARGETS,\n LABEL_PATTERNS,\n classifyAction,\n classifyLabel,\n fallbackLabel,\n refineLendingLabel,\n classifyTransaction,\n extractTransferDetails,\n extractAllUserLegs,\n} from './wallet/classify.js';\nexport type {\n ClassifyBalanceChange,\n ClassifyResult,\n ExtractedTransfer,\n TxDirection,\n} from './wallet/classify.js';\nexport {\n parseSuiRpcTx,\n extractTxSender,\n extractTxCommands,\n queryHistory,\n queryTransaction,\n} from './wallet/history.js';\nexport type { SuiRpcTxBlock } from './wallet/history.js';\nexport { queryBalance } from './wallet/balance.js';\nexport {\n mistToSui,\n suiToMist,\n usdcToRaw,\n rawToUsdc,\n stableToRaw,\n rawToStable,\n getDecimals,\n formatUsd,\n formatSui,\n formatAssetAmount,\n normalizeAsset,\n} from './utils/format.js';\nexport {\n generateKeypair,\n keypairFromPrivateKey,\n saveKey,\n saveBech32,\n loadKey,\n walletExists,\n exportPrivateKey,\n getAddress,\n} from './wallet/keyManager.js';\nexport { buildSendTx, addSendToTx, preflightSend } from './wallet/send.js';\nexport {\n A2A_ESCROW_PACKAGE_ID,\n A2A_ESCROW_FEE_CONFIG_ID,\n MAX_JOB_USDC,\n MAX_REVIEW_WINDOW_MS,\n MAX_DELIVER_HORIZON_MS,\n JOB_STATES,\n preflightCreateJob,\n buildCreateJobTx,\n buildDeliverJobTx,\n buildReleaseJobTx,\n buildRejectJobTx,\n buildRefundJobTx,\n getJob,\n jobActionsFor,\n verifyJobForSeller,\n} from './wallet/job.js';\nexport type { Job, JobState, JobTerms, JobVerification } from './wallet/job.js';\nexport {\n DEFAULT_COMMERCE_API_BASE,\n fetchOffering,\n getJobSpec,\n listOfferings,\n putJobSpec,\n} from './commerce.js';\nexport type { OfferingListing } from './commerce.js';\nexport {\n fetchAllCoins,\n selectAndSplitCoin,\n selectSuiCoin,\n} from './wallet/coinSelection.js';\nexport type { CoinPage, SelectAndSplitResult } from './wallet/coinSelection.js';\nexport {\n composeTx,\n deriveAllowedAddressesFromPtb,\n WRITE_APPENDER_REGISTRY,\n SPONSORED_PYTH_DEPENDENT_PROVIDERS,\n getSponsoredSwapProviders,\n} from './composeTx.js';\nexport type {\n WriteToolName,\n WriteStep,\n ComposeTxOptions,\n ComposeTxResult,\n AppenderContext,\n StepPreview,\n SendTransferInput,\n SwapExecuteInput,\n} from './composeTx.js';\nexport { simulateTransaction, throwIfSimulationFailed } from './utils/simulate.js';\nexport type { SimulationResult } from './utils/simulate.js';\nexport { getSwapQuote } from './swap-quote.js';\nexport {\n findSwapRoute,\n buildSwapTx,\n addSwapToTx,\n preflightSwap,\n OVERLAY_FEE_RATE,\n serializeCetusRoute,\n deserializeCetusRoute,\n verifyCetusRouteCoinMatch,\n isCetusRouteFresh,\n} from './protocols/cetus-swap.js';\nexport type {\n SwapRouteResult,\n OverlayFeeConfig,\n SerializedCetusRoute,\n SerializedRouterDataV3,\n SerializedCetusRoutePath,\n} from './protocols/cetus-swap.js';\nexport {\n COIN_REGISTRY,\n TOKEN_MAP,\n resolveTokenType,\n resolveSymbol,\n getDecimalsForCoinType,\n getCoinMeta,\n isInRegistry,\n SUI_TYPE,\n USDC_TYPE,\n USDT_TYPE,\n USDSUI_TYPE,\n USDE_TYPE,\n ETH_TYPE,\n WBTC_TYPE,\n WAL_TYPE,\n NAVX_TYPE,\n IKA_TYPE,\n LOFI_TYPE,\n MANIFEST_TYPE,\n} from './token-registry.js';\nexport type { CoinMeta } from './token-registry.js';\n// [S.323 / 2026-05-25] VOLO vSUI staking re-exports removed (full cut).\n// vSUI still exists in the codebase as a passive token (NAVI reward type\n// + Cetus swap target), but t2000 no longer exposes mint/redeem surfaces.\nexport {\n AGENT_ID_PARENT,\n AGENT_ID_PARENT_NAME,\n AGENT_ID_PARENT_NFT_ID,\n AUDRIC_PARENT,\n AUDRIC_PARENT_NAME,\n AUDRIC_PARENT_NFT_ID,\n buildAddLeafTx,\n buildRevokeLeafTx,\n displayHandle,\n fullHandle,\n validateLabel,\n} from './protocols/suins-leaf.js';\nexport type {\n BuildAddLeafParams,\n BuildRevokeLeafParams,\n LabelValidationResult,\n SuinsParent,\n} from './protocols/suins-leaf.js';\n// Unified spending limits (per-tx + cumulative daily, USD) — one gate for\n// CLI + MCP + programmatic writes (R-0 Finding 1; closes H5). Node-only.\nexport {\n LimitEnforcer,\n LimitExceededError,\n approxUsdValue,\n assertLimitConfig,\n getLimits,\n hasLimits,\n setLimits,\n clearLimits,\n dailySpentToday,\n recordDailySpend,\n readLimitsFile,\n writeLimitsFile,\n} from './limits/index.js';\nexport type { LimitsConfig, DailySpend, LimitsFile, LimitKind, LimitOperation, LimitAssertInput } from './limits/index.js';\n// Synchronous, network-free preflight (layer 2) — pure input validation the\n// v3 host runs before the LLM round-trip / tap-to-confirm. Per-builder\n// validators (`preflightSend`/`preflightPay`/`preflightSwap`) are exported\n// alongside their builders above; these are the shared primitives.\nexport {\n type PreflightResult,\n PREFLIGHT_MAX_AMOUNT,\n PREFLIGHT_OK,\n preflightFail,\n checkPositiveAmount,\n checkSuiAddress,\n} from './preflight.js';\n","import { Transaction } from '@mysten/sui/transactions';\nimport { T2000Error } from '../errors.js';\nimport { USDC_TYPE } from '../token-registry.js';\nimport { USDC_DECIMALS } from '../constants.js';\nimport {\n type PreflightResult,\n PREFLIGHT_OK,\n preflightFail,\n checkSuiAddress,\n} from '../preflight.js';\nimport { validateAddress, type SuiCoreClient } from '../utils/sui.js';\nimport { selectAndSplitCoin } from './coinSelection.js';\n\n/**\n * A2A Escrow — client for the `a2a_escrow::escrow` Move package\n * (SPEC_A2A_ESCROW, t2 Agents Phase 3).\n *\n * One shared `Job<USDC>` object per engagement; the escrow balance lives IN\n * the object (no treasury, no admin key). These builders construct UNSIGNED\n * transactions; the caller signs (buyer for create/release/reject, seller\n * for deliver, ANYONE for the two timeout cranks) and may sponsor gas — the\n * Move calls authorize on `ctx.sender()`, so sponsorship never weakens auth.\n *\n * Browser-safe (no fs / keyManager imports) so store surfaces can build the\n * buyer-side legs on a zkLogin session key.\n *\n * Deployed on Sui mainnet 2026-07-18 (fresh publish after the contract\n * review — 2.5% in-contract protocol fee (D-1, SPEC_ACP_SUI §7) snapshotted\n * onto the Job at create, FeeConfig versioning, bounded windows). Override\n * via env for testnet/dev.\n */\n\n/** The published `a2a_escrow` package id (mainnet). */\nexport const A2A_ESCROW_PACKAGE_ID =\n process.env.A2A_ESCROW_PACKAGE_ID ??\n '0x358a819c1c016e2cc84ef5fbea81cba90c31f7f8a62bf45cb5e5276acf198bdd';\n\n/** The shared `FeeConfig` object every escrow entry reads (mainnet). */\nexport const A2A_ESCROW_FEE_CONFIG_ID =\n process.env.A2A_ESCROW_FEE_CONFIG_ID ??\n '0xddaa25570950b7484dbf20797ebcf75707be9c87cd67bef2a06ed2e81d2c494b';\n\n/** `initial_shared_version` of the FeeConfig — lets builders reference the\n * shared object without a resolution round-trip (browser + PTB friendly). */\nexport const A2A_ESCROW_FEE_CONFIG_VERSION = Number(\n process.env.A2A_ESCROW_FEE_CONFIG_VERSION ?? 931861903,\n);\n\nconst CLOCK_ID = '0x6';\nconst MODULE = 'escrow';\n\n/** Immutable reference to the shared FeeConfig for the five escrow verbs. */\nfunction feeConfigArg(tx: Transaction) {\n return tx.sharedObjectRef({\n objectId: A2A_ESCROW_FEE_CONFIG_ID,\n initialSharedVersion: A2A_ESCROW_FEE_CONFIG_VERSION,\n mutable: false,\n });\n}\n\n/** v1 job-value cap in USDC — same instinct as the catalog price cap: the\n * no-arbitration reject-split is only fair at sizes where neither side is\n * incentivized to game it (SPEC_A2A_ESCROW §2). */\nexport const MAX_JOB_USDC = 50;\n\n/** Contract-enforced create bounds (mirror `escrow.move` — the caps that\n * close the v1 unbounded-window overflow lock). */\nexport const MAX_REVIEW_WINDOW_MS = 2_592_000_000; // 30 days\nexport const MAX_DELIVER_HORIZON_MS = 31_536_000_000; // 365 days\n\n/** Job lifecycle states, mirroring the Move constants. */\nexport const JOB_STATES = [\n 'funded',\n 'delivered',\n 'released',\n 'refunded',\n 'rejected',\n] as const;\nexport type JobState = (typeof JOB_STATES)[number];\n\nexport interface JobTerms {\n /** The seller's wallet (the listing's payTo / claimed Agent ID wallet). */\n seller: string;\n /** Job value in display USDC (e.g. `5` = 5 USDC). ≤ `MAX_JOB_USDC`. */\n amountUsdc: number;\n /** Hash/commitment of the job spec (hex string, `0x…` or bare). */\n specHash: string;\n /** Epoch-ms deadline the seller must deliver by. */\n deliverByMs: number;\n /** Buyer's accept/reject window (ms) after delivery; lapse = release. */\n reviewWindowMs: number;\n /** Buyer's share in basis points on reject (0–10000). Fixed at create. */\n rejectSplitBps: number;\n}\n\n/** Parsed on-chain `Job` object. */\nexport interface Job {\n id: string;\n buyer: string;\n seller: string;\n /** Locked amount in display USDC (immutable record). */\n amountUsdc: number;\n /** What's still in the object — 0 after settlement. */\n escrowUsdc: number;\n /** Protocol fee bps snapshotted at create (taken from seller-bound funds\n * at settlement; refunds are fee-free). */\n feeBps: number;\n specHash: string;\n deliverByMs: number;\n reviewWindowMs: number;\n rejectSplitBps: number;\n state: JobState;\n deliveryHash: string | null;\n deliveredAtMs: number | null;\n createdAtMs: number;\n}\n\n// ---------------------------------------------------------------------------\n// Hash plumbing — spec/delivery commitments travel as vector<u8>.\n// ---------------------------------------------------------------------------\n\nfunction hexToBytes(hex: string): number[] {\n const clean = hex.startsWith('0x') ? hex.slice(2) : hex;\n if (clean.length === 0 || clean.length % 2 !== 0 || /[^0-9a-fA-F]/.test(clean)) {\n throw new T2000Error(\n 'INVALID_AMOUNT',\n `Expected a hex hash (0x…), got \"${hex.slice(0, 32)}\"`,\n );\n }\n const out: number[] = [];\n for (let i = 0; i < clean.length; i += 2) {\n out.push(Number.parseInt(clean.slice(i, i + 2), 16));\n }\n return out;\n}\n\n/** gRPC's `json` include renders Move `vector<u8>` as a base64 STRING;\n * JSON-RPC (and tests) hand back number arrays. Accept both. */\nfunction bytesToHex(bytes: number[] | Uint8Array | string): string {\n const arr =\n typeof bytes === 'string'\n ? Array.from(atob(bytes), (c) => c.charCodeAt(0))\n : bytes;\n let s = '0x';\n for (const b of arr) s += b.toString(16).padStart(2, '0');\n return s;\n}\n\n// ---------------------------------------------------------------------------\n// Preflight\n// ---------------------------------------------------------------------------\n\n/**\n * Synchronous, network-free preflight for `create`. Terms sanity only —\n * the balance read happens in `buildCreateJobTx`.\n */\nexport function preflightCreateJob(terms: JobTerms): PreflightResult {\n const addressCheck = checkSuiAddress(terms.seller);\n if (!addressCheck.valid) return addressCheck;\n if (!Number.isFinite(terms.amountUsdc) || terms.amountUsdc <= 0) {\n return preflightFail('INVALID_AMOUNT', `Amount must be positive. Got ${terms.amountUsdc}.`);\n }\n if (terms.amountUsdc > MAX_JOB_USDC) {\n return preflightFail(\n 'INVALID_AMOUNT',\n `v1 caps escrow jobs at ${MAX_JOB_USDC} USDC (no-arbitration split only stays fair at small sizes). Got ${terms.amountUsdc}.`,\n );\n }\n if (terms.deliverByMs <= Date.now()) {\n return preflightFail('INVALID_AMOUNT', 'deliverByMs must be in the future.');\n }\n if (terms.deliverByMs > Date.now() + MAX_DELIVER_HORIZON_MS) {\n return preflightFail('INVALID_AMOUNT', 'deliverByMs is more than 365 days out.');\n }\n if (terms.reviewWindowMs < 0 || terms.reviewWindowMs > MAX_REVIEW_WINDOW_MS) {\n return preflightFail('INVALID_AMOUNT', 'reviewWindowMs must be 0–30 days.');\n }\n if (\n !Number.isInteger(terms.rejectSplitBps) ||\n terms.rejectSplitBps < 0 ||\n terms.rejectSplitBps > 10_000\n ) {\n return preflightFail('INVALID_AMOUNT', 'rejectSplitBps must be an integer 0–10000.');\n }\n try {\n hexToBytes(terms.specHash);\n } catch (e) {\n return preflightFail('INVALID_AMOUNT', (e as T2000Error).message);\n }\n return PREFLIGHT_OK;\n}\n\n// ---------------------------------------------------------------------------\n// Transaction builders (unsigned; caller signs + executes / sponsors)\n// ---------------------------------------------------------------------------\n\n/**\n * Buyer creates AND funds a job in one PTB — `escrow::create` consumes a\n * `Coin<USDC>` sourced from the buyer's coins + address balance.\n */\nexport async function buildCreateJobTx({\n client,\n buyer,\n terms,\n}: {\n client: SuiCoreClient;\n buyer: string;\n terms: JobTerms;\n}): Promise<Transaction> {\n const pf = preflightCreateJob(terms);\n if (!pf.valid) throw new T2000Error(pf.code, pf.error);\n\n const seller = validateAddress(terms.seller);\n if (seller === validateAddress(buyer)) {\n throw new T2000Error('INVALID_ADDRESS', 'Buyer and seller must be different wallets.');\n }\n // Floor, never round up — a rounded-up raw amount can exceed the on-chain\n // balance (financial-amounts discipline).\n const rawAmount = BigInt(Math.floor(terms.amountUsdc * 10 ** USDC_DECIMALS));\n\n const tx = new Transaction();\n const { coin } = await selectAndSplitCoin(tx, client, buyer, USDC_TYPE, rawAmount, {\n allowSwapAll: false,\n });\n tx.moveCall({\n target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::create`,\n typeArguments: [USDC_TYPE],\n arguments: [\n tx.pure.address(seller),\n coin,\n tx.pure.vector('u8', hexToBytes(terms.specHash)),\n tx.pure.u64(terms.deliverByMs),\n tx.pure.u64(terms.reviewWindowMs),\n tx.pure.u64(terms.rejectSplitBps),\n feeConfigArg(tx),\n tx.object(CLOCK_ID),\n ],\n });\n return tx;\n}\n\nfunction jobCall(jobId: string, fn: 'release' | 'refund' | 'reject'): Transaction {\n const tx = new Transaction();\n tx.moveCall({\n target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::${fn}`,\n typeArguments: [USDC_TYPE],\n arguments: [tx.object(jobId), feeConfigArg(tx), tx.object(CLOCK_ID)],\n });\n return tx;\n}\n\n/** Seller posts the delivery commitment (hex hash) before the deadline. */\nexport function buildDeliverJobTx(jobId: string, deliveryHash: string): Transaction {\n const tx = new Transaction();\n tx.moveCall({\n target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::deliver`,\n typeArguments: [USDC_TYPE],\n arguments: [\n tx.object(jobId),\n tx.pure.vector('u8', hexToBytes(deliveryHash)),\n feeConfigArg(tx),\n tx.object(CLOCK_ID),\n ],\n });\n return tx;\n}\n\n/** Buyer accepts (or anyone, once the review window lapsed) → funds to seller. */\nexport function buildReleaseJobTx(jobId: string): Transaction {\n return jobCall(jobId, 'release');\n}\n\n/** Buyer rejects within the review window → split per the create terms. */\nexport function buildRejectJobTx(jobId: string): Transaction {\n return jobCall(jobId, 'reject');\n}\n\n/** Anyone, after the deadline with no delivery → funds back to the buyer. */\nexport function buildRefundJobTx(jobId: string): Transaction {\n return jobCall(jobId, 'refund');\n}\n\n// ---------------------------------------------------------------------------\n// Reads\n// ---------------------------------------------------------------------------\n\n/** Fetch + parse a `Job` shared object. Throws `RPC_ERROR` when the id\n * doesn't resolve to an a2a_escrow Job. */\nexport async function getJob(client: SuiCoreClient, jobId: string): Promise<Job> {\n const resp = await client.core\n .getObject({ objectId: jobId, include: { json: true } })\n .catch((e: unknown) => {\n throw new T2000Error(\n 'RPC_ERROR',\n `Job ${jobId} not found: ${e instanceof Error ? e.message : String(e)}`,\n );\n });\n const objType = resp.object?.type ?? '';\n const json = resp.object?.json as Record<string, unknown> | null | undefined;\n if (!json || !objType.includes(`::${MODULE}::Job<`)) {\n throw new T2000Error('RPC_ERROR', `Object ${jobId} is not an a2a_escrow Job.`);\n }\n const stateNum = Number(json.state ?? -1);\n const state = JOB_STATES[stateNum];\n if (!state) {\n throw new T2000Error('RPC_ERROR', `Job ${jobId} has unknown state ${stateNum}.`);\n }\n const deliveredAtMs = Number(json.delivered_at_ms ?? 0);\n const deliveryBytes = (json.delivery_hash ?? []) as number[] | Uint8Array;\n const hasDelivery = deliveredAtMs > 0;\n return {\n id: jobId,\n buyer: String(json.buyer),\n seller: String(json.seller),\n amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,\n escrowUsdc: Number(json.escrow) / 10 ** USDC_DECIMALS,\n feeBps: Number(json.fee_bps ?? 0),\n specHash: bytesToHex((json.spec_hash ?? []) as number[] | Uint8Array),\n deliverByMs: Number(json.deliver_by_ms),\n reviewWindowMs: Number(json.review_window_ms),\n rejectSplitBps: Number(json.reject_split_bps),\n state,\n deliveryHash: hasDelivery ? bytesToHex(deliveryBytes) : null,\n deliveredAtMs: hasDelivery ? deliveredAtMs : null,\n createdAtMs: Number(json.created_at_ms),\n };\n}\n\n/** What `caller` can do to `job` right now — drives `t2 job watch` (the\n * ACP-style \"available action\" readout) and any host UI. */\nexport function jobActionsFor(\n job: Job,\n caller: string,\n nowMs = Date.now(),\n): string[] {\n const me = validateAddress(caller);\n const isBuyer = me === job.buyer;\n const isSeller = me === job.seller;\n const actions: string[] = [];\n if (job.state === 'funded') {\n if (isSeller && nowMs <= job.deliverByMs) actions.push('deliver');\n if (isBuyer) actions.push('release');\n if (nowMs > job.deliverByMs) actions.push('refund');\n } else if (job.state === 'delivered') {\n const windowClosesMs = (job.deliveredAtMs ?? 0) + job.reviewWindowMs;\n if (isBuyer && nowMs <= windowClosesMs) actions.push('release', 'reject');\n if (nowMs > windowClosesMs) actions.push('release');\n }\n return actions;\n}\n\nexport interface JobVerification {\n ok: boolean;\n job: Job;\n /** Human-readable reasons when `ok` is false. */\n problems: string[];\n}\n\n/**\n * Seller-side escrow verification — the x402 `intent: \"escrow\"` credential\n * check. Before starting work on a job id received in an `X-PAYMENT` header,\n * the seller confirms ON-CHAIN (works for every buyer signer, incl. zkLogin):\n * funded, pays ME, covers the price, and leaves enough runway to deliver.\n */\nexport async function verifyJobForSeller({\n client,\n jobId,\n seller,\n minAmountUsdc,\n minRunwayMs = 60_000,\n}: {\n client: SuiCoreClient;\n jobId: string;\n seller: string;\n /** The listing's price for this job class. */\n minAmountUsdc: number;\n /** Minimum time-to-deadline to accept the job (default 60s). */\n minRunwayMs?: number;\n}): Promise<JobVerification> {\n const job = await getJob(client, jobId);\n const problems: string[] = [];\n if (job.state !== 'funded') {\n problems.push(`state is \"${job.state}\", expected \"funded\"`);\n }\n if (job.seller !== validateAddress(seller)) {\n problems.push(`job pays ${job.seller}, not this seller`);\n }\n if (job.escrowUsdc < minAmountUsdc) {\n problems.push(`escrow holds ${job.escrowUsdc} USDC, price is ${minAmountUsdc}`);\n }\n if (job.deliverByMs - Date.now() < minRunwayMs) {\n problems.push('deadline too close to accept');\n }\n return { ok: problems.length === 0, job, problems };\n}\n","// Commerce API client (t2 ACP) — offerings + the content-addressed job-spec\n// store on api.t2000.ai. Shared by `@t2000/cli` (`t2 offering` / `t2 browse` /\n// `t2 job`) and `@t2000/mcp` (the t2000_offering_* / t2000_job_* tools) so the\n// tamper-verify logic exists exactly once.\n//\n// Browser-safe: hashing uses WebCrypto (`crypto.subtle`), available in every\n// browser and Node >= 18. No fs, no node:crypto.\n\nimport { truncateAddress } from './utils/sui.js';\n\nexport const DEFAULT_COMMERCE_API_BASE = 'https://api.t2000.ai/v1';\n\nasync function commerceFetchJson(\n url: string,\n init?: { method: string; body?: unknown },\n): Promise<Record<string, unknown>> {\n const res = await fetch(url, {\n method: init?.method ?? 'GET',\n headers: init?.body ? { 'Content-Type': 'application/json' } : undefined,\n body: init?.body ? JSON.stringify(init.body) : undefined,\n });\n const json = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n if (!res.ok) {\n const err = json.error;\n const msg =\n typeof err === 'string'\n ? err\n : ((err as { message?: string })?.message ?? `HTTP ${res.status}`);\n throw new Error(msg);\n }\n return json;\n}\n\n/** The shape the API returns from GET /v1/offerings. */\nexport interface OfferingListing {\n agent: string;\n agentName: string | null;\n agentNumericId: number | null;\n slug: string;\n name: string;\n description: string;\n priceUsdc: number;\n slaMinutes: number;\n reviewWindowMinutes: number;\n rejectSplitBps: number;\n requirements: unknown;\n deliverable: string;\n retired: boolean;\n}\n\n/** Browse / list offerings — free-text `query` across every agent, or one\n * agent's full catalog (retired included) via `agent`. */\nexport async function listOfferings(\n base: string,\n filter: { agent?: string; query?: string } = {},\n): Promise<{ total: number; offerings: OfferingListing[] }> {\n const params = new URLSearchParams();\n if (filter.agent) params.set('agent', filter.agent);\n if (filter.query) params.set('q', filter.query);\n const qs = params.size > 0 ? `?${params.toString()}` : '';\n const json = await commerceFetchJson(`${base}/offerings${qs}`);\n const offerings = (json.offerings ?? []) as OfferingListing[];\n return { total: (json.total as number | undefined) ?? offerings.length, offerings };\n}\n\n/** Fetch one agent's live offering by slug (the buy-path resolver). */\nexport async function fetchOffering(\n base: string,\n agent: string,\n slug: string,\n): Promise<OfferingListing> {\n const { offerings: rows } = await listOfferings(base, { agent });\n const match = rows.find((o) => o.slug === slug.trim().toLowerCase());\n if (!match) {\n const live = rows.filter((o) => !o.retired).map((o) => o.slug);\n throw new Error(\n `Agent ${truncateAddress(agent)} has no offering \"${slug}\".` +\n (live.length > 0 ? ` Live offerings: ${live.join(', ')}` : ''),\n );\n }\n if (match.retired) {\n throw new Error(\n `Offering \"${slug}\" is retired — the seller no longer sells it.`,\n );\n }\n return match;\n}\n\nasync function sha256Hex(content: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n 'SHA-256',\n new TextEncoder().encode(content),\n );\n return Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/** Upload a job-spec payload to the content-addressed store; returns the\n * sha256 (no 0x) the chain pins as `spec_hash`. */\nexport async function putJobSpec(base: string, content: string): Promise<string> {\n const json = await commerceFetchJson(`${base}/job/spec`, {\n method: 'POST',\n body: { content },\n });\n const hash = json.hash as string | undefined;\n if (!hash) {\n throw new Error('Failed to store the job spec.');\n }\n return hash;\n}\n\n/** Fetch a job-spec payload by hash and VERIFY it (sha256(content) == hash —\n * the store is untrusted; the chain hash is the authority). */\nexport async function getJobSpec(base: string, hash: string): Promise<string> {\n const clean = hash.trim().toLowerCase().replace(/^0x/, '');\n const json = await commerceFetchJson(`${base}/job/spec/${clean}`);\n const content = json.content as string | undefined;\n if (content === undefined) {\n throw new Error('No spec stored for this hash.');\n }\n const actual = await sha256Hex(content);\n if (actual !== clean) {\n throw new Error(\n 'Spec content does NOT match its hash — the store returned tampered data. Do not trust it.',\n );\n }\n return content;\n}\n","/**\n * SPEC 7 v0.4 § Layer 0 — Canonical Write Architecture.\n *\n * `composeTx({ steps })` is the single canonical entry-point for every\n * Audric Enoki-sponsored write. The fragment-appender pattern (Layer 1)\n * is the implementation; this primitive dispatches each step to its\n * registered appender from the typed `WRITE_APPENDER_REGISTRY`.\n *\n * Single-write and multi-write go through the same code path. A 1-step\n * `composeTx([{ toolName: 'send_transfer', input: {...} }])` produces\n * the same shape of result as a 3-step bundle.\n *\n * **Why this exists**\n *\n * Pre-Layer-0, four parallel write stacks lived across the audric host:\n * `transactions/prepare` (fat ~600-line route), `services/prepare`\n * (hand-rolled), `debug-swap` (diagnostic), and PayButton (dapp-kit).\n * Each one re-implemented merge/split/transfer + hand-maintained the\n * `allowedAddresses` array Enoki requires. Two production bugs in the\n * past 60 days came from drift between them — PR-H1 (claim-rewards\n * self-transfer missing from allowedAddresses) and PR-H4 (borrow/\n * withdraw self-transfer same bug).\n *\n * Layer 0 collapses 3 of those stacks into one canonical primitive.\n * PayButton stays out by design (different signer, different trust\n * model — see `audric-canonical-write.mdc` for the rationale and the\n * `// CANONICAL-BYPASS:` escape-hatch contract).\n *\n * **What composeTx owns**\n *\n * - PTB assembly via per-tool wallet-mode appenders (the\n * `WRITE_APPENDER_REGISTRY`).\n * - Pre-built `txKindBytes` (`tx.build({ onlyTransactionKind: true })`)\n * ready for Enoki's `createSponsoredTransaction`.\n * - Auto-derived `derivedAllowedAddresses` from the assembled PTB's\n * top-level `transferObjects` calls — eliminates the PR-H1/H4 bug\n * class permanently. Hand-maintained arrays are now unreachable.\n * - S.38 Pyth flag plumbing — `sponsoredContext: true` automatically\n * applies `skipPythUpdate` (borrow/withdraw) and `skipOracle` (repay)\n * to NAVI appenders so Enoki doesn't reject `tx.gas`-as-argument.\n *\n * **What composeTx does NOT own**\n *\n * - **Fees** — Audric concern, not @t2000/sdk concern (CLAUDE.md\n * rule #9). The SDK is fee-free by design as of @t2000/sdk@1.1.0\n * (B5 v2). Audric host wraps composeTx with fee insertion in P2.2c.\n * - **Sponsorship** — caller's job. composeTx returns `txKindBytes`\n * pre-built for Enoki; the caller calls `createSponsoredTransaction`\n * with their JWT.\n * - **Chain-mode coin handoff between steps** — Layer 2 (engine\n * bundling) ships this. P2.2b is wallet-mode-only: each step fetches\n * coins independently. Layer 2 will extend by introducing\n * `inputCoinFromStep: number` to thread upstream output coins.\n *\n * **Cross-references**\n *\n * - Spec → `spec/SPEC_7_MULTI_WRITE_PTB.md` § \"Layer 0: Canonical\n * Write Architecture\"\n * - Read-side companion → `t2000/.cursor/rules/single-source-of-truth.mdc`\n * + `audric/.cursor/rules/audric-canonical-portfolio.mdc`\n * - Write-side rule → `audric/.cursor/rules/audric-canonical-write.mdc`\n */\n\nimport type { SuiCoreClient } from './utils/sui.js';\nimport {\n Transaction,\n type TransactionObjectArgument,\n} from '@mysten/sui/transactions';\nimport type { OverlayFeeConfig } from './protocols/cetus-swap.js';\nimport { addSwapToTx, type SwapRouteResult } from './protocols/cetus-swap.js';\nimport { addSendToTx } from './wallet/send.js';\nimport {\n selectSuiCoin,\n type SponsoredCoinMergeCache,\n} from './wallet/coinSelection.js';\nimport { resolveTokenType, getDecimalsForCoinType, SUI_TYPE } from './token-registry.js';\nimport {\n GASLESS_MIN_STABLE_AMOUNT,\n GASLESS_STABLE_TYPES,\n SUPPORTED_ASSETS,\n assertAllowedAsset,\n type SendableAsset,\n type SupportedAsset,\n} from './constants.js';\nimport { T2000Error } from './errors.js';\nimport { validateAddress } from './utils/sui.js';\n\n/**\n * Canonical write tools. The 8 tools that can be composed into a PTB.\n *\n * History:\n * - 2026-05-08 (Track B): added `harvest_rewards` (compound macro).\n * - 2026-05-25 (S.323): removed `volo_stake` / `volo_unstake` — full Volo\n * cut across SDK/CLI/MCP after the engine cut Volo in S.277. vSUI\n * remains as a passive token (NAVI reward, Cetus swap target).\n *\n * Excluded by design:\n * - `save_contact` — no on-chain leg (Prisma-only).\n */\n// [S.444 — NAVI/DeFi removed] Canonical write tools narrowed to the two\n// surviving on-chain verbs: gasless send + Cetus swap. save/withdraw/borrow/\n// repay/claim/harvest were deleted with NAVI (v2 keeps them on @t2000/sdk@4.x).\nexport type WriteToolName =\n | 'send_transfer'\n | 'swap_execute';\n\n// Per-tool input contracts. Match the engine tool input schemas, not the\n// audric host's loosely-typed `params` blob — the registry is the typed\n// surface that lets the host shed the `any`-typed switch statement.\n\n/**\n * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]\n * `asset` is now REQUIRED (no more silent USDC default). The parameter\n * type is the wider `SupportedAsset` rather than the narrower\n * `SendableAsset` so callers that thread a wide-typed asset through\n * (primarily the engine LLM tool surface) compile without modification.\n * Runtime narrowing happens via `assertAllowedAsset('send', asset)`,\n * which throws `INVALID_ASSET` for anything outside the\n * `['USDC', 'USDsui', 'SUI']` whitelist. USDC + USDsui route through\n * the gasless `0x2::balance::send_funds` Move call; SUI uses the\n * standard `transferObjects` path.\n *\n * Audric hosts: the audric chat client (`audric-chat-client.tsx`)\n * already defaults asset to `'USDC'` at the marker layer before\n * calling `sponsoredTx({ type: 'send' })`, so this signature change\n * doesn't break the LLM flow. LLM intents like \"send 5 WAL\" now\n * surface a clear error instead of silently building a non-gasless\n * tx.\n */\nexport interface SendTransferInput {\n to: string;\n amount: number;\n asset: SupportedAsset;\n}\n\nexport interface SwapExecuteInput {\n from: string;\n to: string;\n amount: number;\n slippage?: number;\n byAmountIn?: boolean;\n /** Cetus provider allow-list. Sponsored callers MUST pass an exclusion list\n * to remove Pyth-dependent providers — see addSwapToTx JSDoc. composeTx\n * derives this automatically from `sponsoredContext` if omitted. */\n providers?: string[];\n /**\n * [SPEC 20.2 / D-1 (a)] Optional precomputed Cetus route discovered at\n * `swap_quote` time. Bypasses `findSwapRoute()` (-400-500ms) inside\n * `addSwapToTx`. Caller (audric prepare-route) is responsible for\n * coin-type verification (D-2) + freshness check (D-3) before passing.\n * `addSwapToTx` performs an additional sanity check on `amountIn` +\n * `byAmountIn` and falls back to fresh discovery on mismatch.\n */\n precomputedRoute?: SwapRouteResult;\n}\n\n/**\n * Discriminated union mapping `toolName` → `input`. Used to type\n * `WriteStep` so consumers get autocomplete + compile-time validation\n * that the input matches the tool.\n *\n * **[SPEC 13 Phase 1] `inputCoinFromStep`** — consumer steps may\n * reference an earlier step's output coin handle by index. When set,\n * `composeTx`'s orchestration loop threads the producer's\n * `outputCoin` into this step's appender as the `inputCoin` arg,\n * bypassing the wallet pre-fetch path. The producer's terminal\n * `tx.transferObjects([coin], sender)` is suppressed automatically so\n * the same handle isn't double-consumed.\n */\nexport type WriteStep =\n | { toolName: 'send_transfer'; input: SendTransferInput; inputCoinFromStep?: number }\n | { toolName: 'swap_execute'; input: SwapExecuteInput; inputCoinFromStep?: number };\n\nexport interface ComposeTxOptions {\n sender: string;\n steps: WriteStep[];\n client: SuiCoreClient;\n /**\n * S.38 Pyth flag (sponsorship-critical). When true:\n * - NAVI borrow/withdraw appenders apply `skipPythUpdate: true`\n * (preserves on-chain price-feed updates, skips the tx.gas-using\n * Pyth fee payment that Enoki rejects).\n * - NAVI repay appender applies `skipOracle: true` (debt reduction\n * has no health-factor risk, full oracle bypass is safe).\n * - Cetus swap appender applies `getProvidersExcluding([HAEDALPMM,\n * METASTABLE, OBRIC, STEAMM_OMM, STEAMM_OMM_V2, SEVENK,\n * HAEDALHMMV2])` — Pyth-dependent providers reference `tx.gas` for\n * oracle fees, also rejected by Enoki.\n * - SUI sends fetch coins via `getCoins` (tx.gas belongs to sponsor,\n * not user) instead of splitting from `tx.gas`.\n *\n * Self-funded callers (CLI, MCP, server tasks) leave this `false` /\n * omit — they pay all oracle/Pyth fees from their own SUI gas.\n */\n sponsoredContext?: boolean;\n /**\n * Per-call overlay fee config for Cetus swaps. Audric host passes\n * `{ rate: 0.001, receiver: T2000_OVERLAY_FEE_WALLET }` to charge the\n * 0.1% swap overlay. CLI / direct SDK callers omit. Forwarded to\n * `addSwapToTx`'s `input.overlayFee`.\n */\n overlayFee?: OverlayFeeConfig;\n}\n\n/** Per-step preview returned by each registry appender. Tool-specific shape. */\nexport type StepPreview =\n | { toolName: 'send_transfer'; effectiveAmount: number; recipient: string; asset: SendableAsset }\n | { toolName: 'swap_execute'; effectiveAmountIn: number; expectedAmountOut: number; route: SwapRouteResult };\n\nexport interface ComposeTxResult {\n tx: Transaction;\n /**\n * Pre-built bytes for Enoki's `createSponsoredTransaction`. Built\n * with `onlyTransactionKind: true` so the gas coin can be supplied\n * by the sponsor.\n */\n txKindBytes: Uint8Array;\n /**\n * Auto-derived from the assembled PTB's top-level `transferObjects`\n * commands. Replaces hand-maintained `allowedAddresses` arrays in\n * audric host's `transactions/prepare` + `services/prepare` —\n * eliminates the PR-H1/H4 bug class permanently.\n */\n derivedAllowedAddresses: string[];\n perStepPreviews: StepPreview[];\n}\n\n/**\n * Per-appender context passed into every registry entry. Carries the\n * RPC client, sender, sponsorship flag, optional per-call overlay\n * fee config (Cetus swaps), and SPEC 13 Phase 1 chain-mode fields.\n */\nexport interface AppenderContext {\n client: SuiCoreClient;\n sender: string;\n sponsoredContext: boolean;\n overlayFee?: OverlayFeeConfig;\n /**\n * [SPEC 13 Phase 1] When set, the consumer appender consumes this\n * coin handle directly instead of pre-fetching from the wallet via\n * `selectAndSplitCoin` / `selectSuiCoin`. Provided by the\n * orchestration loop when the step has `inputCoinFromStep` set; the\n * loop looks up `priorOutputs[step.inputCoinFromStep]` and threads\n * it through here.\n *\n * In chain mode, the consumer consumes the handle IN FULL — the\n * `input.amount` field is treated as informational (used for preview\n * math). This matches Cetus's `routerSwap`, NAVI's `deposit`/`repay`,\n * and the Sui `transferObjects` semantics: each takes a coin object\n * and consumes its entire balance.\n */\n chainedCoin?: TransactionObjectArgument;\n /**\n * [SPEC 13 Phase 1] True when this step's output coin will be\n * consumed by a downstream step (some later step has\n * `inputCoinFromStep === currentStepIndex`). Producer appenders MUST\n * skip their terminal `tx.transferObjects([coin], ctx.sender)` call\n * when this is true — otherwise the same `TransactionObjectArgument`\n * gets used twice (once by the consumer, once by the transfer) and\n * the PTB build fails or the on-chain leg reverts.\n */\n isOutputConsumed?: boolean;\n /**\n * Per-PTB merge cache for sponsored coin-object sourcing, shared across\n * every appender in a single `composeTx` run. Lets multiple legs that\n * source the same coin type (two SUI swaps, swap USDC + save USDC, etc.)\n * reuse a single merged primary coin instead of each re-fetching +\n * re-merging the same coin objects (the second merge of which references\n * already-consumed coins → Enoki dry-run `ArgumentWithoutValue`). Applies\n * to ALL coin types, not just SUI. See `SponsoredCoinMergeCache` JSDoc.\n */\n coinMergeCache?: SponsoredCoinMergeCache;\n}\n\n/**\n * [SPEC 13 Phase 1] Appender return shape. Producers populate\n * `outputCoin` so the orchestration loop can thread it into a\n * downstream consumer's `chainedCoin`. The terminal consumer\n * (`send_transfer`) omits it.\n *\n * `swap_execute` is the only dual-mode tool — it accepts `chainedCoin`\n * AND populates `outputCoin`. (Pre-S.444 the DeFi tools\n * save/withdraw/borrow/repay were also producers/consumers; removed with NAVI.)\n */\nexport interface AppenderResult<TPreview extends StepPreview> {\n preview: TPreview;\n outputCoin?: TransactionObjectArgument;\n}\n\ntype AppenderFn<TInput, TPreview extends StepPreview> = (\n tx: Transaction,\n input: TInput,\n ctx: AppenderContext,\n) => Promise<AppenderResult<TPreview>>;\n\n/**\n * Cetus provider exclusion list for sponsored flows. Mirrors the\n * audric host's `SPONSORED_TX_PROVIDERS` constant — these 7 providers\n * reference `tx.gas` for Pyth oracle fee payments, which Enoki rejects.\n *\n * NOTE: keeping this hardcoded means `findSwapRoute` doesn't need a\n * dependency on `@cetusprotocol/aggregator-sdk`'s `getProvidersExcluding`\n * helper — composeTx forwards the literal list to Cetus, Cetus does the\n * inverse lookup. Result is identical.\n */\nexport const SPONSORED_PYTH_DEPENDENT_PROVIDERS = [\n 'HAEDALPMM',\n 'METASTABLE',\n 'OBRIC',\n 'STEAMM_OMM',\n 'STEAMM_OMM_V2',\n 'SEVENK',\n 'HAEDALHMMV2',\n] as const;\n\n/**\n * Get all eligible Cetus provider names except the Pyth-dependent ones,\n * for sponsored swap context. Computed from the Cetus SDK's\n * `getAllProviders()` minus the exclusion list.\n *\n * [Bug A fix / 2026-05-10] Exported so the engine's `swap_quote` tool can\n * call this when discovering routes for sponsored hosts. Previously the\n * engine only exclude these providers at COMPOSE time; now it excludes\n * at QUOTE time too, so the precomputed route stashed on\n * `pending_action.cetusRoute` is always sponsor-safe.\n */\nexport async function getSponsoredSwapProviders(): Promise<string[]> {\n const { getProvidersExcluding } = await import('@cetusprotocol/aggregator-sdk');\n return getProvidersExcluding([...SPONSORED_PYTH_DEPENDENT_PROVIDERS]);\n}\n\n/**\n * The typed registry. Each entry is a wallet-mode dispatcher that takes\n * (tx, input, ctx) and returns a per-step preview. Compile-time check\n * that all `WriteToolName` values have an entry — TypeScript will\n * fail the build if a tool is missing.\n *\n * [S.444] Narrowed to send_transfer + swap_execute after the NAVI/DeFi cut.\n */\nexport const WRITE_APPENDER_REGISTRY: {\n send_transfer: AppenderFn<SendTransferInput, Extract<StepPreview, { toolName: 'send_transfer' }>>;\n swap_execute: AppenderFn<SwapExecuteInput, Extract<StepPreview, { toolName: 'swap_execute' }>>;\n} = {\n send_transfer: async (tx, input, ctx) => {\n const recipient = validateAddress(input.to);\n // [v4.0 Phase A Day 2] Asset is required (no `?? 'USDC'` default).\n // assertAllowedAsset narrows the runtime value to\n // `'USDC' | 'USDsui' | 'SUI'` and throws INVALID_ASSET otherwise.\n // The TypeScript shape is `SupportedAsset` (wider, accommodates\n // engine LLM tool callers that pass wide-typed assets through);\n // the runtime assertion is the canonical gate.\n if (!input.asset) {\n throw new T2000Error(\n 'INVALID_ASSET',\n \"send_transfer requires an explicit asset. Use one of: USDC, USDsui, SUI.\",\n );\n }\n assertAllowedAsset('send', input.asset);\n const asset: SendableAsset = input.asset as SendableAsset;\n const assetInfo = SUPPORTED_ASSETS[asset];\n if (input.amount <= 0) {\n throw new T2000Error('INVALID_AMOUNT', 'Send amount must be greater than zero');\n }\n\n const rawAmount = BigInt(Math.floor(input.amount * 10 ** assetInfo.decimals));\n\n // [v4.0 Phase A Day 2] Chain-mode (`chainedCoin` from a previous\n // appender) ALWAYS uses the legacy `transferObjects` path —\n // bundles never qualify for gasless because the protocol allowlist\n // only accepts PTBs whose ops are `balance::send_funds` /\n // `balance::redeem_funds` / `coin::send_funds` etc. A withdraw →\n // send bundle has the withdraw Move call, so the whole tx pays gas.\n if (ctx.chainedCoin) {\n addSendToTx(tx, ctx.chainedCoin, recipient);\n return {\n preview: {\n toolName: 'send_transfer',\n effectiveAmount: Number(rawAmount) / 10 ** assetInfo.decimals,\n recipient,\n asset,\n },\n };\n }\n\n if (asset === 'SUI') {\n // Standard gas-native SUI transfer — NOT gasless (SUI is not on\n // the protocol `balance::send_funds` allowlist).\n const result = await selectSuiCoin(\n tx,\n ctx.client,\n ctx.sender,\n rawAmount,\n ctx.sponsoredContext,\n ctx.coinMergeCache,\n );\n addSendToTx(tx, result.coin, recipient);\n return {\n preview: {\n toolName: 'send_transfer',\n effectiveAmount: Number(result.effectiveAmount) / 10 ** assetInfo.decimals,\n recipient,\n asset,\n },\n };\n }\n\n // USDC / USDsui — gasless single-step send via `0x2::balance::send_funds`.\n // Surfaces the protocol's 0.01 minimum BEFORE building so we don't\n // burn a sponsorship slot on a tx that will revert on-chain.\n if (input.amount < GASLESS_MIN_STABLE_AMOUNT) {\n throw new T2000Error(\n 'INVALID_AMOUNT',\n `Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${asset}. Got ${input.amount}.`,\n );\n }\n // Pre-flight balance check (composeTx's selectAndSplitCoin used to\n // do this; we lose the coin-selection but keep the balance gate so\n // build-time errors stay actionable for audric's prepare route).\n const balanceResp = await ctx.client.core.getBalance({ owner: ctx.sender, coinType: assetInfo.type });\n if (BigInt(balanceResp.balance.balance) < rawAmount) {\n throw new T2000Error('INSUFFICIENT_BALANCE', `Insufficient ${asset} balance`, {\n available: Number(balanceResp.balance.balance) / 10 ** assetInfo.decimals,\n required: input.amount,\n });\n }\n const coinType = GASLESS_STABLE_TYPES[asset];\n tx.moveCall({\n target: '0x2::balance::send_funds',\n typeArguments: [coinType],\n arguments: [\n tx.balance({ type: coinType, balance: rawAmount }),\n tx.pure.address(recipient),\n ],\n });\n return {\n preview: {\n toolName: 'send_transfer',\n effectiveAmount: Number(rawAmount) / 10 ** assetInfo.decimals,\n recipient,\n asset,\n },\n };\n },\n\n swap_execute: async (tx, input, ctx) => {\n const fromType = resolveTokenType(input.from);\n const toType = resolveTokenType(input.to);\n if (!fromType || !toType) {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n `Unknown token in swap: from=${input.from}, to=${input.to}`,\n );\n }\n\n const providers = input.providers\n ?? (ctx.sponsoredContext ? await getSponsoredSwapProviders() : undefined);\n\n const result = await addSwapToTx(tx, ctx.client, ctx.sender, {\n from: input.from,\n to: input.to,\n amount: input.amount,\n slippage: input.slippage,\n byAmountIn: input.byAmountIn,\n overlayFee: ctx.overlayFee,\n providers,\n inputCoin: ctx.chainedCoin,\n precomputedRoute: input.precomputedRoute,\n sponsoredContext: ctx.sponsoredContext,\n coinMergeCache: ctx.coinMergeCache,\n });\n if (!ctx.isOutputConsumed) {\n tx.transferObjects([result.coin], ctx.sender);\n }\n return {\n preview: {\n toolName: 'swap_execute',\n effectiveAmountIn: result.effectiveAmountIn,\n expectedAmountOut: result.expectedAmountOut,\n route: result.route,\n },\n outputCoin: result.coin,\n };\n },\n\n // [S.444] claim_rewards / harvest_rewards appenders removed with NAVI.\n // [S.323] volo_stake / volo_unstake appenders removed earlier.\n};\n\n// Reference unused import to suppress noUnusedLocals; SUI_TYPE is used\n// by selectSuiCoin internally and re-export from index.ts.\nvoid SUI_TYPE;\nvoid getDecimalsForCoinType;\n\n/**\n * Walks the assembled PTB's command list and extracts every recipient\n * address from top-level `TransferObjects` commands. Top-level only —\n * recipients inside nested Move calls are NOT inspected (Enoki only\n * cross-checks top-level commands).\n *\n * Replaces hand-maintained `allowedAddresses` arrays. Two production\n * bugs in 60 days came from drift between the array and the actual\n * PTB recipients (PR-H1 + PR-H4). Computing this from the PTB makes\n * drift impossible by construction.\n */\nexport function deriveAllowedAddressesFromPtb(tx: Transaction): string[] {\n const addresses = new Set<string>();\n const data = tx.getData();\n\n const addAddressFromInput = (inputIndex: number | undefined): void => {\n if (inputIndex === undefined) return;\n const input = data.inputs[inputIndex];\n if (!input) return;\n const pureBytes = (input as { Pure?: { bytes?: string } }).Pure?.bytes;\n if (!pureBytes) return;\n // Pure bytes are base64-encoded BCS for Sui addresses (32 bytes →\n // 44-char base64). Decode + format as 0x-prefixed hex.\n try {\n const bytes = base64ToBytes(pureBytes);\n if (bytes.length !== 32) return; // not an address\n const hex = '0x' + Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');\n addresses.add(hex);\n } catch {\n // not a parseable address — skip\n }\n };\n\n for (const cmd of data.commands) {\n // Path 1 — `TransferObjects.address` (the legacy send/withdraw/\n // claim/fee-transfer recipient surface). The Sui transaction-builder\n // stores each top-level command as a tagged object:\n // { TransferObjects: { objects, address: { Input: <index> } } }.\n const transferCmd = (cmd as { TransferObjects?: unknown }).TransferObjects;\n if (transferCmd) {\n const addressArg = (transferCmd as { address?: unknown }).address;\n const addressInputIndex = (addressArg as { Input?: number } | undefined)?.Input;\n addAddressFromInput(addressInputIndex);\n continue;\n }\n\n // Path 2 — `0x2::balance::send_funds(balance, recipient)` (gasless\n // stablecoin transfer, v4.0 Phase A Day 2). Recipient is arg[1],\n // not a TransferObjects.address. The Move call shape:\n // { MoveCall: { package, module, function, arguments: [...] } }\n // target = `0x2::balance::send_funds`, arguments[1] = recipient.\n const moveCall = (cmd as { MoveCall?: unknown }).MoveCall;\n if (moveCall) {\n const mc = moveCall as {\n package?: string;\n module?: string;\n function?: string;\n arguments?: Array<{ Input?: number } | unknown>;\n };\n // The `package` field is the normalized framework address. For\n // `0x2::balance::send_funds` it's `0x0000…0002` (`SUI_FRAMEWORK_ADDRESS`).\n // Match on module + function defensively; the recipient extraction\n // only fires when the signature matches.\n const isBalanceSendFunds =\n mc.module === 'balance' && mc.function === 'send_funds';\n const isCoinSendFunds =\n mc.module === 'coin' && mc.function === 'send_funds';\n if (isBalanceSendFunds || isCoinSendFunds) {\n const args = mc.arguments ?? [];\n const recipientArg = args[1] as { Input?: number } | undefined;\n addAddressFromInput(recipientArg?.Input);\n }\n continue;\n }\n }\n\n return Array.from(addresses);\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(b64, 'base64'));\n }\n // Browser fallback (in case this ever runs in a worker)\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\n/**\n * Compose a PTB from a list of canonical write steps. Each step\n * dispatches to its registered fragment-appender; the assembled PTB is\n * returned alongside pre-built `txKindBytes` ready for Enoki sponsorship\n * + auto-derived `derivedAllowedAddresses`.\n *\n * Single-step: `composeTx({ steps: [{ toolName: 'send_transfer', input: {...} }], ... })`\n * Multi-step (Layer 2): `composeTx({ steps: [{...}, {...}, {...}], ... })`\n *\n * Throws:\n * - `T2000Error('NO_APPENDER')` — unknown `toolName`\n * - Any error thrown by the per-step appender (insufficient balance,\n * asset not supported, route not found, etc.) — propagates as-is.\n */\nexport async function composeTx(opts: ComposeTxOptions): Promise<ComposeTxResult> {\n const tx = new Transaction();\n tx.setSender(opts.sender);\n\n const baseCtx = {\n client: opts.client,\n sender: opts.sender,\n sponsoredContext: opts.sponsoredContext ?? false,\n overlayFee: opts.overlayFee,\n // One cache per compose run — shared across all legs (any coin type)\n // so multi-leg sponsored bundles that source the same coin (two SUI\n // swaps, swap USDC + save USDC, ...) merge that coin's objects once.\n coinMergeCache: new Map() as SponsoredCoinMergeCache,\n };\n\n // [SPEC 13 Phase 1] First pass: validate every `inputCoinFromStep`\n // reference and build the `consumedSteps` set. Forward-only\n // references; producer-only tools can't be consumers.\n const consumedSteps = new Set<number>();\n for (let i = 0; i < opts.steps.length; i++) {\n const step = opts.steps[i];\n const stepWithChain = step as { inputCoinFromStep?: number };\n const idx = stepWithChain.inputCoinFromStep;\n if (idx === undefined) continue;\n\n if (!Number.isInteger(idx) || idx < 0 || idx >= i) {\n throw new T2000Error(\n 'CHAIN_MODE_INVALID',\n `Step ${i} (${step.toolName}) has inputCoinFromStep=${idx}, ` +\n `which must be a non-negative integer < ${i} (forward-only references).`,\n );\n }\n\n const producer = opts.steps[idx];\n if (producer.toolName === 'send_transfer') {\n throw new T2000Error(\n 'CHAIN_MODE_INVALID',\n `Step ${i} (${step.toolName}) references step ${idx} (${producer.toolName}) as ` +\n `producer, but 'send_transfer' is a terminal consumer that does not ` +\n `produce a chainable coin handle. Allowed producers: swap_execute.`,\n );\n }\n\n consumedSteps.add(idx);\n }\n\n // [SPEC 13 Phase 1] Second pass: dispatch each step in order,\n // capturing producers' output handles in `priorOutputs` and threading\n // them into consumers' `chainedCoin`.\n const priorOutputs: (TransactionObjectArgument | null)[] = [];\n const previews: StepPreview[] = [];\n for (let i = 0; i < opts.steps.length; i++) {\n const step = opts.steps[i];\n const appender = (WRITE_APPENDER_REGISTRY as Record<string, AppenderFn<unknown, StepPreview>>)[step.toolName];\n if (!appender) {\n throw new T2000Error(\n 'UNKNOWN',\n `No fragment appender registered for tool '${step.toolName}'. ` +\n `Allowed: ${(Object.keys(WRITE_APPENDER_REGISTRY) as WriteToolName[]).join(', ')}`,\n );\n }\n\n const stepWithChain = step as { inputCoinFromStep?: number };\n let chainedCoin: TransactionObjectArgument | undefined;\n if (stepWithChain.inputCoinFromStep !== undefined) {\n const upstream = priorOutputs[stepWithChain.inputCoinFromStep];\n if (!upstream) {\n // Producer didn't return an outputCoin (shouldn't happen given the\n // first-pass guard, but defends against future appender bugs).\n throw new T2000Error(\n 'CHAIN_MODE_INVALID',\n `Step ${i} (${step.toolName}) expected a coin handle from step ` +\n `${stepWithChain.inputCoinFromStep}, but the producer did not return one.`,\n );\n }\n chainedCoin = upstream;\n }\n\n const stepCtx: AppenderContext = {\n ...baseCtx,\n chainedCoin,\n isOutputConsumed: consumedSteps.has(i),\n };\n\n const result = await appender(tx, step.input, stepCtx);\n priorOutputs.push(result.outputCoin ?? null);\n previews.push(result.preview);\n }\n\n const txKindBytes = await tx.build({ client: opts.client, onlyTransactionKind: true });\n const derivedAllowedAddresses = deriveAllowedAddressesFromPtb(tx);\n\n return {\n tx,\n txKindBytes,\n derivedAllowedAddresses,\n perStepPreviews: previews,\n };\n}\n","import { Transaction } from '@mysten/sui/transactions';\nimport { T2000Error } from '../errors.js';\nimport { mapMoveAbortCode } from '../errors.js';\nimport type { SuiCoreClient } from './sui.js';\n\nexport interface SimulationResult {\n success: boolean;\n gasEstimateSui: number;\n error?: {\n moveAbortCode?: number;\n moveModule?: string;\n reason: string;\n rawError: string;\n };\n}\n\nexport async function simulateTransaction(\n client: SuiCoreClient,\n tx: Transaction,\n sender: string,\n): Promise<SimulationResult> {\n tx.setSender(sender);\n\n try {\n // [gRPC migration] `core.simulateTransaction` replaces `dryRunTransactionBlock`.\n // It returns a discriminated union; effects.status is `{ success, error }`\n // where `error` is a structured `ExecutionError` (not the legacy raw string).\n const txBytes = await tx.build({ client });\n const sim = await client.core.simulateTransaction({\n transaction: txBytes,\n include: { effects: true },\n });\n const txn = sim.$kind === 'Transaction' ? sim.Transaction : sim.FailedTransaction;\n const effects = txn.effects;\n const gasUsed = effects?.gasUsed;\n\n const gasEstimateSui = gasUsed\n ? (Number(gasUsed.computationCost) +\n Number(gasUsed.storageCost) -\n Number(gasUsed.storageRebate)) / 1e9\n : 0;\n\n const errObj = effects && !effects.status.success ? effects.status.error : undefined;\n if (sim.$kind === 'FailedTransaction' || errObj) {\n const rawError = errObj?.message ?? 'Unknown simulation error';\n // Prefer the structured MoveAbort code; fall back to regex-parsing the\n // message for non-abort errors / pre-structured formats.\n const structuredAbort =\n errObj?.$kind === 'MoveAbort' ? Number(errObj.MoveAbort.abortCode) : undefined;\n const parsed = parseMoveAbort(rawError);\n const abortCode = structuredAbort ?? parsed.abortCode;\n\n return {\n success: false,\n gasEstimateSui,\n error: {\n moveAbortCode: abortCode,\n moveModule: parsed.module,\n reason: abortCode != null ? mapMoveAbortCode(abortCode) : parsed.reason,\n rawError,\n },\n };\n }\n\n return { success: true, gasEstimateSui };\n } catch (err) {\n const rawError = err instanceof Error ? err.message : String(err);\n return {\n success: false,\n gasEstimateSui: 0,\n error: {\n reason: 'Simulation failed: ' + rawError,\n rawError,\n },\n };\n }\n}\n\nexport function throwIfSimulationFailed(sim: SimulationResult): void {\n if (sim.success) return;\n\n throw new T2000Error(\n 'SIMULATION_FAILED',\n sim.error?.reason ?? 'Transaction simulation failed',\n {\n moveAbortCode: sim.error?.moveAbortCode,\n moveModule: sim.error?.moveModule,\n reason: sim.error?.reason,\n rawError: sim.error?.rawError,\n },\n );\n}\n\nfunction parseMoveAbort(errorStr: string): {\n abortCode?: number;\n module?: string;\n reason: string;\n} {\n // Pattern: MoveAbort(MoveLocation { module: ModuleId { ... name: \"module\" }, ... }, code)\n const abortMatch = errorStr.match(/MoveAbort\\([^,]*,\\s*(\\d+)\\)/);\n const moduleMatch = errorStr.match(/name:\\s*Identifier\\(\"([^\"]+)\"\\)/);\n\n if (abortMatch) {\n const code = parseInt(abortMatch[1], 10);\n const module = moduleMatch?.[1];\n const reason = mapMoveAbortCode(code);\n return { abortCode: code, module, reason };\n }\n\n // Pattern: MovePrimitiveRuntimeError\n if (errorStr.includes('MovePrimitiveRuntimeError')) {\n const module = moduleMatch?.[1];\n return {\n module,\n reason: `Move runtime error in ${module ?? 'unknown'} module`,\n };\n }\n\n return { reason: errorStr };\n}\n","/**\n * SuiNS leaf-subname builders for the `audric.sui` parent NFT.\n *\n * Used by SPEC 10 v0.2.1 Phase A.1 — Audric Passport Identity. Lets the audric host\n * mint and revoke `username.audric.sui` leaves under the parent NFT held by the\n * dedicated custody address (`0xaca29165…23d11`).\n *\n * **Why a dedicated SDK module (not inline in the audric route):**\n * - Consumers (audric/web's `/api/identity/{reserve,change,release}` routes) can import\n * the canonical builder shape without re-discovering the `SuinsTransaction` API.\n * - Single source of truth for the parent NFT ID + parent name.\n * - Single source of truth for label validation (length / charset / hyphen rules).\n *\n * **Signer model — read this before wiring into a route:**\n * These builders are signed by the **service account** (the parent NFT custody address),\n * NOT by the user's zkLogin key. Per `audric/.cursor/rules/audric-canonical-write.mdc`,\n * the SPEC 10 leaf-mint API routes are explicitly documented as a CANONICAL-BYPASS of\n * the `composeTx` write contract — they are server-to-server, the user's key is never\n * in the loop, and Enoki sponsors the gas. PTB atomicity requires single-signer, so\n * leaf mints cannot be bundled with chat-agent writes via composeTx.\n *\n * **Reference:** `spec/runbooks/RUNBOOK_audric_sui_parent.md` §1 (parent NFT ID) +\n * §3 (validated SDK reference shape) + §4 (mainnet smoke test 2026-05-01).\n */\n\nimport { Transaction } from '@mysten/sui/transactions';\nimport { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport { SuinsTransaction, type SuinsClient } from '@mysten/suins';\n\n/**\n * Parent name registered on SuiNS mainnet. Audric's identity namespace anchor.\n *\n * Every leaf created via `buildAddLeafTx` becomes `<label>.audric.sui` and resolves\n * via the standard SuiNS resolver (`suix_resolveNameServiceAddress`).\n */\nexport const AUDRIC_PARENT_NAME = 'audric.sui';\n\n/**\n * On-chain object ID of the `audric.sui` parent NFT (a `SuinsRegistration`).\n *\n * Owned by the dedicated custody address `0xaca29165188f10136073788f648e1186dd25100100146186ebecedaf94b23d11`\n * (per `RUNBOOK_audric_sui_parent.md` §1). Every leaf mint / revoke MUST be signed\n * by the address that owns this NFT. Mainnet only.\n */\nexport const AUDRIC_PARENT_NFT_ID =\n '0x070456e283ec988b6302bdd6cc5172bbdcb709998cf116586fb98d19b0870198';\n\n/**\n * A SuiNS parent under which leaf subnames are minted: the registered SLD name\n * + the on-chain `SuinsRegistration` NFT id the minting service must own/sign.\n *\n * Added 2026-06-29 (Agent ID Phase B, gate 2) to let the same leaf machinery\n * serve a SECOND namespace — `agent-id.sui` for Agent ID handles — without\n * forking it. Audric stays the default so every existing caller is unchanged.\n */\nexport interface SuinsParent {\n name: string;\n nftId: string;\n}\n\n/** The Audric consumer-handle parent (`<label>.audric.sui` → `@audric`). */\nexport const AUDRIC_PARENT: SuinsParent = {\n name: AUDRIC_PARENT_NAME,\n nftId: AUDRIC_PARENT_NFT_ID,\n};\n\n/** The Agent ID parent (`<label>.agent-id.sui` → `@agent-id`). Distinct from\n * audric.sui on purpose (infra/agent registry vs consumer brand).\n *\n * Registered on SuiNS mainnet 2026-06-29; the `SuinsRegistration` NFT\n * (`0xc8c1…d5d1f`) is held by the custody address\n * `0x6988a92d…30e4532`, which signs leaf mints + pays their gas. Override via\n * `AGENT_ID_PARENT_NFT_ID` for testnet/dev. */\nexport const AGENT_ID_PARENT_NAME = 'agent-id.sui';\nexport const AGENT_ID_PARENT_NFT_ID =\n process.env.AGENT_ID_PARENT_NFT_ID ??\n '0xc8c13f5b5a6d4c47c04877014794f65e67e2745d3bfa089b736eb54b0ebd5d1f';\nexport const AGENT_ID_PARENT: SuinsParent = {\n name: AGENT_ID_PARENT_NAME,\n nftId: AGENT_ID_PARENT_NFT_ID,\n};\n\nexport interface BuildAddLeafParams {\n /** Bare label, e.g. `'alice'` — NOT the full `'alice.audric.sui'` path. */\n label: string;\n /** Sui address the leaf will resolve to (typically the user's zkLogin wallet). */\n targetAddress: string;\n /** Parent to mint under. Defaults to Audric (back-compat). */\n parent?: SuinsParent;\n}\n\nexport interface BuildRevokeLeafParams {\n /** Bare label of the leaf to revoke. */\n label: string;\n /** Parent the leaf lives under. Defaults to Audric (back-compat). */\n parent?: SuinsParent;\n}\n\nexport type LabelValidationResult = { valid: true } | { valid: false; reason: string };\n\n/**\n * SuiNS labels accept lowercase ASCII letters, digits, and hyphens. Hyphens cannot\n * lead or trail. The 3–63 char window matches SuiNS protocol rules and the SuiNS\n * dashboard's own `Register` form.\n *\n * The regex permits a single character only when it is alphanumeric (rejected by\n * the length check below for being < 3, but the pattern itself stays internally\n * consistent with DNS conventions).\n *\n * SUINS-LABEL-RULE — paired with `audric/apps/web/lib/identity/validate-label.ts`.\n * The audric host duplicates these rules inline to avoid pulling the full SDK\n * (and its server-side transitive deps) into the client bundle. If SuiNS ever\n * label rules, BOTH this file and the audric copy need updating.\n */\nconst LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\n/**\n * Validate a leaf label against SuiNS protocol rules. Pure function; no I/O.\n *\n * Pre-call this before `buildAddLeafTx` / `buildRevokeLeafTx` if you want a\n * structured error (the builder functions throw on invalid labels). The audric\n * `/api/identity/check` endpoint uses this to drive the picker's real-time\n * availability indicator.\n *\n * Reserved-name policy (specific Audric handles like `support`, `admin`,\n * `official`) is NOT enforced here — that's a UI / route-level concern owned\n * by the audric host, not a protocol-level rule. See SPEC 10 D3.\n */\nexport function validateLabel(label: unknown): LabelValidationResult {\n if (typeof label !== 'string') {\n return { valid: false, reason: 'label must be a string' };\n }\n if (label.length < 3) {\n return { valid: false, reason: 'label must be at least 3 characters' };\n }\n if (label.length > 63) {\n return { valid: false, reason: 'label must be at most 63 characters' };\n }\n if (!LABEL_PATTERN.test(label)) {\n return {\n valid: false,\n reason:\n 'label may only contain lowercase letters, digits, and hyphens, and may not start or end with a hyphen',\n };\n }\n if (label.includes('--')) {\n return { valid: false, reason: 'label may not contain consecutive hyphens' };\n }\n return { valid: true };\n}\n\n/**\n * Build an unsigned PTB that creates a `<label>.audric.sui` leaf subname pointing\n * to `targetAddress`.\n *\n * The returned `Transaction` has neither sender nor gas configured — the caller\n * (audric's `/api/identity/reserve` route) sets the sender to the parent NFT\n * custody address and submits via Enoki sponsorship. See `audric-transaction-flow.mdc`\n * for the sponsored-tx wrapper pattern; note SPEC 10 leaf-mint is a documented\n * CANONICAL-BYPASS of `composeTx` because the signer is the service account, not\n * the user's zkLogin key.\n *\n * Throws synchronously if `label` violates protocol rules or `targetAddress` is\n * not a valid Sui address — fail-closed before bytes are built.\n */\nexport function buildAddLeafTx(\n suinsClient: SuinsClient,\n { label, targetAddress, parent = AUDRIC_PARENT }: BuildAddLeafParams,\n): Transaction {\n const labelCheck = validateLabel(label);\n if (!labelCheck.valid) {\n throw new Error(`buildAddLeafTx: invalid label \"${label}\" — ${labelCheck.reason}`);\n }\n if (typeof targetAddress !== 'string' || !isValidSuiAddress(normalizeSuiAddress(targetAddress))) {\n throw new Error(`buildAddLeafTx: invalid targetAddress \"${targetAddress}\"`);\n }\n if (!parent.nftId) {\n throw new Error(`buildAddLeafTx: parent NFT id not configured for \"${parent.name}\"`);\n }\n\n const tx = new Transaction();\n const suinsTx = new SuinsTransaction(suinsClient, tx);\n suinsTx.createLeafSubName({\n parentNft: parent.nftId,\n name: `${label}.${parent.name}`,\n targetAddress: normalizeSuiAddress(targetAddress),\n });\n return tx;\n}\n\n/**\n * Build an unsigned PTB that revokes a `<label>.audric.sui` leaf subname.\n *\n * Used by:\n * 1. The change-username flow (`/api/identity/change`): revoke old leaf inside\n * the same PTB as the new leaf creation, atomically.\n * 2. The release-username flow (`/api/admin/identity/release`): admin recovery\n * of squatted / impersonating handles.\n * 3. Account-deletion flow (future): revoke leaf when user deletes their account.\n *\n * The mainnet smoke test (2026-05-01) confirmed revocation gas cost is roughly\n * negative net (storage rebate exceeds computation) — see RUNBOOK §4.\n */\nexport function buildRevokeLeafTx(\n suinsClient: SuinsClient,\n { label, parent = AUDRIC_PARENT }: BuildRevokeLeafParams,\n): Transaction {\n const labelCheck = validateLabel(label);\n if (!labelCheck.valid) {\n throw new Error(`buildRevokeLeafTx: invalid label \"${label}\" — ${labelCheck.reason}`);\n }\n if (!parent.nftId) {\n throw new Error(`buildRevokeLeafTx: parent NFT id not configured for \"${parent.name}\"`);\n }\n\n const tx = new Transaction();\n const suinsTx = new SuinsTransaction(suinsClient, tx);\n suinsTx.removeLeafSubName({\n parentNft: parent.nftId,\n name: `${label}.${parent.name}`,\n });\n return tx;\n}\n\n/**\n * Convenience: turn a bare label into the full `<label>.audric.sui` path.\n *\n * **Use this for ON-CHAIN operations** — SuiNS leaf NFT `name` field, the\n * `createLeafSubName` / `removeLeafSubName` move calls, and any RPC call\n * that returns/expects the canonical name string. The `<label>.audric.sui`\n * form is what the SuiNS protocol writes into the NFT `name` field.\n *\n * **Do NOT use this for UI rendering** — that's `displayHandle()`'s job\n * (S.118 reversal of SPEC 10 D10, see audric-build-tracker). Pre-S.118\n * we surfaced the full `.sui` form everywhere; we now use the SuiNS V2\n * `@` form (`alice@audric`) for display because it's shorter, fits the\n * agent harness mono aesthetic, and matches SuiNS's own V2 standard.\n *\n * Both forms resolve to the same address via SuiNS RPC (verified\n * mainnet 2026-05-08 PF1) — `displayHandle()` is purely a render-layer\n * choice, not a backend storage change.\n */\nexport function fullHandle(\n label: string,\n parentName: string = AUDRIC_PARENT_NAME,\n): string {\n return `${label}.${parentName}`;\n}\n\n/**\n * SuiNS V2 short-form display alias. `displayHandle('alice')` →\n * `'alice@audric'`. Use for chat narration, permission cards, receipts,\n * profile pages, share-to-X copy, OG metadata, and lookup_user output.\n *\n * **Why a separate function from `fullHandle`:**\n * - `fullHandle('alice')` → `'alice.audric.sui'` is the **on-chain**\n * NFT name field; SuiNS's `createLeafSubName` writes exactly this\n * string and `suix_resolveNameServiceAddress` accepts it.\n * - `displayHandle('alice')` → `'alice@audric'` is the **UI** form\n * that users see and share. SuiNS RPC also accepts this form\n * (verified mainnet 2026-05-08 PF1 — both forms return the same\n * address), so we have one storage form (`<label>.audric.sui`) and\n * two interchangeable input forms (the user can paste either).\n *\n * Reverses SPEC 10 D10 (\"full handle ALWAYS\"). See audric-build-tracker\n * S.118 for the rationale; see also `audric/apps/web/lib/identity/`\n * for canonicalization in the input parser (which is a no-op since\n * SuiNS RPC accepts both — kept available for future-proofing).\n */\nexport function displayHandle(\n label: string,\n parentName: string = AUDRIC_PARENT_NAME,\n): string {\n // Strip the trailing `.sui` TLD for the `@` display form.\n // `displayHandle('alice')` → `'alice@audric'`; for Agent ID,\n // `displayHandle('bot', AGENT_ID_PARENT_NAME)` → `'bot@agent-id'`.\n const parentDisplay = parentName.replace(/\\.sui$/, '');\n return `${label}@${parentDisplay}`;\n}\n"]}