@owney/sdk 0.6.6-beta.1 → 0.6.6-beta.2

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
@@ -8,19 +8,92 @@ interface OwneySDKConfig {
8
8
  * Example: { 8453: "https://...", 42161: "https://..." }
9
9
  */
10
10
  zyfaiRpcUrls?: ZyfaiRpcUrlsConfig;
11
+ /**
12
+ * Optional override for the Owney routing API base URL used by the sponsored
13
+ * deposit callbacks (defaults to the OWNEY_ROUTING_API_BASE_URL env var, then
14
+ * the production URL). Set this to point at a local/staging routing API,
15
+ * e.g. "http://localhost:3000", when testing sponsor changes.
16
+ */
17
+ routingApiBaseUrl?: string;
11
18
  }
12
19
  interface ConnectionState {
13
20
  provider: any;
14
21
  walletAddress: `0x${string}`;
15
22
  chainId: number | null;
16
23
  }
17
- declare const SUPPORTED_TOKENS: readonly ["USDC", "USDT"];
18
- declare const SUPPORTED_CHAIN_IDS: readonly [8453, 42161];
19
- declare const SUPPORTED_CHAINS: readonly ["BASE", "ARBITRUM"];
24
+ declare const SUPPORTED_TOKENS: readonly ["USDC", "USDT", "WETH"];
25
+ declare const SUPPORTED_CHAIN_IDS: readonly [8453, 42161, 1];
26
+ declare const SUPPORTED_CHAINS: readonly ["BASE", "ARBITRUM", "ETHEREUM"];
20
27
  type OwneySupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
21
28
  type OwneySupportedChains = (typeof SUPPORTED_CHAINS)[number];
22
29
  type OwneySupportedTokens = (typeof SUPPORTED_TOKENS)[number];
23
30
 
31
+ type AgentId = "zyfai" | "sail";
32
+ type Asset = string;
33
+ type AgentSupportedAsset = {
34
+ readonly symbol: string;
35
+ readonly minDepositAmount: string;
36
+ };
37
+ type AgentSupportedAssets = {
38
+ readonly chainId: number;
39
+ readonly chain?: string;
40
+ readonly assets: readonly AgentSupportedAsset[];
41
+ };
42
+ type DailyApyDays = "7D" | "14D" | "30D";
43
+ type HistoryFilters = {
44
+ fromDate?: string;
45
+ toDate?: string;
46
+ /** Max entries returned per call. Defaults to 10. */
47
+ limit?: number;
48
+ /** Opaque cursor returned by a previous getHistory call. */
49
+ cursor?: string;
50
+ };
51
+ type HistoryOptions = {
52
+ agentId?: AgentId;
53
+ filters?: HistoryFilters;
54
+ };
55
+ type WithdrawOptions = {
56
+ asset: Asset;
57
+ amount?: string;
58
+ agentId?: AgentId;
59
+ };
60
+ type AccountApyOptions = {
61
+ agentId?: AgentId;
62
+ days: DailyApyDays;
63
+ /**
64
+ * Optional asset symbol (e.g. "USDC", "WETH") to scope the daily APY series
65
+ * to a specific asset on the active chain. Without it the series blends every
66
+ * position on the chain, so two assets sharing a chain (USDC and WETH on
67
+ * Base/Arbitrum) would render one merged line. Agents whose backends do not
68
+ * expose per-asset positions ignore this. (ROUT-186)
69
+ */
70
+ tokenSymbol?: string;
71
+ };
72
+ type AllocationApyOptions = {
73
+ agentId?: AgentId;
74
+ };
75
+ type AgentsApyOptions = {
76
+ agentId?: AgentId;
77
+ days: DailyApyDays;
78
+ /**
79
+ * Optional asset symbol (e.g. "USDC", "WETH") to scope the APY to a
80
+ * specific asset+chain. Ignored by agents whose backends do not yet
81
+ * support per-asset APY.
82
+ */
83
+ tokenSymbol?: string;
84
+ /**
85
+ * Optional chain id for per-asset APY lookups. Typically paired with
86
+ * `tokenSymbol`.
87
+ */
88
+ chainId?: number;
89
+ };
90
+ type DepositOptions = {
91
+ amount: string;
92
+ asset: Asset;
93
+ depositCallback?: DepositCallback;
94
+ agentId?: AgentId;
95
+ };
96
+
24
97
  interface OwneyDepositResult {
25
98
  txHash: string;
26
99
  smartWallet: string;
@@ -28,12 +101,6 @@ interface OwneyDepositResult {
28
101
  }
29
102
  interface OwneyMultiDepositResult {
30
103
  agentResults: Record<string, OwneyDepositResult>;
31
- /**
32
- * Per-agent failure messages for agents that errored during a diversified
33
- * deposit. Present only when at least one (but not all) agents failed —
34
- * the deposit is partial, not total. Omitted when every agent succeeded.
35
- */
36
- agentErrors?: Record<string, string>;
37
104
  }
38
105
  interface AgentWithdrawResult {
39
106
  txHash?: string;
@@ -201,13 +268,25 @@ interface IAgent {
201
268
  readonly supportedAssets: readonly AgentSupportedAssets[];
202
269
  disconnect(): Promise<void>;
203
270
  activateAgent(state: ConnectionState, chainId: number): Promise<void>;
204
- deposit(state: ConnectionState, chainId: number, amount: string, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
271
+ deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
205
272
  withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string): Promise<AgentWithdrawResult>;
206
273
  getBalances(state: ConnectionState, chainId: number): Promise<AgentBalance>;
207
274
  getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
208
- getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays): Promise<AccountAgentApy>;
275
+ getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays,
276
+ /**
277
+ * Optional asset symbol ("USDC" / "WETH") scoping the daily series to a
278
+ * single asset on the chain. Agents without per-asset positions ignore it.
279
+ */
280
+ tokenSymbol?: string): Promise<AccountAgentApy>;
209
281
  getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
210
282
  getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
283
+ /**
284
+ * Ensure the given asset uses backend protocol auto-selection
285
+ * (`autoSelectProtocols: true`). Optional capability — only agents whose
286
+ * backend models per-asset protocol selection implement it. Returns whether
287
+ * a write occurred (`false` = already enabled / not supported).
288
+ */
289
+ ensureAutoSelectProtocols?(state: ConnectionState, chainId: number, asset: "USDC" | "WETH"): Promise<boolean>;
211
290
  getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
212
291
  }
213
292
  /**
@@ -221,64 +300,6 @@ type AgentApyOptions = {
221
300
  chainId?: number;
222
301
  };
223
302
 
224
- type AgentId = "zyfai" | "sail" | "surfliquid";
225
- type Asset = string;
226
- type AgentSupportedAsset = {
227
- readonly symbol: string;
228
- readonly minDepositAmount: string;
229
- };
230
- type AgentSupportedAssets = {
231
- readonly chainId: number;
232
- readonly chain?: string;
233
- readonly assets: readonly AgentSupportedAsset[];
234
- };
235
- type DailyApyDays = "7D" | "14D" | "30D";
236
- type HistoryFilters = {
237
- fromDate?: string;
238
- toDate?: string;
239
- /** Max entries returned per call. Defaults to 10. */
240
- limit?: number;
241
- /** Opaque cursor returned by a previous getHistory call. */
242
- cursor?: string;
243
- };
244
- type HistoryOptions = {
245
- agentId?: AgentId;
246
- filters?: HistoryFilters;
247
- };
248
- type WithdrawOptions = {
249
- asset: Asset;
250
- amount?: string;
251
- agentId?: AgentId;
252
- };
253
- type AccountApyOptions = {
254
- agentId?: AgentId;
255
- days: DailyApyDays;
256
- };
257
- type AllocationApyOptions = {
258
- agentId?: AgentId;
259
- };
260
- type AgentsApyOptions = {
261
- agentId?: AgentId;
262
- days: DailyApyDays;
263
- /**
264
- * Optional asset symbol (e.g. "USDC", "WETH") to scope the APY to a
265
- * specific asset+chain. Ignored by agents whose backends do not yet
266
- * support per-asset APY.
267
- */
268
- tokenSymbol?: string;
269
- /**
270
- * Optional chain id for per-asset APY lookups. Typically paired with
271
- * `tokenSymbol`.
272
- */
273
- chainId?: number;
274
- };
275
- type DepositOptions = {
276
- amount: string;
277
- asset: Asset;
278
- depositCallback?: DepositCallback;
279
- agentId?: AgentId;
280
- };
281
-
282
303
  declare class OwneySDK {
283
304
  private agents;
284
305
  private activeAgents;
@@ -291,7 +312,9 @@ declare class OwneySDK {
291
312
  private state;
292
313
  private apiKey;
293
314
  private zyfaiRpcUrls?;
315
+ private routingApiBaseUrl?;
294
316
  private cachedSponsoredCallback;
317
+ private cachedWethSponsoredCallback;
295
318
  private initializingAgentsPromise;
296
319
  constructor(config: OwneySDKConfig);
297
320
  /**
@@ -326,6 +349,13 @@ declare class OwneySDK {
326
349
  * `TransferWithAuthorization`, then POSTs to the sponsor API.
327
350
  */
328
351
  private getDefaultSponsoredCallback;
352
+ /**
353
+ * Lazily builds (and caches) the default Permit2 sponsored WETH deposit
354
+ * callback used when the caller omits `depositCallback` for a WETH
355
+ * deposit. Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
356
+ * `PermitTransferFrom` instead of an EIP-3009 authorization.
357
+ */
358
+ private getDefaultWethSponsoredCallback;
329
359
  private getAgent;
330
360
  private getActiveAgents;
331
361
  private ensureAgentsInitialized;
@@ -354,6 +384,32 @@ declare class OwneySDK {
354
384
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
355
385
  */
356
386
  deposit(options: DepositOptions): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
387
+ /**
388
+ * Invokes `agent.deposit` with the resolved sponsored callback, composing
389
+ * two independent auto-recovery mechanisms:
390
+ *
391
+ * 1. Missing Permit2 allowance: when the app did not supply its own
392
+ * callback and the attempt fails with `PERMIT2_APPROVAL_REQUIRED` on a
393
+ * WETH deposit, this is the wallet's first gasless WETH deposit. We send
394
+ * the one-time (user-paid) Permit2 approval via `approvePermit2()` and
395
+ * retry the SAME sponsored attempt once. Bounded to one approval attempt
396
+ * per call so a wallet/agent that keeps reporting the allowance as
397
+ * missing can't loop forever. If `approvePermit2()` itself throws (e.g.
398
+ * the user rejects the wallet prompt), that error propagates as-is —
399
+ * the user said no to a transaction, so we must not turn around and ask
400
+ * them to pay for a different one via the fallback below.
401
+ * 2. `shouldFallbackToUserPaid`: the SDK's own WETH sponsor path failed at
402
+ * the infrastructure layer in a provably safe-to-retry way, so we warn
403
+ * and retry once with `undefined`, falling through to a user-paid
404
+ * native deposit. This still applies after a successful Permit2
405
+ * approval retry (the retried sponsored attempt can itself hit a safe
406
+ * sponsor failure).
407
+ *
408
+ * Any other error — an app-supplied callback's own failure in particular —
409
+ * propagates unchanged. Scoped per agent invocation so one agent's failure
410
+ * doesn't force a retry of sibling agents in a multi-agent split.
411
+ */
412
+ private depositWithFallback;
357
413
  private getMinDepositAmount;
358
414
  private splitDepositAmount;
359
415
  private validateMinDepositAmount;
@@ -366,17 +422,6 @@ declare class OwneySDK {
366
422
  private hasExistingBalance;
367
423
  private validateAssetSupport;
368
424
  private getEligibleAgents;
369
- /**
370
- * Agent ids the routing API provisioned for this org that support the given
371
- * chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
372
- * surfliquid first). Returns `[]` when the org has no compatible agent — never
373
- * throws on an empty org. Loads agent keys on first call (apiKey only, no
374
- * wallet), so the UI can resolve which agent to use before the user connects.
375
- *
376
- * This is the source of truth for agent availability: an agent appears here
377
- * iff the routing API returned its key. No per-app feature flags.
378
- */
379
- getEligibleAgentIds(chainId: number, asset: string): Promise<AgentId[]>;
380
425
  /**
381
426
  * Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
382
427
  * Validates that the asset is supported by the target agent(s) on the active chain.
@@ -407,7 +452,7 @@ declare class OwneySDK {
407
452
  * @param options.days - Lookback period: "7D", "14D", or "30D"
408
453
  * @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
409
454
  */
410
- getAccountApy({ agentId, days, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
455
+ getAccountApy({ agentId, days, tokenSymbol, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
411
456
  /**
412
457
  * Get transaction history for a specific agent, or all agents.
413
458
  *
@@ -432,6 +477,23 @@ declare class OwneySDK {
432
477
  * @returns {AgentUserProfile} for a single agent, or {OwneyUserProfile} with per-agent profiles
433
478
  */
434
479
  getUserProfile(agentId?: AgentId): Promise<OwneyUserProfile | AgentUserProfile>;
480
+ /**
481
+ * Ensure the given asset uses backend protocol auto-selection for the active
482
+ * chain's account. No-op (returns false) for agents that don't support it.
483
+ * @param asset - "USDC" or "WETH".
484
+ * @param agentId - Agent to target. Defaults to "zyfai".
485
+ * @returns whether a profile write occurred.
486
+ */
487
+ ensureAutoSelectProtocols(asset: "USDC" | "WETH", agentId?: AgentId): Promise<boolean>;
488
+ /**
489
+ * One-time, user-paid approval of Permit2 on the sponsored WETH token for
490
+ * the active chain. Required once per wallet per chain before gasless WETH
491
+ * deposits; afterwards deposit() is signature-only. Resolves only after the
492
+ * approval transaction is mined (1 confirmation), so a subsequent deposit()
493
+ * will see the new allowance; throws if the transaction reverted.
494
+ * @returns the approval transaction hash.
495
+ */
496
+ approvePermit2(asset?: "WETH"): Promise<`0x${string}`>;
435
497
  /**
436
498
  * Get the agent's average APY performance over a time period. Does not require a wallet connection.
437
499
  * @param options - Contains agentId (optional) and days ("7D", "14D", or "30D")
@@ -455,7 +517,7 @@ declare class OwneySDK {
455
517
  getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
456
518
  }
457
519
 
458
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_ALL_FAILED" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
520
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
459
521
  declare class OwneyError extends Error {
460
522
  readonly code: OwneyErrorCode;
461
523
  readonly details?: Record<string, unknown>;
package/dist/index.d.ts CHANGED
@@ -8,19 +8,92 @@ interface OwneySDKConfig {
8
8
  * Example: { 8453: "https://...", 42161: "https://..." }
9
9
  */
10
10
  zyfaiRpcUrls?: ZyfaiRpcUrlsConfig;
11
+ /**
12
+ * Optional override for the Owney routing API base URL used by the sponsored
13
+ * deposit callbacks (defaults to the OWNEY_ROUTING_API_BASE_URL env var, then
14
+ * the production URL). Set this to point at a local/staging routing API,
15
+ * e.g. "http://localhost:3000", when testing sponsor changes.
16
+ */
17
+ routingApiBaseUrl?: string;
11
18
  }
12
19
  interface ConnectionState {
13
20
  provider: any;
14
21
  walletAddress: `0x${string}`;
15
22
  chainId: number | null;
16
23
  }
17
- declare const SUPPORTED_TOKENS: readonly ["USDC", "USDT"];
18
- declare const SUPPORTED_CHAIN_IDS: readonly [8453, 42161];
19
- declare const SUPPORTED_CHAINS: readonly ["BASE", "ARBITRUM"];
24
+ declare const SUPPORTED_TOKENS: readonly ["USDC", "USDT", "WETH"];
25
+ declare const SUPPORTED_CHAIN_IDS: readonly [8453, 42161, 1];
26
+ declare const SUPPORTED_CHAINS: readonly ["BASE", "ARBITRUM", "ETHEREUM"];
20
27
  type OwneySupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
21
28
  type OwneySupportedChains = (typeof SUPPORTED_CHAINS)[number];
22
29
  type OwneySupportedTokens = (typeof SUPPORTED_TOKENS)[number];
23
30
 
31
+ type AgentId = "zyfai" | "sail";
32
+ type Asset = string;
33
+ type AgentSupportedAsset = {
34
+ readonly symbol: string;
35
+ readonly minDepositAmount: string;
36
+ };
37
+ type AgentSupportedAssets = {
38
+ readonly chainId: number;
39
+ readonly chain?: string;
40
+ readonly assets: readonly AgentSupportedAsset[];
41
+ };
42
+ type DailyApyDays = "7D" | "14D" | "30D";
43
+ type HistoryFilters = {
44
+ fromDate?: string;
45
+ toDate?: string;
46
+ /** Max entries returned per call. Defaults to 10. */
47
+ limit?: number;
48
+ /** Opaque cursor returned by a previous getHistory call. */
49
+ cursor?: string;
50
+ };
51
+ type HistoryOptions = {
52
+ agentId?: AgentId;
53
+ filters?: HistoryFilters;
54
+ };
55
+ type WithdrawOptions = {
56
+ asset: Asset;
57
+ amount?: string;
58
+ agentId?: AgentId;
59
+ };
60
+ type AccountApyOptions = {
61
+ agentId?: AgentId;
62
+ days: DailyApyDays;
63
+ /**
64
+ * Optional asset symbol (e.g. "USDC", "WETH") to scope the daily APY series
65
+ * to a specific asset on the active chain. Without it the series blends every
66
+ * position on the chain, so two assets sharing a chain (USDC and WETH on
67
+ * Base/Arbitrum) would render one merged line. Agents whose backends do not
68
+ * expose per-asset positions ignore this. (ROUT-186)
69
+ */
70
+ tokenSymbol?: string;
71
+ };
72
+ type AllocationApyOptions = {
73
+ agentId?: AgentId;
74
+ };
75
+ type AgentsApyOptions = {
76
+ agentId?: AgentId;
77
+ days: DailyApyDays;
78
+ /**
79
+ * Optional asset symbol (e.g. "USDC", "WETH") to scope the APY to a
80
+ * specific asset+chain. Ignored by agents whose backends do not yet
81
+ * support per-asset APY.
82
+ */
83
+ tokenSymbol?: string;
84
+ /**
85
+ * Optional chain id for per-asset APY lookups. Typically paired with
86
+ * `tokenSymbol`.
87
+ */
88
+ chainId?: number;
89
+ };
90
+ type DepositOptions = {
91
+ amount: string;
92
+ asset: Asset;
93
+ depositCallback?: DepositCallback;
94
+ agentId?: AgentId;
95
+ };
96
+
24
97
  interface OwneyDepositResult {
25
98
  txHash: string;
26
99
  smartWallet: string;
@@ -28,12 +101,6 @@ interface OwneyDepositResult {
28
101
  }
29
102
  interface OwneyMultiDepositResult {
30
103
  agentResults: Record<string, OwneyDepositResult>;
31
- /**
32
- * Per-agent failure messages for agents that errored during a diversified
33
- * deposit. Present only when at least one (but not all) agents failed —
34
- * the deposit is partial, not total. Omitted when every agent succeeded.
35
- */
36
- agentErrors?: Record<string, string>;
37
104
  }
38
105
  interface AgentWithdrawResult {
39
106
  txHash?: string;
@@ -201,13 +268,25 @@ interface IAgent {
201
268
  readonly supportedAssets: readonly AgentSupportedAssets[];
202
269
  disconnect(): Promise<void>;
203
270
  activateAgent(state: ConnectionState, chainId: number): Promise<void>;
204
- deposit(state: ConnectionState, chainId: number, amount: string, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
271
+ deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
205
272
  withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string): Promise<AgentWithdrawResult>;
206
273
  getBalances(state: ConnectionState, chainId: number): Promise<AgentBalance>;
207
274
  getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
208
- getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays): Promise<AccountAgentApy>;
275
+ getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays,
276
+ /**
277
+ * Optional asset symbol ("USDC" / "WETH") scoping the daily series to a
278
+ * single asset on the chain. Agents without per-asset positions ignore it.
279
+ */
280
+ tokenSymbol?: string): Promise<AccountAgentApy>;
209
281
  getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
210
282
  getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
283
+ /**
284
+ * Ensure the given asset uses backend protocol auto-selection
285
+ * (`autoSelectProtocols: true`). Optional capability — only agents whose
286
+ * backend models per-asset protocol selection implement it. Returns whether
287
+ * a write occurred (`false` = already enabled / not supported).
288
+ */
289
+ ensureAutoSelectProtocols?(state: ConnectionState, chainId: number, asset: "USDC" | "WETH"): Promise<boolean>;
211
290
  getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
212
291
  }
213
292
  /**
@@ -221,64 +300,6 @@ type AgentApyOptions = {
221
300
  chainId?: number;
222
301
  };
223
302
 
224
- type AgentId = "zyfai" | "sail" | "surfliquid";
225
- type Asset = string;
226
- type AgentSupportedAsset = {
227
- readonly symbol: string;
228
- readonly minDepositAmount: string;
229
- };
230
- type AgentSupportedAssets = {
231
- readonly chainId: number;
232
- readonly chain?: string;
233
- readonly assets: readonly AgentSupportedAsset[];
234
- };
235
- type DailyApyDays = "7D" | "14D" | "30D";
236
- type HistoryFilters = {
237
- fromDate?: string;
238
- toDate?: string;
239
- /** Max entries returned per call. Defaults to 10. */
240
- limit?: number;
241
- /** Opaque cursor returned by a previous getHistory call. */
242
- cursor?: string;
243
- };
244
- type HistoryOptions = {
245
- agentId?: AgentId;
246
- filters?: HistoryFilters;
247
- };
248
- type WithdrawOptions = {
249
- asset: Asset;
250
- amount?: string;
251
- agentId?: AgentId;
252
- };
253
- type AccountApyOptions = {
254
- agentId?: AgentId;
255
- days: DailyApyDays;
256
- };
257
- type AllocationApyOptions = {
258
- agentId?: AgentId;
259
- };
260
- type AgentsApyOptions = {
261
- agentId?: AgentId;
262
- days: DailyApyDays;
263
- /**
264
- * Optional asset symbol (e.g. "USDC", "WETH") to scope the APY to a
265
- * specific asset+chain. Ignored by agents whose backends do not yet
266
- * support per-asset APY.
267
- */
268
- tokenSymbol?: string;
269
- /**
270
- * Optional chain id for per-asset APY lookups. Typically paired with
271
- * `tokenSymbol`.
272
- */
273
- chainId?: number;
274
- };
275
- type DepositOptions = {
276
- amount: string;
277
- asset: Asset;
278
- depositCallback?: DepositCallback;
279
- agentId?: AgentId;
280
- };
281
-
282
303
  declare class OwneySDK {
283
304
  private agents;
284
305
  private activeAgents;
@@ -291,7 +312,9 @@ declare class OwneySDK {
291
312
  private state;
292
313
  private apiKey;
293
314
  private zyfaiRpcUrls?;
315
+ private routingApiBaseUrl?;
294
316
  private cachedSponsoredCallback;
317
+ private cachedWethSponsoredCallback;
295
318
  private initializingAgentsPromise;
296
319
  constructor(config: OwneySDKConfig);
297
320
  /**
@@ -326,6 +349,13 @@ declare class OwneySDK {
326
349
  * `TransferWithAuthorization`, then POSTs to the sponsor API.
327
350
  */
328
351
  private getDefaultSponsoredCallback;
352
+ /**
353
+ * Lazily builds (and caches) the default Permit2 sponsored WETH deposit
354
+ * callback used when the caller omits `depositCallback` for a WETH
355
+ * deposit. Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
356
+ * `PermitTransferFrom` instead of an EIP-3009 authorization.
357
+ */
358
+ private getDefaultWethSponsoredCallback;
329
359
  private getAgent;
330
360
  private getActiveAgents;
331
361
  private ensureAgentsInitialized;
@@ -354,6 +384,32 @@ declare class OwneySDK {
354
384
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
355
385
  */
356
386
  deposit(options: DepositOptions): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
387
+ /**
388
+ * Invokes `agent.deposit` with the resolved sponsored callback, composing
389
+ * two independent auto-recovery mechanisms:
390
+ *
391
+ * 1. Missing Permit2 allowance: when the app did not supply its own
392
+ * callback and the attempt fails with `PERMIT2_APPROVAL_REQUIRED` on a
393
+ * WETH deposit, this is the wallet's first gasless WETH deposit. We send
394
+ * the one-time (user-paid) Permit2 approval via `approvePermit2()` and
395
+ * retry the SAME sponsored attempt once. Bounded to one approval attempt
396
+ * per call so a wallet/agent that keeps reporting the allowance as
397
+ * missing can't loop forever. If `approvePermit2()` itself throws (e.g.
398
+ * the user rejects the wallet prompt), that error propagates as-is —
399
+ * the user said no to a transaction, so we must not turn around and ask
400
+ * them to pay for a different one via the fallback below.
401
+ * 2. `shouldFallbackToUserPaid`: the SDK's own WETH sponsor path failed at
402
+ * the infrastructure layer in a provably safe-to-retry way, so we warn
403
+ * and retry once with `undefined`, falling through to a user-paid
404
+ * native deposit. This still applies after a successful Permit2
405
+ * approval retry (the retried sponsored attempt can itself hit a safe
406
+ * sponsor failure).
407
+ *
408
+ * Any other error — an app-supplied callback's own failure in particular —
409
+ * propagates unchanged. Scoped per agent invocation so one agent's failure
410
+ * doesn't force a retry of sibling agents in a multi-agent split.
411
+ */
412
+ private depositWithFallback;
357
413
  private getMinDepositAmount;
358
414
  private splitDepositAmount;
359
415
  private validateMinDepositAmount;
@@ -366,17 +422,6 @@ declare class OwneySDK {
366
422
  private hasExistingBalance;
367
423
  private validateAssetSupport;
368
424
  private getEligibleAgents;
369
- /**
370
- * Agent ids the routing API provisioned for this org that support the given
371
- * chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
372
- * surfliquid first). Returns `[]` when the org has no compatible agent — never
373
- * throws on an empty org. Loads agent keys on first call (apiKey only, no
374
- * wallet), so the UI can resolve which agent to use before the user connects.
375
- *
376
- * This is the source of truth for agent availability: an agent appears here
377
- * iff the routing API returned its key. No per-app feature flags.
378
- */
379
- getEligibleAgentIds(chainId: number, asset: string): Promise<AgentId[]>;
380
425
  /**
381
426
  * Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
382
427
  * Validates that the asset is supported by the target agent(s) on the active chain.
@@ -407,7 +452,7 @@ declare class OwneySDK {
407
452
  * @param options.days - Lookback period: "7D", "14D", or "30D"
408
453
  * @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
409
454
  */
410
- getAccountApy({ agentId, days, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
455
+ getAccountApy({ agentId, days, tokenSymbol, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
411
456
  /**
412
457
  * Get transaction history for a specific agent, or all agents.
413
458
  *
@@ -432,6 +477,23 @@ declare class OwneySDK {
432
477
  * @returns {AgentUserProfile} for a single agent, or {OwneyUserProfile} with per-agent profiles
433
478
  */
434
479
  getUserProfile(agentId?: AgentId): Promise<OwneyUserProfile | AgentUserProfile>;
480
+ /**
481
+ * Ensure the given asset uses backend protocol auto-selection for the active
482
+ * chain's account. No-op (returns false) for agents that don't support it.
483
+ * @param asset - "USDC" or "WETH".
484
+ * @param agentId - Agent to target. Defaults to "zyfai".
485
+ * @returns whether a profile write occurred.
486
+ */
487
+ ensureAutoSelectProtocols(asset: "USDC" | "WETH", agentId?: AgentId): Promise<boolean>;
488
+ /**
489
+ * One-time, user-paid approval of Permit2 on the sponsored WETH token for
490
+ * the active chain. Required once per wallet per chain before gasless WETH
491
+ * deposits; afterwards deposit() is signature-only. Resolves only after the
492
+ * approval transaction is mined (1 confirmation), so a subsequent deposit()
493
+ * will see the new allowance; throws if the transaction reverted.
494
+ * @returns the approval transaction hash.
495
+ */
496
+ approvePermit2(asset?: "WETH"): Promise<`0x${string}`>;
435
497
  /**
436
498
  * Get the agent's average APY performance over a time period. Does not require a wallet connection.
437
499
  * @param options - Contains agentId (optional) and days ("7D", "14D", or "30D")
@@ -455,7 +517,7 @@ declare class OwneySDK {
455
517
  getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
456
518
  }
457
519
 
458
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_ALL_FAILED" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
520
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
459
521
  declare class OwneyError extends Error {
460
522
  readonly code: OwneyErrorCode;
461
523
  readonly details?: Record<string, unknown>;