@owney/sdk 0.6.9-beta.7 → 0.6.9-beta.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/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
|
|
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
|
|
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
|
-
|
|
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);
|
|
@@ -748,6 +779,10 @@ var DECIMALS_BY_SYMBOL = {
|
|
|
748
779
|
wbtc: 8,
|
|
749
780
|
cbbtc: 8
|
|
750
781
|
};
|
|
782
|
+
function canonicalSymbol(symbol) {
|
|
783
|
+
const upper = symbol.toUpperCase();
|
|
784
|
+
return upper === "ETH" ? "WETH" : upper;
|
|
785
|
+
}
|
|
751
786
|
function tokenDecimals(symbol, explicit) {
|
|
752
787
|
if (typeof explicit === "number" && Number.isFinite(explicit))
|
|
753
788
|
return explicit;
|
|
@@ -790,7 +825,7 @@ function mapBalances(raw, _chainId, smartWallet) {
|
|
|
790
825
|
const detailByKey = /* @__PURE__ */ new Map();
|
|
791
826
|
for (const p of rawPositions) {
|
|
792
827
|
const cid = resolveChainId(p.chain ?? "");
|
|
793
|
-
const symbol = (p.token_symbol ?? "")
|
|
828
|
+
const symbol = canonicalSymbol(p.token_symbol ?? "");
|
|
794
829
|
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
795
830
|
}
|
|
796
831
|
let totalBalance = 0;
|
|
@@ -810,13 +845,17 @@ function mapBalances(raw, _chainId, smartWallet) {
|
|
|
810
845
|
asset: symbol,
|
|
811
846
|
amount: String(amount)
|
|
812
847
|
});
|
|
813
|
-
const detail = detailByKey.get(
|
|
848
|
+
const detail = detailByKey.get(
|
|
849
|
+
`${positionChainId}:${canonicalSymbol(symbol)}`
|
|
850
|
+
);
|
|
814
851
|
positions.push({
|
|
815
852
|
chain: chainName,
|
|
816
853
|
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
817
854
|
protocolId: detail?.protocol_id,
|
|
818
855
|
pool: detail?.pool,
|
|
819
|
-
|
|
856
|
+
// Report the token the way the rest of owney spells it ("WETH", as the
|
|
857
|
+
// pre-portfolioByChain mapper did), not Zyfai's internal "eth".
|
|
858
|
+
asset: canonicalSymbol(symbol),
|
|
820
859
|
amount: String(amount),
|
|
821
860
|
apy: detail?.pool_apy,
|
|
822
861
|
tvl: detail?.pool_tvl,
|
|
@@ -1931,6 +1970,37 @@ var ZyfaiAgent = class {
|
|
|
1931
1970
|
);
|
|
1932
1971
|
}
|
|
1933
1972
|
}
|
|
1973
|
+
/**
|
|
1974
|
+
* Records the deposit with Zyfai, retrying transient failures.
|
|
1975
|
+
*
|
|
1976
|
+
* This runs AFTER the transfer has already landed on-chain, so it must never
|
|
1977
|
+
* fail the deposit — the funds moved. But it is also the ONLY source of the
|
|
1978
|
+
* "Top up wallet" entry the history is built from: Zyfai auto-deploys the
|
|
1979
|
+
* balance it detects either way, so when this call is lost the user's deposit
|
|
1980
|
+
* never appears in Activity (an earlier withdrawal stays the newest row) and
|
|
1981
|
+
* nothing ever backfills it. Retry, then log loudly enough to be recoverable.
|
|
1982
|
+
*/
|
|
1983
|
+
async logDepositWithRetry(chainId, txHash, amount, tokenAddress) {
|
|
1984
|
+
const ATTEMPTS = 3;
|
|
1985
|
+
const RETRY_DELAY_MS = 1e3;
|
|
1986
|
+
for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
|
|
1987
|
+
try {
|
|
1988
|
+
await (tokenAddress ? this.sdk.logDeposit(chainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(chainId, txHash, amount));
|
|
1989
|
+
return;
|
|
1990
|
+
} catch (logError) {
|
|
1991
|
+
if (attempt === ATTEMPTS) {
|
|
1992
|
+
console.error(
|
|
1993
|
+
"[owney-sdk] Deposit landed on-chain but logDeposit failed \u2014 it will be missing from Zyfai history:",
|
|
1994
|
+
{ txHash, chainId, amount, tokenAddress, error: logError }
|
|
1995
|
+
);
|
|
1996
|
+
return;
|
|
1997
|
+
}
|
|
1998
|
+
await new Promise(
|
|
1999
|
+
(resolve) => setTimeout(resolve, RETRY_DELAY_MS * attempt)
|
|
2000
|
+
);
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
1934
2004
|
async deposit(state, chainId, amount, asset, depositCallback) {
|
|
1935
2005
|
try {
|
|
1936
2006
|
await this.connectFull(state, chainId);
|
|
@@ -1946,14 +2016,12 @@ var ZyfaiAgent = class {
|
|
|
1946
2016
|
amount
|
|
1947
2017
|
);
|
|
1948
2018
|
const tokenAddress = asset === "WETH" ? WETH_ADDRESS_BY_CHAIN[validChainId] : void 0;
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
);
|
|
1956
|
-
}
|
|
2019
|
+
await this.logDepositWithRetry(
|
|
2020
|
+
validChainId,
|
|
2021
|
+
txHash,
|
|
2022
|
+
amount,
|
|
2023
|
+
tokenAddress
|
|
2024
|
+
);
|
|
1957
2025
|
return { txHash, smartWallet: wallet.address, amount };
|
|
1958
2026
|
}
|
|
1959
2027
|
const raw = await this.sdk.depositFunds(
|
|
@@ -2197,11 +2265,10 @@ async function withFailureReporting(apiKey, agentType, fn) {
|
|
|
2197
2265
|
// src/lib/helpers/withdraw-helper.ts
|
|
2198
2266
|
var import_viem2 = require("viem");
|
|
2199
2267
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
2200
|
-
const target = asset.toUpperCase();
|
|
2201
2268
|
return agents.map((agent) => {
|
|
2202
2269
|
const agentBalance = aggregated[agent.id];
|
|
2203
2270
|
const tokenBalance = agentBalance?.tokens.find(
|
|
2204
|
-
(t) => t.chainId === chainId && t.asset
|
|
2271
|
+
(t) => t.chainId === chainId && isSameAsset(t.asset, asset)
|
|
2205
2272
|
);
|
|
2206
2273
|
if (!tokenBalance) return { agent, balance: 0n };
|
|
2207
2274
|
return { agent, balance: (0, import_viem2.parseUnits)(tokenBalance.amount, decimals) };
|
|
@@ -3235,9 +3302,8 @@ var OwneySDK = class {
|
|
|
3235
3302
|
async hasExistingBalance(agent, state, chainId, asset) {
|
|
3236
3303
|
try {
|
|
3237
3304
|
const balance = await agent.getBalances(state, chainId);
|
|
3238
|
-
const target = asset.toLowerCase();
|
|
3239
3305
|
const token = balance.tokens.find(
|
|
3240
|
-
(t) => t.chainId === chainId && t.asset
|
|
3306
|
+
(t) => t.chainId === chainId && isSameAsset(t.asset, asset)
|
|
3241
3307
|
);
|
|
3242
3308
|
return !!token && Number(token.amount) > 0;
|
|
3243
3309
|
} 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);
|
|
@@ -106,6 +112,10 @@ var DECIMALS_BY_SYMBOL = {
|
|
|
106
112
|
wbtc: 8,
|
|
107
113
|
cbbtc: 8
|
|
108
114
|
};
|
|
115
|
+
function canonicalSymbol(symbol) {
|
|
116
|
+
const upper = symbol.toUpperCase();
|
|
117
|
+
return upper === "ETH" ? "WETH" : upper;
|
|
118
|
+
}
|
|
109
119
|
function tokenDecimals(symbol, explicit) {
|
|
110
120
|
if (typeof explicit === "number" && Number.isFinite(explicit))
|
|
111
121
|
return explicit;
|
|
@@ -148,7 +158,7 @@ function mapBalances(raw, _chainId, smartWallet) {
|
|
|
148
158
|
const detailByKey = /* @__PURE__ */ new Map();
|
|
149
159
|
for (const p of rawPositions) {
|
|
150
160
|
const cid = resolveChainId(p.chain ?? "");
|
|
151
|
-
const symbol = (p.token_symbol ?? "")
|
|
161
|
+
const symbol = canonicalSymbol(p.token_symbol ?? "");
|
|
152
162
|
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
153
163
|
}
|
|
154
164
|
let totalBalance = 0;
|
|
@@ -168,13 +178,17 @@ function mapBalances(raw, _chainId, smartWallet) {
|
|
|
168
178
|
asset: symbol,
|
|
169
179
|
amount: String(amount)
|
|
170
180
|
});
|
|
171
|
-
const detail = detailByKey.get(
|
|
181
|
+
const detail = detailByKey.get(
|
|
182
|
+
`${positionChainId}:${canonicalSymbol(symbol)}`
|
|
183
|
+
);
|
|
172
184
|
positions.push({
|
|
173
185
|
chain: chainName,
|
|
174
186
|
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
175
187
|
protocolId: detail?.protocol_id,
|
|
176
188
|
pool: detail?.pool,
|
|
177
|
-
|
|
189
|
+
// Report the token the way the rest of owney spells it ("WETH", as the
|
|
190
|
+
// pre-portfolioByChain mapper did), not Zyfai's internal "eth".
|
|
191
|
+
asset: canonicalSymbol(symbol),
|
|
178
192
|
amount: String(amount),
|
|
179
193
|
apy: detail?.pool_apy,
|
|
180
194
|
tvl: detail?.pool_tvl,
|
|
@@ -1286,6 +1300,37 @@ var ZyfaiAgent = class {
|
|
|
1286
1300
|
);
|
|
1287
1301
|
}
|
|
1288
1302
|
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Records the deposit with Zyfai, retrying transient failures.
|
|
1305
|
+
*
|
|
1306
|
+
* This runs AFTER the transfer has already landed on-chain, so it must never
|
|
1307
|
+
* fail the deposit — the funds moved. But it is also the ONLY source of the
|
|
1308
|
+
* "Top up wallet" entry the history is built from: Zyfai auto-deploys the
|
|
1309
|
+
* balance it detects either way, so when this call is lost the user's deposit
|
|
1310
|
+
* never appears in Activity (an earlier withdrawal stays the newest row) and
|
|
1311
|
+
* nothing ever backfills it. Retry, then log loudly enough to be recoverable.
|
|
1312
|
+
*/
|
|
1313
|
+
async logDepositWithRetry(chainId, txHash, amount, tokenAddress) {
|
|
1314
|
+
const ATTEMPTS = 3;
|
|
1315
|
+
const RETRY_DELAY_MS = 1e3;
|
|
1316
|
+
for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
|
|
1317
|
+
try {
|
|
1318
|
+
await (tokenAddress ? this.sdk.logDeposit(chainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(chainId, txHash, amount));
|
|
1319
|
+
return;
|
|
1320
|
+
} catch (logError) {
|
|
1321
|
+
if (attempt === ATTEMPTS) {
|
|
1322
|
+
console.error(
|
|
1323
|
+
"[owney-sdk] Deposit landed on-chain but logDeposit failed \u2014 it will be missing from Zyfai history:",
|
|
1324
|
+
{ txHash, chainId, amount, tokenAddress, error: logError }
|
|
1325
|
+
);
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
await new Promise(
|
|
1329
|
+
(resolve) => setTimeout(resolve, RETRY_DELAY_MS * attempt)
|
|
1330
|
+
);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1289
1334
|
async deposit(state, chainId, amount, asset, depositCallback) {
|
|
1290
1335
|
try {
|
|
1291
1336
|
await this.connectFull(state, chainId);
|
|
@@ -1301,14 +1346,12 @@ var ZyfaiAgent = class {
|
|
|
1301
1346
|
amount
|
|
1302
1347
|
);
|
|
1303
1348
|
const tokenAddress = asset === "WETH" ? WETH_ADDRESS_BY_CHAIN[validChainId] : void 0;
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
);
|
|
1311
|
-
}
|
|
1349
|
+
await this.logDepositWithRetry(
|
|
1350
|
+
validChainId,
|
|
1351
|
+
txHash,
|
|
1352
|
+
amount,
|
|
1353
|
+
tokenAddress
|
|
1354
|
+
);
|
|
1312
1355
|
return { txHash, smartWallet: wallet.address, amount };
|
|
1313
1356
|
}
|
|
1314
1357
|
const raw = await this.sdk.depositFunds(
|
|
@@ -1547,11 +1590,10 @@ async function withFailureReporting(apiKey, agentType, fn) {
|
|
|
1547
1590
|
// src/lib/helpers/withdraw-helper.ts
|
|
1548
1591
|
import { parseUnits } from "viem";
|
|
1549
1592
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
1550
|
-
const target = asset.toUpperCase();
|
|
1551
1593
|
return agents.map((agent) => {
|
|
1552
1594
|
const agentBalance = aggregated[agent.id];
|
|
1553
1595
|
const tokenBalance = agentBalance?.tokens.find(
|
|
1554
|
-
(t) => t.chainId === chainId && t.asset
|
|
1596
|
+
(t) => t.chainId === chainId && isSameAsset(t.asset, asset)
|
|
1555
1597
|
);
|
|
1556
1598
|
if (!tokenBalance) return { agent, balance: 0n };
|
|
1557
1599
|
return { agent, balance: parseUnits(tokenBalance.amount, decimals) };
|
|
@@ -2278,7 +2320,7 @@ var OwneySDK = class {
|
|
|
2278
2320
|
}
|
|
2279
2321
|
if (agentId === "surfliquid") {
|
|
2280
2322
|
if (!projectName) return null;
|
|
2281
|
-
const { SurfLiquidAgent } = await import("./surfliquid.agent-
|
|
2323
|
+
const { SurfLiquidAgent } = await import("./surfliquid.agent-VNGQUSXN.js");
|
|
2282
2324
|
return new SurfLiquidAgent({
|
|
2283
2325
|
projectName,
|
|
2284
2326
|
appId: key2,
|
|
@@ -2581,9 +2623,8 @@ var OwneySDK = class {
|
|
|
2581
2623
|
async hasExistingBalance(agent, state, chainId, asset) {
|
|
2582
2624
|
try {
|
|
2583
2625
|
const balance = await agent.getBalances(state, chainId);
|
|
2584
|
-
const target = asset.toLowerCase();
|
|
2585
2626
|
const token = balance.tokens.find(
|
|
2586
|
-
(t) => t.chainId === chainId && t.asset
|
|
2627
|
+
(t) => t.chainId === chainId && isSameAsset(t.asset, asset)
|
|
2587
2628
|
);
|
|
2588
2629
|
return !!token && Number(token.amount) > 0;
|
|
2589
2630
|
} catch {
|
|
@@ -174,27 +174,29 @@ var VAULT_STATS_QUERY = `
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
`;
|
|
177
|
-
|
|
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
|
|
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
|
-
|
|
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(
|