@owney/sdk 0.7.26 → 0.7.27-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import * as viem from 'viem';
2
+ import { Address, Hex } 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" | "building" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
225
+ type SwapStage = "withdrawing" | "withdrawn"
226
+ /** Withdrawal incomplete or unconfirmed; no swap was submitted. */
227
+ | "withdrawal-incomplete" | "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,34 @@ type SwapQuoteParams = {
246
250
  direction?: SwapDirection;
247
251
  };
248
252
 
249
- type ZyfaiRpcUrlsConfig = Partial<Record<(typeof SUPPORTED_CHAIN_IDS)[number], string>>;
253
+ type RpcUrlsConfig = Partial<Record<(typeof SUPPORTED_CHAIN_IDS)[number], string>>;
254
+ /** @deprecated Use RpcUrlsConfig. */
255
+ type ZyfaiRpcUrlsConfig = RpcUrlsConfig;
250
256
  interface OwneySDKConfig {
251
257
  apiKey: string;
258
+ /**
259
+ * Optional per-chain RPC overrides used for application-owned reads and
260
+ * transaction receipt polling. Missing chains use the Owney routing API's
261
+ * read-only RPC proxy. No upstream RPC credentials are included in the SDK.
262
+ * Wallet providers remain responsible for account access, chain switching,
263
+ * signatures, and transaction submission.
264
+ */
265
+ rpcUrls?: RpcUrlsConfig;
252
266
  /**
253
267
  * Optional per-chain RPC overrides for Zyfai SDK network calls.
254
268
  * Example: { 8453: "https://...", 42161: "https://..." }
269
+ * @deprecated Use rpcUrls so every agent shares the same read transport.
255
270
  */
256
271
  zyfaiRpcUrls?: ZyfaiRpcUrlsConfig;
272
+ /** Optional Owney Yieldseeker proxy base URL override for integration tests. */
273
+ yieldseekerApiBaseUrl?: string;
274
+ /** Optional SIWE origin override. Defaults to the requesting browser origin. */
275
+ yieldseekerSiweOrigin?: string;
257
276
  /**
258
277
  * 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.
278
+ * calls. RPC proxy requests use OWNEY_ROUTING_API_BASE_URL when this is
279
+ * omitted; without either value, all rpcUrls must be configured.
280
+ * Set this to a local/staging routing API when testing sponsor changes.
262
281
  */
263
282
  routingApiBaseUrl?: string;
264
283
  /**
@@ -300,7 +319,134 @@ type OwneySupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
300
319
  type OwneySupportedChains = (typeof SUPPORTED_CHAINS)[number];
301
320
  type OwneySupportedTokens = (typeof SUPPORTED_TOKENS)[number];
302
321
 
303
- type AgentId = "zyfai";
322
+ /**
323
+ * One protocol's pool selection on one chain. `pools` holds Zyfai pool NAMES
324
+ * verbatim — matched case-sensitively by customizeBatch, and an unrecognised
325
+ * name makes Zyfai's rebalance engine skip the whole protocol, so these strings
326
+ * must not be normalised anywhere.
327
+ *
328
+ * An empty array means "no usable pools on this chain".
329
+ */
330
+ type OrgPoolSelection = {
331
+ protocolId: string;
332
+ chainId: number;
333
+ pools: string[];
334
+ };
335
+ /**
336
+ * The partner's protocol/pool policy (ROUT-224). Sparse — only protocols they
337
+ * narrowed appear. Optional so an older routing API, which does not return the
338
+ * field, still parses; undefined and null both mean "change nothing".
339
+ */
340
+ type OrgPoolPolicy = {
341
+ autoApproveProtocols: boolean;
342
+ autoApprovePools: boolean;
343
+ selections: OrgPoolSelection[];
344
+ };
345
+ /**
346
+ * The organization's agent execution policy, or null when the partner has never
347
+ * configured one — in which case the agents leave the user's profile alone.
348
+ */
349
+ type OrgAgentConfig = {
350
+ splittingMode: "none" | "automatic" | "force";
351
+ minSplits: number | null;
352
+ poolPolicy?: OrgPoolPolicy | null;
353
+ };
354
+
355
+ type DepositCallback = (smartWalletAddress: string, chainId: number, amount: string) => Promise<`0x${string}`> | `0x${string}`;
356
+ interface IAgent {
357
+ readonly id: string;
358
+ readonly supportedChainIds: readonly OwneySupportedChainId[];
359
+ readonly supportedAssets: readonly AgentSupportedAssets[];
360
+ /**
361
+ * Describes how `AgentBalance.tokens` relates to `positions`.
362
+ * Most adapters expose token totals that already include deployed positions.
363
+ * Providers such as Yieldseeker expose idle wallet tokens separately, so
364
+ * withdrawal planning must add matching position amounts.
365
+ */
366
+ readonly balanceComposition?: "tokens-include-positions" | "tokens-plus-positions";
367
+ /**
368
+ * Whether a withdrawal requires an owner-approved wallet transaction.
369
+ * Aggregate withdrawals run these agents before relayer-only agents so a
370
+ * rejected wallet request cannot happen after another leg has committed.
371
+ */
372
+ readonly withdrawalRequiresWalletApproval?: boolean;
373
+ disconnect(): Promise<void>;
374
+ activateAgent(state: ConnectionState, chainId: number, asset?: OwneySupportedTokens): Promise<void>;
375
+ /**
376
+ * Apply the organization's agent policy to this user's account.
377
+ *
378
+ * Optional: an agent that has no equivalent knob simply omits it, which is why
379
+ * this is not part of `activateAgent`'s signature. Declared on the interface
380
+ * rather than only on ZyfaiAgent so the contract stays agent-neutral — the
381
+ * ticket asks for a design that can also cover Surf, which has no adapter yet.
382
+ *
383
+ * Implementations must be **non-fatal**: this runs during activation as a side
384
+ * effect, so a failure has to leave the user connected and their profile
385
+ * unchanged rather than break the connect.
386
+ */
387
+ applyOrgPolicy?(state: ConnectionState, chainId: number, policy: OrgAgentConfig): Promise<void>;
388
+ deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback, onProgress?: FundingProgress, onBeforeSubmission?: (evidence: FundingEvidence) => void | Promise<void>): Promise<OwneyDepositResult>;
389
+ withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string, onProgress?: FundingProgress, gasMode?: "auto" | "sponsored" | "paid", onBeforeSubmission?: FundingProgress): Promise<AgentWithdrawResult>;
390
+ /** A newly observed pool allocation invalidates this asset's portfolio cache only. */
391
+ invalidateAllocationRead?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): void;
392
+ /** Invalidate only the confirmed asset. This hook must not sign or submit transactions. */
393
+ invalidateFundingRead?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, refreshUntil?: number): void;
394
+ /** End accelerated balance reads only for the exact snapshot the caller displayed. */
395
+ endFundingBalanceRefresh?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, read: AssetReadMetadata): boolean;
396
+ getFundingHistory?(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
397
+ getFundingWallet?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<string>;
398
+ /** Verify the displayed remaining balance after a receipt-confirmed payout.
399
+ * Undefined means unknown; never substitute a failed read with zero. */
400
+ verifyWithdrawalBalance?(state: ConnectionState, evidence: FundingEvidence, balance: AgentBalance): Promise<AssetReadMetadata | undefined>;
401
+ /** Read-only chain proof when indexed withdrawal components are incomplete.
402
+ * Returns raw owner-withdrawable units; unavailable proof must throw.
403
+ * minimumAmount is the raw liquidity required from this agent for a typed
404
+ * plan, so adapters can expand discovery when known positions fall short. */
405
+ getWithdrawableBalance?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, minimumAmount?: bigint): Promise<bigint>;
406
+ /** Optional positive proof for a repeat deposit; unknown must fall back to portfolio validation. */
407
+ hasExistingDepositFunds?(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<true | undefined>;
408
+ getBalances(state: ConnectionState, chainId: number, asset?: OwneySupportedTokens): Promise<AgentBalance>;
409
+ getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
410
+ /**
411
+ * Refresh the agent's earnings snapshot when its backend supports doing so.
412
+ * Implementations own freshness and request-deduplication policy.
413
+ */
414
+ refreshEarnings?(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
415
+ getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays,
416
+ /**
417
+ * Optional asset symbol ("USDC" / "WETH") scoping the daily series to a
418
+ * single asset on the chain. Agents without per-asset positions ignore it.
419
+ */
420
+ tokenSymbol?: string): Promise<AccountAgentApy>;
421
+ /**
422
+ * Daily cumulative earnings in token units, scoped to a chain/asset, using
423
+ * the provider's earnings basis. Include an opening snapshot when available
424
+ * so the "recent earnings" subline can difference the endpoints. (ROUT-452)
425
+ */
426
+ getDailyEarnings?(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
427
+ getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
428
+ getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
429
+ /**
430
+ * Ensure the given asset uses backend protocol auto-selection
431
+ * (`autoSelectProtocols: true`). Optional capability — only agents whose
432
+ * backend models per-asset protocol selection implement it. Returns whether
433
+ * a write occurred (`false` = already enabled / not supported).
434
+ */
435
+ ensureAutoSelectProtocols?(state: ConnectionState, chainId: number, asset: "USDC" | "WETH"): Promise<boolean>;
436
+ getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
437
+ }
438
+ /**
439
+ * Optional filters for per-agent APY lookups.
440
+ * - `tokenSymbol` / `chainId` scope the APY to a specific asset+chain when
441
+ * the underlying provider supports it (Zyfai). Agents whose backends do
442
+ * not yet support per-asset APY will ignore these options.
443
+ */
444
+ type AgentApyOptions = {
445
+ tokenSymbol?: string;
446
+ chainId?: number;
447
+ };
448
+
449
+ type AgentId = "zyfai" | "yieldseeker";
304
450
  type Asset = string;
305
451
  type AgentSupportedAsset = {
306
452
  readonly symbol: string;
@@ -349,13 +495,26 @@ type HistoryFilters = {
349
495
  tokenSymbol?: string;
350
496
  };
351
497
  type HistoryOptions = {
498
+ chainId?: number;
352
499
  agentId?: AgentId;
353
500
  filters?: HistoryFilters;
354
501
  };
355
502
  type WithdrawOptions = {
503
+ /** Yieldseeker V2 only. "auto" requests sponsorship for a verified V2 wallet. */
504
+ gasMode?: "auto" | "sponsored" | "paid";
505
+ /** Exclude unresolved providers from aggregate withdrawals; direct agent requests are unchanged. */
506
+ excludeAgentIds?: AgentId[];
507
+ onProgress?: FundingProgress;
508
+ /**
509
+ * Durable pre-dispatch checkpoint for adapters with a recoverable operation ID.
510
+ * Rejection prevents submission; progress observers remain non-fatal.
511
+ */
512
+ onBeforeSubmission?: FundingProgress;
356
513
  asset: Asset;
357
514
  amount?: string;
358
515
  agentId?: AgentId;
516
+ /** Called after each agent returns; callback failures never change a financial result. */
517
+ onAgentResult?: (agentId: AgentId, result: AgentWithdrawResult) => void;
359
518
  };
360
519
  type AccountApyOptions = {
361
520
  agentId?: AgentId;
@@ -402,6 +561,12 @@ type AgentsApyOptions = {
402
561
  chainId?: number;
403
562
  };
404
563
  type DepositOptions = {
564
+ /** Resume only these already signed relayer bytes; never create a new authorization. */
565
+ resumeTxHash?: `0x${string}`;
566
+ onProgress?: FundingProgress;
567
+ /** Awaited immediately before dispatch. Throwing prevents submission.
568
+ * All legs of an atomic batch are checkpointed together. */
569
+ onBeforeSubmission?: (evidence: FundingEvidence[]) => void | Promise<void>;
405
570
  amount: string;
406
571
  asset: Asset;
407
572
  depositCallback?: DepositCallback;
@@ -409,40 +574,85 @@ type DepositOptions = {
409
574
  onApproved?: () => void;
410
575
  };
411
576
 
412
- /**
413
- * One protocol's pool selection on one chain. `pools` holds Zyfai pool NAMES
414
- * verbatim — matched case-sensitively by customizeBatch, and an unrecognised
415
- * name makes Zyfai's rebalance engine skip the whole protocol, so these strings
416
- * must not be normalised anywhere.
417
- *
418
- * An empty array means "no usable pools on this chain".
419
- */
420
- type OrgPoolSelection = {
421
- protocolId: string;
422
- chainId: number;
423
- pools: string[];
424
- };
425
- /**
426
- * The partner's protocol/pool policy (ROUT-224). Sparse — only protocols they
427
- * narrowed appear. Optional so an older routing API, which does not return the
428
- * field, still parses; undefined and null both mean "change nothing".
429
- */
430
- type OrgPoolPolicy = {
431
- autoApproveProtocols: boolean;
432
- autoApprovePools: boolean;
433
- selections: OrgPoolSelection[];
434
- };
435
- /**
436
- * The organization's agent execution policy, or null when the partner has never
437
- * configured one — in which case the agents leave the user's profile alone.
438
- */
439
- type OrgAgentConfig = {
440
- splittingMode: "none" | "automatic" | "force";
441
- minSplits: number | null;
442
- poolPolicy?: OrgPoolPolicy | null;
577
+ type FundingStage = "pending" | "confirmed" | "unknown" | "failed" | "not-applicable";
578
+ /** Hash-bound v0.6 recovery metadata. Deliberately excludes the owner signature. */
579
+ type UnsignedUserOperationEvidence = {
580
+ sender: string;
581
+ nonce: string;
582
+ initCode: string;
583
+ callData: string;
584
+ callGasLimit: string;
585
+ verificationGasLimit: string;
586
+ preVerificationGas: string;
587
+ maxFeePerGas: string;
588
+ maxPriorityFeePerGas: string;
589
+ paymasterAndData: string;
443
590
  };
444
-
591
+ /** Evidence about one provider leg. Amounts are token base units, never USD. */
592
+ interface FundingEvidence {
593
+ agentId: AgentId;
594
+ chainId: number;
595
+ token: OwneySupportedTokens;
596
+ walletAddress: string;
597
+ agentWallet?: string;
598
+ intendedAmount: string;
599
+ confirmedAmount?: string;
600
+ /** Receipt delivery and fulfillment of a typed requested amount are separate facts. */
601
+ amountCompletion?: "complete" | "shortfall";
602
+ /** Verified difference between the typed request and the actual owner payout. */
603
+ shortfallAmount?: string;
604
+ txHash?: string;
605
+ /** Persisted before a sponsored EOA operation is sent. */
606
+ userOpHash?: string;
607
+ /** Lets recovery verify a consumed nonce even if a bundler forgets the operation. */
608
+ userOperation?: UnsignedUserOperationEvidence;
609
+ /** Base Account calls ID used to recover an uncertain wallet submission. */
610
+ callsId?: string;
611
+ /** Deposit execution was attempted, rather than only prepared. Not confirmation. */
612
+ depositSubmission?: "started";
613
+ blockNumber?: string;
614
+ logIndexes?: number[];
615
+ transferLogs?: {
616
+ logIndex: number;
617
+ amountRaw: string;
618
+ }[];
619
+ /** Sanitized execution-request evidence. Attempted does not prove server acceptance. */
620
+ withdrawalRequest?: {
621
+ attempted: boolean;
622
+ method?: "GET" | "POST";
623
+ path?: "/users/withdraw" | "/users/partial-withdraw";
624
+ elapsedMs?: number;
625
+ /** Actual response status captured before the vendor replaces the HTTP error. */
626
+ httpStatus?: number;
627
+ failure?: "network" | "unauthorized" | "forbidden" | "rate-limited" | "insufficient-balance" | "session-key-missing" | "withdrawal-in-progress" | "other";
628
+ };
629
+ transfer: FundingStage;
630
+ registration: FundingStage;
631
+ delivery: FundingStage;
632
+ }
633
+ type FundingProgress = (evidence: FundingEvidence) => void;
634
+ interface AssetReadMetadata {
635
+ chainId: number;
636
+ asset: string;
637
+ fetchedAt?: number;
638
+ /** When the underlying provider request started; preserved on cached reads. */
639
+ requestedAt?: number;
640
+ /** SDK cache generation, not an onchain block or provider timestamp. */
641
+ readVersion?: number;
642
+ providerUpdatedAt?: string;
643
+ snapshotId?: string;
644
+ blockNumber?: string;
645
+ netDepositsRaw?: string;
646
+ /** Display-only agreement with a post-payout read. Does not prove that
647
+ * provider accounting, history or allocations include the transaction. */
648
+ withdrawalCheck?: {
649
+ txHash: string;
650
+ blockNumber: string;
651
+ };
652
+ positionsStatus: "available" | "unavailable";
653
+ }
445
654
  interface OwneyDepositResult {
655
+ evidence?: FundingEvidence;
446
656
  txHash: string;
447
657
  smartWallet: string;
448
658
  amount: string;
@@ -451,16 +661,28 @@ interface OwneyMultiDepositResult {
451
661
  agentResults: Record<string, OwneyDepositResult>;
452
662
  }
453
663
  interface AgentWithdrawResult {
664
+ evidence?: FundingEvidence;
454
665
  txHash?: string;
455
666
  type: "full" | "partial";
456
- /** Smallest-unit amount, or a provider sentinel such as "all" for a full request. */
667
+ /** Owner payout or clearing all MAX positions still needs verification. */
668
+ completion?: "unverified";
669
+ /** Confirmed smallest-unit amount; "0" when no owner payout is verified.
670
+ * Legacy providers may return a sentinel such as "all" for a full request. */
457
671
  amount: string;
672
+ /** Yieldseeker typed withdrawal fulfilled after an exactly verified fee
673
+ * deduction. Amount remains the confirmed net owner payout, and the gross
674
+ * amount must equal that payout plus the fee, all in token base units. */
675
+ feeAdjustment?: {
676
+ grossAmount: string;
677
+ feeAmount: string;
678
+ };
458
679
  }
459
680
  interface OwneyWithdrawResult {
460
681
  agentResult: Record<AgentId, AgentWithdrawResult>;
461
682
  /**
462
- * Sum of reported smallest-unit amounts; null when a full withdrawal's
463
- * amount is not yet known. An accepted request is not proof of settlement.
683
+ * Sum of confirmed smallest-unit amounts; null while any returned leg's
684
+ * payout is not yet known, including typed requests accepted asynchronously.
685
+ * Evidence-less custom adapters retain their confirmed-amount contract.
464
686
  */
465
687
  totalWithdrawn: string | null;
466
688
  }
@@ -478,6 +700,10 @@ interface OwneyPosition {
478
700
  pool?: string;
479
701
  asset: string;
480
702
  amount: string;
703
+ /** Provider-native raw quantity; may represent vault shares, not the underlying asset. */
704
+ amountRaw?: string;
705
+ /** Withdrawable underlying asset amount in that asset's smallest units. */
706
+ withdrawableAmountRaw?: string;
481
707
  apy?: number;
482
708
  tvl?: number;
483
709
  /** Pool liquidity. Prepared slot — Zyfai will add this to its portfolio
@@ -508,10 +734,20 @@ interface OwneyPendingAllocation {
508
734
  since?: string;
509
735
  }
510
736
  interface AgentBalance {
737
+ readMetadata?: AssetReadMetadata[];
738
+ /** Authoritative native balances per asset/network, including idle and invested funds. */
739
+ assetBalances?: OwneyToken[];
511
740
  smartWallet?: `0x${string}`;
512
741
  totalBalance: string;
513
742
  /** Asset that `totalBalance` is denominated in. Currently always `"usdc"`. */
514
743
  totalBalanceAsset: string;
744
+ /**
745
+ * Describes whether `tokens` already includes deployed `positions`.
746
+ * Consumers must add matching positions only for `tokens-plus-positions`;
747
+ * doing so for Zyfai would double-count, while omitting it for Yieldseeker
748
+ * makes its balance disappear as soon as idle funds enter a vault.
749
+ */
750
+ balanceComposition?: "tokens-include-positions" | "tokens-plus-positions";
515
751
  tokens: OwneyToken[];
516
752
  /**
517
753
  * Per-protocol/pool positions when the agent's portfolio payload includes
@@ -526,10 +762,14 @@ interface OwneyBalances {
526
762
  /** Asset that `totalBalance` is denominated in. Currently always `"usdc"`. */
527
763
  totalBalanceAsset: string;
528
764
  agentBalances: Record<AgentId, AgentBalance>;
529
- /** Omitted agents failed to load; they must not be interpreted as zero. */
530
- agentErrors?: Record<AgentId, string>;
765
+ /**
766
+ * Per-agent read failures when an aggregate balance request returned only a
767
+ * partial result. Callers may display the successful balances, but funding
768
+ * operations must not interpret a missing agent as having a zero balance.
769
+ */
770
+ agentErrors?: Partial<Record<AgentId, string>>;
531
771
  /** Absolute provider cooldown deadlines (Unix milliseconds). */
532
- agentRetryAt?: Record<AgentId, number>;
772
+ agentRetryAt?: Partial<Record<AgentId, number>>;
533
773
  }
534
774
  interface AgentEarnings {
535
775
  smartWallet: `0x${string}`;
@@ -539,6 +779,10 @@ interface AgentEarnings {
539
779
  interface OwneyEarnings {
540
780
  totalEarnings: string;
541
781
  agentEarnings: Record<AgentId, AgentEarnings>;
782
+ /** Per-agent failures when an aggregate read returned a partial result. */
783
+ agentErrors?: Partial<Record<AgentId, string>>;
784
+ /** Absolute provider cooldown deadlines (Unix milliseconds). */
785
+ agentRetryAt?: Partial<Record<AgentId, number>>;
542
786
  }
543
787
  type ApyByChainAndAsset = Partial<Record<OwneySupportedChainId, Partial<Record<OwneySupportedTokens, number>>>>;
544
788
  /** A single day's net APY for the connected account, as a percentage number. */
@@ -584,6 +828,15 @@ interface OwneyAllocationApy {
584
828
  }
585
829
  type HistoryAction = "Rebalance" | "Deposit" | "Top up" | "Withdraw" | "Earned";
586
830
  interface HistoryTransaction {
831
+ tokenAddress?: string;
832
+ agentWallet?: string;
833
+ logIndexes?: number[];
834
+ transferLogs?: {
835
+ logIndex: number;
836
+ amountRaw: string;
837
+ }[];
838
+ amountRaw?: string;
839
+ blockNumber?: string;
587
840
  txHashes: string[];
588
841
  chainId?: number;
589
842
  tokenSymbol?: string;
@@ -612,6 +865,8 @@ interface AgentHistoryPosition {
612
865
  amount?: string;
613
866
  }
614
867
  interface AgentHistoryEntry {
868
+ /** Stable provider/transfer identity, independent of row order. */
869
+ id?: string;
615
870
  agent: AgentId;
616
871
  action: HistoryAction;
617
872
  date: string;
@@ -622,6 +877,8 @@ interface AgentHistoryEntry {
622
877
  positions?: AgentHistoryPosition[];
623
878
  }
624
879
  interface OwneyAgentHistory {
880
+ agentErrors?: Partial<Record<AgentId, string>>;
881
+ agentRetryAt?: Partial<Record<AgentId, number>>;
625
882
  data: AgentHistoryEntry[];
626
883
  /** True iff a subsequent page exists; pair with `nextCursor`. */
627
884
  hasMore: boolean;
@@ -662,15 +919,15 @@ interface AgentApy {
662
919
  interface OwneyAgentApy {
663
920
  agentApy: Record<AgentId, AgentApy>;
664
921
  }
665
- /** One day's cumulative NET earnings for a single asset. */
922
+ /** One day's cumulative earnings for a single asset. */
666
923
  interface DailyEarningsPoint {
667
924
  /** ISO date string for the day, e.g. "2026-09-01". */
668
925
  date: string;
669
926
  /**
670
- * Earnings accumulated from the start of the returned series up to and
671
- * including this day, net of the agent's performance fee, denominated in the
672
- * asset's own units. A running total of daily deltas, so it measures the
673
- * window — not the wallet's lifetime.
927
+ * Cumulative earnings in the asset's own units, using the provider's earnings
928
+ * basis. A provider may return lifetime totals or a running window total;
929
+ * difference the last and opening points to measure earnings over the window.
930
+ * Aggregate series normalize each component's opening value before summing.
674
931
  */
675
932
  amount: number;
676
933
  }
@@ -679,8 +936,9 @@ interface AssetDailyEarnings {
679
936
  /** Asset symbol, e.g. "USDC" / "WETH". */
680
937
  asset: string;
681
938
  /**
682
- * Ascending by date. Days the wallet held nothing of this asset are absent
683
- * rather than zero — a zero would read as "earned nothing that day".
939
+ * Ascending by date, including an opening snapshot before the requested
940
+ * window when available. Provider gaps remain absent; aggregates carry the
941
+ * most recent cumulative value across dates reported by other providers.
684
942
  */
685
943
  points: DailyEarningsPoint[];
686
944
  }
@@ -697,70 +955,7 @@ interface AccountDailyEarnings {
697
955
  assets: AssetDailyEarnings[];
698
956
  }
699
957
 
700
- type DepositCallback = (smartWalletAddress: string, chainId: number, amount: string) => Promise<`0x${string}`> | `0x${string}`;
701
- interface IAgent {
702
- readonly id: string;
703
- readonly supportedChainIds: readonly OwneySupportedChainId[];
704
- readonly supportedAssets: readonly AgentSupportedAssets[];
705
- disconnect(): Promise<void>;
706
- activateAgent(state: ConnectionState, chainId: number): Promise<void>;
707
- /**
708
- * Apply the organization's agent policy to this user's account.
709
- *
710
- * Optional: an agent that has no equivalent knob simply omits it, which is why
711
- * this is not part of `activateAgent`'s signature. Declared on the interface
712
- * rather than only on ZyfaiAgent so the contract stays agent-neutral — the
713
- * ticket asks for a design that can also cover Surf, which has no adapter yet.
714
- *
715
- * Implementations must be **non-fatal**: this runs during activation as a side
716
- * effect, so a failure has to leave the user connected and their profile
717
- * unchanged rather than break the connect.
718
- */
719
- applyOrgPolicy?(state: ConnectionState, chainId: number, policy: OrgAgentConfig): Promise<void>;
720
- deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
721
- withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string): Promise<AgentWithdrawResult>;
722
- getBalances(state: ConnectionState, chainId: number): Promise<AgentBalance>;
723
- getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
724
- /**
725
- * Refresh the agent's earnings snapshot when its backend supports doing so.
726
- * Implementations own freshness and request-deduplication policy.
727
- */
728
- refreshEarnings?(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
729
- getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays,
730
- /**
731
- * Optional asset symbol ("USDC" / "WETH") scoping the daily series to a
732
- * single asset on the chain. Agents without per-asset positions ignore it.
733
- */
734
- tokenSymbol?: string): Promise<AccountAgentApy>;
735
- /**
736
- * Daily cumulative NET earnings for the window, scoped to a chain/asset.
737
- * Backs the "recent earnings" subline, whose figure must reconcile with the
738
- * balance headline directly above it. (ROUT-452)
739
- */
740
- getDailyEarnings?(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
741
- getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
742
- getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
743
- /**
744
- * Ensure the given asset uses backend protocol auto-selection
745
- * (`autoSelectProtocols: true`). Optional capability — only agents whose
746
- * backend models per-asset protocol selection implement it. Returns whether
747
- * a write occurred (`false` = already enabled / not supported).
748
- */
749
- ensureAutoSelectProtocols?(state: ConnectionState, chainId: number, asset: "USDC" | "WETH"): Promise<boolean>;
750
- getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
751
- }
752
- /**
753
- * Optional filters for per-agent APY lookups.
754
- * - `tokenSymbol` / `chainId` scope the APY to a specific asset+chain when
755
- * the underlying provider supports it (Zyfai). Agents whose backends do
756
- * not yet support per-asset APY will ignore these options.
757
- */
758
- type AgentApyOptions = {
759
- tokenSymbol?: string;
760
- chainId?: number;
761
- };
762
-
763
- 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_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" | "VALIDATION_INVALID_DAYS";
958
+ 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" | "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" | "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" | "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";
764
959
  declare class OwneyError extends Error {
765
960
  readonly code: OwneyErrorCode;
766
961
  readonly details?: Record<string, unknown>;
@@ -920,10 +1115,15 @@ declare class OwneySDK {
920
1115
  */
921
1116
  private disabledAgents;
922
1117
  private state;
1118
+ private connectionRevision;
1119
+ private disconnectingAgents;
923
1120
  private apiKey;
924
1121
  private orgAgentConfig;
925
1122
  private orgAgentConfigPromise;
1123
+ private rpcUrls?;
926
1124
  private zyfaiRpcUrls?;
1125
+ private yieldseekerApiBaseUrl?;
1126
+ private yieldseekerSiweOrigin?;
927
1127
  private routingApiBaseUrl?;
928
1128
  private referralSource?;
929
1129
  private cachedSponsoredCallback;
@@ -931,7 +1131,11 @@ declare class OwneySDK {
931
1131
  private paymasterServiceUrl?;
932
1132
  private cachedSponsoredCallsCallbacks;
933
1133
  private readonly agentReads;
1134
+ private readonly recoveredFundingReads;
1135
+ private fundingBalanceChecks;
934
1136
  private readonly activationChecks;
1137
+ private readonly withdrawalSubmissions;
1138
+ private readonly withdrawalSwapSubmissions;
935
1139
  private readAgent;
936
1140
  private initializingAgentsPromise;
937
1141
  constructor(config: OwneySDKConfig);
@@ -946,6 +1150,8 @@ declare class OwneySDK {
946
1150
  * After calling this, `connect()` must be called again before using agent methods.
947
1151
  */
948
1152
  disconnect(): Promise<void>;
1153
+ private clearConnectionState;
1154
+ private disconnectAgents;
949
1155
  private isAgentDisabled;
950
1156
  /**
951
1157
  * Check if the SDK has an active connection state.
@@ -960,28 +1166,20 @@ declare class OwneySDK {
960
1166
  private requireState;
961
1167
  private requireChainId;
962
1168
  private requireConnectedProvider;
963
- /**
964
- * Lazily builds (and caches) the default EIP-3009 sponsored deposit callback
965
- * used when the caller omits `depositCallback`. Wraps the connected EIP-1193
966
- * provider with viem `custom(provider)` to read token meta and sign the
967
- * `TransferWithAuthorization`, then POSTs to the sponsor API.
968
- */
1169
+ private getPaidRpcClient;
1170
+ /** Builds the default USDC batch callback for the connected wallet. */
969
1171
  private getDefaultSponsoredCallback;
970
- /**
971
- * Lazily builds (and caches) the default Permit2 sponsored WETH deposit
972
- * callback used when the caller omits `depositCallback` for a WETH
973
- * deposit. Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
974
- * `PermitTransferFrom` instead of an EIP-3009 authorization.
975
- */
1172
+ /** Builds the wallet-native sponsored calls callback for compatible paymasters. */
976
1173
  private getDefaultSponsoredCallsCallback;
977
1174
  /**
978
1175
  * Lazily builds (and caches) the default Permit2 sponsored WETH deposit
979
1176
  * callback used when the caller omits `depositCallback` for a WETH deposit.
980
1177
  * Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
981
- * `PermitTransferFrom` instead of an EIP-3009 authorization.
1178
+ * single-use batch authorization instead of an EIP-3009 authorization.
982
1179
  */
983
1180
  private getDefaultWethSponsoredCallback;
984
1181
  private getAgent;
1182
+ getActiveAgentIds(): AgentId[];
985
1183
  private getActiveAgents;
986
1184
  /**
987
1185
  * Read the org's agent policy once and reuse it. fetchOrgAgentConfig never
@@ -1014,7 +1212,8 @@ declare class OwneySDK {
1014
1212
  * If provided, ALL specified agents must support the chainId or the call
1015
1213
  * throws before activating any agent.
1016
1214
  */
1017
- activateAgent(chainId: number, agentId?: AgentId[]): Promise<void>;
1215
+ activateAgent(chainId: number, agentId?: AgentId[], asset?: OwneySupportedTokens): Promise<void>;
1216
+ private assertActivationSession;
1018
1217
  /**
1019
1218
  * Activate agents ONE AT A TIME, each followed by its org policy.
1020
1219
  *
@@ -1028,10 +1227,9 @@ declare class OwneySDK {
1028
1227
  * Serializing costs no real wall-clock: the user can only approve one prompt
1029
1228
  * at a time anyway.
1030
1229
  *
1031
- * Every agent is attempted even if an earlier one fails, so one declined
1032
- * signature can't deny the remaining agents their turn. The first failure is
1033
- * rethrown (matching the previous `Promise.all` rejection) once all agents
1034
- * have had a chance to activate.
1230
+ * Stop at the first failure so a canceled sign-in does not open another
1231
+ * agent's wallet prompt. Report any earlier successes for diagnostics; the
1232
+ * app discards the session when the complete sign-in does not succeed.
1035
1233
  */
1036
1234
  private activateAgentsInTurn;
1037
1235
  /**
@@ -1042,7 +1240,8 @@ declare class OwneySDK {
1042
1240
  * @param options.asset - Asset symbol to deposit (e.g. "USDC")
1043
1241
  * @param options.depositCallback - Callback that performs the token transfer and returns a tx hash.
1044
1242
  * When agentId is omitted, this callback is invoked once per eligible agent with that agent's
1045
- * split amount and smart wallet address — expect multiple wallet prompts.
1243
+ * split amount and smart wallet address. Default sponsored deposits batch
1244
+ * all shares into one signature; custom callbacks still run once per agent.
1046
1245
  * @param options.agentId - Optional explicit target. Otherwise split equally,
1047
1246
  * or fund remaining agents when a recovery deposit cannot meet every minimum.
1048
1247
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
@@ -1052,10 +1251,12 @@ declare class OwneySDK {
1052
1251
  * Invokes `agent.deposit` with the resolved sponsored callback, composing
1053
1252
  * two independent auto-recovery mechanisms:
1054
1253
  *
1055
- * 1. Missing Permit2 allowance: when the app did not supply its own
1056
- * callback and the attempt fails with `PERMIT2_APPROVAL_REQUIRED` on a
1057
- * WETH deposit, this is the wallet's first gasless WETH deposit. We send
1058
- * the one-time (user-paid) Permit2 approval via `approvePermit2()` and
1254
+ * 1. Missing Permit2 allowance outside the atomic Base-USDC path: when the
1255
+ * app did not supply its own callback and the attempt fails with
1256
+ * `PERMIT2_APPROVAL_REQUIRED`, this is the wallet's first Permit2 deposit
1257
+ * for that token. Base USDC bundles a gasless ERC-2612 approval inside
1258
+ * its sponsored deposit and never reaches this branch. Other tokens send
1259
+ * the one-time user-paid Permit2 approval via `approvePermit2()` and
1059
1260
  * retry the SAME sponsored attempt once. Bounded to one approval attempt
1060
1261
  * per call so a wallet/agent that keeps reporting the allowance as
1061
1262
  * missing can't loop forever. If `approvePermit2()` itself throws (e.g.
@@ -1076,6 +1277,7 @@ declare class OwneySDK {
1076
1277
  private depositWithFallback;
1077
1278
  private getMinDepositAmount;
1078
1279
  private splitDepositAmount;
1280
+ private formatAgentName;
1079
1281
  private validateMinDepositAmount;
1080
1282
  /**
1081
1283
  * Whether the user already holds a non-zero balance with `agent` for the
@@ -1086,6 +1288,48 @@ declare class OwneySDK {
1086
1288
  private hasExistingBalance;
1087
1289
  private validateAssetSupport;
1088
1290
  private getEligibleAgents;
1291
+ /**
1292
+ * Run owner-approved withdrawals before relayer-only withdrawals. Wallet
1293
+ * approval is the only point at which the user can cancel the aggregate
1294
+ * operation, so no relayer leg should commit before it has completed.
1295
+ */
1296
+ private orderAgentsForWithdrawal;
1297
+ private isUserRejectedWithdrawal;
1298
+ private captureReadScope;
1299
+ /** Revalidate a saved transfer against the authenticated account and actual receipt. */
1300
+ inspectFunding(evidence: FundingEvidence, direction: "deposit" | "withdraw", options?: {
1301
+ balanceRefreshUntil?: number;
1302
+ refreshBalance?: boolean;
1303
+ requireAmountMatch?: boolean;
1304
+ }): Promise<FundingEvidence>;
1305
+ /** Resolve a saved sponsored-withdrawal ID without opening a wallet prompt. */
1306
+ resolveSponsoredWithdrawalEvidence(evidence: FundingEvidence, options?: {
1307
+ submittedAt?: number;
1308
+ }): Promise<FundingEvidence>;
1309
+ /** Recover an EIP-5792 deposit or payout using this account's exact batch ID. */
1310
+ resolveWalletCallsFundingEvidence(evidence: FundingEvidence, direction: "deposit" | "withdraw"): Promise<FundingEvidence>;
1311
+ /** Whether a foreground deposit can resume the same signed batch, never a
1312
+ * fresh authorization. The batch rail independently rechecks the exact plan. */
1313
+ canResumePendingDeposit(evidences: FundingEvidence[], amount: string): Promise<boolean>;
1314
+ /** Optional post-payout display proof; receipt verification and the provider
1315
+ * adapter must agree before attaching it to this exact balance object. */
1316
+ verifyWithdrawalBalance(evidence: FundingEvidence, balance: AgentBalance): Promise<AgentBalance>;
1317
+ /** A display acknowledgement controls polling only; it never confirms a financial outcome. */
1318
+ endFundingBalanceRefresh(evidence: FundingEvidence, read: AssetReadMetadata): boolean;
1319
+ /** History lookup for receipt recovery; adapters may not authenticate or sign here. */
1320
+ getFundingHistory(evidence: FundingEvidence, fromDate: string, options?: Pick<HistoryFilters, "cursor" | "toDate">): Promise<OwneyAgentHistory>;
1321
+ recoverDepositRegistration(evidence: FundingEvidence): Promise<FundingEvidence>;
1322
+ /** On-chain version and ownership status for this owner's Yieldseeker agent. */
1323
+ getYieldseekerWalletStatus(asset: OwneySupportedTokens): Promise<YieldseekerWalletStatus | null>;
1324
+ /** Deployment gate; an unavailable response keeps the current paid path. */
1325
+ isYieldseekerWithdrawalSponsorshipAvailable(): Promise<boolean>;
1326
+ isYieldseekerUpgradeSponsorshipAvailable(): Promise<boolean>;
1327
+ private isYieldseekerSponsorshipAvailable;
1328
+ /** Explicit V1-to-V2 upgrade, confirmed on chain before returning. */
1329
+ upgradeYieldseekerWallet(asset: OwneySupportedTokens, gasMode?: "paid" | "sponsored"): Promise<{
1330
+ txHash: viem.Hex;
1331
+ status: YieldseekerWalletStatus;
1332
+ }>;
1089
1333
  /** Lazily built so an app that never swaps pays nothing for it. */
1090
1334
  private swapApiClient?;
1091
1335
  private swapApi;
@@ -1377,10 +1621,9 @@ declare class OwneySDK {
1377
1621
  * Quoting before the tokens land would size the swap against a balance that
1378
1622
  * is not there yet.
1379
1623
  *
1380
- * The swap is therefore sized from the MEASURED arrival, exactly as the
1381
- * deposit path sizes its deposit from the measured swap output. On a full
1382
- * withdrawal there is no other number available — "MAX" has no figure until
1383
- * the agent picks one.
1624
+ * Wait for each participating agent's owner payout and size one swap from
1625
+ * their confirmed net amounts. A first wallet increase cannot establish
1626
+ * that every payout arrived. Failed or incomplete withdrawals stop here.
1384
1627
  *
1385
1628
  * **Failure here is not symmetrical with the deposit path.** A failed
1386
1629
  * deposit-swap leaves the user holding what they started with. A failed
@@ -1407,6 +1650,8 @@ declare class OwneySDK {
1407
1650
  /** Percent, classic rail only. Fusion+ prices through its auction. */
1408
1651
  slippage?: number;
1409
1652
  onSwapProgress?: (stage: SwapStage) => void;
1653
+ /** Receipt evidence for the existing funding/recovery tracker. */
1654
+ onWithdrawalProgress?: FundingProgress;
1410
1655
  /**
1411
1656
  * Fires once the order is with the relayer, before the watch.
1412
1657
  *
@@ -1455,12 +1700,21 @@ declare class OwneySDK {
1455
1700
  * @returns {AgentWithdrawResult} for a single agent, or {OwneyWithdrawResult} with per-agent results
1456
1701
  */
1457
1702
  withdraw(options: WithdrawOptions): Promise<OwneyWithdrawResult | AgentWithdrawResult>;
1703
+ private withdrawFromAgents;
1704
+ /** Read-only invalidation after new pool-deposit activity. Does not restart
1705
+ * funding reconciliation, bypass cooldowns, or authorize a transaction. */
1706
+ invalidateAllocationRead(scope: Pick<FundingEvidence, "agentId" | "walletAddress" | "chainId" | "token">): boolean;
1458
1707
  /**
1459
1708
  * Get the user's balances for a specific agent, or aggregated across all agents.
1460
1709
  * @param agentId - Optional. Agent to query. Omit for aggregated balances.
1461
1710
  * @returns {AgentBalance} for a single agent, or {OwneyBalances} with totalBalance and per-agent breakdown
1462
1711
  */
1463
- getBalances(agentId?: AgentId): Promise<OwneyBalances | AgentBalance>;
1712
+ getBalances(agentId?: AgentId, options?: {
1713
+ chainId?: number;
1714
+ asset?: OwneySupportedTokens;
1715
+ }): Promise<OwneyBalances | AgentBalance>;
1716
+ /** Preserve failure objects for withdrawal recovery without changing public balance results. */
1717
+ private readAggregatedBalances;
1464
1718
  /**
1465
1719
  * Get the user's on-chain earnings for a specific agent, or aggregated across all agents.
1466
1720
  * @param agentId - Optional. Agent to query. Omit for aggregated earnings.
@@ -1472,6 +1726,7 @@ declare class OwneySDK {
1472
1726
  * Agents without a refresh capability fall back to their current snapshot.
1473
1727
  */
1474
1728
  refreshEarnings(agentId?: AgentId): Promise<OwneyEarnings | AgentEarnings>;
1729
+ private aggregateEarnings;
1475
1730
  /**
1476
1731
  * Get the weighted APY for the user's account over a time period.
1477
1732
  * When querying all agents, the total APY is a balance-weighted average.
@@ -1481,10 +1736,8 @@ declare class OwneySDK {
1481
1736
  * @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
1482
1737
  */
1483
1738
  /**
1484
- * Daily cumulative NET earnings for the selected chain/asset, backing the
1485
- * "recent earnings" subline. Net is computed as Zyfai's own
1486
- * `lifetime + unrealized + current x 0.9`, so the figure reconciles with the
1487
- * balance headline rather than reading ~11% high. (ROUT-452)
1739
+ * Daily cumulative earnings in the selected asset's units, backing the
1740
+ * "recent earnings" subline. Each adapter uses its provider's earnings basis.
1488
1741
  *
1489
1742
  * Unlike getAccountApy this does NOT blend across agents: earnings are
1490
1743
  * summed, not weighted, and an agent that fails to report must not silently
@@ -1526,14 +1779,17 @@ declare class OwneySDK {
1526
1779
  */
1527
1780
  ensureAutoSelectProtocols(asset: "USDC" | "WETH", agentId?: AgentId): Promise<boolean>;
1528
1781
  /**
1529
- * One-time, user-paid approval of Permit2 on the sponsored WETH token for
1530
- * the active chain. Required once per wallet per chain before gasless WETH
1531
- * deposits; afterwards deposit() is signature-only. Resolves only after the
1532
- * approval transaction is mined (1 confirmation), so a subsequent deposit()
1533
- * will see the new allowance; throws if the transaction reverted.
1782
+ * User-paid approval of Permit2 on the selected token for the active chain.
1783
+ * Grants the maximum ERC20 allowance so later deposits do not require another
1784
+ * approval. Resolves after one confirmation so the subsequent deposit attempt
1785
+ * sees the new allowance. Deposit retries pass their captured chain id so a
1786
+ * concurrent activation cannot redirect the approval to another network.
1787
+ *
1788
+ * @param requiredAmount Raw base-unit amount the pending deposit must cover.
1789
+ * @param expectedChainId Chain captured by the deposit that requested approval.
1534
1790
  * @returns the approval transaction hash.
1535
1791
  */
1536
- approvePermit2(asset?: "WETH"): Promise<`0x${string}`>;
1792
+ approvePermit2(asset?: OwneySupportedTokens, requiredAmount?: bigint, expectedChainId?: OwneySupportedChainId): Promise<`0x${string}`>;
1537
1793
  /**
1538
1794
  * Get the agent's average APY performance over a time period. Does not require a wallet connection.
1539
1795
  * @param options - Contains agentId (optional) and days ("7D", "14D", or "30D")
@@ -1557,6 +1813,170 @@ declare class OwneySDK {
1557
1813
  getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
1558
1814
  }
1559
1815
 
1816
+ type YieldseekerAuthDependencies = {
1817
+ origin?: string;
1818
+ now?: () => Date;
1819
+ nonce?: () => string;
1820
+ };
1821
+
1822
+ type YieldseekerFetch = typeof fetch;
1823
+
1824
+ type YieldseekerTransaction = {
1825
+ from: `0x${string}`;
1826
+ to: `0x${string}`;
1827
+ data: `0x${string}`;
1828
+ value: string;
1829
+ chainId: number;
1830
+ };
1831
+
1832
+ type YieldseekerWalletStatus = {
1833
+ agentWallet: Address;
1834
+ owner: Address;
1835
+ ownerPath: "eoa" | "smart";
1836
+ asset: Address;
1837
+ implementation: Address;
1838
+ version: "v1" | "v2" | "unknown";
1839
+ upgradeAvailable: boolean;
1840
+ /** The factory, owner, base asset, and provider wallet mapping all agree. */
1841
+ verified: boolean;
1842
+ };
1843
+
1844
+ type YieldseekerAgentOptions = {
1845
+ baseUrl?: string;
1846
+ routingApiBaseUrl?: string;
1847
+ fetchFn?: YieldseekerFetch;
1848
+ auth?: YieldseekerAuthDependencies;
1849
+ /** Dedicated read transport; Base is used for receipt polling. */
1850
+ rpcUrls?: RpcUrlsConfig;
1851
+ /** Test seam for the wallet-submission/receipt boundary. */
1852
+ transactionExecutor?: (state: ConnectionState, chainId: number, transaction: YieldseekerTransaction, onReceipt?: (receipt: viem.TransactionReceipt) => void) => Promise<Hex>;
1853
+ /** Test seam for transactions submitted outside transactionExecutor. */
1854
+ unwindReceiptWaiter?: (state: ConnectionState, chainId: number, transactionHash: Hex) => Promise<void>;
1855
+ };
1856
+ declare class YieldseekerAgent implements IAgent {
1857
+ readonly id = "yieldseeker";
1858
+ readonly balanceComposition: "tokens-plus-positions";
1859
+ readonly withdrawalRequiresWalletApproval = true;
1860
+ readonly supportedChainIds: readonly [8453];
1861
+ readonly supportedAssets: readonly [{
1862
+ readonly chainId: 8453;
1863
+ readonly chain: "BASE";
1864
+ readonly assets: readonly [{
1865
+ readonly symbol: "USDC";
1866
+ readonly minDepositAmount: "10000000";
1867
+ }, {
1868
+ readonly symbol: "WETH";
1869
+ readonly minDepositAmount: "1";
1870
+ }];
1871
+ }];
1872
+ private readonly api;
1873
+ private readonly auth;
1874
+ private readonly rpcUrls?;
1875
+ private readonly owneyApiKey;
1876
+ private readonly routingApiBaseUrl?;
1877
+ private receiptClient?;
1878
+ private readonly withdrawalVersionCache;
1879
+ private readonly pendingUpgrades;
1880
+ private readonly transactionExecutor?;
1881
+ private readonly unwindReceiptWaiter?;
1882
+ private readonly agentContexts;
1883
+ private readonly balanceContexts;
1884
+ private readonly balanceVaults;
1885
+ private readonly users;
1886
+ private readonly pendingAgents;
1887
+ private readonly pendingWalletContexts;
1888
+ private readonly readCache;
1889
+ private readonly pendingReads;
1890
+ private readGeneration;
1891
+ private readonly portfolioVersions;
1892
+ private readonly snapshotFailures;
1893
+ private readonly standardReadFailures;
1894
+ private readonly reconcileUntil;
1895
+ private readonly allocationRefresh;
1896
+ private readonly activityRefreshUntil;
1897
+ private readonly snapshotMovements;
1898
+ private readonly movementEpochs;
1899
+ private readonly yieldOptions;
1900
+ private readonly pendingYieldOptions;
1901
+ constructor(owneyApiKey: string, options?: YieldseekerAgentOptions);
1902
+ private getReceiptClient;
1903
+ /** Reads the actual proxy implementation; Yieldseeker's API walletType is not a version check. */
1904
+ getWalletStatus(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, useCachedV2?: boolean): Promise<YieldseekerWalletStatus | null>;
1905
+ private rememberWalletStatus;
1906
+ /** Explicit owner action. This never runs as a side effect of withdrawal. */
1907
+ upgradeWallet(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, gasMode?: "paid" | "sponsored"): Promise<{
1908
+ txHash: Hex;
1909
+ status: YieldseekerWalletStatus;
1910
+ }>;
1911
+ disconnect(): Promise<void>;
1912
+ activateAgent(state: ConnectionState, chainId: number, asset?: OwneySupportedTokens): Promise<void>;
1913
+ deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback, onProgress?: FundingProgress, onBeforeSubmission?: (evidence: FundingEvidence) => void | Promise<void>): Promise<OwneyDepositResult>;
1914
+ withdraw(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, amount?: string, onProgress?: FundingProgress, gasMode?: "auto" | "sponsored" | "paid", onBeforeSubmission?: FundingProgress): Promise<AgentWithdrawResult>;
1915
+ private withdrawInternal;
1916
+ /** A withdrawal-only liquidity floor; display snapshots never authorize it. */
1917
+ getWithdrawableBalance(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, minimumAmount?: bigint): Promise<bigint>;
1918
+ private readVaultLiquidity;
1919
+ private validateWithdrawalPositions;
1920
+ private withdrawalVaultHints;
1921
+ private readWithdrawalPositions;
1922
+ private resolveWithdrawalLiquidity;
1923
+ getBalances(state: ConnectionState, chainId: number, asset?: OwneySupportedTokens): Promise<AgentBalance>;
1924
+ verifyWithdrawalBalance(state: ConnectionState, evidence: FundingEvidence, balance: AgentBalance): Promise<AssetReadMetadata | undefined>;
1925
+ invalidateAllocationRead(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): void;
1926
+ invalidateFundingRead(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, refreshUntil?: number): void;
1927
+ endFundingBalanceRefresh(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, read: AssetReadMetadata): boolean;
1928
+ getFundingWallet(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<string>;
1929
+ hasExistingDepositFunds(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<true | undefined>;
1930
+ getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
1931
+ getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays, tokenSymbol?: string): Promise<AccountAgentApy>;
1932
+ getDailyEarnings(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
1933
+ getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
1934
+ getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
1935
+ getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
1936
+ private loadYieldOptions;
1937
+ private userKey;
1938
+ private contextKey;
1939
+ private assertSession;
1940
+ private cachedRead;
1941
+ private agentListKey;
1942
+ private listAgents;
1943
+ private contextForAgent;
1944
+ private resolveUser;
1945
+ private forgetUser;
1946
+ private ensureAgent;
1947
+ private findAgent;
1948
+ private resolveAgent;
1949
+ private loadPortfolio;
1950
+ private loadActivityPortfolio;
1951
+ private resolvePortfolioContexts;
1952
+ private portfolioVersion;
1953
+ private portfolioCacheMs;
1954
+ private snapshotMovement;
1955
+ private advancePortfolioVersion;
1956
+ private requestPortfolioSnapshot;
1957
+ private portfolioSnapshot;
1958
+ private loadPortfolioContext;
1959
+ private loadActivityContext;
1960
+ private loadPortfolioParts;
1961
+ private deployAgent;
1962
+ private refreshSnapshotAfterMovement;
1963
+ private agentPath;
1964
+ private walletRequest;
1965
+ private providerRequest;
1966
+ private mapApiError;
1967
+ private submitTransaction;
1968
+ private waitForReceipt;
1969
+ private assertTransaction;
1970
+ private assertAgent;
1971
+ private isOwneyAgent;
1972
+ private assetForAgent;
1973
+ private isTransactionHash;
1974
+ private assertChain;
1975
+ private assertOptionalChain;
1976
+ private assertAsset;
1977
+ private invalidResponse;
1978
+ }
1979
+
1560
1980
  declare class InvalidHistoryCursorError extends Error {
1561
1981
  readonly code: "invalid_cursor";
1562
1982
  constructor(message: string);
@@ -1634,4 +2054,4 @@ type StoredOrder = {
1634
2054
  */
1635
2055
  declare function listOrders(now?: number): StoredOrder[];
1636
2056
 
1637
- 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 ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, 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 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 RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };
2057
+ 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 ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AssetReadMetadata, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type FundingEvidence, type FundingProgress, type FundingStage, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, 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 RebalanceLog, type RpcUrlsConfig, 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, YieldseekerAgent, type YieldseekerWalletStatus, type ZyfaiRpcUrlsConfig, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };