@owney/sdk 0.6.9-beta.7 → 0.6.9-beta.8

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
@@ -334,27 +334,20 @@ var init_surfliquid_wallet_adapter = __esm({
334
334
  });
335
335
 
336
336
  // src/agents/surfliquid/surfliquid.morpho.ts
337
- async function fetchMorphoVaultStats(vaultAddress, chainId) {
337
+ async function queryMorpho(query, vaultAddress, chainId) {
338
338
  try {
339
339
  const res = await fetch(MORPHO_API_URL, {
340
340
  method: "POST",
341
341
  headers: { "Content-Type": "application/json" },
342
342
  body: JSON.stringify({
343
- query: VAULT_STATS_QUERY,
343
+ query,
344
344
  variables: { address: vaultAddress, chainId }
345
345
  })
346
346
  });
347
347
  if (!res.ok) return null;
348
348
  const json = await res.json();
349
349
  if (json.errors) return null;
350
- const vault = json.data?.vaultByAddress;
351
- const tvlUsd = vault?.state?.totalAssetsUsd;
352
- const liquidityUsd = vault?.liquidity?.usd;
353
- if (typeof tvlUsd !== "number" || typeof liquidityUsd !== "number") {
354
- return null;
355
- }
356
- const name = typeof vault?.name === "string" ? vault.name : null;
357
- return { name, tvlUsd, liquidityUsd };
350
+ return json.data ?? null;
358
351
  } catch (error) {
359
352
  console.warn("surfliquid: Morpho vault stats fetch failed", {
360
353
  vaultAddress,
@@ -364,6 +357,29 @@ async function fetchMorphoVaultStats(vaultAddress, chainId) {
364
357
  return null;
365
358
  }
366
359
  }
360
+ function toStats(name, tvlUsd, liquidityUsd) {
361
+ if (typeof tvlUsd !== "number" || typeof liquidityUsd !== "number") {
362
+ return null;
363
+ }
364
+ return {
365
+ name: typeof name === "string" ? name : null,
366
+ tvlUsd,
367
+ liquidityUsd
368
+ };
369
+ }
370
+ async function fetchMorphoVaultStats(vaultAddress, chainId) {
371
+ const v1 = await queryMorpho(VAULT_STATS_QUERY, vaultAddress, chainId);
372
+ const vault = v1?.vaultByAddress;
373
+ const v1Stats = toStats(
374
+ vault?.name,
375
+ vault?.state?.totalAssetsUsd,
376
+ vault?.liquidity?.usd
377
+ );
378
+ if (v1Stats) return v1Stats;
379
+ const v2 = await queryMorpho(VAULT_V2_STATS_QUERY, vaultAddress, chainId);
380
+ const vaultV2 = v2?.vaultV2ByAddress;
381
+ return toStats(vaultV2?.name, vaultV2?.totalAssetsUsd, vaultV2?.liquidityUsd);
382
+ }
367
383
  async function fetchMorphoStatsByVault(vaultAddresses, chainId) {
368
384
  const unique = [...new Set(vaultAddresses.map((a) => a.toLowerCase()))];
369
385
  const entries = await Promise.all(
@@ -377,7 +393,7 @@ async function fetchMorphoStatsByVault(vaultAddresses, chainId) {
377
393
  }
378
394
  return byVault;
379
395
  }
380
- var MORPHO_API_URL, VAULT_STATS_QUERY;
396
+ var MORPHO_API_URL, VAULT_STATS_QUERY, VAULT_V2_STATS_QUERY;
381
397
  var init_surfliquid_morpho = __esm({
382
398
  "src/agents/surfliquid/surfliquid.morpho.ts"() {
383
399
  "use strict";
@@ -390,6 +406,15 @@ var init_surfliquid_morpho = __esm({
390
406
  liquidity { usd }
391
407
  }
392
408
  }
409
+ `;
410
+ VAULT_V2_STATS_QUERY = `
411
+ query VaultV2Stats($address: String!, $chainId: Int!) {
412
+ vaultV2ByAddress(address: $address, chainId: $chainId) {
413
+ name
414
+ totalAssetsUsd
415
+ liquidityUsd
416
+ }
417
+ }
393
418
  `;
394
419
  }
395
420
  });
@@ -723,6 +748,12 @@ var isValidChainId = (chainId) => {
723
748
  }
724
749
  return chainId;
725
750
  };
751
+ function isSameAsset(tokenSymbol, asset) {
752
+ const token = tokenSymbol.toLowerCase();
753
+ const target = asset.toLowerCase();
754
+ if (token === target) return true;
755
+ return target === "weth" && token === "eth" || target === "eth" && token === "weth";
756
+ }
726
757
  function hexToDecimal(hex, decimals = 6) {
727
758
  const normalized = hex.startsWith("0x") || hex.startsWith("0X") ? hex : `0x${hex}`;
728
759
  const parsed = BigInt(normalized);
@@ -1931,6 +1962,37 @@ var ZyfaiAgent = class {
1931
1962
  );
1932
1963
  }
1933
1964
  }
1965
+ /**
1966
+ * Records the deposit with Zyfai, retrying transient failures.
1967
+ *
1968
+ * This runs AFTER the transfer has already landed on-chain, so it must never
1969
+ * fail the deposit — the funds moved. But it is also the ONLY source of the
1970
+ * "Top up wallet" entry the history is built from: Zyfai auto-deploys the
1971
+ * balance it detects either way, so when this call is lost the user's deposit
1972
+ * never appears in Activity (an earlier withdrawal stays the newest row) and
1973
+ * nothing ever backfills it. Retry, then log loudly enough to be recoverable.
1974
+ */
1975
+ async logDepositWithRetry(chainId, txHash, amount, tokenAddress) {
1976
+ const ATTEMPTS = 3;
1977
+ const RETRY_DELAY_MS = 1e3;
1978
+ for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
1979
+ try {
1980
+ await (tokenAddress ? this.sdk.logDeposit(chainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(chainId, txHash, amount));
1981
+ return;
1982
+ } catch (logError) {
1983
+ if (attempt === ATTEMPTS) {
1984
+ console.error(
1985
+ "[owney-sdk] Deposit landed on-chain but logDeposit failed \u2014 it will be missing from Zyfai history:",
1986
+ { txHash, chainId, amount, tokenAddress, error: logError }
1987
+ );
1988
+ return;
1989
+ }
1990
+ await new Promise(
1991
+ (resolve) => setTimeout(resolve, RETRY_DELAY_MS * attempt)
1992
+ );
1993
+ }
1994
+ }
1995
+ }
1934
1996
  async deposit(state, chainId, amount, asset, depositCallback) {
1935
1997
  try {
1936
1998
  await this.connectFull(state, chainId);
@@ -1946,14 +2008,12 @@ var ZyfaiAgent = class {
1946
2008
  amount
1947
2009
  );
1948
2010
  const tokenAddress = asset === "WETH" ? WETH_ADDRESS_BY_CHAIN[validChainId] : void 0;
1949
- try {
1950
- await (tokenAddress ? this.sdk.logDeposit(validChainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(validChainId, txHash, amount));
1951
- } catch (logError) {
1952
- console.warn(
1953
- "[owney-sdk] Deposit landed on-chain but logDeposit failed (non-fatal):",
1954
- logError
1955
- );
1956
- }
2011
+ await this.logDepositWithRetry(
2012
+ validChainId,
2013
+ txHash,
2014
+ amount,
2015
+ tokenAddress
2016
+ );
1957
2017
  return { txHash, smartWallet: wallet.address, amount };
1958
2018
  }
1959
2019
  const raw = await this.sdk.depositFunds(
@@ -2197,11 +2257,10 @@ async function withFailureReporting(apiKey, agentType, fn) {
2197
2257
  // src/lib/helpers/withdraw-helper.ts
2198
2258
  var import_viem2 = require("viem");
2199
2259
  function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
2200
- const target = asset.toUpperCase();
2201
2260
  return agents.map((agent) => {
2202
2261
  const agentBalance = aggregated[agent.id];
2203
2262
  const tokenBalance = agentBalance?.tokens.find(
2204
- (t) => t.chainId === chainId && t.asset.toUpperCase() === target
2263
+ (t) => t.chainId === chainId && isSameAsset(t.asset, asset)
2205
2264
  );
2206
2265
  if (!tokenBalance) return { agent, balance: 0n };
2207
2266
  return { agent, balance: (0, import_viem2.parseUnits)(tokenBalance.amount, decimals) };
@@ -3235,9 +3294,8 @@ var OwneySDK = class {
3235
3294
  async hasExistingBalance(agent, state, chainId, asset) {
3236
3295
  try {
3237
3296
  const balance = await agent.getBalances(state, chainId);
3238
- const target = asset.toLowerCase();
3239
3297
  const token = balance.tokens.find(
3240
- (t) => t.chainId === chainId && t.asset.toLowerCase() === target
3298
+ (t) => t.chainId === chainId && isSameAsset(t.asset, asset)
3241
3299
  );
3242
3300
  return !!token && Number(token.amount) > 0;
3243
3301
  } catch {
package/dist/index.js CHANGED
@@ -81,6 +81,12 @@ var isValidChainId = (chainId) => {
81
81
  }
82
82
  return chainId;
83
83
  };
84
+ function isSameAsset(tokenSymbol, asset) {
85
+ const token = tokenSymbol.toLowerCase();
86
+ const target = asset.toLowerCase();
87
+ if (token === target) return true;
88
+ return target === "weth" && token === "eth" || target === "eth" && token === "weth";
89
+ }
84
90
  function hexToDecimal(hex, decimals = 6) {
85
91
  const normalized = hex.startsWith("0x") || hex.startsWith("0X") ? hex : `0x${hex}`;
86
92
  const parsed = BigInt(normalized);
@@ -1286,6 +1292,37 @@ var ZyfaiAgent = class {
1286
1292
  );
1287
1293
  }
1288
1294
  }
1295
+ /**
1296
+ * Records the deposit with Zyfai, retrying transient failures.
1297
+ *
1298
+ * This runs AFTER the transfer has already landed on-chain, so it must never
1299
+ * fail the deposit — the funds moved. But it is also the ONLY source of the
1300
+ * "Top up wallet" entry the history is built from: Zyfai auto-deploys the
1301
+ * balance it detects either way, so when this call is lost the user's deposit
1302
+ * never appears in Activity (an earlier withdrawal stays the newest row) and
1303
+ * nothing ever backfills it. Retry, then log loudly enough to be recoverable.
1304
+ */
1305
+ async logDepositWithRetry(chainId, txHash, amount, tokenAddress) {
1306
+ const ATTEMPTS = 3;
1307
+ const RETRY_DELAY_MS = 1e3;
1308
+ for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
1309
+ try {
1310
+ await (tokenAddress ? this.sdk.logDeposit(chainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(chainId, txHash, amount));
1311
+ return;
1312
+ } catch (logError) {
1313
+ if (attempt === ATTEMPTS) {
1314
+ console.error(
1315
+ "[owney-sdk] Deposit landed on-chain but logDeposit failed \u2014 it will be missing from Zyfai history:",
1316
+ { txHash, chainId, amount, tokenAddress, error: logError }
1317
+ );
1318
+ return;
1319
+ }
1320
+ await new Promise(
1321
+ (resolve) => setTimeout(resolve, RETRY_DELAY_MS * attempt)
1322
+ );
1323
+ }
1324
+ }
1325
+ }
1289
1326
  async deposit(state, chainId, amount, asset, depositCallback) {
1290
1327
  try {
1291
1328
  await this.connectFull(state, chainId);
@@ -1301,14 +1338,12 @@ var ZyfaiAgent = class {
1301
1338
  amount
1302
1339
  );
1303
1340
  const tokenAddress = asset === "WETH" ? WETH_ADDRESS_BY_CHAIN[validChainId] : void 0;
1304
- try {
1305
- await (tokenAddress ? this.sdk.logDeposit(validChainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(validChainId, txHash, amount));
1306
- } catch (logError) {
1307
- console.warn(
1308
- "[owney-sdk] Deposit landed on-chain but logDeposit failed (non-fatal):",
1309
- logError
1310
- );
1311
- }
1341
+ await this.logDepositWithRetry(
1342
+ validChainId,
1343
+ txHash,
1344
+ amount,
1345
+ tokenAddress
1346
+ );
1312
1347
  return { txHash, smartWallet: wallet.address, amount };
1313
1348
  }
1314
1349
  const raw = await this.sdk.depositFunds(
@@ -1547,11 +1582,10 @@ async function withFailureReporting(apiKey, agentType, fn) {
1547
1582
  // src/lib/helpers/withdraw-helper.ts
1548
1583
  import { parseUnits } from "viem";
1549
1584
  function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
1550
- const target = asset.toUpperCase();
1551
1585
  return agents.map((agent) => {
1552
1586
  const agentBalance = aggregated[agent.id];
1553
1587
  const tokenBalance = agentBalance?.tokens.find(
1554
- (t) => t.chainId === chainId && t.asset.toUpperCase() === target
1588
+ (t) => t.chainId === chainId && isSameAsset(t.asset, asset)
1555
1589
  );
1556
1590
  if (!tokenBalance) return { agent, balance: 0n };
1557
1591
  return { agent, balance: parseUnits(tokenBalance.amount, decimals) };
@@ -2278,7 +2312,7 @@ var OwneySDK = class {
2278
2312
  }
2279
2313
  if (agentId === "surfliquid") {
2280
2314
  if (!projectName) return null;
2281
- const { SurfLiquidAgent } = await import("./surfliquid.agent-JOJJ3C5Y.js");
2315
+ const { SurfLiquidAgent } = await import("./surfliquid.agent-VNGQUSXN.js");
2282
2316
  return new SurfLiquidAgent({
2283
2317
  projectName,
2284
2318
  appId: key2,
@@ -2581,9 +2615,8 @@ var OwneySDK = class {
2581
2615
  async hasExistingBalance(agent, state, chainId, asset) {
2582
2616
  try {
2583
2617
  const balance = await agent.getBalances(state, chainId);
2584
- const target = asset.toLowerCase();
2585
2618
  const token = balance.tokens.find(
2586
- (t) => t.chainId === chainId && t.asset.toLowerCase() === target
2619
+ (t) => t.chainId === chainId && isSameAsset(t.asset, asset)
2587
2620
  );
2588
2621
  return !!token && Number(token.amount) > 0;
2589
2622
  } catch {
@@ -174,27 +174,29 @@ var VAULT_STATS_QUERY = `
174
174
  }
175
175
  }
176
176
  `;
177
- async function fetchMorphoVaultStats(vaultAddress, chainId) {
177
+ var VAULT_V2_STATS_QUERY = `
178
+ query VaultV2Stats($address: String!, $chainId: Int!) {
179
+ vaultV2ByAddress(address: $address, chainId: $chainId) {
180
+ name
181
+ totalAssetsUsd
182
+ liquidityUsd
183
+ }
184
+ }
185
+ `;
186
+ async function queryMorpho(query, vaultAddress, chainId) {
178
187
  try {
179
188
  const res = await fetch(MORPHO_API_URL, {
180
189
  method: "POST",
181
190
  headers: { "Content-Type": "application/json" },
182
191
  body: JSON.stringify({
183
- query: VAULT_STATS_QUERY,
192
+ query,
184
193
  variables: { address: vaultAddress, chainId }
185
194
  })
186
195
  });
187
196
  if (!res.ok) return null;
188
197
  const json = await res.json();
189
198
  if (json.errors) return null;
190
- const vault = json.data?.vaultByAddress;
191
- const tvlUsd = vault?.state?.totalAssetsUsd;
192
- const liquidityUsd = vault?.liquidity?.usd;
193
- if (typeof tvlUsd !== "number" || typeof liquidityUsd !== "number") {
194
- return null;
195
- }
196
- const name = typeof vault?.name === "string" ? vault.name : null;
197
- return { name, tvlUsd, liquidityUsd };
199
+ return json.data ?? null;
198
200
  } catch (error) {
199
201
  console.warn("surfliquid: Morpho vault stats fetch failed", {
200
202
  vaultAddress,
@@ -204,6 +206,29 @@ async function fetchMorphoVaultStats(vaultAddress, chainId) {
204
206
  return null;
205
207
  }
206
208
  }
209
+ function toStats(name, tvlUsd, liquidityUsd) {
210
+ if (typeof tvlUsd !== "number" || typeof liquidityUsd !== "number") {
211
+ return null;
212
+ }
213
+ return {
214
+ name: typeof name === "string" ? name : null,
215
+ tvlUsd,
216
+ liquidityUsd
217
+ };
218
+ }
219
+ async function fetchMorphoVaultStats(vaultAddress, chainId) {
220
+ const v1 = await queryMorpho(VAULT_STATS_QUERY, vaultAddress, chainId);
221
+ const vault = v1?.vaultByAddress;
222
+ const v1Stats = toStats(
223
+ vault?.name,
224
+ vault?.state?.totalAssetsUsd,
225
+ vault?.liquidity?.usd
226
+ );
227
+ if (v1Stats) return v1Stats;
228
+ const v2 = await queryMorpho(VAULT_V2_STATS_QUERY, vaultAddress, chainId);
229
+ const vaultV2 = v2?.vaultV2ByAddress;
230
+ return toStats(vaultV2?.name, vaultV2?.totalAssetsUsd, vaultV2?.liquidityUsd);
231
+ }
207
232
  async function fetchMorphoStatsByVault(vaultAddresses, chainId) {
208
233
  const unique = [...new Set(vaultAddresses.map((a) => a.toLowerCase()))];
209
234
  const entries = await Promise.all(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.6.9-beta.7",
3
+ "version": "0.6.9-beta.8",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",