@owney/sdk 0.2.13 → 0.2.15

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
@@ -125,7 +125,7 @@ await sdk.activateAgent(42161);
125
125
 
126
126
  ### `deposit(options)`
127
127
 
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.
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 per-agent minimum deposit amounts (defined per chain+asset on `agent.supportedAssets[].assets[].minDepositAmount`) 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.
129
129
 
130
130
  | Param | Type | Description |
131
131
  | ------------------------- | -------------------- | --------------------------------------------------------------- |
@@ -167,13 +167,18 @@ console.log(results.agentResults.sail.amount); // "50000000"
167
167
 
168
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.
169
169
 
170
- When `agentId` is omitted with a partial `amount`, the SDK splits the requested amount proportionally across eligible agents based on each agent's per-asset balance. If an agent's withdraw fails, its share is redistributed to remaining not-yet-attempted agents (capped by their headroom). Throws:
170
+ When `agentId` is omitted with a partial `amount`, the SDK splits the requested amount proportionally across eligible agents based on each agent's per-asset balance. If an agent's withdraw fails, its share is redistributed to remaining not-yet-attempted agents (capped by their headroom).
171
+
172
+ Full withdrawals (no `amount`) iterate every eligible agent and continue on per-agent failures — successful agents still return their results. Per-agent failures (e.g. backend returns `success: false`) surface as `WITHDRAW_FAILED` from the agent and are caught at the aggregation layer.
173
+
174
+ Throws:
171
175
 
172
176
  - `WITHDRAW_INSUFFICIENT_BALANCE` — total available across agents is less than `amount`.
173
- - `WITHDRAW_ALL_FAILED` — every agent's withdraw call failed.
174
- - `WITHDRAW_PARTIAL_FAILURE` — some agents succeeded but total withdrawn is less than `amount`. Successful txs are surfaced via `error.details.partialResults`; per-agent failure messages via `error.details.agentErrors`.
177
+ - `WITHDRAW_ALL_FAILED` — every agent's withdraw call failed (full or partial). Carries per-agent failure messages via `error.details.agentErrors` (a `Record<agentId, string>`).
178
+ - `WITHDRAW_PARTIAL_FAILURE` — partial withdrawals only: some agents succeeded but total withdrawn is less than `amount`. Successful txs surfaced via `error.details.partialResults`; per-agent failures via `error.details.agentErrors`.
179
+ - `WITHDRAW_FAILED` — a single agent's underlying withdraw call returned an unsuccessful response. Includes `error.agentId` and the backend message in `error.details.response`.
175
180
 
176
- `WITHDRAW_ALL_FAILED` also carries per-agent failure messages via `error.details.agentErrors` (a `Record<agentId, string>`). Any error originating from a specific agent also has `error.agentId` set and a `[agent:<id>]` prefix on `error.message`.
181
+ Any error originating from a specific agent also has `error.agentId` set and a `[<code>][agent:<id>]` prefix on `error.message`.
177
182
 
178
183
  | Param | Type | Description |
179
184
  | ----------------- | -------------------- | --------------------------------------------- |
@@ -441,10 +446,16 @@ type OwneySupportedChainId = 8453 | 42161;
441
446
  type OwneySupportedChains = "BASE" | "ARBITRUM";
442
447
  type OwneySupportedTokens = "USDC" | "USDT";
443
448
 
449
+ type AgentSupportedAsset = {
450
+ readonly symbol: string;
451
+ /** Minimum deposit in the asset's smallest unit (e.g. wei, "0" for none). */
452
+ readonly minDepositAmount: string;
453
+ };
454
+
444
455
  type AgentSupportedAssets = {
445
456
  readonly chainId: number;
446
457
  readonly chain?: string;
447
- readonly assets: readonly string[];
458
+ readonly assets: readonly AgentSupportedAsset[];
448
459
  };
449
460
 
450
461
  interface OwneySDKConfig {
@@ -646,7 +657,7 @@ type DepositCallback = (
646
657
 
647
658
  ### Error Handling
648
659
 
649
- All errors thrown by the SDK are instances of `OwneyError` (which extends `Error`), each carrying a stable `code` string, optional `details` object, and optional `agentId` identifying the originating agent. When `agentId` is set, `error.message` is also prefixed with `[agent:<id>]` for logs.
660
+ All errors thrown by the SDK are instances of `OwneyError` (which extends `Error`), each carrying a stable `code` string, optional `details` object, and optional `agentId` identifying the originating agent. `error.message` is always prefixed with `[<code>]` (and `[<code>][agent:<id>]` when agent-scoped) so the code is visible in browser console logs without inspecting the error object.
650
661
 
651
662
  ```typescript
652
663
  import { OwneyError } from "@owney/sdk";
@@ -690,7 +701,7 @@ type OwneyErrorCode =
690
701
  | "ASSET_UNSUPPORTED" // Agent doesn't support the asset on the active chain
691
702
  | "ASSET_NO_COMPATIBLE_AGENTS" // No agents support the asset on the active chain
692
703
  // Deposit
693
- | "DEPOSIT_AMOUNT_BELOW_MINIMUM" // Amount below an agent's required minimum deposit
704
+ | "DEPOSIT_AMOUNT_BELOW_MINIMUM" // Amount below an agent's required minimum deposit for the chain+asset
694
705
  | "DEPOSIT_CALLBACK_REQUIRED" // Sail agent requires a depositCallback
695
706
  | "DEPOSIT_CALLBACK_INVALID" // depositCallback didn't return a tx hash
696
707
  | "DEPOSIT_NO_PERMITTED_TOKENS" // No permitted tokens available for deposit
@@ -699,6 +710,7 @@ type OwneyErrorCode =
699
710
  | "WITHDRAW_INSUFFICIENT_BALANCE" // Requested amount exceeds total available across agents
700
711
  | "WITHDRAW_ALL_FAILED" // Every eligible agent's withdraw call failed
701
712
  | "WITHDRAW_PARTIAL_FAILURE" // Some agents succeeded; total withdrawn < requested
713
+ | "WITHDRAW_FAILED" // Agent backend returned an unsuccessful withdraw response
702
714
  // API
703
715
  | "API_ROUTING_ERROR" // Routing API returned a non-OK HTTP status
704
716
  | "API_ROUTING_FAILED" // Routing API returned { success: false }
package/dist/index.cjs CHANGED
@@ -65,7 +65,8 @@ var OwneyError = class extends Error {
65
65
  details;
66
66
  agentId;
67
67
  constructor(code, message, details, agentId) {
68
- super(agentId ? `[agent:${agentId}] ${message}` : message);
68
+ const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
69
+ super(`${prefix} ${message}`);
69
70
  this.name = "OwneyError";
70
71
  this.code = code;
71
72
  this.details = details;
@@ -316,18 +317,17 @@ var DEFAULT_ZYFAI_RPC_URLS = {
316
317
  };
317
318
  var ZyfaiAgent = class {
318
319
  id = "zyfai";
319
- minDepositAmount = "0";
320
320
  supportedChainIds = [8453, 42161];
321
321
  supportedAssets = [
322
322
  {
323
323
  chainId: 8453,
324
324
  chain: "BASE",
325
- assets: ["USDC"]
325
+ assets: [{ symbol: "USDC", minDepositAmount: "1500000" }]
326
326
  },
327
327
  {
328
328
  chainId: 42161,
329
329
  chain: "ARBITRUM",
330
- assets: ["USDC"]
330
+ assets: [{ symbol: "USDC", minDepositAmount: "1500000" }]
331
331
  }
332
332
  ];
333
333
  sdk;
@@ -463,6 +463,14 @@ var ZyfaiAgent = class {
463
463
  amount,
464
464
  token
465
465
  );
466
+ if (!raw.success) {
467
+ throw new OwneyError(
468
+ "WITHDRAW_FAILED",
469
+ raw.message || "Zyfai withdraw failed.",
470
+ { chainId: validChainId, token, amount, response: raw },
471
+ this.id
472
+ );
473
+ }
466
474
  return mapWithdraw(raw);
467
475
  }
468
476
  // --- IAgent: Portfolio reads ---
@@ -499,7 +507,11 @@ var ZyfaiAgent = class {
499
507
  }
500
508
  async getUserProfile(state, chainId) {
501
509
  await this.connectAuth(state, chainId);
510
+ const validChainId = isValidChainId(chainId);
502
511
  const raw = await this.sdk.getUserDetails();
512
+ if (!raw.hasActiveSessionKey) {
513
+ await this.sdk.createSessionKey(this.getAddress(), validChainId);
514
+ }
503
515
  return mapUserProfile(raw, this.connectedAddress);
504
516
  }
505
517
  // --- IAgent: Discovery (no wallet required) ---
@@ -813,12 +825,17 @@ var OwneySDK = class {
813
825
  if (agentId) {
814
826
  const agent = this.getAgent(agentId);
815
827
  this.validateAssetSupport(agent, chainId, asset);
816
- this.validateMinDepositAmount(agent, amount);
828
+ this.validateMinDepositAmount(agent, chainId, asset, amount);
817
829
  return agent.deposit(state, chainId, amount, depositCallback);
818
830
  }
819
831
  const totalAmount = BigInt(amount);
820
832
  const eligibleAgents = this.getEligibleAgents(chainId, asset);
821
- const agentAmounts = this.splitDepositAmount(totalAmount, eligibleAgents);
833
+ const agentAmounts = this.splitDepositAmount(
834
+ totalAmount,
835
+ eligibleAgents,
836
+ chainId,
837
+ asset
838
+ );
822
839
  if (agentAmounts.length === 0) {
823
840
  throw new OwneyError(
824
841
  "DEPOSIT_AMOUNT_BELOW_MINIMUM",
@@ -837,7 +854,14 @@ var OwneySDK = class {
837
854
  }
838
855
  return { agentResults };
839
856
  }
840
- splitDepositAmount(totalAmount, agents) {
857
+ getMinDepositAmount(agent, chainId, asset) {
858
+ const chainAssets = agent.supportedAssets.find(
859
+ (sa) => sa.chainId === chainId
860
+ );
861
+ const assetEntry = chainAssets?.assets.find((a) => a.symbol === asset);
862
+ return BigInt(assetEntry?.minDepositAmount ?? "0");
863
+ }
864
+ splitDepositAmount(totalAmount, agents, chainId, asset) {
841
865
  if (agents.length === 0)
842
866
  return [];
843
867
  const perAgent = totalAmount / BigInt(agents.length);
@@ -847,26 +871,31 @@ var OwneySDK = class {
847
871
  amount: i === agents.length - 1 ? perAgent + remainder : perAgent
848
872
  }));
849
873
  const valid = splits.filter(
850
- (s) => s.amount >= BigInt(s.agent.minDepositAmount)
874
+ (s) => s.amount >= this.getMinDepositAmount(s.agent, chainId, asset)
851
875
  );
852
876
  if (valid.length === agents.length) {
853
877
  return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
854
878
  }
855
879
  return this.splitDepositAmount(
856
880
  totalAmount,
857
- valid.map((s) => s.agent)
881
+ valid.map((s) => s.agent),
882
+ chainId,
883
+ asset
858
884
  );
859
885
  }
860
- validateMinDepositAmount(agent, amount) {
861
- const minDepositAmount = BigInt(agent.minDepositAmount);
886
+ validateMinDepositAmount(agent, chainId, asset, amount) {
887
+ const minDepositAmount = this.getMinDepositAmount(agent, chainId, asset);
862
888
  const parsedAmount = BigInt(amount);
863
889
  if (parsedAmount < minDepositAmount) {
864
890
  throw new OwneyError(
865
891
  "DEPOSIT_AMOUNT_BELOW_MINIMUM",
866
- `Amount "${amount}" is below the required minimum deposit for agent "${agent.id}".`,
892
+ `Amount "${amount}" is below the required minimum deposit "${minDepositAmount.toString()}" for agent "${agent.id}" on chain ${chainId} for asset "${asset}".`,
867
893
  {
868
894
  agentId: agent.id,
869
- amount
895
+ chainId,
896
+ asset,
897
+ amount,
898
+ minDepositAmount: minDepositAmount.toString()
870
899
  }
871
900
  );
872
901
  }
@@ -875,7 +904,7 @@ var OwneySDK = class {
875
904
  const chainAssets = agent.supportedAssets.find(
876
905
  (sa) => sa.chainId === chainId
877
906
  );
878
- if (!chainAssets || !chainAssets.assets.includes(asset)) {
907
+ if (!chainAssets || !chainAssets.assets.some((a) => a.symbol === asset)) {
879
908
  throw new OwneyError(
880
909
  "ASSET_UNSUPPORTED",
881
910
  `Agent "${agent.id}" does not support asset "${asset}" on chain ${chainId}.`,
@@ -889,7 +918,7 @@ var OwneySDK = class {
889
918
  const chainAssets = agent.supportedAssets.find(
890
919
  (sa) => sa.chainId === chainId
891
920
  );
892
- return chainAssets && chainAssets.assets.includes(asset);
921
+ return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
893
922
  });
894
923
  if (eligible.length === 0) {
895
924
  throw new OwneyError(
@@ -932,8 +961,21 @@ var OwneySDK = class {
932
961
  const eligibleAgents = this.getEligibleAgents(chainId, asset);
933
962
  if (!amount) {
934
963
  const results2 = {};
964
+ const agentErrors2 = {};
935
965
  for (const agent of eligibleAgents) {
936
- results2[agent.id] = await agent.withdraw(state, chainId, token);
966
+ try {
967
+ results2[agent.id] = await agent.withdraw(state, chainId, token);
968
+ } catch (err) {
969
+ console.error(`withdraw failed for agent "${agent.id}":`, err);
970
+ agentErrors2[agent.id] = err instanceof Error ? err.message : String(err);
971
+ }
972
+ }
973
+ if (Object.keys(results2).length === 0) {
974
+ throw new OwneyError(
975
+ "WITHDRAW_ALL_FAILED",
976
+ `Failed to withdraw "${asset}" from all eligible agents.`,
977
+ { asset, agentErrors: agentErrors2 }
978
+ );
937
979
  }
938
980
  return { agentResult: results2 };
939
981
  }
@@ -942,7 +984,7 @@ var OwneySDK = class {
942
984
  const balances = eligibleAgents.map((agent) => {
943
985
  const agentBalance = aggregated.agentBalances[agent.id];
944
986
  const tokenBalance = agentBalance?.tokens.find(
945
- (t) => t.chainId === chainId && t.asset === asset
987
+ (t) => t.chainId === chainId && t.asset.toUpperCase() === asset.toUpperCase()
946
988
  );
947
989
  if (!tokenBalance)
948
990
  return { agent, balance: 0n };
package/dist/index.d.cts CHANGED
@@ -24,7 +24,6 @@ interface IAgent {
24
24
  readonly id: string;
25
25
  readonly supportedChainIds: readonly OwneySupportedChainId[];
26
26
  readonly supportedAssets: readonly AgentSupportedAssets[];
27
- readonly minDepositAmount: string;
28
27
  disconnect(): Promise<void>;
29
28
  activateAgent(state: ConnectionState, chainId: number): Promise<void>;
30
29
  deposit(state: ConnectionState, chainId: number, amount: string, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
@@ -51,10 +50,14 @@ type AgentApyOptions = {
51
50
 
52
51
  type AgentId = "zyfai";
53
52
  type Asset = string;
53
+ type AgentSupportedAsset = {
54
+ readonly symbol: string;
55
+ readonly minDepositAmount: string;
56
+ };
54
57
  type AgentSupportedAssets = {
55
58
  readonly chainId: number;
56
59
  readonly chain?: string;
57
- readonly assets: readonly string[];
60
+ readonly assets: readonly AgentSupportedAsset[];
58
61
  };
59
62
  type DailyApyDays = "7D" | "14D" | "30D";
60
63
  type HistoryFilters = {
@@ -261,6 +264,7 @@ declare class OwneySDK {
261
264
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
262
265
  */
263
266
  deposit(options: DepositOptions): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
267
+ private getMinDepositAmount;
264
268
  private splitDepositAmount;
265
269
  private validateMinDepositAmount;
266
270
  private validateAssetSupport;
@@ -342,7 +346,7 @@ declare class OwneySDK {
342
346
  getAgentAllocation(): Promise<OwneyAgentAllocation>;
343
347
  }
344
348
 
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_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" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
349
+ 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" | "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" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
346
350
  declare class OwneyError extends Error {
347
351
  readonly code: OwneyErrorCode;
348
352
  readonly details?: Record<string, unknown>;
@@ -367,4 +371,4 @@ declare class AgentChainIncompatibleError extends OwneyError {
367
371
  }>, connectedChainId: number);
368
372
  }
369
373
 
370
- 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 };
374
+ export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAsset, 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,7 +24,6 @@ interface IAgent {
24
24
  readonly id: string;
25
25
  readonly supportedChainIds: readonly OwneySupportedChainId[];
26
26
  readonly supportedAssets: readonly AgentSupportedAssets[];
27
- readonly minDepositAmount: string;
28
27
  disconnect(): Promise<void>;
29
28
  activateAgent(state: ConnectionState, chainId: number): Promise<void>;
30
29
  deposit(state: ConnectionState, chainId: number, amount: string, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
@@ -51,10 +50,14 @@ type AgentApyOptions = {
51
50
 
52
51
  type AgentId = "zyfai";
53
52
  type Asset = string;
53
+ type AgentSupportedAsset = {
54
+ readonly symbol: string;
55
+ readonly minDepositAmount: string;
56
+ };
54
57
  type AgentSupportedAssets = {
55
58
  readonly chainId: number;
56
59
  readonly chain?: string;
57
- readonly assets: readonly string[];
60
+ readonly assets: readonly AgentSupportedAsset[];
58
61
  };
59
62
  type DailyApyDays = "7D" | "14D" | "30D";
60
63
  type HistoryFilters = {
@@ -261,6 +264,7 @@ declare class OwneySDK {
261
264
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
262
265
  */
263
266
  deposit(options: DepositOptions): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
267
+ private getMinDepositAmount;
264
268
  private splitDepositAmount;
265
269
  private validateMinDepositAmount;
266
270
  private validateAssetSupport;
@@ -342,7 +346,7 @@ declare class OwneySDK {
342
346
  getAgentAllocation(): Promise<OwneyAgentAllocation>;
343
347
  }
344
348
 
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_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" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
349
+ 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" | "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" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
346
350
  declare class OwneyError extends Error {
347
351
  readonly code: OwneyErrorCode;
348
352
  readonly details?: Record<string, unknown>;
@@ -367,4 +371,4 @@ declare class AgentChainIncompatibleError extends OwneyError {
367
371
  }>, connectedChainId: number);
368
372
  }
369
373
 
370
- 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 };
374
+ export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAsset, 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
@@ -35,7 +35,8 @@ var OwneyError = class extends Error {
35
35
  details;
36
36
  agentId;
37
37
  constructor(code, message, details, agentId) {
38
- super(agentId ? `[agent:${agentId}] ${message}` : message);
38
+ const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
39
+ super(`${prefix} ${message}`);
39
40
  this.name = "OwneyError";
40
41
  this.code = code;
41
42
  this.details = details;
@@ -286,18 +287,17 @@ var DEFAULT_ZYFAI_RPC_URLS = {
286
287
  };
287
288
  var ZyfaiAgent = class {
288
289
  id = "zyfai";
289
- minDepositAmount = "0";
290
290
  supportedChainIds = [8453, 42161];
291
291
  supportedAssets = [
292
292
  {
293
293
  chainId: 8453,
294
294
  chain: "BASE",
295
- assets: ["USDC"]
295
+ assets: [{ symbol: "USDC", minDepositAmount: "1500000" }]
296
296
  },
297
297
  {
298
298
  chainId: 42161,
299
299
  chain: "ARBITRUM",
300
- assets: ["USDC"]
300
+ assets: [{ symbol: "USDC", minDepositAmount: "1500000" }]
301
301
  }
302
302
  ];
303
303
  sdk;
@@ -433,6 +433,14 @@ var ZyfaiAgent = class {
433
433
  amount,
434
434
  token
435
435
  );
436
+ if (!raw.success) {
437
+ throw new OwneyError(
438
+ "WITHDRAW_FAILED",
439
+ raw.message || "Zyfai withdraw failed.",
440
+ { chainId: validChainId, token, amount, response: raw },
441
+ this.id
442
+ );
443
+ }
436
444
  return mapWithdraw(raw);
437
445
  }
438
446
  // --- IAgent: Portfolio reads ---
@@ -469,7 +477,11 @@ var ZyfaiAgent = class {
469
477
  }
470
478
  async getUserProfile(state, chainId) {
471
479
  await this.connectAuth(state, chainId);
480
+ const validChainId = isValidChainId(chainId);
472
481
  const raw = await this.sdk.getUserDetails();
482
+ if (!raw.hasActiveSessionKey) {
483
+ await this.sdk.createSessionKey(this.getAddress(), validChainId);
484
+ }
473
485
  return mapUserProfile(raw, this.connectedAddress);
474
486
  }
475
487
  // --- IAgent: Discovery (no wallet required) ---
@@ -783,12 +795,17 @@ var OwneySDK = class {
783
795
  if (agentId) {
784
796
  const agent = this.getAgent(agentId);
785
797
  this.validateAssetSupport(agent, chainId, asset);
786
- this.validateMinDepositAmount(agent, amount);
798
+ this.validateMinDepositAmount(agent, chainId, asset, amount);
787
799
  return agent.deposit(state, chainId, amount, depositCallback);
788
800
  }
789
801
  const totalAmount = BigInt(amount);
790
802
  const eligibleAgents = this.getEligibleAgents(chainId, asset);
791
- const agentAmounts = this.splitDepositAmount(totalAmount, eligibleAgents);
803
+ const agentAmounts = this.splitDepositAmount(
804
+ totalAmount,
805
+ eligibleAgents,
806
+ chainId,
807
+ asset
808
+ );
792
809
  if (agentAmounts.length === 0) {
793
810
  throw new OwneyError(
794
811
  "DEPOSIT_AMOUNT_BELOW_MINIMUM",
@@ -807,7 +824,14 @@ var OwneySDK = class {
807
824
  }
808
825
  return { agentResults };
809
826
  }
810
- splitDepositAmount(totalAmount, agents) {
827
+ getMinDepositAmount(agent, chainId, asset) {
828
+ const chainAssets = agent.supportedAssets.find(
829
+ (sa) => sa.chainId === chainId
830
+ );
831
+ const assetEntry = chainAssets?.assets.find((a) => a.symbol === asset);
832
+ return BigInt(assetEntry?.minDepositAmount ?? "0");
833
+ }
834
+ splitDepositAmount(totalAmount, agents, chainId, asset) {
811
835
  if (agents.length === 0)
812
836
  return [];
813
837
  const perAgent = totalAmount / BigInt(agents.length);
@@ -817,26 +841,31 @@ var OwneySDK = class {
817
841
  amount: i === agents.length - 1 ? perAgent + remainder : perAgent
818
842
  }));
819
843
  const valid = splits.filter(
820
- (s) => s.amount >= BigInt(s.agent.minDepositAmount)
844
+ (s) => s.amount >= this.getMinDepositAmount(s.agent, chainId, asset)
821
845
  );
822
846
  if (valid.length === agents.length) {
823
847
  return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
824
848
  }
825
849
  return this.splitDepositAmount(
826
850
  totalAmount,
827
- valid.map((s) => s.agent)
851
+ valid.map((s) => s.agent),
852
+ chainId,
853
+ asset
828
854
  );
829
855
  }
830
- validateMinDepositAmount(agent, amount) {
831
- const minDepositAmount = BigInt(agent.minDepositAmount);
856
+ validateMinDepositAmount(agent, chainId, asset, amount) {
857
+ const minDepositAmount = this.getMinDepositAmount(agent, chainId, asset);
832
858
  const parsedAmount = BigInt(amount);
833
859
  if (parsedAmount < minDepositAmount) {
834
860
  throw new OwneyError(
835
861
  "DEPOSIT_AMOUNT_BELOW_MINIMUM",
836
- `Amount "${amount}" is below the required minimum deposit for agent "${agent.id}".`,
862
+ `Amount "${amount}" is below the required minimum deposit "${minDepositAmount.toString()}" for agent "${agent.id}" on chain ${chainId} for asset "${asset}".`,
837
863
  {
838
864
  agentId: agent.id,
839
- amount
865
+ chainId,
866
+ asset,
867
+ amount,
868
+ minDepositAmount: minDepositAmount.toString()
840
869
  }
841
870
  );
842
871
  }
@@ -845,7 +874,7 @@ var OwneySDK = class {
845
874
  const chainAssets = agent.supportedAssets.find(
846
875
  (sa) => sa.chainId === chainId
847
876
  );
848
- if (!chainAssets || !chainAssets.assets.includes(asset)) {
877
+ if (!chainAssets || !chainAssets.assets.some((a) => a.symbol === asset)) {
849
878
  throw new OwneyError(
850
879
  "ASSET_UNSUPPORTED",
851
880
  `Agent "${agent.id}" does not support asset "${asset}" on chain ${chainId}.`,
@@ -859,7 +888,7 @@ var OwneySDK = class {
859
888
  const chainAssets = agent.supportedAssets.find(
860
889
  (sa) => sa.chainId === chainId
861
890
  );
862
- return chainAssets && chainAssets.assets.includes(asset);
891
+ return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
863
892
  });
864
893
  if (eligible.length === 0) {
865
894
  throw new OwneyError(
@@ -902,8 +931,21 @@ var OwneySDK = class {
902
931
  const eligibleAgents = this.getEligibleAgents(chainId, asset);
903
932
  if (!amount) {
904
933
  const results2 = {};
934
+ const agentErrors2 = {};
905
935
  for (const agent of eligibleAgents) {
906
- results2[agent.id] = await agent.withdraw(state, chainId, token);
936
+ try {
937
+ results2[agent.id] = await agent.withdraw(state, chainId, token);
938
+ } catch (err) {
939
+ console.error(`withdraw failed for agent "${agent.id}":`, err);
940
+ agentErrors2[agent.id] = err instanceof Error ? err.message : String(err);
941
+ }
942
+ }
943
+ if (Object.keys(results2).length === 0) {
944
+ throw new OwneyError(
945
+ "WITHDRAW_ALL_FAILED",
946
+ `Failed to withdraw "${asset}" from all eligible agents.`,
947
+ { asset, agentErrors: agentErrors2 }
948
+ );
907
949
  }
908
950
  return { agentResult: results2 };
909
951
  }
@@ -912,7 +954,7 @@ var OwneySDK = class {
912
954
  const balances = eligibleAgents.map((agent) => {
913
955
  const agentBalance = aggregated.agentBalances[agent.id];
914
956
  const tokenBalance = agentBalance?.tokens.find(
915
- (t) => t.chainId === chainId && t.asset === asset
957
+ (t) => t.chainId === chainId && t.asset.toUpperCase() === asset.toUpperCase()
916
958
  );
917
959
  if (!tokenBalance)
918
960
  return { agent, balance: 0n };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.2.13",
3
+ "version": "0.2.15",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",