@owney/sdk 0.2.8 → 0.2.9

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/README.md CHANGED
@@ -32,9 +32,10 @@ const balances = await sdk.getBalances();
32
32
 
33
33
  Create a new SDK instance.
34
34
 
35
- | Param | Type | Description |
36
- |-------|------|-------------|
37
- | `config.apiKey` | `string` | Your Owney API key, used to authenticate with the routing API and fetch agent-specific keys |
35
+ | Param | Type | Description |
36
+ | --------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------- |
37
+ | `config.apiKey` | `string` | Your Owney API key, used to authenticate with the routing API and fetch agent-specific keys |
38
+ | `config.zyfaiRpcUrls` | `{ 8453?: string; 42161?: string }` (optional) | Per-chain RPC URL overrides used by Zyfai SDK network calls |
38
39
 
39
40
  ```typescript
40
41
  import { OwneySDK } from "@owney/sdk";
@@ -42,12 +43,32 @@ import { OwneySDK } from "@owney/sdk";
42
43
  const sdk = new OwneySDK({ apiKey: "your-owney-api-key" });
43
44
  ```
44
45
 
46
+ #### Custom Zyfai RPC URLs
47
+
48
+ Use `zyfaiRpcUrls` to override Zyfai SDK RPC endpoints (for example, to avoid public endpoint rate limits).
49
+
50
+ ```typescript
51
+ const sdk = new OwneySDK({
52
+ apiKey: "your-owney-api-key",
53
+ zyfaiRpcUrls: {
54
+ 8453: "https://base-mainnet.g.alchemy.com/v2/<key>",
55
+ 42161: "https://arb-mainnet.g.alchemy.com/v2/<key>",
56
+ },
57
+ });
58
+ ```
59
+
60
+ Notes:
61
+
62
+ - These overrides are used by Zyfai SDK flows only.
63
+ - If omitted, Zyfai SDK uses its default RPC endpoints.
64
+ - Other app-level RPC clients (for example, direct viem calls outside Zyfai) are configured separately.
65
+
45
66
  ### `connect(provider)`
46
67
 
47
68
  Establish connection state. Must be called before any wallet-dependent operation.
48
69
 
49
- | Param | Type | Description |
50
- |-------|------|-------------|
70
+ | Param | Type | Description |
71
+ | ---------- | ----------------- | ---------------------------------------------- |
51
72
  | `provider` | EIP-1193 provider | Wallet provider (e.g. MetaMask, WalletConnect) |
52
73
 
53
74
  ```typescript
@@ -89,9 +110,9 @@ if (chainId) {
89
110
 
90
111
  Activate the user's smart wallet for the specified agents, or all chain-compatible agents if omitted. Deploys the Safe contract and creates a session key if not already set up. Saves the chainId for use by all subsequent SDK calls.
91
112
 
92
- | Param | Type | Description |
93
- |-------|------|-------------|
94
- | `chainId` | `number` | Target chain ID (e.g. `8453` for Base, `42161` for Arbitrum) |
113
+ | Param | Type | Description |
114
+ | --------- | ---------------------- | ----------------------------------------------------------------------------- |
115
+ | `chainId` | `number` | Target chain ID (e.g. `8453` for Base, `42161` for Arbitrum) |
95
116
  | `agentId` | `AgentId[]` (optional) | Agents to activate. Omit to activate all agents that support the given chain. |
96
117
 
97
118
  ```typescript
@@ -104,14 +125,14 @@ await sdk.activateAgent(42161);
104
125
 
105
126
  ### `deposit(options)`
106
127
 
107
- Deposit funds into a specific agent, or split equally across all agents if `agentId` is omitted. Validates that the asset is supported by the target agent(s) on the active chain. When splitting across agents, `depositCallback` is invoked once per agent with that agent's split amount and smart wallet address — expect multiple wallet prompts.
128
+ Deposit funds into a specific agent, or split equally across all agents if `agentId` is omitted. Validates that the asset is supported by the target agent(s) on the active chain, and agent minimum deposit amounts are taken into account. When splitting across agents, `depositCallback` is invoked once per final valid agent with that agent's split amount and smart wallet address — expect multiple wallet prompts.
108
129
 
109
- | Param | Type | Description |
110
- |-------|------|-------------|
111
- | `options.amount` | `string` | Amount in smallest unit (e.g. `"100000000"` for 100 USDC) |
112
- | `options.asset` | `string` | Asset symbol (e.g. `"USDC"`) |
113
- | `options.depositCallback` | `DepositCallback` | Callback that performs the token transfer and returns a tx hash |
114
- | `options.agentId` | `AgentId` (optional) | Target agent. Omit to split equally across all agents. |
130
+ | Param | Type | Description |
131
+ | ------------------------- | -------------------- | --------------------------------------------------------------- |
132
+ | `options.amount` | `string` | Amount in smallest unit (e.g. `"100000000"` for 100 USDC) |
133
+ | `options.asset` | `string` | Asset symbol (e.g. `"USDC"`) |
134
+ | `options.depositCallback` | `DepositCallback` | Callback that performs the token transfer and returns a tx hash |
135
+ | `options.agentId` | `AgentId` (optional) | Target agent. Omit to split equally across all agents. |
115
136
 
116
137
  Returns: `OwneyDepositResult` (single agent) or `OwneyMultiDepositResult` (all agents)
117
138
 
@@ -126,9 +147,9 @@ const result = await sdk.deposit({
126
147
  return txHash;
127
148
  },
128
149
  });
129
- console.log(result.txHash); // "0x..."
130
- console.log(result.smartWallet); // "0x..."
131
- console.log(result.amount); // "100000000"
150
+ console.log(result.txHash); // "0x..."
151
+ console.log(result.smartWallet); // "0x..."
152
+ console.log(result.amount); // "100000000"
132
153
 
133
154
  // Split equally across all agents
134
155
  const results = await sdk.deposit({
@@ -138,19 +159,19 @@ const results = await sdk.deposit({
138
159
  return await transferTokens(smartWallet, amount);
139
160
  },
140
161
  });
141
- console.log(results.agentResults.zyfai.amount); // "50000000"
142
- console.log(results.agentResults.sail.amount); // "50000000"
162
+ console.log(results.agentResults.zyfai.amount); // "50000000"
163
+ console.log(results.agentResults.sail.amount); // "50000000"
143
164
  ```
144
165
 
145
166
  ### `withdraw(options)`
146
167
 
147
168
  Withdraw funds from a specific agent, or all agents that support the active chain+asset if `agentId` is omitted. Validates that the asset is supported.
148
169
 
149
- | Param | Type | Description |
150
- |-------|------|-------------|
151
- | `options.asset` | `string` | Asset symbol (e.g. `"USDC"`) |
152
- | `options.amount` | `string` (optional) | Amount to withdraw. Omit for full withdrawal. |
153
- | `options.agentId` | `AgentId` (optional) | Target agent. Omit to withdraw from all. |
170
+ | Param | Type | Description |
171
+ | ----------------- | -------------------- | --------------------------------------------- |
172
+ | `options.asset` | `string` | Asset symbol (e.g. `"USDC"`) |
173
+ | `options.amount` | `string` (optional) | Amount to withdraw. Omit for full withdrawal. |
174
+ | `options.agentId` | `AgentId` (optional) | Target agent. Omit to withdraw from all. |
154
175
 
155
176
  Returns: `AgentWithdrawResult` (single agent) or `OwneyWithdrawResult` (all agents)
156
177
 
@@ -161,21 +182,21 @@ const result = await sdk.withdraw({
161
182
  agentId: "zyfai",
162
183
  amount: "50000000",
163
184
  });
164
- console.log(result.type); // "partial"
165
- console.log(result.amount); // "50000000"
185
+ console.log(result.type); // "partial"
186
+ console.log(result.amount); // "50000000"
166
187
 
167
188
  // Full withdrawal from all agents
168
189
  const results = await sdk.withdraw({ asset: "USDC" });
169
- console.log(results.agentResult.zyfai.type); // "full"
170
- console.log(results.agentResult.sail.type); // "full"
190
+ console.log(results.agentResult.zyfai.type); // "full"
191
+ console.log(results.agentResult.sail.type); // "full"
171
192
  ```
172
193
 
173
194
  ### `getBalances(agentId?)`
174
195
 
175
196
  Get the user's balances for a specific agent, or aggregated across all agents.
176
197
 
177
- | Param | Type | Description |
178
- |-------|------|-------------|
198
+ | Param | Type | Description |
199
+ | --------- | ------------------------------ | ------------------------------------ |
179
200
  | `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for all agents. |
180
201
 
181
202
  Returns: `AgentBalance` (single agent) or `OwneyBalances` (all agents)
@@ -183,23 +204,23 @@ Returns: `AgentBalance` (single agent) or `OwneyBalances` (all agents)
183
204
  ```typescript
184
205
  // Single agent
185
206
  const balance = await sdk.getBalances("zyfai");
186
- console.log(balance.totalBalance); // "150.25"
187
- console.log(balance.smartWallet); // "0x..."
188
- console.log(balance.tokens); // [{ chain: "BASE", chainId: 8453, asset: "USDC", amount: "150.25" }]
207
+ console.log(balance.totalBalance); // "150.25"
208
+ console.log(balance.smartWallet); // "0x..."
209
+ console.log(balance.tokens); // [{ chain: "BASE", chainId: 8453, asset: "USDC", amount: "150.25" }]
189
210
 
190
211
  // All agents
191
212
  const allBalances = await sdk.getBalances();
192
- console.log(allBalances.totalBalance); // "300.50"
213
+ console.log(allBalances.totalBalance); // "300.50"
193
214
  console.log(allBalances.agentBalances.zyfai.totalBalance); // "150.25"
194
- console.log(allBalances.agentBalances.sail.totalBalance); // "150.25"
215
+ console.log(allBalances.agentBalances.sail.totalBalance); // "150.25"
195
216
  ```
196
217
 
197
218
  ### `getEarnings(agentId?)`
198
219
 
199
220
  Get the user's on-chain earnings for a specific agent, or aggregated across all agents.
200
221
 
201
- | Param | Type | Description |
202
- |-------|------|-------------|
222
+ | Param | Type | Description |
223
+ | --------- | ------------------------------ | ------------------------------------ |
203
224
  | `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for all agents. |
204
225
 
205
226
  Returns: `AgentEarnings` (single agent) or `OwneyEarnings` (all agents)
@@ -207,12 +228,12 @@ Returns: `AgentEarnings` (single agent) or `OwneyEarnings` (all agents)
207
228
  ```typescript
208
229
  // Single agent
209
230
  const earnings = await sdk.getEarnings("zyfai");
210
- console.log(earnings.smartWallet); // "0x..."
211
- console.log(earnings.lifetimeEarnings); // 42.5
231
+ console.log(earnings.smartWallet); // "0x..."
232
+ console.log(earnings.lifetimeEarnings); // 42.5
212
233
 
213
234
  // All agents
214
235
  const allEarnings = await sdk.getEarnings();
215
- console.log(allEarnings.totalEarnings); // "85.0"
236
+ console.log(allEarnings.totalEarnings); // "85.0"
216
237
  console.log(allEarnings.agentEarnings.zyfai.lifetimeEarnings); // 42.5
217
238
  ```
218
239
 
@@ -220,37 +241,37 @@ console.log(allEarnings.agentEarnings.zyfai.lifetimeEarnings); // 42.5
220
241
 
221
242
  Get the weighted APY for the user's account. When querying all agents, the total APY is a balance-weighted average.
222
243
 
223
- | Param | Type | Description |
224
- |-------|------|-------------|
244
+ | Param | Type | Description |
245
+ | --------- | ------------------------------ | ------------------------------------------------ |
225
246
  | `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for balance-weighted total. |
226
- | `days` | `"7D" \| "14D" \| "30D"` | Lookback period |
247
+ | `days` | `"7D" \| "14D" \| "30D"` | Lookback period |
227
248
 
228
249
  Returns: `AccountAgentApy` (single agent) or `OwneyAccountApy` (all agents)
229
250
 
230
251
  ```typescript
231
252
  // Single agent
232
253
  const apy = await sdk.getAccountApy({ agentId: "zyfai", days: "30D" });
233
- console.log(apy.walletAddress); // "0x..."
254
+ console.log(apy.walletAddress); // "0x..."
234
255
  console.log(apy.weightedApyAfterFee); // 5.2
235
256
  // Per chain + token breakdown, when the agent reports it
236
- console.log(apy.weightedApyAfterFeeDetails?.apyPerAsset[8453]?.USDC); // 5.4
257
+ console.log(apy.weightedApyAfterFeeDetails?.apyPerAsset[8453]?.USDC); // 5.4
237
258
 
238
259
  // All agents (balance-weighted)
239
260
  const allApy = await sdk.getAccountApy({ days: "30D" });
240
- console.log(allApy.totalApy); // "5.6"
261
+ console.log(allApy.totalApy); // "5.6"
241
262
  console.log(allApy.agentApy.zyfai.weightedApyAfterFee); // 6.0
242
- console.log(allApy.agentApy.sail.weightedApyAfterFee); // 4.0
263
+ console.log(allApy.agentApy.sail.weightedApyAfterFee); // 4.0
243
264
  ```
244
265
 
245
266
  ### `getHistory({ agentId?, filters? })`
246
267
 
247
268
  Get transaction history for a specific agent, or all agents. When querying all agents, results are merged into a single list sorted by date (newest first). Each entry includes the originating `agent` and a `transactions` array with typed on-chain transaction details.
248
269
 
249
- | Param | Type | Description |
250
- |-------|------|-------------|
251
- | `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for all agents. |
252
- | `filters.fromDate` | `string` (optional) | Start date (`YYYY-MM-DD`) |
253
- | `filters.toDate` | `string` (optional) | End date (`YYYY-MM-DD`) |
270
+ | Param | Type | Description |
271
+ | ------------------ | ------------------------------ | ------------------------------------ |
272
+ | `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for all agents. |
273
+ | `filters.fromDate` | `string` (optional) | Start date (`YYYY-MM-DD`) |
274
+ | `filters.toDate` | `string` (optional) | End date (`YYYY-MM-DD`) |
254
275
 
255
276
  Returns: `OwneyAgentHistory`
256
277
 
@@ -260,65 +281,65 @@ const history = await sdk.getHistory({
260
281
  agentId: "zyfai",
261
282
  filters: { fromDate: "2025-01-01" },
262
283
  });
263
- console.log(history.total); // 42
264
- console.log(history.data[0].agent); // "zyfai"
265
- console.log(history.data[0].action); // "Rebalance"
266
- console.log(history.data[0].date); // "2025-03-15T12:00:00Z"
267
- console.log(history.data[0].transactions[0].txHashes); // ["0x..."]
268
- console.log(history.data[0].transactions[0].amount); // "100.00"
284
+ console.log(history.total); // 42
285
+ console.log(history.data[0].agent); // "zyfai"
286
+ console.log(history.data[0].action); // "Rebalance"
287
+ console.log(history.data[0].date); // "2025-03-15T12:00:00Z"
288
+ console.log(history.data[0].transactions[0].txHashes); // ["0x..."]
289
+ console.log(history.data[0].transactions[0].amount); // "100.00"
269
290
  console.log(history.data[0].transactions[0].tokenSymbol); // "USDC"
270
291
 
271
292
  // Rebalance logs show fund movement between protocols
272
293
  console.log(history.data[0].rebalanceLog[0].fromProtocol); // "Aave V3"
273
- console.log(history.data[0].rebalanceLog[0].toProtocol); // "Morpho Blue"
274
- console.log(history.data[0].rebalanceLog[0].tokenSymbol); // "USDC"
275
- console.log(history.data[0].rebalanceLog[0].amount); // "100.00"
276
- console.log(history.data[0].rebalanceLog[0].status); // "success"
294
+ console.log(history.data[0].rebalanceLog[0].toProtocol); // "Morpho Blue"
295
+ console.log(history.data[0].rebalanceLog[0].tokenSymbol); // "USDC"
296
+ console.log(history.data[0].rebalanceLog[0].amount); // "100.00"
297
+ console.log(history.data[0].rebalanceLog[0].status); // "success"
277
298
 
278
299
  // All agents (merged and sorted by date)
279
300
  const allHistory = await sdk.getHistory();
280
- console.log(allHistory.total); // 57
281
- console.log(allHistory.data[0].agent); // "sail" (most recent entry)
282
- console.log(allHistory.data[0].action); // "Rebalance"
301
+ console.log(allHistory.total); // 57
302
+ console.log(allHistory.data[0].agent); // "sail" (most recent entry)
303
+ console.log(allHistory.data[0].action); // "Rebalance"
283
304
  ```
284
305
 
285
306
  ### `pauseAgent(agentId)`
286
307
 
287
308
  Pause an agent's automated operations. The agent will stop rebalancing until resumed.
288
309
 
289
- | Param | Type | Description |
290
- |-------|------|-------------|
310
+ | Param | Type | Description |
311
+ | --------- | ------------------- | -------------- |
291
312
  | `agentId` | `"zyfai" \| "sail"` | Agent to pause |
292
313
 
293
314
  Returns: `OwneyAgentStatus`
294
315
 
295
316
  ```typescript
296
317
  const status = await sdk.pauseAgent("zyfai");
297
- console.log(status.success); // true
318
+ console.log(status.success); // true
298
319
  ```
299
320
 
300
321
  ### `resumeAgent(agentId)`
301
322
 
302
323
  Resume an agent's automated operations.
303
324
 
304
- | Param | Type | Description |
305
- |-------|------|-------------|
325
+ | Param | Type | Description |
326
+ | --------- | ------------------- | --------------- |
306
327
  | `agentId` | `"zyfai" \| "sail"` | Agent to resume |
307
328
 
308
329
  Returns: `OwneyAgentStatus`
309
330
 
310
331
  ```typescript
311
332
  const status = await sdk.resumeAgent("zyfai");
312
- console.log(status.success); // true
313
- console.log(status.protocols); // ["aave", "compound"]
333
+ console.log(status.success); // true
334
+ console.log(status.protocols); // ["aave", "compound"]
314
335
  ```
315
336
 
316
337
  ### `getUserProfile(agentId?)`
317
338
 
318
339
  Get the user's profile for a specific agent, or all agents.
319
340
 
320
- | Param | Type | Description |
321
- |-------|------|-------------|
341
+ | Param | Type | Description |
342
+ | --------- | ------------------------------ | ------------------------------------ |
322
343
  | `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for all agents. |
323
344
 
324
345
  Returns: `AgentUserProfile` (single agent) or `OwneyUserProfile` (all agents)
@@ -326,28 +347,28 @@ Returns: `AgentUserProfile` (single agent) or `OwneyUserProfile` (all agents)
326
347
  ```typescript
327
348
  // Single agent
328
349
  const profile = await sdk.getUserProfile("zyfai");
329
- console.log(profile.address); // "0x..."
330
- console.log(profile.smartWallet); // "0x..."
331
- console.log(profile.chains); // [8453]
350
+ console.log(profile.address); // "0x..."
351
+ console.log(profile.smartWallet); // "0x..."
352
+ console.log(profile.chains); // [8453]
332
353
  console.log(profile.hasActiveSessionKey); // true
333
- console.log(profile.protocols); // ["aave", "compound"]
354
+ console.log(profile.protocols); // ["aave", "compound"]
334
355
 
335
356
  // All agents
336
357
  const allProfiles = await sdk.getUserProfile();
337
358
  console.log(allProfiles.agentUserProfile.zyfai.smartWallet); // "0x..."
338
- console.log(allProfiles.agentUserProfile.sail.smartWallet); // "0x..."
359
+ console.log(allProfiles.agentUserProfile.sail.smartWallet); // "0x..."
339
360
  ```
340
361
 
341
362
  ### `getAgentApy({ agentId?, days, tokenSymbol?, chainId? })`
342
363
 
343
364
  Get the agent's average APY performance over a time period. Does not require a wallet connection.
344
365
 
345
- | Param | Type | Description |
346
- |-------|------|-------------|
347
- | `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for all agents. |
348
- | `days` | `"7D" \| "14D" \| "30D"` | Lookback period |
349
- | `tokenSymbol` | `string` (optional) | Asset symbol (e.g. `"USDC"`, `"WETH"`). Scopes the upstream request to a specific asset when the agent's backend supports it. Zyfai forwards this; Sail currently ignores it at the API level. |
350
- | `chainId` | `number` (optional) | Chain id. Typically paired with `tokenSymbol` for per-asset+chain APY. Zyfai forwards this; Sail currently ignores it at the API level. |
366
+ | Param | Type | Description |
367
+ | ------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
368
+ | `agentId` | `"zyfai" \| "sail"` (optional) | Agent to query. Omit for all agents. |
369
+ | `days` | `"7D" \| "14D" \| "30D"` | Lookback period |
370
+ | `tokenSymbol` | `string` (optional) | Asset symbol (e.g. `"USDC"`, `"WETH"`). Scopes the upstream request to a specific asset when the agent's backend supports it. Zyfai forwards this; Sail currently ignores it at the API level. |
371
+ | `chainId` | `number` (optional) | Chain id. Typically paired with `tokenSymbol` for per-asset+chain APY. Zyfai forwards this; Sail currently ignores it at the API level. |
351
372
 
352
373
  Returns: `AgentApy` (single agent) or `OwneyAgentApy` (all agents)
353
374
 
@@ -359,13 +380,13 @@ returns.
359
380
  ```typescript
360
381
  // Single agent
361
382
  const apy = await sdk.getAgentApy({ agentId: "zyfai", days: "30D" });
362
- console.log(apy.averageApy); // 8.5
383
+ console.log(apy.averageApy); // 8.5
363
384
  console.log(apy.detailedApys?.apyPerAsset[8453]?.USDC); // 8.7
364
385
 
365
386
  // All agents
366
387
  const allApy = await sdk.getAgentApy({ days: "30D" });
367
388
  console.log(allApy.agentApy.zyfai.averageApy); // 8.5
368
- console.log(allApy.agentApy.sail.averageApy); // 6.2
389
+ console.log(allApy.agentApy.sail.averageApy); // 6.2
369
390
  console.log(allApy.agentApy.sail.detailedApys?.apyPerAsset[42161]?.USDT); // 6.4
370
391
 
371
392
  // Scope the upstream query to USDC on Base (Zyfai-aware; Sail ignores the filter)
@@ -385,7 +406,7 @@ Returns: `OwneyAgentAllocation`
385
406
 
386
407
  ```typescript
387
408
  const allocation = await sdk.getAgentAllocation();
388
- console.log(allocation.agentAllocation); // { zyfai: 75, sail: 25 }
409
+ console.log(allocation.agentAllocation); // { zyfai: 75, sail: 25 }
389
410
  ```
390
411
 
391
412
  ## Types
@@ -408,6 +429,10 @@ type AgentSupportedAssets = {
408
429
 
409
430
  interface OwneySDKConfig {
410
431
  apiKey: string;
432
+ zyfaiRpcUrls?: {
433
+ 8453?: string;
434
+ 42161?: string;
435
+ };
411
436
  }
412
437
 
413
438
  interface ConnectionState {
@@ -417,8 +442,8 @@ interface ConnectionState {
417
442
  }
418
443
 
419
444
  type HistoryFilters = {
420
- fromDate?: string; // YYYY-MM-DD
421
- toDate?: string; // YYYY-MM-DD
445
+ fromDate?: string; // YYYY-MM-DD
446
+ toDate?: string; // YYYY-MM-DD
422
447
  };
423
448
 
424
449
  type HistoryOptions = {
@@ -447,8 +472,8 @@ type AccountApyOptions = {
447
472
  type AgentsApyOptions = {
448
473
  agentId?: AgentId;
449
474
  days: DailyApyDays;
450
- tokenSymbol?: string; // e.g. "USDC", "WETH"
451
- chainId?: number; // typically paired with tokenSymbol
475
+ tokenSymbol?: string; // e.g. "USDC", "WETH"
476
+ chainId?: number; // typically paired with tokenSymbol
452
477
  };
453
478
  ```
454
479
 
@@ -634,36 +659,36 @@ try {
634
659
  ```typescript
635
660
  type OwneyErrorCode =
636
661
  // Connection & wallet
637
- | "NOT_CONNECTED" // Wallet-dependent method called before connect()
638
- | "NO_ACTIVE_CHAIN" // Method called before activateAgent()
639
- | "WALLET_NO_ACCOUNTS" // Provider returned no accounts during connect()
662
+ | "NOT_CONNECTED" // Wallet-dependent method called before connect()
663
+ | "NO_ACTIVE_CHAIN" // Method called before activateAgent()
664
+ | "WALLET_NO_ACCOUNTS" // Provider returned no accounts during connect()
640
665
  | "WALLET_ADDRESS_REQUIRED" // Wallet address missing during agent auth
641
666
  // Agent resolution
642
- | "AGENT_NOT_FOUND" // Unknown agent ID passed
667
+ | "AGENT_NOT_FOUND" // Unknown agent ID passed
643
668
  | "AGENT_CHAIN_INCOMPATIBLE" // Agent(s) don't support the given chain
644
- | "AGENT_EMPTY_LIST" // Empty agentId array passed to activateAgent()
669
+ | "AGENT_EMPTY_LIST" // Empty agentId array passed to activateAgent()
645
670
  // Chain
646
- | "CHAIN_UNSUPPORTED" // Chain ID not in supported list (8453, 42161)
647
- | "CHAIN_NO_COMPATIBLE_AGENTS" // No agents support the given chain
671
+ | "CHAIN_UNSUPPORTED" // Chain ID not in supported list (8453, 42161)
672
+ | "CHAIN_NO_COMPATIBLE_AGENTS" // No agents support the given chain
648
673
  // Asset
649
- | "ASSET_UNSUPPORTED" // Agent doesn't support the asset on the active chain
650
- | "ASSET_NO_COMPATIBLE_AGENTS" // No agents support the asset on the active chain
674
+ | "ASSET_UNSUPPORTED" // Agent doesn't support the asset on the active chain
675
+ | "ASSET_NO_COMPATIBLE_AGENTS" // No agents support the asset on the active chain
651
676
  // Deposit
652
- | "DEPOSIT_AMOUNT_TOO_SMALL" // Amount too small to split across agents
653
- | "DEPOSIT_CALLBACK_REQUIRED" // Sail agent requires a depositCallback
654
- | "DEPOSIT_CALLBACK_INVALID" // depositCallback didn't return a tx hash
677
+ | "DEPOSIT_AMOUNT_BELOW_MINIMUM" // Amount below an agent's required minimum deposit
678
+ | "DEPOSIT_CALLBACK_REQUIRED" // Sail agent requires a depositCallback
679
+ | "DEPOSIT_CALLBACK_INVALID" // depositCallback didn't return a tx hash
655
680
  | "DEPOSIT_NO_PERMITTED_TOKENS" // No permitted tokens available for deposit
656
681
  // Withdraw
657
682
  | "WITHDRAW_NO_PERMITTED_TOKENS" // No permitted tokens available for withdrawal
658
683
  // API
659
- | "API_ROUTING_ERROR" // Routing API returned a non-OK HTTP status
684
+ | "API_ROUTING_ERROR" // Routing API returned a non-OK HTTP status
660
685
  | "API_ROUTING_FAILED" // Routing API returned { success: false }
661
- | "API_SAIL_ERROR" // Sail API returned a non-OK HTTP status
662
- | "API_SAIL_TIMEOUT" // Sail API request timed out
663
- | "API_NO_AGENTS" // No supported agents returned by routing API
686
+ | "API_SAIL_ERROR" // Sail API returned a non-OK HTTP status
687
+ | "API_SAIL_TIMEOUT" // Sail API request timed out
688
+ | "API_NO_AGENTS" // No supported agents returned by routing API
664
689
  // Aggregation
665
- | "BALANCE_ALL_FAILED" // All agents failed to return balances
666
- | "ALLOCATION_ALL_FAILED" // All agents failed to return allocation data
690
+ | "BALANCE_ALL_FAILED" // All agents failed to return balances
691
+ | "ALLOCATION_ALL_FAILED" // All agents failed to return allocation data
667
692
  // Validation
668
693
  | "VALIDATION_INVALID_DAYS"; // Invalid days value (expected "7D", "14D", or "30D")
669
694
 
@@ -675,10 +700,10 @@ class OwneyError extends Error {
675
700
 
676
701
  The three convenience subclasses extend `OwneyError` and remain backwards-compatible:
677
702
 
678
- | Class | Code | Extra properties |
679
- |-------|------|------------------|
680
- | `NotConnectedError` | `NOT_CONNECTED` | — |
681
- | `AgentNotFoundError` | `AGENT_NOT_FOUND` | — |
703
+ | Class | Code | Extra properties |
704
+ | ----------------------------- | -------------------------- | ---------------------------------------- |
705
+ | `NotConnectedError` | `NOT_CONNECTED` | — |
706
+ | `AgentNotFoundError` | `AGENT_NOT_FOUND` | — |
682
707
  | `AgentChainIncompatibleError` | `AGENT_CHAIN_INCOMPATIBLE` | `incompatibleAgents`, `connectedChainId` |
683
708
 
684
709
  ## License
package/dist/index.cjs CHANGED
@@ -303,8 +303,13 @@ function mapApyByStrategy(raw) {
303
303
  }
304
304
 
305
305
  // src/agents/zyfai/zyfai.agent.ts
306
+ var DEFAULT_ZYFAI_RPC_URLS = {
307
+ 8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
308
+ 42161: "https://arb-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V"
309
+ };
306
310
  var ZyfaiAgent = class {
307
311
  id = "zyfai";
312
+ minDepositAmount = "0";
308
313
  supportedChainIds = [8453, 42161];
309
314
  supportedAssets = [
310
315
  {
@@ -324,7 +329,10 @@ var ZyfaiAgent = class {
324
329
  smartWalletCache = /* @__PURE__ */ new Map();
325
330
  connectAuthPromise = null;
326
331
  constructor(apiKey, rpcUrls) {
327
- this.sdk = new import_sdk.ZyfaiSDK({ apiKey, rpcUrls });
332
+ this.sdk = new import_sdk.ZyfaiSDK({
333
+ apiKey,
334
+ rpcUrls: rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS
335
+ });
328
336
  }
329
337
  // --- Private helpers ---
330
338
  getAddress() {
@@ -640,7 +648,7 @@ function mapHistory2(raw) {
640
648
  rewards: "Earned"
641
649
  };
642
650
  const filtered = raw.result.items.filter(
643
- (i) => i.status === "success" && i.transactions.length
651
+ (i) => !(i.type === "execution" && (i.status === "failed" || !i.transactions.length))
644
652
  );
645
653
  return {
646
654
  total: filtered.length,
@@ -707,6 +715,7 @@ var PAGE_ID = "home";
707
715
  var SAIL_PORTFOLIO_TIMEOUT_MS = 8e3;
708
716
  var SailAgent = class {
709
717
  id = "sail";
718
+ minDepositAmount = "4800000000";
710
719
  supportedChainIds = [8453, 42161];
711
720
  supportedAssets = [
712
721
  {
@@ -1372,7 +1381,7 @@ var OwneySDK = class {
1372
1381
  }
1373
1382
  /**
1374
1383
  * Deposit funds into a specific agent, or split equally across all agents if agentId is omitted.
1375
- * Validates that the asset is supported by the target agent(s) on the active chain.
1384
+ * Validates that the asset is supported and amount meets minimums for the target agent(s).
1376
1385
  * @param options - Deposit parameters
1377
1386
  * @param options.amount - Amount to deposit in smallest unit (e.g. "100000000" for 100 USDC)
1378
1387
  * @param options.asset - Asset symbol to deposit (e.g. "USDC")
@@ -1384,28 +1393,29 @@ var OwneySDK = class {
1384
1393
  */
1385
1394
  async deposit(options) {
1386
1395
  const { amount, asset, depositCallback, agentId } = options;
1396
+ if (BigInt(amount) === 0n) {
1397
+ return { agentResults: {} };
1398
+ }
1387
1399
  const state = this.requireState();
1388
1400
  const chainId = this.requireChainId();
1389
1401
  if (agentId) {
1390
1402
  const agent = this.getAgent(agentId);
1391
1403
  this.validateAssetSupport(agent, chainId, asset);
1404
+ this.validateMinDepositAmount(agent, amount);
1392
1405
  return agent.deposit(state, chainId, amount, depositCallback);
1393
1406
  }
1394
- const eligibleAgents = this.getEligibleAgents(chainId, asset);
1395
1407
  const totalAmount = BigInt(amount);
1396
- if (totalAmount < BigInt(eligibleAgents.length)) {
1408
+ const eligibleAgents = this.getEligibleAgents(chainId, asset);
1409
+ const agentAmounts = this.splitDepositAmount(totalAmount, eligibleAgents);
1410
+ if (agentAmounts.length === 0) {
1397
1411
  throw new OwneyError(
1398
- "DEPOSIT_AMOUNT_TOO_SMALL",
1399
- `Amount "${amount}" is too small to split across ${eligibleAgents.length} agents.`,
1400
- { amount, agentCount: eligibleAgents.length }
1412
+ "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1413
+ `Amount "${amount}" cannot satisfy minimum deposit requirements for any eligible agent.`,
1414
+ { amount }
1401
1415
  );
1402
1416
  }
1403
- const perAgent = totalAmount / BigInt(eligibleAgents.length);
1404
- const remainder = totalAmount % BigInt(eligibleAgents.length);
1405
1417
  const agentResults = {};
1406
- for (let i = 0; i < eligibleAgents.length; i++) {
1407
- const agent = eligibleAgents[i];
1408
- const agentAmount = i === eligibleAgents.length - 1 ? String(perAgent + remainder) : String(perAgent);
1418
+ for (const { agent, amount: agentAmount } of agentAmounts) {
1409
1419
  agentResults[agent.id] = await agent.deposit(
1410
1420
  state,
1411
1421
  chainId,
@@ -1415,6 +1425,37 @@ var OwneySDK = class {
1415
1425
  }
1416
1426
  return { agentResults };
1417
1427
  }
1428
+ splitDepositAmount(totalAmount, agents) {
1429
+ if (agents.length === 0)
1430
+ return [];
1431
+ const perAgent = totalAmount / BigInt(agents.length);
1432
+ const remainder = totalAmount % BigInt(agents.length);
1433
+ const splits = agents.map((agent, i) => ({
1434
+ agent,
1435
+ amount: i === agents.length - 1 ? perAgent + remainder : perAgent
1436
+ }));
1437
+ const valid = splits.filter(
1438
+ (s) => s.amount >= BigInt(s.agent.minDepositAmount)
1439
+ );
1440
+ if (valid.length === agents.length) {
1441
+ return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
1442
+ }
1443
+ return this.splitDepositAmount(totalAmount, valid.map((s) => s.agent));
1444
+ }
1445
+ validateMinDepositAmount(agent, amount) {
1446
+ const minDepositAmount = BigInt(agent.minDepositAmount);
1447
+ const parsedAmount = BigInt(amount);
1448
+ if (parsedAmount < minDepositAmount) {
1449
+ throw new OwneyError(
1450
+ "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1451
+ `Amount "${amount}" is below the required minimum deposit for agent "${agent.id}".`,
1452
+ {
1453
+ agentId: agent.id,
1454
+ amount
1455
+ }
1456
+ );
1457
+ }
1458
+ }
1418
1459
  validateAssetSupport(agent, chainId, asset) {
1419
1460
  const chainAssets = agent.supportedAssets.find(
1420
1461
  (sa) => sa.chainId === chainId
@@ -1597,18 +1638,30 @@ var OwneySDK = class {
1597
1638
  results[id] = apy;
1598
1639
  }
1599
1640
  const balances = {};
1600
- let totalBalance = 0;
1601
1641
  for (const [id, bal] of balanceResults) {
1602
1642
  balances[id] = bal;
1603
- totalBalance += bal;
1604
1643
  }
1605
1644
  let totalApy = 0;
1606
- if (totalBalance > 0) {
1645
+ let relevantBalance = 0;
1646
+ for (const id of Object.keys(results)) {
1647
+ const agentApy = Number(results[id].weightedApyAfterFee ?? 0);
1648
+ if (agentApy === 0)
1649
+ continue;
1650
+ relevantBalance += balances[id];
1651
+ }
1652
+ if (relevantBalance > 0) {
1607
1653
  for (const id of Object.keys(results)) {
1608
- const weight = balances[id] / totalBalance;
1609
- totalApy += Number(results[id].weightedApyAfterFee ?? 0) * weight;
1654
+ const agentApy = Number(results[id].weightedApyAfterFee ?? 0);
1655
+ if (agentApy === 0)
1656
+ continue;
1657
+ const weight = balances[id] / relevantBalance;
1658
+ totalApy += agentApy * weight;
1610
1659
  }
1611
1660
  }
1661
+ console.log("account apy", {
1662
+ totalApy: String(totalApy),
1663
+ agentApy: results
1664
+ });
1612
1665
  return {
1613
1666
  totalApy: String(totalApy),
1614
1667
  agentApy: results
package/dist/index.d.cts CHANGED
@@ -24,6 +24,7 @@ interface IAgent {
24
24
  readonly id: string;
25
25
  readonly supportedChainIds: readonly OwneySupportedChainId[];
26
26
  readonly supportedAssets: readonly AgentSupportedAssets[];
27
+ readonly minDepositAmount: string;
27
28
  disconnect(): Promise<void>;
28
29
  activateAgent(state: ConnectionState, chainId: number): Promise<void>;
29
30
  deposit(state: ConnectionState, chainId: number, amount: string, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
@@ -196,10 +197,6 @@ interface AgentApy {
196
197
  interface OwneyAgentApy {
197
198
  agentApy: Record<AgentId, AgentApy>;
198
199
  }
199
- interface OwneyRouteResponse {
200
- agent: AgentId;
201
- chainId: number;
202
- }
203
200
  interface OwneyAgentAllocation {
204
201
  agentAllocation: Record<AgentId, number>;
205
202
  }
@@ -252,7 +249,7 @@ declare class OwneySDK {
252
249
  activateAgent(chainId: number, agentId?: AgentId[]): Promise<void>;
253
250
  /**
254
251
  * Deposit funds into a specific agent, or split equally across all agents if agentId is omitted.
255
- * Validates that the asset is supported by the target agent(s) on the active chain.
252
+ * Validates that the asset is supported and amount meets minimums for the target agent(s).
256
253
  * @param options - Deposit parameters
257
254
  * @param options.amount - Amount to deposit in smallest unit (e.g. "100000000" for 100 USDC)
258
255
  * @param options.asset - Asset symbol to deposit (e.g. "USDC")
@@ -263,6 +260,8 @@ declare class OwneySDK {
263
260
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
264
261
  */
265
262
  deposit(options: DepositOptions): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
263
+ private splitDepositAmount;
264
+ private validateMinDepositAmount;
266
265
  private validateAssetSupport;
267
266
  private getEligibleAgents;
268
267
  /**
@@ -342,7 +341,7 @@ declare class OwneySDK {
342
341
  getAgentAllocation(): Promise<OwneyAgentAllocation>;
343
342
  }
344
343
 
345
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_TOO_SMALL" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
344
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "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" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
346
345
  declare class OwneyError extends Error {
347
346
  readonly code: OwneyErrorCode;
348
347
  readonly details?: Record<string, unknown>;
@@ -366,4 +365,4 @@ declare class AgentChainIncompatibleError extends OwneyError {
366
365
  }>, connectedChainId: number);
367
366
  }
368
367
 
369
- export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyRouteResponse, OwneySDK, OwneySDKConfig, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
368
+ export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneySDK, OwneySDKConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
package/dist/index.d.ts CHANGED
@@ -24,6 +24,7 @@ interface IAgent {
24
24
  readonly id: string;
25
25
  readonly supportedChainIds: readonly OwneySupportedChainId[];
26
26
  readonly supportedAssets: readonly AgentSupportedAssets[];
27
+ readonly minDepositAmount: string;
27
28
  disconnect(): Promise<void>;
28
29
  activateAgent(state: ConnectionState, chainId: number): Promise<void>;
29
30
  deposit(state: ConnectionState, chainId: number, amount: string, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
@@ -196,10 +197,6 @@ interface AgentApy {
196
197
  interface OwneyAgentApy {
197
198
  agentApy: Record<AgentId, AgentApy>;
198
199
  }
199
- interface OwneyRouteResponse {
200
- agent: AgentId;
201
- chainId: number;
202
- }
203
200
  interface OwneyAgentAllocation {
204
201
  agentAllocation: Record<AgentId, number>;
205
202
  }
@@ -252,7 +249,7 @@ declare class OwneySDK {
252
249
  activateAgent(chainId: number, agentId?: AgentId[]): Promise<void>;
253
250
  /**
254
251
  * Deposit funds into a specific agent, or split equally across all agents if agentId is omitted.
255
- * Validates that the asset is supported by the target agent(s) on the active chain.
252
+ * Validates that the asset is supported and amount meets minimums for the target agent(s).
256
253
  * @param options - Deposit parameters
257
254
  * @param options.amount - Amount to deposit in smallest unit (e.g. "100000000" for 100 USDC)
258
255
  * @param options.asset - Asset symbol to deposit (e.g. "USDC")
@@ -263,6 +260,8 @@ declare class OwneySDK {
263
260
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
264
261
  */
265
262
  deposit(options: DepositOptions): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
263
+ private splitDepositAmount;
264
+ private validateMinDepositAmount;
266
265
  private validateAssetSupport;
267
266
  private getEligibleAgents;
268
267
  /**
@@ -342,7 +341,7 @@ declare class OwneySDK {
342
341
  getAgentAllocation(): Promise<OwneyAgentAllocation>;
343
342
  }
344
343
 
345
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_TOO_SMALL" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
344
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "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" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
346
345
  declare class OwneyError extends Error {
347
346
  readonly code: OwneyErrorCode;
348
347
  readonly details?: Record<string, unknown>;
@@ -366,4 +365,4 @@ declare class AgentChainIncompatibleError extends OwneyError {
366
365
  }>, connectedChainId: number);
367
366
  }
368
367
 
369
- export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyRouteResponse, OwneySDK, OwneySDKConfig, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
368
+ export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneySDK, OwneySDKConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
package/dist/index.js CHANGED
@@ -273,8 +273,13 @@ function mapApyByStrategy(raw) {
273
273
  }
274
274
 
275
275
  // src/agents/zyfai/zyfai.agent.ts
276
+ var DEFAULT_ZYFAI_RPC_URLS = {
277
+ 8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
278
+ 42161: "https://arb-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V"
279
+ };
276
280
  var ZyfaiAgent = class {
277
281
  id = "zyfai";
282
+ minDepositAmount = "0";
278
283
  supportedChainIds = [8453, 42161];
279
284
  supportedAssets = [
280
285
  {
@@ -294,7 +299,10 @@ var ZyfaiAgent = class {
294
299
  smartWalletCache = /* @__PURE__ */ new Map();
295
300
  connectAuthPromise = null;
296
301
  constructor(apiKey, rpcUrls) {
297
- this.sdk = new ZyfaiSDK({ apiKey, rpcUrls });
302
+ this.sdk = new ZyfaiSDK({
303
+ apiKey,
304
+ rpcUrls: rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS
305
+ });
298
306
  }
299
307
  // --- Private helpers ---
300
308
  getAddress() {
@@ -610,7 +618,7 @@ function mapHistory2(raw) {
610
618
  rewards: "Earned"
611
619
  };
612
620
  const filtered = raw.result.items.filter(
613
- (i) => i.status === "success" && i.transactions.length
621
+ (i) => !(i.type === "execution" && (i.status === "failed" || !i.transactions.length))
614
622
  );
615
623
  return {
616
624
  total: filtered.length,
@@ -677,6 +685,7 @@ var PAGE_ID = "home";
677
685
  var SAIL_PORTFOLIO_TIMEOUT_MS = 8e3;
678
686
  var SailAgent = class {
679
687
  id = "sail";
688
+ minDepositAmount = "4800000000";
680
689
  supportedChainIds = [8453, 42161];
681
690
  supportedAssets = [
682
691
  {
@@ -1342,7 +1351,7 @@ var OwneySDK = class {
1342
1351
  }
1343
1352
  /**
1344
1353
  * Deposit funds into a specific agent, or split equally across all agents if agentId is omitted.
1345
- * Validates that the asset is supported by the target agent(s) on the active chain.
1354
+ * Validates that the asset is supported and amount meets minimums for the target agent(s).
1346
1355
  * @param options - Deposit parameters
1347
1356
  * @param options.amount - Amount to deposit in smallest unit (e.g. "100000000" for 100 USDC)
1348
1357
  * @param options.asset - Asset symbol to deposit (e.g. "USDC")
@@ -1354,28 +1363,29 @@ var OwneySDK = class {
1354
1363
  */
1355
1364
  async deposit(options) {
1356
1365
  const { amount, asset, depositCallback, agentId } = options;
1366
+ if (BigInt(amount) === 0n) {
1367
+ return { agentResults: {} };
1368
+ }
1357
1369
  const state = this.requireState();
1358
1370
  const chainId = this.requireChainId();
1359
1371
  if (agentId) {
1360
1372
  const agent = this.getAgent(agentId);
1361
1373
  this.validateAssetSupport(agent, chainId, asset);
1374
+ this.validateMinDepositAmount(agent, amount);
1362
1375
  return agent.deposit(state, chainId, amount, depositCallback);
1363
1376
  }
1364
- const eligibleAgents = this.getEligibleAgents(chainId, asset);
1365
1377
  const totalAmount = BigInt(amount);
1366
- if (totalAmount < BigInt(eligibleAgents.length)) {
1378
+ const eligibleAgents = this.getEligibleAgents(chainId, asset);
1379
+ const agentAmounts = this.splitDepositAmount(totalAmount, eligibleAgents);
1380
+ if (agentAmounts.length === 0) {
1367
1381
  throw new OwneyError(
1368
- "DEPOSIT_AMOUNT_TOO_SMALL",
1369
- `Amount "${amount}" is too small to split across ${eligibleAgents.length} agents.`,
1370
- { amount, agentCount: eligibleAgents.length }
1382
+ "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1383
+ `Amount "${amount}" cannot satisfy minimum deposit requirements for any eligible agent.`,
1384
+ { amount }
1371
1385
  );
1372
1386
  }
1373
- const perAgent = totalAmount / BigInt(eligibleAgents.length);
1374
- const remainder = totalAmount % BigInt(eligibleAgents.length);
1375
1387
  const agentResults = {};
1376
- for (let i = 0; i < eligibleAgents.length; i++) {
1377
- const agent = eligibleAgents[i];
1378
- const agentAmount = i === eligibleAgents.length - 1 ? String(perAgent + remainder) : String(perAgent);
1388
+ for (const { agent, amount: agentAmount } of agentAmounts) {
1379
1389
  agentResults[agent.id] = await agent.deposit(
1380
1390
  state,
1381
1391
  chainId,
@@ -1385,6 +1395,37 @@ var OwneySDK = class {
1385
1395
  }
1386
1396
  return { agentResults };
1387
1397
  }
1398
+ splitDepositAmount(totalAmount, agents) {
1399
+ if (agents.length === 0)
1400
+ return [];
1401
+ const perAgent = totalAmount / BigInt(agents.length);
1402
+ const remainder = totalAmount % BigInt(agents.length);
1403
+ const splits = agents.map((agent, i) => ({
1404
+ agent,
1405
+ amount: i === agents.length - 1 ? perAgent + remainder : perAgent
1406
+ }));
1407
+ const valid = splits.filter(
1408
+ (s) => s.amount >= BigInt(s.agent.minDepositAmount)
1409
+ );
1410
+ if (valid.length === agents.length) {
1411
+ return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
1412
+ }
1413
+ return this.splitDepositAmount(totalAmount, valid.map((s) => s.agent));
1414
+ }
1415
+ validateMinDepositAmount(agent, amount) {
1416
+ const minDepositAmount = BigInt(agent.minDepositAmount);
1417
+ const parsedAmount = BigInt(amount);
1418
+ if (parsedAmount < minDepositAmount) {
1419
+ throw new OwneyError(
1420
+ "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1421
+ `Amount "${amount}" is below the required minimum deposit for agent "${agent.id}".`,
1422
+ {
1423
+ agentId: agent.id,
1424
+ amount
1425
+ }
1426
+ );
1427
+ }
1428
+ }
1388
1429
  validateAssetSupport(agent, chainId, asset) {
1389
1430
  const chainAssets = agent.supportedAssets.find(
1390
1431
  (sa) => sa.chainId === chainId
@@ -1567,18 +1608,30 @@ var OwneySDK = class {
1567
1608
  results[id] = apy;
1568
1609
  }
1569
1610
  const balances = {};
1570
- let totalBalance = 0;
1571
1611
  for (const [id, bal] of balanceResults) {
1572
1612
  balances[id] = bal;
1573
- totalBalance += bal;
1574
1613
  }
1575
1614
  let totalApy = 0;
1576
- if (totalBalance > 0) {
1615
+ let relevantBalance = 0;
1616
+ for (const id of Object.keys(results)) {
1617
+ const agentApy = Number(results[id].weightedApyAfterFee ?? 0);
1618
+ if (agentApy === 0)
1619
+ continue;
1620
+ relevantBalance += balances[id];
1621
+ }
1622
+ if (relevantBalance > 0) {
1577
1623
  for (const id of Object.keys(results)) {
1578
- const weight = balances[id] / totalBalance;
1579
- totalApy += Number(results[id].weightedApyAfterFee ?? 0) * weight;
1624
+ const agentApy = Number(results[id].weightedApyAfterFee ?? 0);
1625
+ if (agentApy === 0)
1626
+ continue;
1627
+ const weight = balances[id] / relevantBalance;
1628
+ totalApy += agentApy * weight;
1580
1629
  }
1581
1630
  }
1631
+ console.log("account apy", {
1632
+ totalApy: String(totalApy),
1633
+ agentApy: results
1634
+ });
1582
1635
  return {
1583
1636
  totalApy: String(totalApy),
1584
1637
  agentApy: results
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -26,5 +26,8 @@
26
26
  "dotenv": "^17.3.1",
27
27
  "tsup": "^7.0.0",
28
28
  "typescript": "^5.0.0"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
29
32
  }
30
33
  }