@owney/sdk 0.7.28-beta.3 → 0.7.32-beta.1

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.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import * as viem from 'viem';
2
+ import { Hex, Address } from 'viem';
1
3
  import { SIWXConfig } from '@reown/appkit-controllers';
2
4
 
3
5
  /**
@@ -220,7 +222,9 @@ type SwapOrderStatus = "pending" | "executed" | "expired" | "cancelled" | "refun
220
222
  * of the flow and the one place a user would otherwise think nothing is
221
223
  * happening.
222
224
  */
223
- type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "wrapping" | "wrapped" | "approving" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
225
+ type SwapStage = "withdrawing" | "withdrawn"
226
+ /** Withdrawal incomplete or unconfirmed; no swap was submitted. */
227
+ | "withdrawal-incomplete" | "swap-unknown" | "swap-partial" | "swap-not-started" | "quoting" | "wrapping" | "wrapped" | "approving" | "building" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
224
228
  /**
225
229
  * Which way the funds travel, which decides what each side may be.
226
230
  *
@@ -246,19 +250,88 @@ type SwapQuoteParams = {
246
250
  direction?: SwapDirection;
247
251
  };
248
252
 
249
- type ZyfaiRpcUrlsConfig = Partial<Record<(typeof SUPPORTED_CHAIN_IDS)[number], string>>;
253
+ type FundingOperationKind = "deposit" | "withdraw" | "swap_deposit" | "withdraw_swap";
254
+ /** One leg of a ledger operation, as the API returns it. */
255
+ type FundingOperationLeg = {
256
+ /** e.g. `agent:zyfai`, `swap`, `approval`. */
257
+ legKey: string;
258
+ agentType: string | null;
259
+ /** created | submitted | unknown | failed | confirmed */
260
+ status: string;
261
+ /** uint256 decimal string. */
262
+ confirmedAmountRaw: string | null;
263
+ /** bigint decimal string. */
264
+ blockNumber: string | null;
265
+ txHash: string | null;
266
+ /** ISO. Kept as stored: a confirmed -> failed leg keeps its value, so key off `status`. */
267
+ confirmedAt: string | null;
268
+ /** Lowercase agent wallet the leg moved funds to or from; null when unknown. */
269
+ agentWallet: string | null;
270
+ /** ISO. First time the provider's proxied history listed this leg's tx hash (Yieldseeker). Never cleared. */
271
+ providerIndexedAt: string | null;
272
+ /**
273
+ * ISO. When a proxied provider snapshot first showed this leg in net deposits
274
+ * (Yieldseeker). Never cleared. Null means "not booked or undecidable", never
275
+ * "definitely not booked".
276
+ */
277
+ providerBookedAt: string | null;
278
+ };
279
+ /** One ledger operation, as the API returns it. */
280
+ type FundingOperationRow = {
281
+ /** First 8 hex chars of the client operation id, lowercase. */
282
+ reference: string;
283
+ /** Present only for operations whose id the caller passed in `ids`. */
284
+ clientOperationId?: string;
285
+ kind: FundingOperationKind;
286
+ /** created | submitted | unknown | failed | confirmed | partial */
287
+ status: string;
288
+ /** ISO. */
289
+ createdAt: string;
290
+ /** ISO. */
291
+ settledAt: string | null;
292
+ stuck: boolean;
293
+ legs: FundingOperationLeg[];
294
+ };
295
+ /** The newest server-side provider snapshot sample at or before a time. */
296
+ type ProviderSnapshotSample = {
297
+ /** Signed decimal strings in the asset's base units, or null. */
298
+ netDepositsRaw: string | null;
299
+ cumulativeYieldRaw: string | null;
300
+ totalValueRaw: string | null;
301
+ /** ISO or null. */
302
+ providerUpdatedAt: string | null;
303
+ /** ISO. */
304
+ observedAt: string;
305
+ };
306
+
307
+ type RpcUrlsConfig = Partial<Record<(typeof SUPPORTED_CHAIN_IDS)[number], string>>;
308
+ /** @deprecated Use RpcUrlsConfig. */
309
+ type ZyfaiRpcUrlsConfig = RpcUrlsConfig;
250
310
  interface OwneySDKConfig {
251
311
  apiKey: string;
312
+ /**
313
+ * Optional per-chain RPC overrides used for application-owned reads and
314
+ * transaction receipt polling. Missing chains use the Owney routing API's
315
+ * read-only RPC proxy. No upstream RPC credentials are included in the SDK.
316
+ * Wallet providers remain responsible for account access, chain switching,
317
+ * signatures, and transaction submission.
318
+ */
319
+ rpcUrls?: RpcUrlsConfig;
252
320
  /**
253
321
  * Optional per-chain RPC overrides for Zyfai SDK network calls.
254
322
  * Example: { 8453: "https://...", 42161: "https://..." }
323
+ * @deprecated Use rpcUrls so every agent shares the same read transport.
255
324
  */
256
325
  zyfaiRpcUrls?: ZyfaiRpcUrlsConfig;
326
+ /** Optional Owney Yieldseeker proxy base URL override for integration tests. */
327
+ yieldseekerApiBaseUrl?: string;
328
+ /** Optional SIWE origin override. Defaults to the requesting browser origin. */
329
+ yieldseekerSiweOrigin?: string;
257
330
  /**
258
331
  * Optional override for the Owney routing API base URL used by all routing
259
- * calls (defaults to the OWNEY_ROUTING_API_BASE_URL env var, then the
260
- * production URL). Set this to point at a local/staging routing API,
261
- * e.g. "http://localhost:3000", when testing sponsor changes.
332
+ * calls. RPC proxy requests use OWNEY_ROUTING_API_BASE_URL when this is
333
+ * omitted; without either value, all rpcUrls must be configured.
334
+ * Set this to a local/staging routing API when testing sponsor changes.
262
335
  */
263
336
  routingApiBaseUrl?: string;
264
337
  /**
@@ -267,6 +340,13 @@ interface OwneySDKConfig {
267
340
  * for apps that don't use the AppKit SIWX modal.
268
341
  */
269
342
  referralSource?: string;
343
+ /**
344
+ * Mini-app identifier (`web`, `base`, `ellipal` …) recorded on funding ledger
345
+ * operations. Not `referralSource`, which is a Zyfai attribution tag. The
346
+ * ledger records `unknown` when this is omitted. Lowercased before sending;
347
+ * a value that is not 1-32 of `a-z 0-9 _ -` after that is left out.
348
+ */
349
+ appName?: string;
270
350
  /**
271
351
  * Turn on the SDK's debug logging (default false). Traces the decisions that
272
352
  * are otherwise invisible — notably how the organization's agent policy is
@@ -276,15 +356,6 @@ interface OwneySDKConfig {
276
356
  * already-deployed app: set `globalThis.__OWNEY_DEBUG__ = true` in devtools.
277
357
  */
278
358
  debug?: boolean;
279
- /**
280
- * When true, the organization's pool policy is NOT applied on connect, so a
281
- * user's own deposit-time pool selection (ROUT-569) is never overwritten by
282
- * the org-level one on their next reconnect. Splitting and the rest of the
283
- * org policy still apply. Turn this on in apps that expose the deposit-time
284
- * Pools step (the spread flow); leave it off where the partner dashboard's
285
- * pool customization is the source of truth.
286
- */
287
- userPoolCustomization?: boolean;
288
359
  /**
289
360
  * Absolute URL of an ERC-7677 paymaster service. When set, deposits go out as
290
361
  * an EIP-5792 `wallet_sendCalls` with `capabilities.paymasterService`, so a
@@ -296,6 +367,19 @@ interface OwneySDKConfig {
296
367
  * unresolvable. Omit it and every rail behaves exactly as before.
297
368
  */
298
369
  paymasterServiceUrl?: string;
370
+ /**
371
+ * Cross-device withdrawal reservation (default `"fail-open"`). `withdraw()`
372
+ * claims a hold on the owner's funds before any provider call; a hold held by
373
+ * another device or app rejects with `WITHDRAW_IN_PROGRESS` /
374
+ * `details.reason === "RESERVED_ELSEWHERE"`.
375
+ * - `"fail-open"`: when the reservation API cannot answer (network error,
376
+ * timeout, 5xx, 404, 429, ...) the withdrawal proceeds as before.
377
+ * - `"fail-closed"`: it rejects with `WITHDRAW_RESERVATION_UNAVAILABLE`
378
+ * before anything is submitted.
379
+ * - `"off"`: never calls the reservation API.
380
+ * `OWNEY_WITHDRAWAL_RESERVATION_DISABLED=1` in the environment acts as `"off"`.
381
+ */
382
+ withdrawalReservation?: "fail-open" | "fail-closed" | "off";
299
383
  }
300
384
  interface ConnectionState {
301
385
  provider: any;
@@ -309,7 +393,166 @@ type OwneySupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
309
393
  type OwneySupportedChains = (typeof SUPPORTED_CHAINS)[number];
310
394
  type OwneySupportedTokens = (typeof SUPPORTED_TOKENS)[number];
311
395
 
312
- type AgentId = "zyfai";
396
+ /**
397
+ * One protocol's pool selection on one chain. `pools` holds Zyfai pool NAMES
398
+ * verbatim — matched case-sensitively by customizeBatch, and an unrecognised
399
+ * name makes Zyfai's rebalance engine skip the whole protocol, so these strings
400
+ * must not be normalised anywhere.
401
+ *
402
+ * An empty array means "no usable pools on this chain".
403
+ */
404
+ type OrgPoolSelection = {
405
+ protocolId: string;
406
+ chainId: number;
407
+ pools: string[];
408
+ };
409
+ /**
410
+ * The partner's protocol/pool policy (ROUT-224). Sparse — only protocols they
411
+ * narrowed appear. Optional so an older routing API, which does not return the
412
+ * field, still parses; undefined and null both mean "change nothing".
413
+ */
414
+ type OrgPoolPolicy = {
415
+ autoApproveProtocols: boolean;
416
+ autoApprovePools: boolean;
417
+ selections: OrgPoolSelection[];
418
+ };
419
+ /**
420
+ * The organization's agent execution policy, or null when the partner has never
421
+ * configured one — in which case the agents leave the user's profile alone.
422
+ */
423
+ type OrgAgentConfig = {
424
+ splittingMode: "none" | "automatic" | "force";
425
+ minSplits: number | null;
426
+ poolPolicy?: OrgPoolPolicy | null;
427
+ };
428
+
429
+ type DepositCallback = (smartWalletAddress: string, chainId: number, amount: string) => Promise<`0x${string}`> | `0x${string}`;
430
+ /**
431
+ * Read access to the funding ledger, given to agents by the client so they can
432
+ * hold earnings while a provider lags (spec B2). Both reads never throw:
433
+ * null means "no ledger information", and callers then behave as before.
434
+ */
435
+ type AgentFundingLedgerAccess = {
436
+ /** `sdk.listFundingOperations` for this owner; null when the owner is not the connected one or on failure. */
437
+ listOperations(input: {
438
+ owner: string;
439
+ chainId: number;
440
+ asset: string;
441
+ since?: Date;
442
+ }): Promise<FundingOperationRow[] | null>;
443
+ /** The newest server provider-snapshot sample at or before `before`; null when none or on failure. */
444
+ providerSnapshot?(input: {
445
+ owner: string;
446
+ chainId: number;
447
+ asset: string;
448
+ agentWallet: string;
449
+ before: Date;
450
+ }): Promise<ProviderSnapshotSample | null>;
451
+ };
452
+ interface IAgent {
453
+ readonly id: string;
454
+ readonly supportedChainIds: readonly OwneySupportedChainId[];
455
+ readonly supportedAssets: readonly AgentSupportedAssets[];
456
+ /**
457
+ * Describes how `AgentBalance.tokens` relates to `positions`.
458
+ * Most adapters expose token totals that already include deployed positions.
459
+ * Providers such as Yieldseeker expose idle wallet tokens separately, so
460
+ * withdrawal planning must add matching position amounts.
461
+ */
462
+ readonly balanceComposition?: "tokens-include-positions" | "tokens-plus-positions";
463
+ /**
464
+ * Whether a withdrawal requires an owner-approved wallet transaction.
465
+ * Aggregate withdrawals run these agents before relayer-only agents so a
466
+ * rejected wallet request cannot happen after another leg has committed.
467
+ */
468
+ readonly withdrawalRequiresWalletApproval?: boolean;
469
+ disconnect(): Promise<void>;
470
+ activateAgent(state: ConnectionState, chainId: number, asset?: OwneySupportedTokens): Promise<void>;
471
+ /**
472
+ * Apply the organization's agent policy to this user's account.
473
+ *
474
+ * Optional: an agent that has no equivalent knob simply omits it, which is why
475
+ * this is not part of `activateAgent`'s signature. Declared on the interface
476
+ * rather than only on ZyfaiAgent so the contract stays agent-neutral — the
477
+ * ticket asks for a design that can also cover Surf, which has no adapter yet.
478
+ *
479
+ * Implementations must be **non-fatal**: this runs during activation as a side
480
+ * effect, so a failure has to leave the user connected and their profile
481
+ * unchanged rather than break the connect.
482
+ */
483
+ applyOrgPolicy?(state: ConnectionState, chainId: number, policy: OrgAgentConfig): Promise<void>;
484
+ deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback, onProgress?: FundingProgress, onBeforeSubmission?: (evidence: FundingEvidence) => void | Promise<void>): Promise<OwneyDepositResult>;
485
+ withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string, onProgress?: FundingProgress, gasMode?: "auto" | "sponsored" | "paid", onBeforeSubmission?: FundingProgress, assertCurrent?: () => void): Promise<AgentWithdrawResult>;
486
+ /** Read-only MAX proof at the owner payout block; never sends another withdrawal. */
487
+ verifyWithdrawalCompletion?(state: ConnectionState, evidence: FundingEvidence): Promise<WithdrawalCompletion>;
488
+ /** A newly observed pool allocation invalidates this asset's portfolio cache only. */
489
+ invalidateAllocationRead?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): void;
490
+ /** Invalidate only the confirmed asset. This hook must not sign or submit transactions. */
491
+ invalidateFundingRead?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, refreshUntil?: number, txHash?: string): void;
492
+ /** End accelerated balance reads only for the exact snapshot the caller displayed. */
493
+ endFundingBalanceRefresh?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, read: AssetReadMetadata): boolean;
494
+ getFundingHistory?(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
495
+ getFundingWallet?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<string>;
496
+ /** Verify the displayed remaining balance after a receipt-confirmed payout.
497
+ * Undefined means unknown; never substitute a failed read with zero. */
498
+ verifyWithdrawalBalance?(state: ConnectionState, evidence: FundingEvidence, balance: AgentBalance): Promise<AssetReadMetadata | undefined>;
499
+ /** Read-only chain proof when indexed withdrawal components are incomplete.
500
+ * Returns raw owner-withdrawable units; unavailable proof must throw.
501
+ * minimumAmount is the raw liquidity required from this agent for a typed
502
+ * plan, so adapters can expand discovery when known positions fall short. */
503
+ getWithdrawableBalance?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, minimumAmount?: bigint): Promise<bigint>;
504
+ /** Optional positive proof for a repeat deposit; unknown must fall back to portfolio validation. */
505
+ hasExistingDepositFunds?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<true | undefined>;
506
+ getBalances(state: ConnectionState, chainId: number, asset?: OwneySupportedTokens): Promise<AgentBalance>;
507
+ getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
508
+ /** Funding-ledger read access for earnings holds. Optional; without it an agent behaves as before. */
509
+ setFundingLedgerAccess?(access: AgentFundingLedgerAccess | undefined): void;
510
+ /**
511
+ * A small, never-prompting read of the provider's earnings bookkeeping for a
512
+ * `provider.sample` ledger event (Zyfai). Null when unavailable; never throws.
513
+ */
514
+ providerEarningsSample?(state: ConnectionState, chainId: number): Promise<Record<string, unknown> | null>;
515
+ /**
516
+ * Refresh the agent's earnings snapshot when its backend supports doing so.
517
+ * Implementations own freshness and request-deduplication policy.
518
+ */
519
+ refreshEarnings?(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
520
+ getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays,
521
+ /**
522
+ * Optional asset symbol ("USDC" / "WETH") scoping the daily series to a
523
+ * single asset on the chain. Agents without per-asset positions ignore it.
524
+ */
525
+ tokenSymbol?: string): Promise<AccountAgentApy>;
526
+ /**
527
+ * Daily cumulative earnings in token units, scoped to a chain/asset, using
528
+ * the provider's earnings basis. Include an opening snapshot when available
529
+ * so the "recent earnings" subline can difference the endpoints. (ROUT-452)
530
+ */
531
+ getDailyEarnings?(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
532
+ getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
533
+ getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
534
+ /**
535
+ * Ensure the given asset uses backend protocol auto-selection
536
+ * (`autoSelectProtocols: true`). Optional capability — only agents whose
537
+ * backend models per-asset protocol selection implement it. Returns whether
538
+ * a write occurred (`false` = already enabled / not supported).
539
+ */
540
+ ensureAutoSelectProtocols?(state: ConnectionState, chainId: number, asset: "USDC" | "WETH"): Promise<boolean>;
541
+ supportsAgentApyPeriod?(days: DailyApyDays): boolean;
542
+ getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
543
+ }
544
+ /**
545
+ * Optional filters for per-agent APY lookups.
546
+ * - `tokenSymbol` / `chainId` scope the APY to a specific asset+chain when
547
+ * the underlying provider supports it (Zyfai). Agents whose backends do
548
+ * not yet support per-asset APY will ignore these options.
549
+ */
550
+ type AgentApyOptions = {
551
+ tokenSymbol?: string;
552
+ chainId?: number;
553
+ };
554
+
555
+ type AgentId = "zyfai" | "yieldseeker";
313
556
  type Asset = string;
314
557
  type AgentSupportedAsset = {
315
558
  readonly symbol: string;
@@ -358,43 +601,51 @@ type HistoryFilters = {
358
601
  tokenSymbol?: string;
359
602
  };
360
603
  type HistoryOptions = {
604
+ chainId?: number;
361
605
  agentId?: AgentId;
362
606
  filters?: HistoryFilters;
363
- /**
364
- * Chains to read, instead of the one `activateAgent` last set (ROUT-479).
365
- *
366
- * Each chain pages independently and the results merge into one
367
- * chronological list, with every entry stamped with the chain it came from.
368
- * Omit for the single-chain behaviour, which stays the default: fanning out
369
- * by default would multiply every existing caller's request count.
370
- */
371
- chainIds?: OwneySupportedChainId[];
372
607
  };
373
608
  type WithdrawOptions = {
609
+ /** Internal orchestration observation deadline; never retries a send. */
610
+ observationDeadline?: number;
611
+ assertCurrent?: () => void;
612
+ /** Yieldseeker V2 only. "auto" requests sponsorship for a verified V2 wallet. */
613
+ gasMode?: "auto" | "sponsored" | "paid";
614
+ /** Exclude unresolved providers from aggregate withdrawals; direct agent requests are unchanged. */
615
+ excludeAgentIds?: AgentId[];
616
+ onProgress?: FundingProgress;
617
+ /**
618
+ * Durable pre-dispatch checkpoint for adapters with a recoverable operation ID.
619
+ * Rejection prevents submission; progress observers remain non-fatal.
620
+ */
621
+ onBeforeSubmission?: FundingProgress;
374
622
  asset: Asset;
375
623
  amount?: string;
376
624
  agentId?: AgentId;
377
- /**
378
- * Chain to withdraw from. Defaults to the chain `activateAgent` last set.
379
- * See `DepositOptions.chainId` — the same rules apply.
380
- */
381
- chainId?: number;
625
+ /** Called after each agent returns; callback failures never change a financial result. */
626
+ onAgentResult?: (agentId: AgentId, result: AgentWithdrawResult) => void;
627
+ /** Funding ledger reference (a UUID). Defaults to a new random UUID; apps pass
628
+ * their own so the app record and the ledger share one reference. It is also
629
+ * the withdrawal reservation's operationId. */
630
+ operationId?: string;
631
+ /**
632
+ * Cross-device withdrawal reservation options.
633
+ * - `override`: the `reference` from an overridable `RESERVED_ELSEWHERE`
634
+ * error, sent after the user chose "Withdraw anyway".
635
+ * - `supersedesOperationId`: an earlier operation of this SDK (for example
636
+ * the sponsored attempt a paid retry replaces). Its hold is released when
637
+ * this SDK still has that operation's holder token; otherwise ignored.
638
+ */
639
+ reservation?: WithdrawalReservationOptions;
640
+ };
641
+ /** `WithdrawOptions.reservation`: see there. */
642
+ type WithdrawalReservationOptions = {
643
+ override?: string;
644
+ supersedesOperationId?: string;
382
645
  };
383
646
  type AccountApyOptions = {
384
647
  agentId?: AgentId;
385
648
  days: LookbackDays;
386
- /**
387
- * Chain to scope the daily series to, instead of the one `activateAgent`
388
- * last set (ROUT-479).
389
- *
390
- * `"all"` blends every chain the wallet held that day, which is what the
391
- * chart's "All chains" filter asks for. Unlike the history and earnings
392
- * reads this needs no fan-out: the provider's daily-APY payload is already
393
- * wallet-wide and names each position's chain, so the scope is a filter over
394
- * one response rather than several calls. Omit for the active chain, which
395
- * stays the default.
396
- */
397
- chainId?: OwneySupportedChainId | "all";
398
649
  /**
399
650
  * Optional asset symbol (e.g. "USDC", "WETH") to scope the daily APY series
400
651
  * to a specific asset on the active chain. Without it the series blends every
@@ -412,14 +663,6 @@ type AccountApyOptions = {
412
663
  type DailyEarningsOptions = {
413
664
  agentId?: AgentId;
414
665
  days: LookbackDays;
415
- /**
416
- * Chains to read, instead of the one `activateAgent` last set (ROUT-479).
417
- *
418
- * The same asset is summed across them — USDC on Base and USDC on Arbitrum
419
- * are the same unit. Different assets stay apart, as they already do within
420
- * one chain. Omit for the single-chain behaviour, which stays the default.
421
- */
422
- chainIds?: OwneySupportedChainId[];
423
666
  /**
424
667
  * Optional asset symbol (e.g. "USDC", "WETH") scoping the series to one
425
668
  * asset on the active chain.
@@ -445,154 +688,176 @@ type AgentsApyOptions = {
445
688
  chainId?: number;
446
689
  };
447
690
  type DepositOptions = {
691
+ /** Optional synchronous foreground ownership fence for the default Permit2 rail.
692
+ * Throw to stop preparation/dispatch and late journal writes after lease/session loss. */
693
+ assertSubmissionCurrent?: () => void;
694
+ /** Resume only these already signed relayer bytes; never create a new authorization. */
695
+ resumeTxHash?: `0x${string}`;
696
+ onProgress?: FundingProgress;
697
+ /** Awaited immediately before dispatch. Throwing prevents submission.
698
+ * All legs of an atomic batch are checkpointed together. */
699
+ onBeforeSubmission?: (evidence: FundingEvidence[]) => void | Promise<void>;
448
700
  amount: string;
449
701
  asset: Asset;
450
702
  depositCallback?: DepositCallback;
451
703
  agentId?: AgentId;
452
704
  onApproved?: () => void;
453
- /**
454
- * Chain to deposit on. Defaults to the chain `activateAgent` last set, so
455
- * omitting it behaves exactly as before.
456
- *
457
- * Pass it to fund several chains in a row without re-activating between
458
- * them (ROUT-245's spread strategies). It selects the target; it does not
459
- * replace activation, which is what populates `activeAgents`, and it does
460
- * not remove the wallet's network switch — the default deposit callbacks
461
- * still put the wallet on this chain before signing, since a deposit
462
- * signature is EIP-712 with the chain in its domain.
463
- */
464
- chainId?: number;
705
+ /** Funding ledger reference (a UUID). Defaults to a new random UUID; apps pass
706
+ * their own so the app record and the ledger share one reference. */
707
+ operationId?: string;
465
708
  };
466
709
 
467
- /**
468
- * One protocol's pool selection on one chain. `pools` holds Zyfai pool NAMES
469
- * verbatim — matched case-sensitively by customizeBatch, and an unrecognised
470
- * name makes Zyfai's rebalance engine skip the whole protocol, so these strings
471
- * must not be normalised anywhere.
472
- *
473
- * An empty array means "no usable pools on this chain".
474
- */
475
- type OrgPoolSelection = {
476
- protocolId: string;
477
- chainId: number;
478
- pools: string[];
710
+ type FundingStage = "pending" | "confirmed" | "unknown" | "failed" | "not-applicable";
711
+ /** Vault inventory retained before the MAX payout. No signatures or secrets. */
712
+ type WithdrawalCompletionContext = {
713
+ vaults: string[];
714
+ userId: string;
715
+ agentId: string;
716
+ inventoryComplete: boolean;
479
717
  };
480
- /**
481
- * The partner's protocol/pool policy (ROUT-224). Sparse — only protocols they
482
- * narrowed appear. Optional so an older routing API, which does not return the
483
- * field, still parses; undefined and null both mean "change nothing".
484
- */
485
- type OrgPoolPolicy = {
486
- autoApproveProtocols: boolean;
487
- autoApprovePools: boolean;
488
- selections: OrgPoolSelection[];
718
+ type WithdrawalCompletion = {
719
+ status: "complete" | "remaining" | "unavailable";
720
+ reason?: string;
721
+ checkedVaults?: number;
489
722
  };
490
- /**
491
- * The organization's agent execution policy, or null when the partner has never
492
- * configured one — in which case the agents leave the user's profile alone.
493
- */
494
- type OrgAgentConfig = {
495
- splittingMode: "none" | "automatic" | "force";
496
- minSplits: number | null;
497
- poolPolicy?: OrgPoolPolicy | null;
723
+ /** Hash-bound v0.6 recovery metadata. Deliberately excludes the owner signature. */
724
+ type UnsignedUserOperationEvidence = {
725
+ sender: string;
726
+ nonce: string;
727
+ initCode: string;
728
+ callData: string;
729
+ callGasLimit: string;
730
+ verificationGasLimit: string;
731
+ preVerificationGas: string;
732
+ maxFeePerGas: string;
733
+ maxPriorityFeePerGas: string;
734
+ paymasterAndData: string;
498
735
  };
499
-
500
- /**
501
- * Pool policy: Owney's org-level protocol/pool policy -> Zyfai's two mismatched
502
- * write shapes.
503
- *
504
- * Zyfai splits "which protocols and pools may this user's funds sit in" across
505
- * two calls that do not share an axis:
506
- *
507
- * updateUserProfile({ protocols }) per ASSET, chain-agnostic
508
- * customizeBatch([{ protocolId, per (PROTOCOL, CHAIN), asset-agnostic
509
- * chainId, pools, autoselect }])
510
- *
511
- * `protocols` is an explicit ALLOW-LIST: a protocol left out of it is disabled
512
- * for that asset, on every chain, immediately. `customizeBatch` is the opposite
513
- * shape — one record per (protocol, chain) pair, asset-agnostic, and per
514
- * docs.zyf.ai it "creates or updates a record for the (user, protocol, chain)
515
- * combination"; "previous customizations for the same combination are
516
- * overwritten".
517
- *
518
- * That second property is the reason this file exists rather than a single
519
- * flat translation: customizeBatch overwrites only the combinations it is
520
- * GIVEN. The partner's stored policy (`OrgPoolPolicy.selections`) is sparse —
521
- * only the protocols they actually narrowed appear — but the payload we send
522
- * must be EXHAUSTIVE over every (protocol, chain) pair Zyfai offers this user.
523
- * If we only sent the narrowed pairs, a partner who restricts Morpho, saves,
524
- * then later re-ticks every pool box would never be able to undo it: nothing
525
- * in the (sparse) policy would tell us to send a record clearing it, and the
526
- * old restrictive record would stay live on the user's profile forever.
527
- *
528
- * Pure functions, kept out of the agent so the mapping is testable without a
529
- * Zyfai client. See splitting.ts for the same pattern on the other lever.
530
- */
531
-
532
- /** One selectable pool, with the figures the deposit-time Pools step shows. */
533
- type AvailablePool = {
534
- chainId: number;
535
- token: string;
536
- name: string;
537
- /** combined_apy (pool + rewards), already a percent. null when absent. */
538
- apy: number | null;
539
- /** TVL in USD. null when absent. See ZyfCustomizationPoolInfo: `tvl` is in
540
- * the pool's own token, `tvlUsd` is the dollar figure — only the latter is
541
- * safe to show with a currency symbol. */
542
- tvlUsd: number | null;
543
- /** Per-pool deep link (e.g. the Morpho vault page). null when absent. */
544
- link: string | null;
545
- };
546
- /** Public Zyfai strategies used by deposit-time pool customization. */
547
- type PoolSelectionStrategy = "aggressive" | "yieldmaxxing";
548
- /** One asset's explicit choice for a protocol on one chain. */
549
- type UserPoolSelection = {
550
- asset: "USDC" | "WETH";
551
- protocolId: string;
552
- chainId: number;
553
- /** Names enabled by the user for this asset/protocol/chain. */
554
- pools: string[];
555
- /** Every name shown for this asset/protocol/chain in the superset catalog. */
556
- availablePools: string[];
557
- };
558
- /** The complete saved draft for the asset/chain legs selected in the deposit. */
559
- type UserPoolSelectionRequest = {
560
- strategies: Array<{
561
- asset: "USDC" | "WETH";
562
- strategy: PoolSelectionStrategy;
563
- }>;
564
- selections: UserPoolSelection[];
736
+ type DepositAuthorizationReference = {
737
+ authorizationId: `0x${string}`;
738
+ predecessorTxHash?: `0x${string}`;
565
739
  };
566
- /** One protocol with its pools for the deposit asset — what the Pools step
567
- * renders: a protocol row that opens to a list of selectable pools. */
568
- type PoolCatalogProtocol = {
569
- protocolId: string;
570
- name: string;
571
- logo: string | null;
572
- pools: AvailablePool[];
740
+ type DepositReplacementValidation = {
741
+ authorizationId: `0x${string}`;
742
+ predecessorTxHash: `0x${string}`;
743
+ replacementTxHash: `0x${string}`;
573
744
  };
574
-
745
+ /** Evidence about one provider leg. Amounts are token base units, never USD. */
746
+ interface FundingEvidence {
747
+ agentId: AgentId;
748
+ chainId: number;
749
+ token: OwneySupportedTokens;
750
+ walletAddress: string;
751
+ agentWallet?: string;
752
+ maxCompletion?: WithdrawalCompletionContext;
753
+ maxCompletionCheck?: WithdrawalCompletion;
754
+ intendedAmount: string;
755
+ confirmedAmount?: string;
756
+ /** Receipt delivery and fulfillment of a typed requested amount are separate facts. */
757
+ amountCompletion?: "complete" | "shortfall";
758
+ /** Verified difference between the typed request and the actual owner payout. */
759
+ shortfallAmount?: string;
760
+ txHash?: string;
761
+ /** Persisted before a sponsored EOA operation is sent. */
762
+ userOpHash?: string;
763
+ /** Lets recovery verify a consumed nonce even if a bundler forgets the operation. */
764
+ userOperation?: UnsignedUserOperationEvidence;
765
+ /** Base Account calls ID used to recover an uncertain wallet submission. */
766
+ callsId?: string;
767
+ /** Deposit execution was attempted, rather than only prepared. Not confirmation. */
768
+ depositSubmission?: "started";
769
+ depositAuthorization?: DepositAuthorizationReference;
770
+ blockNumber?: string;
771
+ logIndexes?: number[];
772
+ transferLogs?: {
773
+ logIndex: number;
774
+ amountRaw: string;
775
+ }[];
776
+ /** Sanitized execution-request evidence. Attempted does not prove server acceptance. */
777
+ withdrawalRequest?: {
778
+ attempted: boolean;
779
+ method?: "GET" | "POST";
780
+ path?: "/users/withdraw" | "/users/partial-withdraw";
781
+ elapsedMs?: number;
782
+ /** Actual response status captured before the vendor replaces the HTTP error. */
783
+ httpStatus?: number;
784
+ failure?: "network" | "unauthorized" | "forbidden" | "rate-limited" | "insufficient-balance" | "session-key-missing" | "withdrawal-in-progress" | "other";
785
+ /** When the provider accepted the request without a hash (ms since epoch). */
786
+ acceptedAt?: number;
787
+ };
788
+ /** Where an on-chain payout search may start, for a hashless acceptance.
789
+ * `fromBlock` is the chain head read just before the request (decimal string). */
790
+ payoutSearch?: {
791
+ fromBlock?: string;
792
+ };
793
+ transfer: FundingStage;
794
+ registration: FundingStage;
795
+ delivery: FundingStage;
796
+ }
797
+ type FundingProgress = (evidence: FundingEvidence) => void;
798
+ interface AssetReadMetadata {
799
+ chainId: number;
800
+ asset: string;
801
+ fetchedAt?: number;
802
+ /** When the underlying provider request started; preserved on cached reads. */
803
+ requestedAt?: number;
804
+ /** SDK cache generation, not an onchain block or provider timestamp. */
805
+ readVersion?: number;
806
+ providerUpdatedAt?: string;
807
+ snapshotId?: string;
808
+ blockNumber?: string;
809
+ netDepositsRaw?: string;
810
+ /** Display-only agreement with a post-payout read. Does not prove that
811
+ * provider accounting, history or allocations include the transaction. */
812
+ withdrawalCheck?: {
813
+ txHash: string;
814
+ blockNumber: string;
815
+ };
816
+ positionsStatus: "available" | "unavailable";
817
+ }
575
818
  interface OwneyDepositResult {
819
+ evidence?: FundingEvidence;
576
820
  txHash: string;
577
821
  smartWallet: string;
578
822
  amount: string;
823
+ /** Funding ledger reference for this deposit (quote it in support tickets). */
824
+ operationId?: string;
579
825
  }
580
826
  interface OwneyMultiDepositResult {
581
827
  agentResults: Record<string, OwneyDepositResult>;
828
+ /** Funding ledger reference for this deposit (quote it in support tickets). */
829
+ operationId?: string;
582
830
  }
583
831
  interface AgentWithdrawResult {
832
+ evidence?: FundingEvidence;
584
833
  txHash?: string;
585
834
  type: "full" | "partial";
586
- /** Smallest-unit amount, or a provider sentinel such as "all" for a full request. */
835
+ /** Owner payout or clearing all MAX positions still needs verification. */
836
+ completion?: "unverified";
837
+ /** Confirmed smallest-unit amount; "0" when no owner payout is verified.
838
+ * Legacy providers may return a sentinel such as "all" for a full request. */
587
839
  amount: string;
840
+ /** Yieldseeker typed withdrawal fulfilled after an exactly verified fee
841
+ * deduction. Amount remains the confirmed net owner payout, and the gross
842
+ * amount must equal that payout plus the fee, all in token base units. */
843
+ feeAdjustment?: {
844
+ grossAmount: string;
845
+ feeAmount: string;
846
+ };
847
+ /** Funding ledger reference for this withdrawal (quote it in support tickets).
848
+ * Set on the result of a single-agent `withdraw()`, not on per-agent entries. */
849
+ operationId?: string;
588
850
  }
589
851
  interface OwneyWithdrawResult {
590
852
  agentResult: Record<AgentId, AgentWithdrawResult>;
591
853
  /**
592
- * Sum of reported smallest-unit amounts; null when a full withdrawal's
593
- * amount is not yet known. An accepted request is not proof of settlement.
854
+ * Sum of confirmed smallest-unit amounts; null while any returned leg's
855
+ * payout is not yet known, including typed requests accepted asynchronously.
856
+ * Evidence-less custom adapters retain their confirmed-amount contract.
594
857
  */
595
858
  totalWithdrawn: string | null;
859
+ /** Funding ledger reference for this withdrawal (quote it in support tickets). */
860
+ operationId?: string;
596
861
  }
597
862
  interface OwneyToken {
598
863
  chain: OwneySupportedChains;
@@ -608,6 +873,10 @@ interface OwneyPosition {
608
873
  pool?: string;
609
874
  asset: string;
610
875
  amount: string;
876
+ /** Provider-native raw quantity; may represent vault shares, not the underlying asset. */
877
+ amountRaw?: string;
878
+ /** Withdrawable underlying asset amount in that asset's smallest units. */
879
+ withdrawableAmountRaw?: string;
611
880
  apy?: number;
612
881
  tvl?: number;
613
882
  /** Pool liquidity. Prepared slot — Zyfai will add this to its portfolio
@@ -638,10 +907,20 @@ interface OwneyPendingAllocation {
638
907
  since?: string;
639
908
  }
640
909
  interface AgentBalance {
910
+ readMetadata?: AssetReadMetadata[];
911
+ /** Authoritative native balances per asset/network, including idle and invested funds. */
912
+ assetBalances?: OwneyToken[];
641
913
  smartWallet?: `0x${string}`;
642
914
  totalBalance: string;
643
915
  /** Asset that `totalBalance` is denominated in. Currently always `"usdc"`. */
644
916
  totalBalanceAsset: string;
917
+ /**
918
+ * Describes whether `tokens` already includes deployed `positions`.
919
+ * Consumers must add matching positions only for `tokens-plus-positions`;
920
+ * doing so for Zyfai would double-count, while omitting it for Yieldseeker
921
+ * makes its balance disappear as soon as idle funds enter a vault.
922
+ */
923
+ balanceComposition?: "tokens-include-positions" | "tokens-plus-positions";
645
924
  tokens: OwneyToken[];
646
925
  /**
647
926
  * Per-protocol/pool positions when the agent's portfolio payload includes
@@ -651,34 +930,19 @@ interface AgentBalance {
651
930
  /** Funds received but not yet deployed. Omitted when nothing is pending. */
652
931
  pendingAllocations?: OwneyPendingAllocation[];
653
932
  }
654
- /**
655
- * One position drained by `withdrawAll()` — a chain and asset pair.
656
- *
657
- * Carries either a result or an error, never both: a leg that failed while
658
- * others succeeded is the normal case, not an exception, and the caller needs
659
- * to name the ones that did not arrive.
660
- */
661
- interface OwneyWithdrawAllLeg {
662
- chainId: OwneySupportedChainId;
663
- asset: OwneySupportedTokens;
664
- /** What the position held when the sweep started. */
665
- amount: string;
666
- result?: OwneyWithdrawResult | AgentWithdrawResult;
667
- error?: string;
668
- }
669
- interface OwneyWithdrawAllResult {
670
- /** Every position attempted, in the order it was attempted. */
671
- legs: OwneyWithdrawAllLeg[];
672
- }
673
933
  interface OwneyBalances {
674
934
  totalBalance: string;
675
935
  /** Asset that `totalBalance` is denominated in. Currently always `"usdc"`. */
676
936
  totalBalanceAsset: string;
677
937
  agentBalances: Record<AgentId, AgentBalance>;
678
- /** Omitted agents failed to load; they must not be interpreted as zero. */
679
- agentErrors?: Record<AgentId, string>;
938
+ /**
939
+ * Per-agent read failures when an aggregate balance request returned only a
940
+ * partial result. Callers may display the successful balances, but funding
941
+ * operations must not interpret a missing agent as having a zero balance.
942
+ */
943
+ agentErrors?: Partial<Record<AgentId, string>>;
680
944
  /** Absolute provider cooldown deadlines (Unix milliseconds). */
681
- agentRetryAt?: Record<AgentId, number>;
945
+ agentRetryAt?: Partial<Record<AgentId, number>>;
682
946
  }
683
947
  interface AgentEarnings {
684
948
  smartWallet: `0x${string}`;
@@ -688,6 +952,10 @@ interface AgentEarnings {
688
952
  interface OwneyEarnings {
689
953
  totalEarnings: string;
690
954
  agentEarnings: Record<AgentId, AgentEarnings>;
955
+ /** Per-agent failures when an aggregate read returned a partial result. */
956
+ agentErrors?: Partial<Record<AgentId, string>>;
957
+ /** Absolute provider cooldown deadlines (Unix milliseconds). */
958
+ agentRetryAt?: Partial<Record<AgentId, number>>;
691
959
  }
692
960
  type ApyByChainAndAsset = Partial<Record<OwneySupportedChainId, Partial<Record<OwneySupportedTokens, number>>>>;
693
961
  /** A single day's net APY for the connected account, as a percentage number. */
@@ -702,28 +970,6 @@ interface ApyHistoryPoint {
702
970
  unit: string;
703
971
  };
704
972
  }
705
- /**
706
- * What the APY chart's chain/asset menus are allowed to offer, and how far
707
- * back each option reaches (ROUT-479).
708
- *
709
- * An option only earns a place if some day in the window held a real position
710
- * on it — a balance and a rate. Listing anything else would offer a filter
711
- * that draws a blank chart. `days` is what the menu prints beside each row,
712
- * and the legs genuinely differ: a wallet can hold USDC for a fortnight and
713
- * WETH for three days.
714
- */
715
- interface ApyCoverage {
716
- chains: {
717
- chainId: number;
718
- days: number;
719
- }[];
720
- /** Legs whose `tokenSymbol` the provider left unset are absent — they cannot
721
- * be named, so they cannot be picked. Their chain still counts. */
722
- assets: {
723
- asset: string;
724
- days: number;
725
- }[];
726
- }
727
973
  interface AccountAgentApy {
728
974
  walletAddress: string;
729
975
  weightedApyAfterFee?: number;
@@ -734,8 +980,6 @@ interface AccountAgentApy {
734
980
  * date. Empty when the provider returns no daily history.
735
981
  */
736
982
  history?: ApyHistoryPoint[];
737
- /** Which chains/assets this history can be filtered down to. */
738
- coverage?: ApyCoverage;
739
983
  }
740
984
  interface OwneyAccountApy {
741
985
  totalApy: string;
@@ -757,6 +1001,15 @@ interface OwneyAllocationApy {
757
1001
  }
758
1002
  type HistoryAction = "Rebalance" | "Deposit" | "Top up" | "Withdraw" | "Earned";
759
1003
  interface HistoryTransaction {
1004
+ tokenAddress?: string;
1005
+ agentWallet?: string;
1006
+ logIndexes?: number[];
1007
+ transferLogs?: {
1008
+ logIndex: number;
1009
+ amountRaw: string;
1010
+ }[];
1011
+ amountRaw?: string;
1012
+ blockNumber?: string;
760
1013
  txHashes: string[];
761
1014
  chainId?: number;
762
1015
  tokenSymbol?: string;
@@ -777,6 +1030,10 @@ interface RebalanceLog {
777
1030
  tokenSymbol: string;
778
1031
  amount: string;
779
1032
  status: "success" | "failed";
1033
+ /** Fee-net APY at execution time for the source leg, in percentage points. */
1034
+ fromApy?: string;
1035
+ /** Fee-net APY at execution time for the destination leg, in percentage points. */
1036
+ toApy?: string;
780
1037
  }
781
1038
  interface AgentHistoryPosition {
782
1039
  protocol: string;
@@ -785,17 +1042,10 @@ interface AgentHistoryPosition {
785
1042
  amount?: string;
786
1043
  }
787
1044
  interface AgentHistoryEntry {
1045
+ /** Stable provider/transfer identity, independent of row order. */
1046
+ id?: string;
788
1047
  agent: AgentId;
789
1048
  action: HistoryAction;
790
- /**
791
- * Chain this entry came from, stamped by the history fan-out (ROUT-479).
792
- *
793
- * Absent on a single-chain read, where the caller already knows the chain.
794
- * The entry has no chain of its own otherwise: `transactions[].chainId` is
795
- * optional and missing whenever the indexer has not attached the transfer,
796
- * so a row cannot be labelled from it reliably.
797
- */
798
- chainId?: OwneySupportedChainId;
799
1049
  date: string;
800
1050
  oldApy: string | null;
801
1051
  newApy: string | null;
@@ -804,6 +1054,8 @@ interface AgentHistoryEntry {
804
1054
  positions?: AgentHistoryPosition[];
805
1055
  }
806
1056
  interface OwneyAgentHistory {
1057
+ agentErrors?: Partial<Record<AgentId, string>>;
1058
+ agentRetryAt?: Partial<Record<AgentId, number>>;
807
1059
  data: AgentHistoryEntry[];
808
1060
  /** True iff a subsequent page exists; pair with `nextCursor`. */
809
1061
  hasMore: boolean;
@@ -842,17 +1094,18 @@ interface AgentApy {
842
1094
  detailedApys?: AgentApyDetails;
843
1095
  }
844
1096
  interface OwneyAgentApy {
845
- agentApy: Record<AgentId, AgentApy>;
1097
+ /** Agents without data for the requested period are omitted. */
1098
+ agentApy: Partial<Record<AgentId, AgentApy>>;
846
1099
  }
847
- /** One day's cumulative NET earnings for a single asset. */
1100
+ /** One day's cumulative earnings for a single asset. */
848
1101
  interface DailyEarningsPoint {
849
1102
  /** ISO date string for the day, e.g. "2026-09-01". */
850
1103
  date: string;
851
1104
  /**
852
- * Earnings accumulated from the start of the returned series up to and
853
- * including this day, net of the agent's performance fee, denominated in the
854
- * asset's own units. A running total of daily deltas, so it measures the
855
- * window — not the wallet's lifetime.
1105
+ * Cumulative earnings in the asset's own units, using the provider's earnings
1106
+ * basis. A provider may return lifetime totals or a running window total;
1107
+ * difference the last and opening points to measure earnings over the window.
1108
+ * Aggregate series normalize each component's opening value before summing.
856
1109
  */
857
1110
  amount: number;
858
1111
  }
@@ -861,8 +1114,9 @@ interface AssetDailyEarnings {
861
1114
  /** Asset symbol, e.g. "USDC" / "WETH". */
862
1115
  asset: string;
863
1116
  /**
864
- * Ascending by date. Days the wallet held nothing of this asset are absent
865
- * rather than zero — a zero would read as "earned nothing that day".
1117
+ * Ascending by date, including an opening snapshot before the requested
1118
+ * window when available. Provider gaps remain absent; aggregates carry the
1119
+ * most recent cumulative value across dates reported by other providers.
866
1120
  */
867
1121
  points: DailyEarningsPoint[];
868
1122
  }
@@ -879,96 +1133,50 @@ interface AccountDailyEarnings {
879
1133
  assets: AssetDailyEarnings[];
880
1134
  }
881
1135
 
882
- type DepositCallback = (smartWalletAddress: string, chainId: number, amount: string) => Promise<`0x${string}`> | `0x${string}`;
883
- interface IAgent {
884
- readonly id: string;
885
- readonly supportedChainIds: readonly OwneySupportedChainId[];
886
- readonly supportedAssets: readonly AgentSupportedAssets[];
887
- disconnect(): Promise<void>;
888
- activateAgent(state: ConnectionState, chainId: number): Promise<void>;
889
- /**
890
- * Apply the organization's agent policy to this user's account.
891
- *
892
- * Optional: an agent that has no equivalent knob simply omits it, which is why
893
- * this is not part of `activateAgent`'s signature. Declared on the interface
894
- * rather than only on ZyfaiAgent so the contract stays agent-neutral — the
895
- * ticket asks for a design that can also cover Surf, which has no adapter yet.
896
- *
897
- * Implementations must be **non-fatal**: this runs during activation as a side
898
- * effect, so a failure has to leave the user connected and their profile
899
- * unchanged rather than break the connect.
900
- */
901
- applyOrgPolicy?(state: ConnectionState, chainId: number, policy: OrgAgentConfig): Promise<void>;
902
- /**
903
- * The deposit-time pool catalogue for one asset and strategy: protocols with
904
- * their selectable pools and figures. Optional — an agent with no pool
905
- * customization omits it. (ROUT-569)
906
- */
907
- getPoolCatalog?(params: {
908
- asset: string;
909
- strategy: "conservative" | "aggressive" | "yieldmaxxing";
910
- }): Promise<PoolCatalogProtocol[]>;
911
- /**
912
- * Apply a user's own pool selection to their account, driven by the
913
- * deposit-time Pools step. Optional, and non-fatal like `applyOrgPolicy`.
914
- * (ROUT-569)
915
- */
916
- setPoolSelection?(selection: UserPoolSelectionRequest): Promise<void>;
917
- deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
918
- withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string): Promise<AgentWithdrawResult>;
919
- getBalances(state: ConnectionState, chainId: number): Promise<AgentBalance>;
920
- getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
921
- /**
922
- * Refresh the agent's earnings snapshot when its backend supports doing so.
923
- * Implementations own freshness and request-deduplication policy.
924
- */
925
- refreshEarnings?(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
926
- getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays,
927
- /**
928
- * Optional asset symbol ("USDC" / "WETH") scoping the daily series to a
929
- * single asset on the chain. Agents without per-asset positions ignore it.
930
- */
931
- tokenSymbol?: string,
932
- /**
933
- * Chain the series is scoped to, when that differs from the chain the
934
- * connection is on. `null` spans every chain the wallet held (ROUT-479);
935
- * omitted means `chainId`. Kept apart from `chainId` because that one
936
- * still resolves the wallet and must stay a real, connected chain.
937
- */
938
- scopeChainId?: number | null): Promise<AccountAgentApy>;
939
- /**
940
- * Daily cumulative NET earnings for the window, scoped to a chain/asset.
941
- * Backs the "recent earnings" subline, whose figure must reconcile with the
942
- * balance headline directly above it. (ROUT-452)
943
- */
944
- getDailyEarnings?(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
945
- getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
946
- getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
947
- /**
948
- * Ensure the given asset uses backend protocol auto-selection
949
- * (`autoSelectProtocols: true`). Optional capability — only agents whose
950
- * backend models per-asset protocol selection implement it. Returns whether
951
- * a write occurred (`false` = already enabled / not supported).
952
- */
953
- ensureAutoSelectProtocols?(state: ConnectionState, chainId: number, asset: "USDC" | "WETH"): Promise<boolean>;
954
- getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
955
- }
1136
+ type ReservationAgent = "zyfai" | "surfliquid" | "yieldseeker";
1137
+ type WithdrawalReservationMode = "fail-open" | "fail-closed" | "off";
1138
+ type ReservationReleaseReason = "confirmed" | "failed" | "not_submitted";
1139
+ /** What the 409 tells the app. The holding operation's id and token are never returned. */
1140
+ type WithdrawalReservationConflict = {
1141
+ /** First 8 hex characters of the holding operation's id. */
1142
+ reference: string;
1143
+ ageSec: number;
1144
+ expiresInSec: number;
1145
+ agents: ReservationAgent[];
1146
+ state: "preparing" | "dispatched";
1147
+ /** True for an unproven hold: the app may resend with `override: reference`. */
1148
+ overridable: boolean;
1149
+ };
1150
+
956
1151
  /**
957
- * Optional filters for per-agent APY lookups.
958
- * - `tokenSymbol` / `chainId` scope the APY to a specific asset+chain when
959
- * the underlying provider supports it (Zyfai). Agents whose backends do
960
- * not yet support per-asset APY will ignore these options.
1152
+ * On-chain discovery of a hashless withdrawal's payout.
1153
+ *
1154
+ * Lists ERC-20 `Transfer` logs on the operation's token that reach the owner.
1155
+ * The sender is never filtered: routed payouts hop through intermediaries.
1156
+ * This only finds candidates; each one must still be proven with the receipt
1157
+ * inspection (`inspectFunding(candidate, "withdraw", { requireAmountMatch: true })`).
961
1158
  */
962
- type AgentApyOptions = {
963
- tokenSymbol?: string;
964
- chainId?: number;
1159
+ type WithdrawalPayoutCandidate = {
1160
+ txHash: string;
1161
+ /** Decimal block number. */
1162
+ blockNumber: string;
1163
+ logIndex: number;
1164
+ /** Transferred amount in token base units. */
1165
+ amountRaw: string;
1166
+ };
1167
+ type WithdrawalPayoutScan = {
1168
+ candidates: WithdrawalPayoutCandidate[];
1169
+ /** Last block scanned (inclusive, decimal). Pass it back as the next `cursor`. */
1170
+ scannedTo: string;
965
1171
  };
966
1172
 
967
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "WALLET_NOT_DEPLOYED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "CHAIN_MISMATCH" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_BALANCE_UNAVAILABLE" | "DEPOSIT_PARTIAL_FAILURE" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_INSUFFICIENT_BALANCE" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_NOTHING_TO_WITHDRAW" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "AGENT_RATE_LIMITED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "SPONSORED_CALLS_UNSUPPORTED" | "SPONSORED_CALLS_NO_ID" | "SPONSORED_CALLS_NO_RECEIPT" | "SWAP_DISABLED" | "SWAP_RATE_LIMITED" | "SWAP_REQUEST_FAILED" | "SWAP_QUOTE_FAILED" | "SWAP_UNSUPPORTED_PAIR" | "SWAP_APPROVAL_REQUIRED" | "SWAP_BELOW_DEPOSIT_MINIMUM" | "SWAP_DEPOSIT_PENDING" | "SWAP_WALLET_PROMPT_TIMEOUT" | "SWAP_INSUFFICIENT_GAS" | "SWAP_NATIVE_UNSUPPORTED" | "SWAP_ORDER_EXPIRED" | "SWAP_ORDER_REFUNDED" | "SWAP_ORDER_CANCELLED" | "WITHDRAW_ARRIVAL_TIMEOUT" | "WITHDRAW_SWAP_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "POOL_CATALOG_UNSUPPORTED" | "POOL_SELECTION_UNSUPPORTED" | "VALIDATION_INVALID_DAYS";
1173
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "WALLET_NOT_DEPLOYED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "AGENT_ACTIVATION_PARTIAL_FAILURE" | "YIELDSEEKER_AGENT_MISSING" | "YIELDSEEKER_WALLET_UNVERIFIED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "CHAIN_MISMATCH" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_BALANCE_UNAVAILABLE" | "DEPOSIT_PARTIAL_FAILURE" | "DEPOSIT_IN_PROGRESS" | "DEPOSIT_CHECKPOINT_FAILED" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_INVALID_AMOUNT" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_INSUFFICIENT_BALANCE" | "WITHDRAW_IN_PROGRESS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_BALANCE_UNAVAILABLE" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_UNCONFIRMED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_SWAP_INCOMPLETE" | "WITHDRAW_FAILED" | "WITHDRAW_INVALID_AMOUNT" | "WITHDRAW_RESERVATION_UNAVAILABLE" | "AGENT_RATE_LIMITED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_NO_AGENTS" | "AGENT_API_ERROR" | "AGENT_AUTH_FAILED" | "AGENT_INVALID_RESPONSE" | "AGENT_TIMEOUT" | "AGENT_TRANSACTION_REVERTED" | "AGENT_APY_PERIOD_UNSUPPORTED" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "SPONSORED_CALLS_UNSUPPORTED" | "SPONSORED_CALLS_NO_ID" | "SPONSORED_CALLS_NO_RECEIPT" | "SWAP_DISABLED" | "SWAP_RATE_LIMITED" | "SWAP_REQUEST_FAILED" | "SWAP_QUOTE_FAILED" | "SWAP_UNSUPPORTED_PAIR" | "SWAP_APPROVAL_REQUIRED" | "SWAP_BELOW_DEPOSIT_MINIMUM" | "SWAP_DEPOSIT_PENDING" | "SWAP_WALLET_PROMPT_TIMEOUT" | "SWAP_INSUFFICIENT_GAS" | "SWAP_NATIVE_UNSUPPORTED" | "SWAP_ORDER_EXPIRED" | "SWAP_ORDER_REFUNDED" | "SWAP_ORDER_CANCELLED" | "WITHDRAW_ARRIVAL_TIMEOUT" | "WITHDRAW_SWAP_FAILED" | "BALANCE_ALL_FAILED" | "EARNINGS_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
968
1174
  declare class OwneyError extends Error {
969
1175
  readonly code: OwneyErrorCode;
970
1176
  readonly details?: Record<string, unknown>;
971
1177
  readonly agentId?: string;
1178
+ /** Funding ledger reference, set when a funding operation fails. */
1179
+ operationId?: string;
972
1180
  constructor(code: OwneyErrorCode, message: string, details?: Record<string, unknown>, agentId?: string);
973
1181
  }
974
1182
  declare class AgentNotFoundError extends OwneyError {
@@ -989,41 +1197,35 @@ declare class AgentChainIncompatibleError extends OwneyError {
989
1197
  }>, connectedChainId: number);
990
1198
  }
991
1199
 
992
- /**
993
- * Withdrawal swaps the user has walked away from, and how they ended.
994
- *
995
- * The deposit side has `swap.pending-deposit.ts` for the same shape of
996
- * problem, but the two are not symmetrical. A pending deposit is a JOB: the
997
- * money is in the wallet and an ordinary deposit finishes it. This is a
998
- * WATCH — the funds are in escrow, nothing the user does moves them along,
999
- * and the only question is where they ended up.
1000
- *
1001
- * That is the whole reason this exists. `withdrawAndSwap` used to hold the
1002
- * screen for the entire escrow lifecycle, which on a slow mainnet fill is
1003
- * minutes of a modal the user cannot leave (ROUT-242). Backgrounding it means
1004
- * the outcome arrives after the UI that started it has gone, so the outcome
1005
- * has to be written down somewhere the next render can find it.
1006
- *
1007
- * Only cross-chain swaps are recorded. A same-chain classic swap is one
1008
- * transaction and resolves in seconds; a same-chain fusion order has no stored
1009
- * preimages, so there would be nothing for a reloaded session to resume and
1010
- * the record would sit at `swapping` for ever.
1011
- *
1012
- * Kept deliberately separate from the secret store. Secrets are retired the
1013
- * moment an order reaches a verdict — that is a safety property, not a display
1014
- * one — and the record has to outlive them so the user can still be told what
1015
- * happened after they come back.
1016
- */
1017
- /**
1018
- * `swapping` is the only non-terminal state. `unknown` is what a watch that
1019
- * gave up looks like: we stopped polling before the order spoke, so the order
1020
- * may well have filled. It is not a failure, and it must never be shown as
1021
- * one.
1022
- */
1023
- type WithdrawSwapStatus = "swapping" | "landed" | "refunded" | "unknown";
1200
+ /** Durable intent and evidence, including the gap before an order exists. */
1201
+ type WithdrawalSwapRecovery = {
1202
+ attemptId: string;
1203
+ phase: "withdrawing" | "verifying" | "ready" | "submitted" | "incomplete";
1204
+ baseline: string;
1205
+ baselineBlock: string;
1206
+ submittedAt: number;
1207
+ deadline: number;
1208
+ requested?: string;
1209
+ agentId?: AgentId;
1210
+ results?: Record<string, AgentWithdrawResult>;
1211
+ evidence: Record<string, FundingEvidence>;
1212
+ reason?: string;
1213
+ };
1214
+ /** Unknown and partial outcomes remain recoverable until settlement is verified. */
1215
+ type WithdrawSwapStatus = "swapping" | "landed" | "refunded" | "unknown" | "refund-pending" | "partially-filled" | "withdrawal-pending" | "withdrawal-incomplete" | "ready" | "not-swapped";
1024
1216
  type WithdrawSwapRecord = {
1025
1217
  /** Identity. One record per Fusion+ order. */
1026
1218
  orderHash: string;
1219
+ walletAddress?: string;
1220
+ txHash?: string;
1221
+ /**
1222
+ * The funding-ledger operation of this withdrawal and swap, reused when it
1223
+ * is continued or rechecked. Absent on records written by an older SDK.
1224
+ */
1225
+ operationId?: string;
1226
+ recovery?: WithdrawalSwapRecovery;
1227
+ spent?: string;
1228
+ dismissed?: boolean;
1027
1229
  status: WithdrawSwapStatus;
1028
1230
  /**
1029
1231
  * What actually left the agent, smallest unit of the SOURCE asset.
@@ -1060,7 +1262,7 @@ declare function subscribeWithdrawSwaps(listener: () => void): () => void;
1060
1262
  * Not after the swap resolves: the point is to survive the gap between submit
1061
1263
  * and settle, which is exactly when the user closes the tab.
1062
1264
  */
1063
- declare function saveWithdrawSwap(record: WithdrawSwapRecord): void;
1265
+ declare function saveWithdrawSwap(record: WithdrawSwapRecord): boolean;
1064
1266
  /**
1065
1267
  * Move a record to its outcome.
1066
1268
  *
@@ -1074,8 +1276,8 @@ declare function saveWithdrawSwap(record: WithdrawSwapRecord): void;
1074
1276
  declare function updateWithdrawSwap(orderHash: string, patch: Partial<Omit<WithdrawSwapRecord, "orderHash">>): void;
1075
1277
  /** The user has read the outcome. Only they do this. */
1076
1278
  declare function clearWithdrawSwap(orderHash: string): void;
1077
- /** Every record, newest first, sweeping anything past MAX_AGE_MS. */
1078
- declare function listWithdrawSwaps(now?: number): WithdrawSwapRecord[];
1279
+ /** Visible records, newest first. Only verified terminal records expire by age. */
1280
+ declare function listWithdrawSwaps(now?: number, includeDismissed?: boolean): WithdrawSwapRecord[];
1079
1281
 
1080
1282
  /**
1081
1283
  * Swaps that landed but were never deposited.
@@ -1110,6 +1312,11 @@ type PendingDeposit = {
1110
1312
  agentId?: string;
1111
1313
  /** Epoch ms, for the sweep. */
1112
1314
  createdAt: number;
1315
+ /**
1316
+ * The swap's funding-ledger operation, so finishing the deposit reports into
1317
+ * it. Absent on records written by an older SDK.
1318
+ */
1319
+ operationId?: string;
1113
1320
  };
1114
1321
  /** Every record, dismissed ones included, newest first. Sweeps as it goes. */
1115
1322
  declare function listPendingDeposits(now?: number): PendingDeposit[];
@@ -1124,22 +1331,80 @@ declare class OwneySDK {
1124
1331
  */
1125
1332
  private disabledAgents;
1126
1333
  private state;
1334
+ private connectionRevision;
1335
+ private disconnectingAgents;
1127
1336
  private apiKey;
1128
1337
  private orgAgentConfig;
1129
1338
  private orgAgentConfigPromise;
1339
+ private rpcUrls?;
1130
1340
  private zyfaiRpcUrls?;
1131
- private userPoolCustomization;
1341
+ private yieldseekerApiBaseUrl?;
1342
+ private yieldseekerSiweOrigin?;
1132
1343
  private routingApiBaseUrl?;
1133
1344
  private referralSource?;
1345
+ private readonly ledger;
1346
+ private readonly reservationMode;
1347
+ private readonly reservationTransport;
1134
1348
  private cachedSponsoredCallback;
1135
1349
  private cachedWethSponsoredCallback;
1136
1350
  private paymasterServiceUrl?;
1137
1351
  private cachedSponsoredCallsCallbacks;
1138
1352
  private readonly agentReads;
1353
+ private readonly depositFamilyReads;
1354
+ private readonly recoveredFundingReads;
1355
+ private fundingBalanceChecks;
1139
1356
  private readonly activationChecks;
1357
+ private readonly withdrawalSubmissions;
1358
+ private readonly withdrawalSwapSubmissions;
1140
1359
  private readAgent;
1141
1360
  private initializingAgentsPromise;
1142
1361
  constructor(config: OwneySDKConfig);
1362
+ /** Finishes a funding-ledger operation on success and adds its reference to
1363
+ * the result. The result object is copied, never mutated or replaced.
1364
+ * `OK` replaces any failure code an earlier attempt of the same operation
1365
+ * recorded (a resumed pending deposit, a continuation). */
1366
+ private ledgerSucceeded;
1367
+ /** Tags a failure with its funding-ledger reference and finishes the
1368
+ * operation. The error is never wrapped or replaced. */
1369
+ private ledgerFailed;
1370
+ /**
1371
+ * Swap operations running right now, by operationId. A deposit or withdrawal
1372
+ * started with one of these ids is the inner half of that swap and joins its
1373
+ * operation instead of starting its own (see `startLedger`).
1374
+ */
1375
+ private readonly openSwapLedgers;
1376
+ /**
1377
+ * Starts a funding-ledger operation, or joins the open swap operation with
1378
+ * the same id. A joined call reports its legs into the swap's operation and
1379
+ * leaves finishing to the swap, so the operation gets one outcome, sent on
1380
+ * one ordered request chain.
1381
+ */
1382
+ private startLedger;
1383
+ /** Starts a swap's operation and opens it to the swap's inner deposit or
1384
+ * withdrawal. Never throws: reporting never blocks a swap. */
1385
+ private openSwapLedger;
1386
+ private closeSwapLedger;
1387
+ /** Reports one agent's withdrawal evidence as its leg. Never throws. */
1388
+ private ledgerWithdrawalLeg;
1389
+ /** Operation/leg/tx keys whose provider samples are already scheduled. */
1390
+ private readonly providerSampleKeys;
1391
+ /**
1392
+ * For a confirmed leg of an operation this SDK reported, records the agent's
1393
+ * own earnings bookkeeping as `provider.sample` events at confirmation, +5
1394
+ * and +30 min (Zyfai; evidence for provider lag). Only agents that expose a
1395
+ * never-prompting sample read take part. Fire-and-forget, never throws;
1396
+ * a later sample is skipped once the wallet disconnects or changes.
1397
+ */
1398
+ private ledgerProviderSamples;
1399
+ /**
1400
+ * Funding-ledger read access handed to agents for earnings holds. Reads only
1401
+ * for the connected owner; null otherwise and on any failure.
1402
+ */
1403
+ private agentLedgerAccess;
1404
+ /** Reports the swap leg. Never throws: reporting never affects a swap. */
1405
+ private ledgerSwap;
1406
+ /** Reports the swap leg of a swap that threw, with any identifier it carried. */
1407
+ private ledgerSwapFailed;
1143
1408
  /**
1144
1409
  * Establish connection state for all subsequent SDK calls.
1145
1410
  * Must be called once before any agent operation that requires a wallet.
@@ -1151,6 +1416,8 @@ declare class OwneySDK {
1151
1416
  * After calling this, `connect()` must be called again before using agent methods.
1152
1417
  */
1153
1418
  disconnect(): Promise<void>;
1419
+ private clearConnectionState;
1420
+ private disconnectAgents;
1154
1421
  private isAgentDisabled;
1155
1422
  /**
1156
1423
  * Check if the SDK has an active connection state.
@@ -1162,31 +1429,39 @@ declare class OwneySDK {
1162
1429
  * @returns The active chain ID, or `null` if `activateAgent` has not been called
1163
1430
  */
1164
1431
  getActiveChainId(): number | null;
1432
+ /**
1433
+ * The funding-ledger operations this app has for the connected wallet and
1434
+ * `asset` (default chain: the active one). Never throws: resolves `null` when
1435
+ * not connected, with no chain, when ledger reporting is disabled, or on any
1436
+ * failure, which callers treat as "no ledger information".
1437
+ *
1438
+ * Full `clientOperationId`s come back only for ids passed in `ids`. The ids
1439
+ * are trimmed and lowercased, non-uuid strings are dropped, and the first 50
1440
+ * distinct ids (caller order) are sent; the rest are ignored.
1441
+ */
1442
+ listFundingOperations(opts: {
1443
+ chainId?: number;
1444
+ asset: string;
1445
+ ids?: string[];
1446
+ since?: Date;
1447
+ }): Promise<FundingOperationRow[] | null>;
1165
1448
  private requireState;
1166
1449
  private requireChainId;
1167
1450
  private requireConnectedProvider;
1168
- /**
1169
- * Lazily builds (and caches) the default EIP-3009 sponsored deposit callback
1170
- * used when the caller omits `depositCallback`. Wraps the connected EIP-1193
1171
- * provider with viem `custom(provider)` to read token meta and sign the
1172
- * `TransferWithAuthorization`, then POSTs to the sponsor API.
1173
- */
1451
+ private getPaidRpcClient;
1452
+ /** Builds the default USDC batch callback for the connected wallet. */
1174
1453
  private getDefaultSponsoredCallback;
1175
- /**
1176
- * Lazily builds (and caches) the default Permit2 sponsored WETH deposit
1177
- * callback used when the caller omits `depositCallback` for a WETH
1178
- * deposit. Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
1179
- * `PermitTransferFrom` instead of an EIP-3009 authorization.
1180
- */
1454
+ /** Builds the wallet-native sponsored calls callback for compatible paymasters. */
1181
1455
  private getDefaultSponsoredCallsCallback;
1182
1456
  /**
1183
1457
  * Lazily builds (and caches) the default Permit2 sponsored WETH deposit
1184
1458
  * callback used when the caller omits `depositCallback` for a WETH deposit.
1185
1459
  * Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
1186
- * `PermitTransferFrom` instead of an EIP-3009 authorization.
1460
+ * single-use batch authorization instead of an EIP-3009 authorization.
1187
1461
  */
1188
1462
  private getDefaultWethSponsoredCallback;
1189
1463
  private getAgent;
1464
+ getActiveAgentIds(): AgentId[];
1190
1465
  private getActiveAgents;
1191
1466
  /**
1192
1467
  * Read the org's agent policy once and reuse it. fetchOrgAgentConfig never
@@ -1219,7 +1494,8 @@ declare class OwneySDK {
1219
1494
  * If provided, ALL specified agents must support the chainId or the call
1220
1495
  * throws before activating any agent.
1221
1496
  */
1222
- activateAgent(chainId: number, agentId?: AgentId[]): Promise<void>;
1497
+ activateAgent(chainId: number, agentId?: AgentId[], asset?: OwneySupportedTokens): Promise<void>;
1498
+ private assertActivationSession;
1223
1499
  /**
1224
1500
  * Activate agents ONE AT A TIME, each followed by its org policy.
1225
1501
  *
@@ -1233,10 +1509,9 @@ declare class OwneySDK {
1233
1509
  * Serializing costs no real wall-clock: the user can only approve one prompt
1234
1510
  * at a time anyway.
1235
1511
  *
1236
- * Every agent is attempted even if an earlier one fails, so one declined
1237
- * signature can't deny the remaining agents their turn. The first failure is
1238
- * rethrown (matching the previous `Promise.all` rejection) once all agents
1239
- * have had a chance to activate.
1512
+ * Stop at the first failure so a canceled sign-in does not open another
1513
+ * agent's wallet prompt. Report any earlier successes for diagnostics; the
1514
+ * app discards the session when the complete sign-in does not succeed.
1240
1515
  */
1241
1516
  private activateAgentsInTurn;
1242
1517
  /**
@@ -1247,7 +1522,8 @@ declare class OwneySDK {
1247
1522
  * @param options.asset - Asset symbol to deposit (e.g. "USDC")
1248
1523
  * @param options.depositCallback - Callback that performs the token transfer and returns a tx hash.
1249
1524
  * When agentId is omitted, this callback is invoked once per eligible agent with that agent's
1250
- * split amount and smart wallet address — expect multiple wallet prompts.
1525
+ * split amount and smart wallet address. Default sponsored deposits batch
1526
+ * all shares into one signature; custom callbacks still run once per agent.
1251
1527
  * @param options.agentId - Optional explicit target. Otherwise split equally,
1252
1528
  * or fund remaining agents when a recovery deposit cannot meet every minimum.
1253
1529
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
@@ -1257,10 +1533,12 @@ declare class OwneySDK {
1257
1533
  * Invokes `agent.deposit` with the resolved sponsored callback, composing
1258
1534
  * two independent auto-recovery mechanisms:
1259
1535
  *
1260
- * 1. Missing Permit2 allowance: when the app did not supply its own
1261
- * callback and the attempt fails with `PERMIT2_APPROVAL_REQUIRED` on a
1262
- * WETH deposit, this is the wallet's first gasless WETH deposit. We send
1263
- * the one-time (user-paid) Permit2 approval via `approvePermit2()` and
1536
+ * 1. Missing Permit2 allowance outside the sponsored ERC-2612 path: when the
1537
+ * app did not supply its own callback and the attempt fails with
1538
+ * `PERMIT2_APPROVAL_REQUIRED`, this is the wallet's first Permit2 deposit
1539
+ * for that token. Native Base/Arbitrum USDC uses gasless ERC-2612 approval in
1540
+ * its sponsored deposit and never reaches this branch. Other tokens send
1541
+ * the one-time user-paid Permit2 approval via `approvePermit2()` and
1264
1542
  * retry the SAME sponsored attempt once. Bounded to one approval attempt
1265
1543
  * per call so a wallet/agent that keeps reporting the allowance as
1266
1544
  * missing can't loop forever. If `approvePermit2()` itself throws (e.g.
@@ -1281,6 +1559,7 @@ declare class OwneySDK {
1281
1559
  private depositWithFallback;
1282
1560
  private getMinDepositAmount;
1283
1561
  private splitDepositAmount;
1562
+ private formatAgentName;
1284
1563
  private validateMinDepositAmount;
1285
1564
  /**
1286
1565
  * Whether the user already holds a non-zero balance with `agent` for the
@@ -1289,25 +1568,70 @@ declare class OwneySDK {
1289
1568
  * false, so the minimum is enforced as today.
1290
1569
  */
1291
1570
  private hasExistingBalance;
1292
- /**
1293
- * Guard an explicitly requested chain against one agent's own list.
1294
- *
1295
- * Only reachable when the caller passes `chainId` — the activated chain has
1296
- * already been checked by `activateAgent`. Kept separate from
1297
- * `validateAssetSupport` so "this agent is not on Ethereum" does not arrive
1298
- * worded as "this agent does not support USDC".
1299
- */
1300
- private validateChainSupport;
1301
- /**
1302
- * Guard an explicitly requested chain before a fan-out.
1303
- *
1304
- * Without this the split simply produces no agents, and the caller is told
1305
- * their amount "cannot activate every eligible agent" against a combined
1306
- * minimum of 0 — an error about the amount when the chain is at fault.
1307
- */
1308
- private validateChainHasAgents;
1309
1571
  private validateAssetSupport;
1310
1572
  private getEligibleAgents;
1573
+ /**
1574
+ * Run owner-approved withdrawals before relayer-only withdrawals. Wallet
1575
+ * approval is the only point at which the user can cancel the aggregate
1576
+ * operation, so no relayer leg should commit before it has completed.
1577
+ */
1578
+ private orderAgentsForWithdrawal;
1579
+ private isUserRejectedWithdrawal;
1580
+ private captureReadScope;
1581
+ /** Revalidate a saved transfer against the authenticated account and actual receipt. */
1582
+ inspectFunding(evidence: FundingEvidence, direction: "deposit" | "withdraw", options?: {
1583
+ balanceRefreshUntil?: number;
1584
+ refreshBalance?: boolean;
1585
+ requireAmountMatch?: boolean;
1586
+ }): Promise<FundingEvidence>;
1587
+ /**
1588
+ * Lists on-chain payout candidates for a withdrawal the provider accepted
1589
+ * without a hash: ERC-20 `Transfer` logs on the evidence's token that reach
1590
+ * the owner, from `max(fromBlock, cursor − 20)` to `latest − 3`, chunked.
1591
+ * Discovery only: prove each candidate with
1592
+ * `inspectFunding({ ...evidence, txHash }, "withdraw", { requireAmountMatch: true })`.
1593
+ *
1594
+ * `fromBlock` defaults to `evidence.payoutSearch.fromBlock`; without either
1595
+ * (legacy records) the start is estimated from
1596
+ * `withdrawalRequest.acceptedAt ?? submittedAt` minus 5 minutes. Pass the
1597
+ * returned `scannedTo` back as `cursor` to scan only new blocks.
1598
+ * Never prompts and never throws: null on any failure or scope mismatch.
1599
+ */
1600
+ findWithdrawalPayoutCandidates(evidence: FundingEvidence, opts?: {
1601
+ fromBlock?: string;
1602
+ cursor?: string;
1603
+ submittedAt?: number;
1604
+ }): Promise<WithdrawalPayoutScan | null>;
1605
+ /** Resolve a saved sponsored-withdrawal ID without opening a wallet prompt. */
1606
+ resolveSponsoredWithdrawalEvidence(evidence: FundingEvidence, options?: {
1607
+ submittedAt?: number;
1608
+ }): Promise<FundingEvidence>;
1609
+ /** Recover an EIP-5792 deposit or payout using this account's exact batch ID. */
1610
+ resolveWalletCallsFundingEvidence(evidence: FundingEvidence, direction: "deposit" | "withdraw"): Promise<FundingEvidence>;
1611
+ /** Whether a foreground deposit can resume the same signed batch, never a
1612
+ * fresh authorization. The batch rail independently rechecks the exact plan. */
1613
+ canResumePendingDeposit(evidences: FundingEvidence[], amount: string): Promise<boolean>;
1614
+ /** Validate signed journal membership, never just a caller-supplied family ID. */
1615
+ validateDepositReplacement(previous: FundingEvidence[], next: FundingEvidence[]): Promise<DepositReplacementValidation | undefined>;
1616
+ /** Optional post-payout display proof; receipt verification and the provider
1617
+ * adapter must agree before attaching it to this exact balance object. */
1618
+ verifyWithdrawalBalance(evidence: FundingEvidence, balance: AgentBalance): Promise<AgentBalance>;
1619
+ /** A display acknowledgement controls polling only; it never confirms a financial outcome. */
1620
+ endFundingBalanceRefresh(evidence: FundingEvidence, read: AssetReadMetadata): boolean;
1621
+ /** History lookup for receipt recovery; adapters may not authenticate or sign here. */
1622
+ getFundingHistory(evidence: FundingEvidence, fromDate: string, options?: Pick<HistoryFilters, "cursor" | "toDate">): Promise<OwneyAgentHistory>;
1623
+ recoverDepositRegistration(evidence: FundingEvidence): Promise<FundingEvidence>;
1624
+ /** On-chain version and ownership status for this owner's Yieldseeker agent. */
1625
+ getYieldseekerWalletStatus(asset: OwneySupportedTokens): Promise<YieldseekerWalletStatus | null>;
1626
+ /** Deployment gate; an unavailable response keeps the current paid path. */
1627
+ isYieldseekerWithdrawalSponsorshipAvailable(): Promise<boolean>;
1628
+ isYieldseekerUpgradeSponsorshipAvailable(): Promise<boolean>;
1629
+ private isYieldseekerSponsorshipAvailable;
1630
+ /** Explicit V1-to-V2 upgrade, confirmed on chain before returning. */
1631
+ upgradeYieldseekerWallet(asset: OwneySupportedTokens, gasMode?: "paid" | "sponsored"): Promise<{
1632
+ txHash: viem.Hex;
1633
+ status: YieldseekerWalletStatus;
1634
+ }>;
1311
1635
  /** Lazily built so an app that never swaps pays nothing for it. */
1312
1636
  private swapApiClient?;
1313
1637
  private swapApi;
@@ -1352,45 +1676,15 @@ declare class OwneySDK {
1352
1676
  * would strand funds we might have been able to move.
1353
1677
  */
1354
1678
  /** ERC20 balance of the connected wallet, read through the wallet's own node. */
1355
- /**
1356
- * A read client pinned to `chainId`, over HTTP rather than the wallet.
1357
- *
1358
- * The swap rail has read this way from the start, and the reason is written
1359
- * out at `buildSwapDeps`: a provider-backed client reads from whatever chain
1360
- * the WALLET is on, which after a cross-chain swap is the source chain, not
1361
- * the one the funds landed on. The deposit's own reads did not, so a Permit2
1362
- * check for WETH on Arbitrum went to Base — where that address is not a
1363
- * contract at all, so viem got "0x" back and threw "The contract function
1364
- * 'allowance' returned no data".
1365
- */
1366
- private chainReader;
1367
1679
  private readTokenBalance;
1368
1680
  /** How much of `token` the wallet has already approved Permit2 to move. */
1369
1681
  private readTokenPermit2Allowance;
1370
1682
  /**
1371
- * How much of a landed swap to actually deposit.
1372
- *
1373
- * The swap reports what ARRIVED, and the deposit used to be handed that
1374
- * figure directly. It is the entire arrival, so there is no slack: anything
1375
- * that spends the target asset between the two fails the deposit outright.
1376
- *
1377
- * Something does. A first WETH deposit needs a one-time Permit2 approval,
1378
- * and that approval is a transaction. A wallet holding no native gas token -
1379
- * the normal state of someone who just swapped everything INTO WETH - pays
1380
- * for it out of the WETH. The deposit then asked for ~2e12 wei more than was
1381
- * left and refused with DEPOSIT_INSUFFICIENT_BALANCE, under a wrapper saying
1382
- * the funds were safe but unadded (ROUT-242).
1383
- *
1384
- * So the approval happens here, before the amount is settled, and the amount
1385
- * comes from a read taken after it. Two things this deliberately is not:
1386
- *
1387
- * - It is not a balance sweep. `received` is a DELTA over the pre-swap
1388
- * balance, so a wallet already holding WETH reads far above it; depositing
1389
- * the balance would move funds the user never offered. The arrival is the
1390
- * ceiling and the balance is only ever allowed to lower it.
1391
- * - It does not touch USDC, which moves on signed typed data and so spends
1392
- * nothing of the user's in between, nor a paymaster-configured client,
1393
- * where the sponsor covers the transfer and Permit2 never applies.
1683
+ * Finish any user-paid Permit2 approval before measuring the deposit.
1684
+ * Wallets can charge approval gas in the received token (ROUT-242/544).
1685
+ * Cap the result at the swap arrival to preserve pre-existing wallet funds.
1686
+ * Native Base/Arbitrum USDC uses sponsored ERC-2612; configured paymaster
1687
+ * wallet calls also cover approval without spending the received tokens.
1394
1688
  */
1395
1689
  private settleSwapDepositAmount;
1396
1690
  private walletSeesBalance;
@@ -1463,11 +1757,12 @@ declare class OwneySDK {
1463
1757
  * Every order is attempted even if an earlier one throws: they are unrelated
1464
1758
  * escrows, and one ending badly must not abandon the next one's secrets.
1465
1759
  * `unfinished` is not a verdict — the order may still settle, so unless the
1466
- * chain has said refunded or cancelled its preimages are kept.
1760
+ * provider has confirmed full settlement or refund, its preimages are kept.
1467
1761
  */
1468
1762
  resumePendingSwaps(options?: {
1469
1763
  onStage?: (orderHash: string, stage: SwapStage) => void;
1470
1764
  timeoutMs?: number;
1765
+ orderHash?: string;
1471
1766
  }): Promise<{
1472
1767
  orderHash: string;
1473
1768
  status: "completed" | "unfinished";
@@ -1585,6 +1880,14 @@ declare class OwneySDK {
1585
1880
  /** Percent, classic rail only. Fusion+ prices through its auction. */
1586
1881
  slippage?: number;
1587
1882
  onSwapProgress?: (stage: SwapStage) => void;
1883
+ /** Destination balance baseline, read after the swap and before deposit preparation. */
1884
+ onBeforeDeposit?: () => Promise<void>;
1885
+ onDepositProgress?: FundingProgress;
1886
+ onBeforeDepositSubmission?: DepositOptions["onBeforeSubmission"];
1887
+ /** Stop a stale foreground attempt before it prepares or sends another transaction. */
1888
+ assertCurrent?: () => void;
1889
+ /** Funding-ledger reference for this swap and its deposit. Generated when omitted. */
1890
+ operationId?: string;
1588
1891
  }): Promise<{
1589
1892
  swap: {
1590
1893
  received: string;
@@ -1598,6 +1901,24 @@ declare class OwneySDK {
1598
1901
  * want this one; `swap.received` stays what it says it is.
1599
1902
  */
1600
1903
  deposited: string;
1904
+ /** Funding-ledger reference shared by the swap and its deposit. */
1905
+ operationId?: string;
1906
+ }>;
1907
+ /** Read-only confirmation of a saved pre-swap withdrawal. Never withdraws or swaps. */
1908
+ recheckWithdrawalSwap(id: string): Promise<WithdrawSwapRecord>;
1909
+ /** Explicit foreground continuation: spends verified payouts, never withdraws again. */
1910
+ continueWithdrawalSwap(id: string, callbacks?: Pick<Parameters<OwneySDK["withdrawAndSwap"]>[0], "onSwapProgress" | "onOrderSubmitted" | "onWithdrawalProgress" | "assertCurrent">): Promise<{
1911
+ withdraw: OwneyWithdrawResult | AgentWithdrawResult;
1912
+ /** What actually arrived in the wallet, smallest unit of the agent's asset. */
1913
+ withdrawn: string;
1914
+ swap: {
1915
+ received: string;
1916
+ spent?: string;
1917
+ orderHash?: string;
1918
+ txHash?: string;
1919
+ };
1920
+ /** Funding-ledger reference shared by the withdrawal and the swap. */
1921
+ operationId?: string;
1601
1922
  }>;
1602
1923
  /**
1603
1924
  * Withdraw from an agent and swap the proceeds into whatever the user wants
@@ -1611,10 +1932,9 @@ declare class OwneySDK {
1611
1932
  * Quoting before the tokens land would size the swap against a balance that
1612
1933
  * is not there yet.
1613
1934
  *
1614
- * The swap is therefore sized from the MEASURED arrival, exactly as the
1615
- * deposit path sizes its deposit from the measured swap output. On a full
1616
- * withdrawal there is no other number available — "MAX" has no figure until
1617
- * the agent picks one.
1935
+ * Wait for each participating agent's owner payout and size one swap from
1936
+ * their confirmed net amounts. A first wallet increase cannot establish
1937
+ * that every payout arrived. Failed or incomplete withdrawals stop here.
1618
1938
  *
1619
1939
  * **Failure here is not symmetrical with the deposit path.** A failed
1620
1940
  * deposit-swap leaves the user holding what they started with. A failed
@@ -1634,6 +1954,7 @@ declare class OwneySDK {
1634
1954
  to: {
1635
1955
  chainId: number;
1636
1956
  symbol: string;
1957
+ decimals?: number;
1637
1958
  };
1638
1959
  /** Human units ("10.5"). Omit to withdraw the full agent balance. */
1639
1960
  amount?: string;
@@ -1641,6 +1962,8 @@ declare class OwneySDK {
1641
1962
  /** Percent, classic rail only. Fusion+ prices through its auction. */
1642
1963
  slippage?: number;
1643
1964
  onSwapProgress?: (stage: SwapStage) => void;
1965
+ /** Receipt evidence for the existing funding/recovery tracker. */
1966
+ onWithdrawalProgress?: FundingProgress;
1644
1967
  /**
1645
1968
  * Fires once the order is with the relayer, before the watch.
1646
1969
  *
@@ -1666,18 +1989,32 @@ declare class OwneySDK {
1666
1989
  withdrawn: string;
1667
1990
  /** Smallest unit of the destination — the auction's start, not its floor. */
1668
1991
  expected: string;
1992
+ spent?: string;
1993
+ durable?: boolean;
1669
1994
  }) => void;
1670
1995
  /** How long to wait for the withdrawal to land before giving up on the swap. */
1671
1996
  arrivalTimeoutMs?: number;
1997
+ /** UI ownership fence, checked before each financial continuation. */
1998
+ assertCurrent?: () => void;
1999
+ /** Used only by explicit continueWithdrawalSwap; it never sends another withdrawal. */
2000
+ recoveryId?: string;
2001
+ /**
2002
+ * Funding-ledger reference for this withdrawal and swap. Generated when
2003
+ * omitted; a continuation reuses the one saved on its record.
2004
+ */
2005
+ operationId?: string;
1672
2006
  }): Promise<{
1673
2007
  withdraw: OwneyWithdrawResult | AgentWithdrawResult;
1674
2008
  /** What actually arrived in the wallet, smallest unit of the agent's asset. */
1675
2009
  withdrawn: string;
1676
2010
  swap: {
1677
2011
  received: string;
2012
+ spent?: string;
1678
2013
  orderHash?: string;
1679
2014
  txHash?: string;
1680
2015
  };
2016
+ /** Funding-ledger reference shared by the withdrawal and the swap. */
2017
+ operationId?: string;
1681
2018
  }>;
1682
2019
  /**
1683
2020
  * Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
@@ -1689,25 +2026,62 @@ declare class OwneySDK {
1689
2026
  * @returns {AgentWithdrawResult} for a single agent, or {OwneyWithdrawResult} with per-agent results
1690
2027
  */
1691
2028
  withdraw(options: WithdrawOptions): Promise<OwneyWithdrawResult | AgentWithdrawResult>;
2029
+ /**
2030
+ * Claims the cross-device hold for every agent in the plan. Returns the hold,
2031
+ * or undefined when the reservation is off or the API is unavailable and the
2032
+ * mode is fail-open. Throws only before anything is submitted:
2033
+ * - `WITHDRAW_IN_PROGRESS` / `RESERVED_ELSEWHERE` on a 409;
2034
+ * - `WITHDRAW_RESERVATION_UNAVAILABLE` when unavailable and fail-closed.
2035
+ */
2036
+ private reserveWithdrawal;
2037
+ /**
2038
+ * The cached Yieldseeker SIWE proof, when Yieldseeker is active for this
2039
+ * SDK. Cache only: never prompts. Yieldseeker signs on Base, so a claim on
2040
+ * another chain falls back to the Base proof (the server checks the
2041
+ * signature, the address and its age, not the chain).
2042
+ */
2043
+ private peekReservationProof;
2044
+ /**
2045
+ * Releases or keeps each agent's hold when `withdraw()` ends. Never throws.
2046
+ * - unattempted agents: `not_submitted`;
2047
+ * - `confirmed` / definitively `failed` legs: released;
2048
+ * - pending/unknown legs (Zyfai's hashless acknowledgement): kept;
2049
+ * - a throw without submission evidence: `not_submitted`;
2050
+ * - Zyfai "withdrawal already in progress": kept, dispatch `provider_in_progress`.
2051
+ */
2052
+ private settleWithdrawalReservation;
2053
+ /**
2054
+ * Releases a withdrawal reservation this browser still holds (the holder
2055
+ * token is kept per operationId). Use it when the app learns the outcome of a
2056
+ * kept hold, for example a Zyfai payout that arrived later. Never throws; a
2057
+ * hold this SDK does not know about is left to the server's expiry.
2058
+ */
2059
+ releaseWithdrawalReservation(operationId: string, reason: ReservationReleaseReason, agents?: ReservationAgent[]): Promise<void>;
2060
+ /**
2061
+ * Reports a withdrawal leg that was proven after its call ended (a hashless
2062
+ * Zyfai payout found on chain or in history) to the funding ledger, then
2063
+ * releases the withdrawal reservation this browser holds, as a fallback to
2064
+ * the server's own release. Only evidence with a hash whose transfer and
2065
+ * delivery are both confirmed is reported; anything else is ignored.
2066
+ * The ledger PATCHes the existing operation (creating it only on a 404) and
2067
+ * the server re-verifies the hash. Never throws.
2068
+ */
2069
+ reportWithdrawalRecovery(operationId: string, evidence: FundingEvidence): Promise<void>;
2070
+ private withdrawFromAgents;
2071
+ /** Read-only invalidation after new pool-deposit activity. Does not restart
2072
+ * funding reconciliation, bypass cooldowns, or authorize a transaction. */
2073
+ invalidateAllocationRead(scope: Pick<FundingEvidence, "agentId" | "walletAddress" | "chainId" | "token">): boolean;
1692
2074
  /**
1693
2075
  * Get the user's balances for a specific agent, or aggregated across all agents.
1694
2076
  * @param agentId - Optional. Agent to query. Omit for aggregated balances.
1695
2077
  * @returns {AgentBalance} for a single agent, or {OwneyBalances} with totalBalance and per-agent breakdown
1696
2078
  */
1697
- /**
1698
- * Withdraw every position the wallet holds, across chains and assets.
1699
- *
1700
- * `withdraw()` drains one asset on one chain, so this is N of those. It
1701
- * deliberately does not stop at the first failure: the funds in the other
1702
- * positions are just as withdrawable, and someone who asked for everything
1703
- * is better served by three of four than by none. Each leg reports its own
1704
- * outcome so the caller can name the ones that did not arrive; only a total
1705
- * failure throws.
1706
- *
1707
- * @returns {OwneyWithdrawAllResult} one leg per position attempted.
1708
- */
1709
- withdrawAll(): Promise<OwneyWithdrawAllResult>;
1710
- getBalances(agentId?: AgentId): Promise<OwneyBalances | AgentBalance>;
2079
+ getBalances(agentId?: AgentId, options?: {
2080
+ chainId?: number;
2081
+ asset?: OwneySupportedTokens;
2082
+ }): Promise<OwneyBalances | AgentBalance>;
2083
+ /** Preserve failure objects for withdrawal recovery without changing public balance results. */
2084
+ private readAggregatedBalances;
1711
2085
  /**
1712
2086
  * Get the user's on-chain earnings for a specific agent, or aggregated across all agents.
1713
2087
  * @param agentId - Optional. Agent to query. Omit for aggregated earnings.
@@ -1719,6 +2093,7 @@ declare class OwneySDK {
1719
2093
  * Agents without a refresh capability fall back to their current snapshot.
1720
2094
  */
1721
2095
  refreshEarnings(agentId?: AgentId): Promise<OwneyEarnings | AgentEarnings>;
2096
+ private aggregateEarnings;
1722
2097
  /**
1723
2098
  * Get the weighted APY for the user's account over a time period.
1724
2099
  * When querying all agents, the total APY is a balance-weighted average.
@@ -1728,37 +2103,16 @@ declare class OwneySDK {
1728
2103
  * @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
1729
2104
  */
1730
2105
  /**
1731
- * Daily cumulative NET earnings for the selected chain/asset, backing the
1732
- * "recent earnings" subline. Net is computed as Zyfai's own
1733
- * `lifetime + unrealized + current x 0.9`, so the figure reconciles with the
1734
- * balance headline rather than reading ~11% high. (ROUT-452)
2106
+ * Daily cumulative earnings in the selected asset's units, backing the
2107
+ * "recent earnings" subline. Each adapter uses its provider's earnings basis.
1735
2108
  *
1736
2109
  * Unlike getAccountApy this does NOT blend across agents: earnings are
1737
2110
  * summed, not weighted, and an agent that fails to report must not silently
1738
2111
  * subtract from the total. Without an agentId the series is the sum of the
1739
2112
  * agents that answered.
1740
2113
  */
1741
- getDailyEarnings({ agentId, days, tokenSymbol, chainIds, }: DailyEarningsOptions): Promise<AccountDailyEarnings>;
1742
- /**
1743
- * The deposit-time pool catalogue (ROUT-569): every protocol with its
1744
- * selectable pools (name, APY, TVL, link) for `asset` under `strategy`.
1745
- * Defaults to the zyfai agent, the only one with pool customization today.
1746
- */
1747
- getPoolCatalog(params: {
1748
- asset: OwneySupportedTokens;
1749
- strategy: "conservative" | "aggressive" | "yieldmaxxing";
1750
- agentId?: AgentId;
1751
- }): Promise<PoolCatalogProtocol[]>;
1752
- /**
1753
- * Apply a user's deposit-time pool selection to their account (ROUT-569).
1754
- * The request carries explicit pool choices plus the resulting strategy for
1755
- * each asset reviewed in the deposit flow.
1756
- */
1757
- setPoolSelection(params: {
1758
- selection: UserPoolSelectionRequest;
1759
- agentId?: AgentId;
1760
- }): Promise<void>;
1761
- getAccountApy({ agentId, days, tokenSymbol, chainId: scope, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
2114
+ getDailyEarnings({ agentId, days, tokenSymbol, }: DailyEarningsOptions): Promise<AccountDailyEarnings>;
2115
+ getAccountApy({ agentId, days, tokenSymbol, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
1762
2116
  /**
1763
2117
  * Get transaction history for a specific agent, or all agents.
1764
2118
  *
@@ -1792,14 +2146,17 @@ declare class OwneySDK {
1792
2146
  */
1793
2147
  ensureAutoSelectProtocols(asset: "USDC" | "WETH", agentId?: AgentId): Promise<boolean>;
1794
2148
  /**
1795
- * One-time, user-paid approval of Permit2 on the sponsored WETH token for
1796
- * the active chain. Required once per wallet per chain before gasless WETH
1797
- * deposits; afterwards deposit() is signature-only. Resolves only after the
1798
- * approval transaction is mined (1 confirmation), so a subsequent deposit()
1799
- * will see the new allowance; throws if the transaction reverted.
2149
+ * User-paid approval of Permit2 on the selected token for the active chain.
2150
+ * Grants the maximum ERC20 allowance so later deposits do not require another
2151
+ * approval. Resolves after one confirmation so the subsequent deposit attempt
2152
+ * sees the new allowance. Deposit retries pass their captured chain id so a
2153
+ * concurrent activation cannot redirect the approval to another network.
2154
+ *
2155
+ * @param requiredAmount Raw base-unit amount the pending deposit must cover.
2156
+ * @param expectedChainId Chain captured by the deposit that requested approval.
1800
2157
  * @returns the approval transaction hash.
1801
2158
  */
1802
- approvePermit2(asset?: "WETH"): Promise<`0x${string}`>;
2159
+ approvePermit2(asset?: OwneySupportedTokens, requiredAmount?: bigint, expectedChainId?: OwneySupportedChainId, assertCurrent?: () => void): Promise<`0x${string}`>;
1803
2160
  /**
1804
2161
  * Get the agent's average APY performance over a time period. Does not require a wallet connection.
1805
2162
  * @param options - Contains agentId (optional) and days ("7D", "14D", or "30D")
@@ -1823,6 +2180,365 @@ declare class OwneySDK {
1823
2180
  getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
1824
2181
  }
1825
2182
 
2183
+ type YieldseekerAuthToken = {
2184
+ message: string;
2185
+ signature: Hex;
2186
+ };
2187
+ type YieldseekerAuthDependencies = {
2188
+ origin?: string;
2189
+ now?: () => Date;
2190
+ nonce?: () => string;
2191
+ };
2192
+
2193
+ type YieldseekerFetch = typeof fetch;
2194
+
2195
+ type YieldseekerTransaction = {
2196
+ from: `0x${string}`;
2197
+ to: `0x${string}`;
2198
+ data: `0x${string}`;
2199
+ value: string;
2200
+ chainId: number;
2201
+ };
2202
+
2203
+ type YieldseekerWalletStatus = {
2204
+ agentWallet: Address;
2205
+ owner: Address;
2206
+ ownerPath: "eoa" | "smart";
2207
+ asset: Address;
2208
+ implementation: Address;
2209
+ version: "v1" | "v2" | "unknown";
2210
+ upgradeAvailable: boolean;
2211
+ /** The factory, owner, base asset, and provider wallet mapping all agree. */
2212
+ verified: boolean;
2213
+ };
2214
+
2215
+ type YieldseekerAgentOptions = {
2216
+ baseUrl?: string;
2217
+ routingApiBaseUrl?: string;
2218
+ fetchFn?: YieldseekerFetch;
2219
+ auth?: YieldseekerAuthDependencies;
2220
+ /** Dedicated read transport; Base is used for receipt polling. */
2221
+ rpcUrls?: RpcUrlsConfig;
2222
+ /** Test seam for the wallet-submission/receipt boundary. */
2223
+ transactionExecutor?: (state: ConnectionState, chainId: number, transaction: YieldseekerTransaction, onReceipt?: (receipt: viem.TransactionReceipt) => void) => Promise<Hex>;
2224
+ /** Test seam for transactions submitted outside transactionExecutor. */
2225
+ unwindReceiptWaiter?: (state: ConnectionState, chainId: number, transactionHash: Hex) => Promise<void>;
2226
+ };
2227
+ declare class YieldseekerAgent implements IAgent {
2228
+ readonly id = "yieldseeker";
2229
+ readonly balanceComposition: "tokens-plus-positions";
2230
+ readonly withdrawalRequiresWalletApproval = true;
2231
+ readonly supportedChainIds: readonly [8453];
2232
+ readonly supportedAssets: readonly [{
2233
+ readonly chainId: 8453;
2234
+ readonly chain: "BASE";
2235
+ readonly assets: readonly [{
2236
+ readonly symbol: "USDC";
2237
+ readonly minDepositAmount: "10000000";
2238
+ }, {
2239
+ readonly symbol: "WETH";
2240
+ readonly minDepositAmount: "1";
2241
+ }];
2242
+ }];
2243
+ private readonly api;
2244
+ private readonly auth;
2245
+ private readonly rpcUrls?;
2246
+ private readonly owneyApiKey;
2247
+ private readonly routingApiBaseUrl?;
2248
+ private receiptClient?;
2249
+ private readonly withdrawalVersionCache;
2250
+ private readonly pendingWalletStatus;
2251
+ /** Lowercase Agent Wallet -> when this instance's deploy request succeeded. */
2252
+ private readonly recentDeployments;
2253
+ private readonly pendingUpgrades;
2254
+ private readonly transactionExecutor?;
2255
+ private readonly unwindReceiptWaiter?;
2256
+ private readonly agentContexts;
2257
+ private readonly walletContexts;
2258
+ private readonly agentAccountReads;
2259
+ private readonly reportedAccounts;
2260
+ private readonly missingSlots;
2261
+ private readonly freshListReads;
2262
+ private readonly knownContextKeys;
2263
+ private readonly pendingSlotInvalidations;
2264
+ private readonly balanceContexts;
2265
+ private readonly balanceVaults;
2266
+ private readonly users;
2267
+ private readonly pendingAgents;
2268
+ private readonly pendingWalletContexts;
2269
+ private readonly readCache;
2270
+ private readonly pendingReads;
2271
+ private readGeneration;
2272
+ private readonly portfolioVersions;
2273
+ private readonly liquidityVersions;
2274
+ private readonly snapshotFailures;
2275
+ private readonly standardReadFailures;
2276
+ private readonly endpointReadFailures;
2277
+ private readonly reconcileUntil;
2278
+ private readonly allocationRefresh;
2279
+ private readonly activityRefreshUntil;
2280
+ private readonly snapshotMovements;
2281
+ private readonly movementEpochs;
2282
+ private readonly settlementChecks;
2283
+ private ledgerAccess?;
2284
+ private readonly ledgerReads;
2285
+ /** contextKey -> movements this instance started settling (by tx hash) and how they refresh:
2286
+ * awaiting the ledger, refreshed when ready (ledger), or on the timed backoff (legacy). */
2287
+ private readonly localMovements;
2288
+ /** contextKey -> tx hash -> refresh-when-ready state of a ledger movement. */
2289
+ private readonly refreshPlans;
2290
+ /** contextKey -> the agent's ledger movements from the latest ledger read. */
2291
+ private readonly ledgerMovementCache;
2292
+ /** Contexts whose next snapshot request is a refresh-when-ready force. */
2293
+ private readonly readyForces;
2294
+ private readonly serverBaselines;
2295
+ private readonly snapshotHistory;
2296
+ /** contextKey -> the history key its refresh plans persist forced times under. */
2297
+ private readonly planHistoryKeys;
2298
+ /** A ledger read slower than this counts as "no ledger information" for that read. */
2299
+ private ledgerBudgetMs;
2300
+ /** slotKey -> the last successful ledger rows and when they arrived. */
2301
+ private readonly lastLedgerRows;
2302
+ private readonly vaultOptions;
2303
+ private readonly pendingVaultOptions;
2304
+ private readonly assetApyStats;
2305
+ private readonly pendingAssetApyStats;
2306
+ constructor(owneyApiKey: string, options?: YieldseekerAgentOptions);
2307
+ private getReceiptClient;
2308
+ /** Reads the actual proxy implementation; Yieldseeker's API walletType is not a version check. */
2309
+ getWalletStatus(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, useCachedV2?: boolean): Promise<YieldseekerWalletStatus | null>;
2310
+ /** Reads (or reuses the 15-minute verified V2 hint for) this exact context's wallet. */
2311
+ private readWalletStatus;
2312
+ /**
2313
+ * Deposits go only to a wallet whose identity is verified on chain (factory
2314
+ * mapping, owner, base asset, FACTORY). The API key is public, so the wallet
2315
+ * the provider API returned is not trusted on its own. V1 wallets still
2316
+ * accept deposits: only identity is required, not the V2 implementation.
2317
+ * A failed read fails closed (reason UNAVAILABLE): an unverified wallet never
2318
+ * receives funds. Session changes keep their own NOT_CONNECTED error.
2319
+ */
2320
+ private assertDepositWalletVerified;
2321
+ private rememberWalletStatus;
2322
+ /** Explicit owner action. This never runs as a side effect of withdrawal. */
2323
+ upgradeWallet(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, gasMode?: "paid" | "sponsored"): Promise<{
2324
+ txHash: Hex;
2325
+ status: YieldseekerWalletStatus;
2326
+ }>;
2327
+ disconnect(): Promise<void>;
2328
+ activateAgent(state: ConnectionState, chainId: number, asset?: OwneySupportedTokens): Promise<void>;
2329
+ deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback, onProgress?: FundingProgress, onBeforeSubmission?: (evidence: FundingEvidence) => void | Promise<void>): Promise<OwneyDepositResult>;
2330
+ withdraw(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, amount?: string, onProgress?: FundingProgress, gasMode?: "auto" | "sponsored" | "paid", onBeforeSubmission?: FundingProgress, assertOperation?: () => void): Promise<AgentWithdrawResult>;
2331
+ private withdrawInternal;
2332
+ /** Fresh position amounts for withdrawal planning, net of reserved fees. */
2333
+ getWithdrawableBalance(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, minimumAmount?: bigint): Promise<bigint>;
2334
+ /**
2335
+ * The cached SIWE proof, decoded, for the withdrawal reservation claim's
2336
+ * owner proof. Only a proof already in the cache: this never prompts the
2337
+ * wallet and never throws. Never log the result.
2338
+ */
2339
+ peekReservationProof(state: ConnectionState, chainId: number): YieldseekerAuthToken | undefined;
2340
+ /** Recheck MAX without re-unwinding, paying out, or requesting a signature. */
2341
+ verifyWithdrawalCompletion(state: ConnectionState, evidence: FundingEvidence): Promise<WithdrawalCompletion>;
2342
+ private readVaultShares;
2343
+ private validateWithdrawalPositions;
2344
+ private withdrawalVaultHints;
2345
+ private readWithdrawalPositions;
2346
+ private resolveWithdrawalLiquidity;
2347
+ getBalances(state: ConnectionState, chainId: number, asset?: OwneySupportedTokens): Promise<AgentBalance>;
2348
+ verifyWithdrawalBalance(state: ConnectionState, evidence: FundingEvidence, balance: AgentBalance): Promise<AssetReadMetadata | undefined>;
2349
+ invalidateAllocationRead(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): void;
2350
+ invalidateFundingRead(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, refreshUntil?: number, txHash?: string): void;
2351
+ endFundingBalanceRefresh(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, read: AssetReadMetadata): boolean;
2352
+ getFundingWallet(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<string>;
2353
+ hasExistingDepositFunds(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<true | undefined>;
2354
+ getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
2355
+ getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays, tokenSymbol?: string): Promise<AccountAgentApy>;
2356
+ getDailyEarnings(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
2357
+ getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
2358
+ getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
2359
+ getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
2360
+ supportsAgentApyPeriod(days: DailyApyDays): boolean;
2361
+ private loadAssetApyStats;
2362
+ private loadVaultOptions;
2363
+ private userKey;
2364
+ /** One deposit/withdraw slot: owner, chain and asset. */
2365
+ private slotKey;
2366
+ /**
2367
+ * One agent's portfolio state. Includes the agentId so duplicate or renamed
2368
+ * agents for the same asset never share caches, versions or settlement.
2369
+ */
2370
+ private contextKey;
2371
+ /**
2372
+ * Context keys an asset-only call applies to: the selected agent when known,
2373
+ * else every agent of the slot seen this session.
2374
+ */
2375
+ private slotContextKeys;
2376
+ /**
2377
+ * Apply an asset-only invalidation. Before any agent of the slot resolves,
2378
+ * queue it so the first resolved agents still see it (as the slot-keyed
2379
+ * state did before contexts were keyed by agentId).
2380
+ */
2381
+ private invalidateSlot;
2382
+ /** Record the selected agent for a slot; queued invalidations are now settled. */
2383
+ private selectContext;
2384
+ private assertSession;
2385
+ private cachedRead;
2386
+ private agentListKey;
2387
+ private listAgents;
2388
+ /**
2389
+ * The routing API's stored accounts for owner+chain, read once per session.
2390
+ * Resolves null when unavailable (callers keep name matching) and never
2391
+ * rejects. A failure is retried after a short window.
2392
+ */
2393
+ private agentAccounts;
2394
+ /** Yieldseeker accounts for one slot (returned addresses are compared lowercase). */
2395
+ private slotAccounts;
2396
+ private agentFits;
2397
+ /**
2398
+ * The listed agent of the slot whose resolved wallet is in the
2399
+ * highest-priority set of `priorities` (index 0 first). Hinted agentIds are
2400
+ * resolved first and a hinted top-priority match ends the search; then other
2401
+ * listed agents, at most YIELDSEEKER_WALLET_MATCH_LIMIT wallets in total.
2402
+ */
2403
+ private agentWithWallet;
2404
+ /**
2405
+ * chooseAgent, re-reading a cached list once (bypassing its cache) when the
2406
+ * verified agent is missing. A slot still missing after that re-read is
2407
+ * remembered for the list cache window, so later reads fail from the cached
2408
+ * list without another re-read.
2409
+ */
2410
+ private chooseAgentRefreshing;
2411
+ private isSlotMissing;
2412
+ /**
2413
+ * The agent that serves deposits and withdrawals for a slot (Ruling 23):
2414
+ * 1. the listed fitting agent whose wallet is the verified account's wallet,
2415
+ * whatever its name; the stored agentId is only a hint;
2416
+ * 2. else a listed fitting agent whose wallet is a superseded account's wallet;
2417
+ * 3. else the fitting agent named "owney" (first use, migration, or a
2418
+ * verified wallet that is not a fitting listed agent);
2419
+ * 4. else, with a verified account, throw YIELDSEEKER_AGENT_MISSING (never
2420
+ * create); without one, undefined (the caller may create).
2421
+ * Steps 1 and 2 share one search of at most YIELDSEEKER_WALLET_MATCH_LIMIT
2422
+ * wallet reads. The account report then records the selected wallet; the
2423
+ * server marks it superseded when it differs from the verified wallet.
2424
+ */
2425
+ private chooseAgent;
2426
+ private isAgentMissing;
2427
+ private agentMissing;
2428
+ /**
2429
+ * Fire-and-forget: record which agent serves this slot. Never awaited on the
2430
+ * funds path and never throws; once per agent wallet and deployment state
2431
+ * per session.
2432
+ */
2433
+ private reportAccount;
2434
+ private contextForAgent;
2435
+ private resolveUser;
2436
+ private forgetUser;
2437
+ private ensureAgent;
2438
+ private findAgent;
2439
+ private resolveAgent;
2440
+ /** Create the slot's agent. Only reached when no stored or named agent matched. */
2441
+ private createAgent;
2442
+ /**
2443
+ * The routing create lock refused the create: another tab or app owns or is
2444
+ * creating this slot's agent. Re-read the accounts and the list (bypassing
2445
+ * their caches) and select that agent, once more after 2 s if needed. A
2446
+ * verified account is matched by wallet; otherwise the returned agentId is
2447
+ * used. Never creates again.
2448
+ */
2449
+ private adoptConflictingAgent;
2450
+ private loadPortfolio;
2451
+ private loadActivityPortfolio;
2452
+ private resolvePortfolioContexts;
2453
+ private portfolioVersion;
2454
+ /** Snapshot cache lifetime: the settlement backoff while a movement is being
2455
+ * checked, otherwise the routine non-forced cadence. */
2456
+ private portfolioCacheMs;
2457
+ /** A pending movement inside its ten-minute window. */
2458
+ private settlementWindow;
2459
+ /** A pending movement inside its ten-minute window forces snapshots, unless
2460
+ * every movement being settled is refreshed when ready through the ledger. */
2461
+ private settling;
2462
+ /** Start a new forced-check schedule, or keep the active one. */
2463
+ private beginSettlement;
2464
+ private snapshotMovement;
2465
+ private advancePortfolioVersion;
2466
+ private requestPortfolioSnapshot;
2467
+ private portfolioSnapshot;
2468
+ private loadPortfolioContext;
2469
+ private loadActivityContext;
2470
+ private loadPortfolioParts;
2471
+ private deployAgent;
2472
+ setFundingLedgerAccess(access: AgentFundingLedgerAccess | undefined): void;
2473
+ private historyKey;
2474
+ /** Funding-ledger rows for this slot, cached 15 s. Never throws: null on any failure. */
2475
+ private readLedger;
2476
+ /**
2477
+ * A ledger read within the read budget. On a timeout or failure, the last
2478
+ * successful rows are reused if at most 60 s old (no hold flicker); older
2479
+ * means null, i.e. today's behaviour.
2480
+ */
2481
+ private readLedgerBudgeted;
2482
+ private ledgerMovementsFor;
2483
+ /** Track a movement this instance is settling. With ledger access and a tx
2484
+ * hash it awaits the ledger; otherwise it keeps the timed backoff. */
2485
+ private trackLocalMovement;
2486
+ /** Timed (legacy) entries end with their ten-minute window; ledger ones after the one-hour index window. */
2487
+ private pruneLocalMovements;
2488
+ private hasAwaitingMovement;
2489
+ /** Every movement being settled here is (or may yet be) refreshed when ready through the ledger. */
2490
+ private deferredToLedger;
2491
+ /** A null ledger sends every local movement back to the timed backoff; a
2492
+ * listed tx hash is refreshed when ready; an unlisted one after the grace too. */
2493
+ private resolveLocalMovements;
2494
+ /**
2495
+ * Refresh when ready, before a portfolio read: read the ledger (cached) when
2496
+ * an earnings read asks for it or a movement is being tracked, update each
2497
+ * recent movement's plan, poll the provider's history (non-forced, 15 s
2498
+ * cache) for un-indexed tx hashes, and mark the next snapshot as forced when
2499
+ * a plan is due. Never throws.
2500
+ */
2501
+ private prepareLedgerRefresh;
2502
+ /** Apply one ledger read to local movements and refresh plans. False when the ledger is unavailable. */
2503
+ private applyLedgerRows;
2504
+ private updateRefreshPlans;
2505
+ /** Non-forced provider history read (15 s cache) to learn when a tx hash is indexed. */
2506
+ private pollIndexing;
2507
+ /** The forced snapshot about to be requested counts for every plan that is
2508
+ * due. False (do not force) when none is. */
2509
+ private noteReadyForce;
2510
+ private recordSnapshotHistory;
2511
+ private localHistory;
2512
+ /** After a snapshot: if this SDK's own history shows every recent ledger
2513
+ * movement in net deposits, no plan needs (more) forcing. */
2514
+ private checkLocalBooking;
2515
+ /** The newest server sample observed at or before `cutoff`, cached. Null when none or on failure. */
2516
+ private serverBaseline;
2517
+ /**
2518
+ * Earnings hold (spec B2): while a recent ledger movement is not booked by
2519
+ * the provider, report the last good `cumulativeYieldBase`. The balance is
2520
+ * untouched. Any missing input (no ledger, no baseline) or failure returns
2521
+ * the provider's value. Never throws.
2522
+ */
2523
+ private applyEarningsHold;
2524
+ private refreshSnapshotAfterMovement;
2525
+ private agentPath;
2526
+ private walletRequest;
2527
+ private providerRequest;
2528
+ private mapApiError;
2529
+ private submitTransaction;
2530
+ private waitForReceipt;
2531
+ private assertTransaction;
2532
+ private assertAgent;
2533
+ private isOwneyAgent;
2534
+ private assetForAgent;
2535
+ private isTransactionHash;
2536
+ private assertChain;
2537
+ private assertOptionalChain;
2538
+ private assertAsset;
2539
+ private invalidResponse;
2540
+ }
2541
+
1826
2542
  declare class InvalidHistoryCursorError extends Error {
1827
2543
  readonly code: "invalid_cursor";
1828
2544
  constructor(message: string);
@@ -1882,6 +2598,7 @@ declare function createOwneySIWX(config: OwneySIWXConfig): SIWXConfig;
1882
2598
  */
1883
2599
  type StoredOrder = {
1884
2600
  orderHash: string;
2601
+ walletAddress?: string;
1885
2602
  /** Preimages, one per fill. Index matters — fill N needs secret N. */
1886
2603
  secrets: string[];
1887
2604
  /** Chain the funds left from, so a resumed session can report it. */
@@ -1891,13 +2608,56 @@ type StoredOrder = {
1891
2608
  dstSymbol: string;
1892
2609
  dstChainId: number;
1893
2610
  amount: string;
1894
- /** Epoch ms. Used to drop orders far past any plausible timelock. */
2611
+ /** Epoch ms, for ordering recovery records. */
1895
2612
  createdAt: number;
1896
2613
  };
1897
2614
  /**
1898
- * Every stored order, newest first, dropping anything past MAX_AGE_MS.
2615
+ * Every unresolved stored order, newest first.
1899
2616
  * Used on mount to resume orders the user left in flight.
1900
2617
  */
1901
- declare function listOrders(now?: number): StoredOrder[];
2618
+ declare function listOrders(_now?: number): StoredOrder[];
2619
+
2620
+ /**
2621
+ * Non-blocking funding ledger reporter.
2622
+ *
2623
+ * Reports each funding operation (deposit / withdraw / swap) to the routing
2624
+ * API's `/api/v1/funding/operations` endpoints so support can reconstruct what
2625
+ * happened. Hard rule: reporting NEVER blocks or fails a funding action.
2626
+ *
2627
+ * - `start()` / `leg()` / `finish()` are synchronous and never throw.
2628
+ * - Requests run on a per-operation promise chain, create first.
2629
+ * - Every error is swallowed (visible only with debug logging on).
2630
+ */
2631
+ /** Set by tsup's `define`; "dev" when running from source. */
2632
+ declare const SDK_VERSION: string;
2633
+ type LedgerLegReport = {
2634
+ legKey: string;
2635
+ legKind: "agent" | "swap" | "approval";
2636
+ agentType?: string;
2637
+ agentWallet?: string;
2638
+ rail?: string;
2639
+ amountRaw?: string;
2640
+ status?: "created" | "submitted" | "unknown" | "failed" | "confirmed";
2641
+ txHash?: string;
2642
+ userOpHash?: string;
2643
+ callsId?: string;
2644
+ orderHash?: string;
2645
+ confirmedAmountRaw?: string;
2646
+ blockNumber?: string;
2647
+ errorCode?: string;
2648
+ swap?: {
2649
+ rail: "swap_classic" | "swap_fusion" | "swap_fusion_plus";
2650
+ srcChainId: number;
2651
+ dstChainId: number;
2652
+ srcToken: string;
2653
+ dstToken: string;
2654
+ srcAmountRaw: string;
2655
+ quotedDstAmountRaw?: string;
2656
+ receivedDstAmountRaw?: string;
2657
+ feeBps?: number;
2658
+ feeBpsSource?: "measured" | "stated";
2659
+ feeToken?: string;
2660
+ };
2661
+ };
1902
2662
 
1903
- export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyCoverage, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type AvailablePool, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OrgPoolPolicy, type OrgPoolSelection, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawAllLeg, type OwneyWithdrawAllResult, type OwneyWithdrawResult, type PendingDeposit, type PoolCatalogProtocol, type PoolSelectionStrategy, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type UserPoolSelection, type UserPoolSelectionRequest, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };
2663
+ export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentFundingLedgerAccess, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AssetReadMetadata, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositAuthorizationReference, type DepositCallback, type DepositOptions, type DepositReplacementValidation, type FundingEvidence, type FundingOperationKind, type FundingOperationLeg, type FundingOperationRow, type FundingProgress, type FundingStage, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LedgerLegReport, type LookbackDays, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type PendingDeposit, type ProviderSnapshotSample, type RebalanceLog, type ReservationAgent, type ReservationReleaseReason, type RpcUrlsConfig, SDK_VERSION, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type UnsignedUserOperationEvidence, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, type WithdrawalCompletion, type WithdrawalCompletionContext, type WithdrawalPayoutCandidate, type WithdrawalPayoutScan, type WithdrawalReservationConflict, type WithdrawalReservationMode, type WithdrawalReservationOptions, type WithdrawalSwapRecovery, YieldseekerAgent, type YieldseekerWalletStatus, type ZyfaiRpcUrlsConfig, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };