@owney/sdk 0.7.19 → 0.7.20

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
@@ -495,7 +495,7 @@ function rawPoolApyForChain(entry, chainId, tokenSymbol) {
495
495
  let totalBalance = 0;
496
496
  for (const p of entry.positions ?? []) {
497
497
  if (p.chainId !== chainId) continue;
498
- if (tokenSymbol && p.tokenSymbol !== tokenSymbol) continue;
498
+ if (tokenSymbol && p.tokenSymbol?.toUpperCase() !== tokenSymbol.toUpperCase()) continue;
499
499
  const balance = p.balance ?? 0;
500
500
  const apy = netApy(p.apy_withFee, p.apy, "apy_withFee");
501
501
  if (balance <= 0 || typeof apy !== "number") continue;
@@ -507,7 +507,18 @@ function rawPoolApyForChain(entry, chainId, tokenSymbol) {
507
507
  function mapApyHistory(raw, chainId, tokenSymbol) {
508
508
  const history = Object.entries(raw.history ?? {}).map(([date, entry]) => ({
509
509
  date,
510
- apy: rawPoolApyForChain(entry, chainId, tokenSymbol)
510
+ apy: rawPoolApyForChain(entry, chainId, tokenSymbol),
511
+ // Provider position balances are treated as decimal amounts of the
512
+ // selected token. Carry its unit dynamically for every asset; never
513
+ // attach a token unit to an unscoped mix of assets.
514
+ ...tokenSymbol ? {
515
+ historicalBalance: {
516
+ amount: (entry.positions ?? []).filter(
517
+ (p) => p.chainId === chainId && p.tokenSymbol?.toUpperCase() === tokenSymbol.toUpperCase() && Number.isFinite(p.balance) && p.balance > 0 && Number.isFinite(p.apy_withFee ?? p.apy)
518
+ ).reduce((sum, p) => sum + p.balance, 0),
519
+ unit: tokenSymbol.toUpperCase()
520
+ }
521
+ } : {}
511
522
  })).filter((p) => p.apy !== null).sort((a, b) => a.date.localeCompare(b.date));
512
523
  return {
513
524
  walletAddress: raw.walletAddress,
@@ -2237,24 +2248,31 @@ function balanceForApyScope(balance, chainId, tokenSymbol) {
2237
2248
  return Number.isFinite(amount) && amount > 0 ? total + amount : total;
2238
2249
  }, 0);
2239
2250
  }
2240
- function aggregateApyHistory(agentApys, agentBalances) {
2251
+ function aggregateApyHistory(agentApys) {
2241
2252
  const byDate = /* @__PURE__ */ new Map();
2242
- for (const [id, accountApy] of Object.entries(agentApys)) {
2243
- const balance = agentBalances[id] ?? 0;
2244
- if (!Number.isFinite(balance) || balance <= 0) continue;
2253
+ for (const accountApy of Object.values(agentApys)) {
2254
+ const seen = /* @__PURE__ */ new Set();
2245
2255
  for (const point of accountApy.history ?? []) {
2246
- const apy = Number(point.apy);
2247
- if (!point.date || !Number.isFinite(apy)) continue;
2248
- const current = byDate.get(point.date) ?? { weightedSum: 0, weight: 0 };
2249
- current.weightedSum += apy * balance;
2250
- current.weight += balance;
2251
- byDate.set(point.date, current);
2252
- }
2253
- }
2254
- return [...byDate.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([date, value]) => ({
2255
- date,
2256
- apy: value.weightedSum / value.weight
2257
- }));
2256
+ if (!point.date || seen.has(point.date) || !Number.isFinite(point.apy)) continue;
2257
+ seen.add(point.date);
2258
+ const points = byDate.get(point.date) ?? [];
2259
+ points.push(point);
2260
+ byDate.set(point.date, points);
2261
+ }
2262
+ }
2263
+ return [...byDate.entries()].sort(([left], [right]) => left.localeCompare(right)).flatMap(([date, points]) => {
2264
+ if (points.length === 1 && !points[0].historicalBalance) {
2265
+ return [{ date, apy: points[0].apy }];
2266
+ }
2267
+ const unit = points[0].historicalBalance?.unit;
2268
+ if (!unit || points.some(
2269
+ ({ historicalBalance: balance }) => !balance || balance.unit !== unit || !Number.isFinite(balance.amount) || balance.amount < 0
2270
+ )) return [];
2271
+ const total = points.reduce((sum, p) => sum + p.historicalBalance.amount, 0);
2272
+ if (total <= 0 || !Number.isFinite(total)) return [];
2273
+ const apy = points.reduce((sum, p) => sum + p.apy * (p.historicalBalance.amount / total), 0);
2274
+ return Number.isFinite(apy) ? [{ date, apy }] : [];
2275
+ });
2258
2276
  }
2259
2277
  function aggregateApyByChainAndAsset(agentApys, agentBalances) {
2260
2278
  const sums = {};
@@ -3954,7 +3972,7 @@ var OwneySDK = class {
3954
3972
  }
3955
3973
  }
3956
3974
  const apyByChainAndAsset = aggregateApyByChainAndAsset(results, balances);
3957
- const history = aggregateApyHistory(results, balances);
3975
+ const history = aggregateApyHistory(results);
3958
3976
  return {
3959
3977
  totalApy: String(totalApy),
3960
3978
  agentApy: results,
package/dist/index.d.cts CHANGED
@@ -280,6 +280,11 @@ interface ApyHistoryPoint {
280
280
  date: string;
281
281
  /** Net (after-fee) weighted APY for that day, summed across tokens. */
282
282
  apy: number;
283
+ /** Balance on this date, in the explicitly named unit; never today's balance. */
284
+ historicalBalance?: {
285
+ amount: number;
286
+ unit: string;
287
+ };
283
288
  }
284
289
  interface AccountAgentApy {
285
290
  walletAddress: string;
@@ -296,7 +301,7 @@ interface OwneyAccountApy {
296
301
  totalApy: string;
297
302
  agentApy: Record<AgentId, AccountAgentApy>;
298
303
  apyByChainAndAsset: ApyByChainAndAsset;
299
- /** Daily APY weighted by current balances in the requested chain/asset scope. */
304
+ /** APY weighted by same-date balances in matching units, independent of current balances. */
300
305
  history?: ApyHistoryPoint[];
301
306
  }
302
307
  interface AllocationAgentApy {
package/dist/index.d.ts CHANGED
@@ -280,6 +280,11 @@ interface ApyHistoryPoint {
280
280
  date: string;
281
281
  /** Net (after-fee) weighted APY for that day, summed across tokens. */
282
282
  apy: number;
283
+ /** Balance on this date, in the explicitly named unit; never today's balance. */
284
+ historicalBalance?: {
285
+ amount: number;
286
+ unit: string;
287
+ };
283
288
  }
284
289
  interface AccountAgentApy {
285
290
  walletAddress: string;
@@ -296,7 +301,7 @@ interface OwneyAccountApy {
296
301
  totalApy: string;
297
302
  agentApy: Record<AgentId, AccountAgentApy>;
298
303
  apyByChainAndAsset: ApyByChainAndAsset;
299
- /** Daily APY weighted by current balances in the requested chain/asset scope. */
304
+ /** APY weighted by same-date balances in matching units, independent of current balances. */
300
305
  history?: ApyHistoryPoint[];
301
306
  }
302
307
  interface AllocationAgentApy {
package/dist/index.js CHANGED
@@ -462,7 +462,7 @@ function rawPoolApyForChain(entry, chainId, tokenSymbol) {
462
462
  let totalBalance = 0;
463
463
  for (const p of entry.positions ?? []) {
464
464
  if (p.chainId !== chainId) continue;
465
- if (tokenSymbol && p.tokenSymbol !== tokenSymbol) continue;
465
+ if (tokenSymbol && p.tokenSymbol?.toUpperCase() !== tokenSymbol.toUpperCase()) continue;
466
466
  const balance = p.balance ?? 0;
467
467
  const apy = netApy(p.apy_withFee, p.apy, "apy_withFee");
468
468
  if (balance <= 0 || typeof apy !== "number") continue;
@@ -474,7 +474,18 @@ function rawPoolApyForChain(entry, chainId, tokenSymbol) {
474
474
  function mapApyHistory(raw, chainId, tokenSymbol) {
475
475
  const history = Object.entries(raw.history ?? {}).map(([date, entry]) => ({
476
476
  date,
477
- apy: rawPoolApyForChain(entry, chainId, tokenSymbol)
477
+ apy: rawPoolApyForChain(entry, chainId, tokenSymbol),
478
+ // Provider position balances are treated as decimal amounts of the
479
+ // selected token. Carry its unit dynamically for every asset; never
480
+ // attach a token unit to an unscoped mix of assets.
481
+ ...tokenSymbol ? {
482
+ historicalBalance: {
483
+ amount: (entry.positions ?? []).filter(
484
+ (p) => p.chainId === chainId && p.tokenSymbol?.toUpperCase() === tokenSymbol.toUpperCase() && Number.isFinite(p.balance) && p.balance > 0 && Number.isFinite(p.apy_withFee ?? p.apy)
485
+ ).reduce((sum, p) => sum + p.balance, 0),
486
+ unit: tokenSymbol.toUpperCase()
487
+ }
488
+ } : {}
478
489
  })).filter((p) => p.apy !== null).sort((a, b) => a.date.localeCompare(b.date));
479
490
  return {
480
491
  walletAddress: raw.walletAddress,
@@ -2204,24 +2215,31 @@ function balanceForApyScope(balance, chainId, tokenSymbol) {
2204
2215
  return Number.isFinite(amount) && amount > 0 ? total + amount : total;
2205
2216
  }, 0);
2206
2217
  }
2207
- function aggregateApyHistory(agentApys, agentBalances) {
2218
+ function aggregateApyHistory(agentApys) {
2208
2219
  const byDate = /* @__PURE__ */ new Map();
2209
- for (const [id, accountApy] of Object.entries(agentApys)) {
2210
- const balance = agentBalances[id] ?? 0;
2211
- if (!Number.isFinite(balance) || balance <= 0) continue;
2220
+ for (const accountApy of Object.values(agentApys)) {
2221
+ const seen = /* @__PURE__ */ new Set();
2212
2222
  for (const point of accountApy.history ?? []) {
2213
- const apy = Number(point.apy);
2214
- if (!point.date || !Number.isFinite(apy)) continue;
2215
- const current = byDate.get(point.date) ?? { weightedSum: 0, weight: 0 };
2216
- current.weightedSum += apy * balance;
2217
- current.weight += balance;
2218
- byDate.set(point.date, current);
2219
- }
2220
- }
2221
- return [...byDate.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([date, value]) => ({
2222
- date,
2223
- apy: value.weightedSum / value.weight
2224
- }));
2223
+ if (!point.date || seen.has(point.date) || !Number.isFinite(point.apy)) continue;
2224
+ seen.add(point.date);
2225
+ const points = byDate.get(point.date) ?? [];
2226
+ points.push(point);
2227
+ byDate.set(point.date, points);
2228
+ }
2229
+ }
2230
+ return [...byDate.entries()].sort(([left], [right]) => left.localeCompare(right)).flatMap(([date, points]) => {
2231
+ if (points.length === 1 && !points[0].historicalBalance) {
2232
+ return [{ date, apy: points[0].apy }];
2233
+ }
2234
+ const unit = points[0].historicalBalance?.unit;
2235
+ if (!unit || points.some(
2236
+ ({ historicalBalance: balance }) => !balance || balance.unit !== unit || !Number.isFinite(balance.amount) || balance.amount < 0
2237
+ )) return [];
2238
+ const total = points.reduce((sum, p) => sum + p.historicalBalance.amount, 0);
2239
+ if (total <= 0 || !Number.isFinite(total)) return [];
2240
+ const apy = points.reduce((sum, p) => sum + p.apy * (p.historicalBalance.amount / total), 0);
2241
+ return Number.isFinite(apy) ? [{ date, apy }] : [];
2242
+ });
2225
2243
  }
2226
2244
  function aggregateApyByChainAndAsset(agentApys, agentBalances) {
2227
2245
  const sums = {};
@@ -3925,7 +3943,7 @@ var OwneySDK = class {
3925
3943
  }
3926
3944
  }
3927
3945
  const apyByChainAndAsset = aggregateApyByChainAndAsset(results, balances);
3928
- const history = aggregateApyHistory(results, balances);
3946
+ const history = aggregateApyHistory(results);
3929
3947
  return {
3930
3948
  totalApy: String(totalApy),
3931
3949
  agentApy: results,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.7.19",
3
+ "version": "0.7.20",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",