@owney/sdk 0.5.2 → 0.5.3

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.cjs CHANGED
@@ -157,6 +157,18 @@ var CHAIN_ID_TO_NAME = {
157
157
  8453: "BASE",
158
158
  42161: "ARBITRUM"
159
159
  };
160
+ var NAME_TO_CHAIN_ID = Object.entries(
161
+ CHAIN_ID_TO_NAME
162
+ ).reduce((acc, [id, name]) => {
163
+ acc[name.toLowerCase()] = Number(id);
164
+ return acc;
165
+ }, {});
166
+ function resolveChainId(chain) {
167
+ const asNum = Number(chain);
168
+ if (Number.isFinite(asNum) && asNum > 0)
169
+ return asNum;
170
+ return NAME_TO_CHAIN_ID[chain.trim().toLowerCase()] ?? NaN;
171
+ }
160
172
  function mapBalances(raw, _chainId, smartWallet) {
161
173
  const portfolio = raw.portfolio;
162
174
  const portfolioByChain = portfolio.portfolioByChain ?? {};
@@ -340,6 +352,46 @@ function mapApyByStrategy(raw) {
340
352
  detailedApys: hasDetails ? { apyPerAsset } : void 0
341
353
  };
342
354
  }
355
+ function computeAllocationApy(positions) {
356
+ let weightedSum = 0;
357
+ let totalValue = 0;
358
+ const buckets = {};
359
+ for (const p of positions) {
360
+ const apy = p.apy;
361
+ const value = Number(p.amount);
362
+ if (typeof apy !== "number" || !Number.isFinite(value) || value <= 0) {
363
+ continue;
364
+ }
365
+ weightedSum += apy * value;
366
+ totalValue += value;
367
+ const chainId = resolveChainId(p.chain);
368
+ const token = p.asset;
369
+ if (!SUPPORTED_CHAIN_IDS.includes(chainId))
370
+ continue;
371
+ if (!SUPPORTED_TOKENS.includes(token))
372
+ continue;
373
+ const perAsset = buckets[chainId] ?? {};
374
+ const cell = perAsset[token] ?? { weightedSum: 0, value: 0 };
375
+ cell.weightedSum += apy * value;
376
+ cell.value += value;
377
+ perAsset[token] = cell;
378
+ buckets[chainId] = perAsset;
379
+ }
380
+ const apyByChainAndAsset = {};
381
+ for (const [chainKey, perAsset] of Object.entries(buckets)) {
382
+ const chainId = Number(chainKey);
383
+ const out = {};
384
+ for (const [token, cell] of Object.entries(perAsset ?? {})) {
385
+ if (cell && cell.value > 0) {
386
+ out[token] = cell.weightedSum / cell.value;
387
+ }
388
+ }
389
+ if (Object.keys(out).length > 0)
390
+ apyByChainAndAsset[chainId] = out;
391
+ }
392
+ const totalApy = totalValue > 0 ? String(weightedSum / totalValue) : "0";
393
+ return { totalApy, apyByChainAndAsset };
394
+ }
343
395
 
344
396
  // src/agents/zyfai/zyfai.history-cursor.ts
345
397
  var InvalidHistoryCursorError = class extends Error {
@@ -1082,7 +1134,10 @@ var SPONSORED_USDC_BY_CHAIN = {
1082
1134
  8453: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
1083
1135
  42161: "0xaf88d065e77c8cc2239327c5edb3a432268e5831"
1084
1136
  };
1085
- var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum };
1137
+ var VIEM_CHAIN = {
1138
+ 8453: import_chains.base,
1139
+ 42161: import_chains.arbitrum
1140
+ };
1086
1141
  var OwneySDK = class {
1087
1142
  agents = /* @__PURE__ */ new Map();
1088
1143
  activeAgents = /* @__PURE__ */ new Set();
@@ -1602,10 +1657,7 @@ var OwneySDK = class {
1602
1657
  disabledBalances,
1603
1658
  requested
1604
1659
  );
1605
- const enabledTotal = enabledBalances.reduce(
1606
- (s, b) => s + b.balance,
1607
- 0n
1608
- );
1660
+ const enabledTotal = enabledBalances.reduce((s, b) => s + b.balance, 0n);
1609
1661
  const enabledPlans = afterDrain > 0n ? planProportionalShares(enabledBalances, afterDrain, enabledTotal) : enabledBalances.map(({ agent, balance }) => ({
1610
1662
  agent,
1611
1663
  balance,
@@ -2005,6 +2057,62 @@ var OwneySDK = class {
2005
2057
  agentPositions: positionsByAgent
2006
2058
  };
2007
2059
  }
2060
+ /**
2061
+ * Allocation-weighted APY from the current portfolio: each pool's APY
2062
+ * weighted by the user's position value in it. More accurate per-user than
2063
+ * the historical 30D APY. (ROUT-228)
2064
+ * @param options.agentId - Optional. Scope to one agent. Omit to aggregate
2065
+ * positions across all active agents.
2066
+ */
2067
+ async getAllocationApy({
2068
+ agentId
2069
+ } = {}) {
2070
+ const state = this.requireState();
2071
+ const chainId = this.requireChainId();
2072
+ const activeAgents = agentId ? /* @__PURE__ */ new Map([[agentId, this.getAgent(agentId)]]) : this.getActiveAgents();
2073
+ const entries = [...activeAgents.entries()];
2074
+ const balanceResults = await Promise.allSettled(
2075
+ entries.map(async ([id, agent]) => {
2076
+ const b = await agent.getBalances(state, chainId);
2077
+ return [id, b.positions ?? []];
2078
+ })
2079
+ );
2080
+ const agentApy = {};
2081
+ const allPositions = [];
2082
+ let successCount = 0;
2083
+ const agentErrors = {};
2084
+ for (let i = 0; i < balanceResults.length; i++) {
2085
+ const settled = balanceResults[i];
2086
+ const [aid] = entries[i];
2087
+ if (settled.status === "fulfilled") {
2088
+ const [id, positions] = settled.value;
2089
+ const per = computeAllocationApy(positions);
2090
+ agentApy[id] = {
2091
+ totalApy: per.totalApy,
2092
+ apyByChainAndAsset: per.apyByChainAndAsset
2093
+ };
2094
+ allPositions.push(...positions);
2095
+ successCount += 1;
2096
+ } else {
2097
+ const reason = settled.reason;
2098
+ agentErrors[aid] = reason instanceof Error ? reason.message : String(reason);
2099
+ console.error(`getAllocationApy agent "${aid}" failed:`, reason);
2100
+ }
2101
+ }
2102
+ if (successCount === 0) {
2103
+ throw new OwneyError(
2104
+ "ALLOCATION_ALL_FAILED",
2105
+ "Failed to fetch allocation APY: all agents failed.",
2106
+ { agentErrors }
2107
+ );
2108
+ }
2109
+ const overall = computeAllocationApy(allPositions);
2110
+ return {
2111
+ totalApy: overall.totalApy,
2112
+ apyByChainAndAsset: overall.apyByChainAndAsset,
2113
+ agentApy
2114
+ };
2115
+ }
2008
2116
  };
2009
2117
 
2010
2118
  // src/agents/zyfai/zyfai.siwx.ts
package/dist/index.d.cts CHANGED
@@ -93,6 +93,17 @@ interface OwneyAccountApy {
93
93
  agentApy: Record<AgentId, AccountAgentApy>;
94
94
  apyByChainAndAsset: ApyByChainAndAsset;
95
95
  }
96
+ interface AllocationAgentApy {
97
+ /** Account-wide weighted APY for this agent, as a decimal string. */
98
+ totalApy: string;
99
+ apyByChainAndAsset: ApyByChainAndAsset;
100
+ }
101
+ interface OwneyAllocationApy {
102
+ /** Account-wide weighted APY across all active agents, as a decimal string. */
103
+ totalApy: string;
104
+ apyByChainAndAsset: ApyByChainAndAsset;
105
+ agentApy: Record<AgentId, AllocationAgentApy>;
106
+ }
96
107
  type HistoryAction = "Rebalance" | "Deposit" | "Top up" | "Withdraw" | "Earned";
97
108
  interface HistoryTransaction {
98
109
  txHashes: string[];
@@ -399,6 +410,16 @@ declare class OwneySDK {
399
410
  * @returns Object with agent names as keys and allocation percentages as values
400
411
  */
401
412
  getAgentAllocation(): Promise<OwneyAgentAllocation>;
413
+ /**
414
+ * Allocation-weighted APY from the current portfolio: each pool's APY
415
+ * weighted by the user's position value in it. More accurate per-user than
416
+ * the historical 30D APY. (ROUT-228)
417
+ * @param options.agentId - Optional. Scope to one agent. Omit to aggregate
418
+ * positions across all active agents.
419
+ */
420
+ getAllocationApy({ agentId, }?: {
421
+ agentId?: AgentId;
422
+ }): Promise<OwneyAllocationApy>;
402
423
  }
403
424
 
404
425
  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" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
@@ -444,4 +465,4 @@ type OwneySIWXConfig = {
444
465
  */
445
466
  declare function createOwneySIWX(config: OwneySIWXConfig): SIWXConfig;
446
467
 
447
- export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentHistoryPosition, AgentId, AgentNotFoundError, AgentSupportedAsset, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, ApyByChainAndAsset, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, InvalidHistoryCursorError, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyPosition, OwneySDK, OwneySDKConfig, OwneySIWXConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions, createOwneySIWX };
468
+ export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentHistoryPosition, AgentId, AgentNotFoundError, AgentSupportedAsset, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, AllocationAgentApy, ApyByChainAndAsset, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, InvalidHistoryCursorError, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAllocationApy, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyPosition, OwneySDK, OwneySDKConfig, OwneySIWXConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions, createOwneySIWX };
package/dist/index.d.ts CHANGED
@@ -93,6 +93,17 @@ interface OwneyAccountApy {
93
93
  agentApy: Record<AgentId, AccountAgentApy>;
94
94
  apyByChainAndAsset: ApyByChainAndAsset;
95
95
  }
96
+ interface AllocationAgentApy {
97
+ /** Account-wide weighted APY for this agent, as a decimal string. */
98
+ totalApy: string;
99
+ apyByChainAndAsset: ApyByChainAndAsset;
100
+ }
101
+ interface OwneyAllocationApy {
102
+ /** Account-wide weighted APY across all active agents, as a decimal string. */
103
+ totalApy: string;
104
+ apyByChainAndAsset: ApyByChainAndAsset;
105
+ agentApy: Record<AgentId, AllocationAgentApy>;
106
+ }
96
107
  type HistoryAction = "Rebalance" | "Deposit" | "Top up" | "Withdraw" | "Earned";
97
108
  interface HistoryTransaction {
98
109
  txHashes: string[];
@@ -399,6 +410,16 @@ declare class OwneySDK {
399
410
  * @returns Object with agent names as keys and allocation percentages as values
400
411
  */
401
412
  getAgentAllocation(): Promise<OwneyAgentAllocation>;
413
+ /**
414
+ * Allocation-weighted APY from the current portfolio: each pool's APY
415
+ * weighted by the user's position value in it. More accurate per-user than
416
+ * the historical 30D APY. (ROUT-228)
417
+ * @param options.agentId - Optional. Scope to one agent. Omit to aggregate
418
+ * positions across all active agents.
419
+ */
420
+ getAllocationApy({ agentId, }?: {
421
+ agentId?: AgentId;
422
+ }): Promise<OwneyAllocationApy>;
402
423
  }
403
424
 
404
425
  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" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
@@ -444,4 +465,4 @@ type OwneySIWXConfig = {
444
465
  */
445
466
  declare function createOwneySIWX(config: OwneySIWXConfig): SIWXConfig;
446
467
 
447
- export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentHistoryPosition, AgentId, AgentNotFoundError, AgentSupportedAsset, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, ApyByChainAndAsset, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, InvalidHistoryCursorError, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyPosition, OwneySDK, OwneySDKConfig, OwneySIWXConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions, createOwneySIWX };
468
+ export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentHistoryPosition, AgentId, AgentNotFoundError, AgentSupportedAsset, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, AllocationAgentApy, ApyByChainAndAsset, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, InvalidHistoryCursorError, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAllocationApy, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyPosition, OwneySDK, OwneySDKConfig, OwneySIWXConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions, createOwneySIWX };
package/dist/index.js CHANGED
@@ -125,6 +125,18 @@ var CHAIN_ID_TO_NAME = {
125
125
  8453: "BASE",
126
126
  42161: "ARBITRUM"
127
127
  };
128
+ var NAME_TO_CHAIN_ID = Object.entries(
129
+ CHAIN_ID_TO_NAME
130
+ ).reduce((acc, [id, name]) => {
131
+ acc[name.toLowerCase()] = Number(id);
132
+ return acc;
133
+ }, {});
134
+ function resolveChainId(chain) {
135
+ const asNum = Number(chain);
136
+ if (Number.isFinite(asNum) && asNum > 0)
137
+ return asNum;
138
+ return NAME_TO_CHAIN_ID[chain.trim().toLowerCase()] ?? NaN;
139
+ }
128
140
  function mapBalances(raw, _chainId, smartWallet) {
129
141
  const portfolio = raw.portfolio;
130
142
  const portfolioByChain = portfolio.portfolioByChain ?? {};
@@ -308,6 +320,46 @@ function mapApyByStrategy(raw) {
308
320
  detailedApys: hasDetails ? { apyPerAsset } : void 0
309
321
  };
310
322
  }
323
+ function computeAllocationApy(positions) {
324
+ let weightedSum = 0;
325
+ let totalValue = 0;
326
+ const buckets = {};
327
+ for (const p of positions) {
328
+ const apy = p.apy;
329
+ const value = Number(p.amount);
330
+ if (typeof apy !== "number" || !Number.isFinite(value) || value <= 0) {
331
+ continue;
332
+ }
333
+ weightedSum += apy * value;
334
+ totalValue += value;
335
+ const chainId = resolveChainId(p.chain);
336
+ const token = p.asset;
337
+ if (!SUPPORTED_CHAIN_IDS.includes(chainId))
338
+ continue;
339
+ if (!SUPPORTED_TOKENS.includes(token))
340
+ continue;
341
+ const perAsset = buckets[chainId] ?? {};
342
+ const cell = perAsset[token] ?? { weightedSum: 0, value: 0 };
343
+ cell.weightedSum += apy * value;
344
+ cell.value += value;
345
+ perAsset[token] = cell;
346
+ buckets[chainId] = perAsset;
347
+ }
348
+ const apyByChainAndAsset = {};
349
+ for (const [chainKey, perAsset] of Object.entries(buckets)) {
350
+ const chainId = Number(chainKey);
351
+ const out = {};
352
+ for (const [token, cell] of Object.entries(perAsset ?? {})) {
353
+ if (cell && cell.value > 0) {
354
+ out[token] = cell.weightedSum / cell.value;
355
+ }
356
+ }
357
+ if (Object.keys(out).length > 0)
358
+ apyByChainAndAsset[chainId] = out;
359
+ }
360
+ const totalApy = totalValue > 0 ? String(weightedSum / totalValue) : "0";
361
+ return { totalApy, apyByChainAndAsset };
362
+ }
311
363
 
312
364
  // src/agents/zyfai/zyfai.history-cursor.ts
313
365
  var InvalidHistoryCursorError = class extends Error {
@@ -1054,7 +1106,10 @@ var SPONSORED_USDC_BY_CHAIN = {
1054
1106
  8453: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
1055
1107
  42161: "0xaf88d065e77c8cc2239327c5edb3a432268e5831"
1056
1108
  };
1057
- var VIEM_CHAIN = { 8453: base, 42161: arbitrum };
1109
+ var VIEM_CHAIN = {
1110
+ 8453: base,
1111
+ 42161: arbitrum
1112
+ };
1058
1113
  var OwneySDK = class {
1059
1114
  agents = /* @__PURE__ */ new Map();
1060
1115
  activeAgents = /* @__PURE__ */ new Set();
@@ -1574,10 +1629,7 @@ var OwneySDK = class {
1574
1629
  disabledBalances,
1575
1630
  requested
1576
1631
  );
1577
- const enabledTotal = enabledBalances.reduce(
1578
- (s, b) => s + b.balance,
1579
- 0n
1580
- );
1632
+ const enabledTotal = enabledBalances.reduce((s, b) => s + b.balance, 0n);
1581
1633
  const enabledPlans = afterDrain > 0n ? planProportionalShares(enabledBalances, afterDrain, enabledTotal) : enabledBalances.map(({ agent, balance }) => ({
1582
1634
  agent,
1583
1635
  balance,
@@ -1977,6 +2029,62 @@ var OwneySDK = class {
1977
2029
  agentPositions: positionsByAgent
1978
2030
  };
1979
2031
  }
2032
+ /**
2033
+ * Allocation-weighted APY from the current portfolio: each pool's APY
2034
+ * weighted by the user's position value in it. More accurate per-user than
2035
+ * the historical 30D APY. (ROUT-228)
2036
+ * @param options.agentId - Optional. Scope to one agent. Omit to aggregate
2037
+ * positions across all active agents.
2038
+ */
2039
+ async getAllocationApy({
2040
+ agentId
2041
+ } = {}) {
2042
+ const state = this.requireState();
2043
+ const chainId = this.requireChainId();
2044
+ const activeAgents = agentId ? /* @__PURE__ */ new Map([[agentId, this.getAgent(agentId)]]) : this.getActiveAgents();
2045
+ const entries = [...activeAgents.entries()];
2046
+ const balanceResults = await Promise.allSettled(
2047
+ entries.map(async ([id, agent]) => {
2048
+ const b = await agent.getBalances(state, chainId);
2049
+ return [id, b.positions ?? []];
2050
+ })
2051
+ );
2052
+ const agentApy = {};
2053
+ const allPositions = [];
2054
+ let successCount = 0;
2055
+ const agentErrors = {};
2056
+ for (let i = 0; i < balanceResults.length; i++) {
2057
+ const settled = balanceResults[i];
2058
+ const [aid] = entries[i];
2059
+ if (settled.status === "fulfilled") {
2060
+ const [id, positions] = settled.value;
2061
+ const per = computeAllocationApy(positions);
2062
+ agentApy[id] = {
2063
+ totalApy: per.totalApy,
2064
+ apyByChainAndAsset: per.apyByChainAndAsset
2065
+ };
2066
+ allPositions.push(...positions);
2067
+ successCount += 1;
2068
+ } else {
2069
+ const reason = settled.reason;
2070
+ agentErrors[aid] = reason instanceof Error ? reason.message : String(reason);
2071
+ console.error(`getAllocationApy agent "${aid}" failed:`, reason);
2072
+ }
2073
+ }
2074
+ if (successCount === 0) {
2075
+ throw new OwneyError(
2076
+ "ALLOCATION_ALL_FAILED",
2077
+ "Failed to fetch allocation APY: all agents failed.",
2078
+ { agentErrors }
2079
+ );
2080
+ }
2081
+ const overall = computeAllocationApy(allPositions);
2082
+ return {
2083
+ totalApy: overall.totalApy,
2084
+ apyByChainAndAsset: overall.apyByChainAndAsset,
2085
+ agentApy
2086
+ };
2087
+ }
1980
2088
  };
1981
2089
 
1982
2090
  // src/agents/zyfai/zyfai.siwx.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",