@1delta/margin-fetcher 0.0.283 → 0.0.285
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.js +423 -103
- package/dist/index.js.map +1 -1
- package/dist/lending/public-data/init/publicCallParse.d.ts.map +1 -1
- package/dist/lending/user-data/euler/eulerDataApi.d.ts +36 -0
- package/dist/lending/user-data/euler/eulerDataApi.d.ts.map +1 -0
- package/dist/lending/user-data/euler/userCallBuild.d.ts +6 -6
- package/dist/lending/user-data/euler/userCallBuild.d.ts.map +1 -1
- package/dist/lending/user-data/fetch-balances/e2e.d.ts +3 -1
- package/dist/lending/user-data/fetch-balances/e2e.d.ts.map +1 -1
- package/dist/utils/multicall.d.ts +15 -0
- package/dist/utils/multicall.d.ts.map +1 -1
- package/dist/vaults/euler-earn/fetchFromApi.d.ts +18 -0
- package/dist/vaults/euler-earn/fetchFromApi.d.ts.map +1 -0
- package/dist/vaults/euler-earn/fetchFromSubgraph.d.ts +2 -0
- package/dist/vaults/euler-earn/fetchFromSubgraph.d.ts.map +1 -1
- package/dist/vaults/euler-earn/fetchPublic.d.ts +10 -8
- package/dist/vaults/euler-earn/fetchPublic.d.ts.map +1 -1
- package/dist/vaults/euler-earn/index.d.ts +2 -1
- package/dist/vaults/euler-earn/index.d.ts.map +1 -1
- package/dist/vaults/savings/registry.d.ts.map +1 -1
- package/dist/yields/intrinsic/fetchers/hastra.d.ts +5 -0
- package/dist/yields/intrinsic/fetchers/hastra.d.ts.map +1 -0
- package/dist/yields/intrinsic/index.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -9021,6 +9021,7 @@ var INIT_POOL_NAME_OVERRIDES = {
|
|
|
9021
9021
|
"0x592c91ac727da556dc90ddf5630e1901efcd0c92": "Init FBTC Isolated"
|
|
9022
9022
|
};
|
|
9023
9023
|
var INIT_DEFAULT_LIQUIDATION_PENALTY = 0.05;
|
|
9024
|
+
var INIT_POOLS_FROZEN = true;
|
|
9024
9025
|
var INIT_EMODE_LABELS = {
|
|
9025
9026
|
[1]: "Default",
|
|
9026
9027
|
[2]: "Blue Chip Volatile",
|
|
@@ -9095,8 +9096,12 @@ var getInitReservesDataConverter = (lender, chainId, prices, additionalYields, t
|
|
|
9095
9096
|
rewards: [],
|
|
9096
9097
|
config: {},
|
|
9097
9098
|
closeFactor: 1,
|
|
9098
|
-
|
|
9099
|
-
|
|
9099
|
+
// Reserve still exists (positions must remain visible & withdrawable);
|
|
9100
|
+
// only new deposits/borrows are blocked → active but frozen.
|
|
9101
|
+
isActive: true,
|
|
9102
|
+
isFrozen: INIT_POOLS_FROZEN,
|
|
9103
|
+
borrowingEnabled: false ,
|
|
9104
|
+
depositsEnabled: !INIT_POOLS_FROZEN,
|
|
9100
9105
|
params
|
|
9101
9106
|
};
|
|
9102
9107
|
});
|
|
@@ -22004,68 +22009,100 @@ function createCompoundV2Entry(i, data, key, assetsIn, vToken, meta, claimableRe
|
|
|
22004
22009
|
};
|
|
22005
22010
|
}
|
|
22006
22011
|
|
|
22012
|
+
// src/lending/user-data/euler/eulerDataApi.ts
|
|
22013
|
+
var EULER_DATA_API_BASE = "https://v3.euler.finance/v3";
|
|
22014
|
+
var EULER_API_REQUEST_TIMEOUT_MS = 1e4;
|
|
22015
|
+
var EULER_API_CHAINS = /* @__PURE__ */ new Set([
|
|
22016
|
+
"1",
|
|
22017
|
+
// Ethereum
|
|
22018
|
+
"56",
|
|
22019
|
+
// BSC
|
|
22020
|
+
"130",
|
|
22021
|
+
// Unichain
|
|
22022
|
+
"146",
|
|
22023
|
+
// Sonic
|
|
22024
|
+
"239",
|
|
22025
|
+
// TAC
|
|
22026
|
+
"999",
|
|
22027
|
+
// HyperEVM
|
|
22028
|
+
"1923",
|
|
22029
|
+
// Swell
|
|
22030
|
+
"8453",
|
|
22031
|
+
// Base
|
|
22032
|
+
"9745",
|
|
22033
|
+
// Plasma
|
|
22034
|
+
"42161",
|
|
22035
|
+
// Arbitrum
|
|
22036
|
+
"43114",
|
|
22037
|
+
// Avalanche
|
|
22038
|
+
"60808",
|
|
22039
|
+
// BOB
|
|
22040
|
+
"80094"
|
|
22041
|
+
// Berachain
|
|
22042
|
+
]);
|
|
22043
|
+
var eulerApiSupportsChain = (chainId) => EULER_API_CHAINS.has(chainId);
|
|
22044
|
+
async function fetchEulerPositionsFromApi(chainId, owner, forceFresh = true) {
|
|
22045
|
+
if (!eulerApiSupportsChain(chainId)) return void 0;
|
|
22046
|
+
const controller = new AbortController();
|
|
22047
|
+
const timeout = setTimeout(
|
|
22048
|
+
() => controller.abort(),
|
|
22049
|
+
EULER_API_REQUEST_TIMEOUT_MS
|
|
22050
|
+
);
|
|
22051
|
+
try {
|
|
22052
|
+
const positions = [];
|
|
22053
|
+
const limit = 100;
|
|
22054
|
+
let offset = 0;
|
|
22055
|
+
for (let page = 0; page < 10; page++) {
|
|
22056
|
+
const url = `${EULER_DATA_API_BASE}/accounts/${owner.toLowerCase()}/positions?chainId=${chainId}&forceFresh=${forceFresh}&limit=${limit}&offset=${offset}`;
|
|
22057
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
22058
|
+
if (!response.ok) return offset === 0 ? void 0 : positions;
|
|
22059
|
+
const body = await response.json();
|
|
22060
|
+
const page_ = body?.data ?? [];
|
|
22061
|
+
positions.push(...page_);
|
|
22062
|
+
const total = body?.meta?.total;
|
|
22063
|
+
offset += limit;
|
|
22064
|
+
if (page_.length < limit || typeof total === "number" && offset >= total)
|
|
22065
|
+
break;
|
|
22066
|
+
}
|
|
22067
|
+
return positions;
|
|
22068
|
+
} catch {
|
|
22069
|
+
return void 0;
|
|
22070
|
+
} finally {
|
|
22071
|
+
clearTimeout(timeout);
|
|
22072
|
+
}
|
|
22073
|
+
}
|
|
22074
|
+
|
|
22007
22075
|
// src/lending/user-data/euler/userCallBuild.ts
|
|
22008
|
-
Array.from(
|
|
22076
|
+
var ALL_EULER_SUB_ACCOUNT_INDEXES = Array.from(
|
|
22009
22077
|
{ length: 256 },
|
|
22010
22078
|
(_3, i) => i
|
|
22011
22079
|
);
|
|
22012
|
-
var
|
|
22013
|
-
var
|
|
22014
|
-
|
|
22015
|
-
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
22019
|
-
|
|
22020
|
-
|
|
22021
|
-
|
|
22022
|
-
|
|
22023
|
-
"1923": `${EULER_SUBGRAPH_BASE}/euler-v2-swell/latest/gn`,
|
|
22024
|
-
"5000": `${EULER_SUBGRAPH_BASE}/euler-v2-mantle/latest/gn`,
|
|
22025
|
-
"8453": `${EULER_SUBGRAPH_BASE}/euler-v2-base/latest/gn`,
|
|
22026
|
-
"9745": `${EULER_SUBGRAPH_BASE}/euler-v2-plasma/latest/gn`,
|
|
22027
|
-
"42161": `${EULER_SUBGRAPH_BASE}/euler-v2-arbitrum/latest/gn`,
|
|
22028
|
-
"43114": `${EULER_SUBGRAPH_BASE}/euler-v2-avalanche/latest/gn`,
|
|
22029
|
-
"57073": `${EULER_SUBGRAPH_BASE}/euler-v2-ink/latest/gn`,
|
|
22030
|
-
"60808": `${EULER_SUBGRAPH_BASE}/euler-v2-bob/latest/gn`,
|
|
22031
|
-
"80094": `${EULER_SUBGRAPH_BASE}/euler-v2-berachain/latest/gn`
|
|
22032
|
-
};
|
|
22033
|
-
var SUBGRAPH_CACHE_TTL_MS = 3e4;
|
|
22034
|
-
var subgraphCache = /* @__PURE__ */ new Map();
|
|
22035
|
-
function fetchEulerSubAccountIndexes(chainId, owner) {
|
|
22080
|
+
var ACCOUNT_CACHE_TTL_MS = 5e3;
|
|
22081
|
+
var accountCache = /* @__PURE__ */ new Map();
|
|
22082
|
+
function indexesFromApiPositions(positions, owner) {
|
|
22083
|
+
const set = /* @__PURE__ */ new Set();
|
|
22084
|
+
for (const p of positions) {
|
|
22085
|
+
if (p.account) set.add(getSubAccountIndex(p.account, owner));
|
|
22086
|
+
}
|
|
22087
|
+
if (set.size === 0) set.add(0);
|
|
22088
|
+
return [...set];
|
|
22089
|
+
}
|
|
22090
|
+
function fetchEulerActiveIndexesViaApi(chainId, owner) {
|
|
22036
22091
|
const key = `${chainId}:${owner.toLowerCase()}`;
|
|
22037
|
-
const cached =
|
|
22092
|
+
const cached = accountCache.get(key);
|
|
22038
22093
|
if (cached) return cached.promise;
|
|
22039
|
-
const promise =
|
|
22040
|
-
|
|
22041
|
-
|
|
22042
|
-
|
|
22043
|
-
);
|
|
22044
|
-
subgraphCache.set(key, { promise, timer });
|
|
22094
|
+
const promise = fetchEulerPositionsFromApi(chainId, owner).then(
|
|
22095
|
+
(positions) => positions === void 0 ? void 0 : indexesFromApiPositions(positions, owner)
|
|
22096
|
+
).catch(() => void 0);
|
|
22097
|
+
const timer = setTimeout(() => accountCache.delete(key), ACCOUNT_CACHE_TTL_MS);
|
|
22098
|
+
accountCache.set(key, { promise, timer });
|
|
22045
22099
|
return promise;
|
|
22046
22100
|
}
|
|
22047
|
-
async function
|
|
22048
|
-
|
|
22049
|
-
|
|
22050
|
-
|
|
22051
|
-
|
|
22052
|
-
id
|
|
22053
|
-
subAccount
|
|
22054
|
-
}
|
|
22055
|
-
}`;
|
|
22056
|
-
const response = await fetch(url, {
|
|
22057
|
-
method: "POST",
|
|
22058
|
-
headers: { "Content-Type": "application/json" },
|
|
22059
|
-
body: JSON.stringify({ query: query3 })
|
|
22060
|
-
});
|
|
22061
|
-
if (!response.ok) return [0];
|
|
22062
|
-
const data = await response.json();
|
|
22063
|
-
const accounts = data?.data?.accounts;
|
|
22064
|
-
if (!accounts || accounts.length === 0) return [0];
|
|
22065
|
-
return accounts.map((a) => {
|
|
22066
|
-
const addr = a.subAccount || a.id;
|
|
22067
|
-
return getSubAccountIndex(addr, owner);
|
|
22068
|
-
});
|
|
22101
|
+
async function fetchEulerSubAccountIndexes(chainId, owner) {
|
|
22102
|
+
return await fetchEulerActiveIndexesViaApi(chainId, owner) ?? [0];
|
|
22103
|
+
}
|
|
22104
|
+
async function resolveEulerBuildIndexes(chainId, owner) {
|
|
22105
|
+
return await fetchEulerActiveIndexesViaApi(chainId, owner) ?? ALL_EULER_SUB_ACCOUNT_INDEXES;
|
|
22069
22106
|
}
|
|
22070
22107
|
var RESOLVED_STORE_TTL_MS = 6e4;
|
|
22071
22108
|
var resolvedIndexesStore = /* @__PURE__ */ new Map();
|
|
@@ -22107,7 +22144,7 @@ var buildEulerUserCall = async (chainId, lender, account, subAccountIndexes) =>
|
|
|
22107
22144
|
const accountLensAddress = config.accountLens;
|
|
22108
22145
|
const evcAddress = config.evc;
|
|
22109
22146
|
if (!accountLensAddress || !evcAddress) return [];
|
|
22110
|
-
const indexes = subAccountIndexes ?? await
|
|
22147
|
+
const indexes = subAccountIndexes ?? await resolveEulerBuildIndexes(chainId, account);
|
|
22111
22148
|
const sortedIndices = resolveSubAccountIndexes(account, indexes);
|
|
22112
22149
|
storeResolvedIndexes(chainId, account, indexes);
|
|
22113
22150
|
return sortedIndices.map((i) => ({
|
|
@@ -22311,16 +22348,16 @@ var buildGearboxV3UserCall = (chainId, _lender, account) => {
|
|
|
22311
22348
|
};
|
|
22312
22349
|
|
|
22313
22350
|
// src/lending/user-data/dolomite/userCallBuild.ts
|
|
22314
|
-
var
|
|
22351
|
+
var SUBGRAPH_CACHE_TTL_MS = 3e4;
|
|
22315
22352
|
var SUBGRAPH_TIMEOUT_MS2 = 1e4;
|
|
22316
|
-
var
|
|
22353
|
+
var subgraphCache = /* @__PURE__ */ new Map();
|
|
22317
22354
|
function fetchDolomiteAccountNumbers(chainId, owner) {
|
|
22318
22355
|
const key = `${chainId}:${owner.toLowerCase()}`;
|
|
22319
|
-
const cached =
|
|
22356
|
+
const cached = subgraphCache.get(key);
|
|
22320
22357
|
if (cached) return cached.promise;
|
|
22321
22358
|
const promise = fetchAccountNumbersFromSubgraph(chainId, owner).then((ns) => dedupeWithDefault(ns)).catch(() => ["0"]);
|
|
22322
|
-
const timer = setTimeout(() =>
|
|
22323
|
-
|
|
22359
|
+
const timer = setTimeout(() => subgraphCache.delete(key), SUBGRAPH_CACHE_TTL_MS);
|
|
22360
|
+
subgraphCache.set(key, { promise, timer });
|
|
22324
22361
|
return promise;
|
|
22325
22362
|
}
|
|
22326
22363
|
function dedupeWithDefault(numbers) {
|
|
@@ -24845,6 +24882,72 @@ var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient16, retry =
|
|
|
24845
24882
|
);
|
|
24846
24883
|
}
|
|
24847
24884
|
};
|
|
24885
|
+
var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient16, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false) => {
|
|
24886
|
+
if (poolSize <= 1) {
|
|
24887
|
+
return multicallViemAbiArray(
|
|
24888
|
+
chainId,
|
|
24889
|
+
abi,
|
|
24890
|
+
calls,
|
|
24891
|
+
getEvmClient16,
|
|
24892
|
+
true,
|
|
24893
|
+
0,
|
|
24894
|
+
retries,
|
|
24895
|
+
allowFailure,
|
|
24896
|
+
batchSize,
|
|
24897
|
+
logs
|
|
24898
|
+
);
|
|
24899
|
+
}
|
|
24900
|
+
const abiIsArray = isArray(abi[0]);
|
|
24901
|
+
const contracts = calls.map(({ address, name, params }, i) => ({
|
|
24902
|
+
abi: abiIsArray ? abi?.[i] : abi,
|
|
24903
|
+
address,
|
|
24904
|
+
functionName: name,
|
|
24905
|
+
args: params
|
|
24906
|
+
}));
|
|
24907
|
+
const batches = [];
|
|
24908
|
+
for (let i = 0; i < contracts.length; i += batchSize) {
|
|
24909
|
+
batches.push({ start: i, items: contracts.slice(i, i + batchSize) });
|
|
24910
|
+
}
|
|
24911
|
+
const results = new Array(contracts.length);
|
|
24912
|
+
const runBatch = async (batch, rpcId, attemptsLeft, size) => {
|
|
24913
|
+
try {
|
|
24914
|
+
const provider = getEvmClient16(chainId, rpcId);
|
|
24915
|
+
const returnData = await provider.multicall({
|
|
24916
|
+
allowFailure,
|
|
24917
|
+
batchSize: size,
|
|
24918
|
+
contracts: batch.items
|
|
24919
|
+
});
|
|
24920
|
+
const mapped = allowFailure ? returnData.map(
|
|
24921
|
+
({ result, status }) => status !== "success" ? "0x" : result
|
|
24922
|
+
) : returnData;
|
|
24923
|
+
for (let j = 0; j < mapped.length; j++) {
|
|
24924
|
+
results[batch.start + j] = mapped[j];
|
|
24925
|
+
}
|
|
24926
|
+
} catch (error) {
|
|
24927
|
+
if (logs) console.log("error in sharded multicall batch", error);
|
|
24928
|
+
if (attemptsLeft <= 0) throw error;
|
|
24929
|
+
return runBatch(
|
|
24930
|
+
batch,
|
|
24931
|
+
rpcId + 1,
|
|
24932
|
+
attemptsLeft - 1,
|
|
24933
|
+
Math.max(1, Math.floor(size / 2))
|
|
24934
|
+
);
|
|
24935
|
+
}
|
|
24936
|
+
};
|
|
24937
|
+
const workers = Math.max(1, Math.min(poolSize, batches.length));
|
|
24938
|
+
let cursor = 0;
|
|
24939
|
+
const worker = async (workerId) => {
|
|
24940
|
+
while (true) {
|
|
24941
|
+
const idx = cursor++;
|
|
24942
|
+
if (idx >= batches.length) break;
|
|
24943
|
+
await runBatch(batches[idx], workerId, retries, batchSize);
|
|
24944
|
+
}
|
|
24945
|
+
};
|
|
24946
|
+
await Promise.all(
|
|
24947
|
+
Array.from({ length: workers }, (_3, w) => worker(w))
|
|
24948
|
+
);
|
|
24949
|
+
return results;
|
|
24950
|
+
};
|
|
24848
24951
|
function prepareMulticallInputs(abi, calls) {
|
|
24849
24952
|
const abiIsArray = isArray(abi[0]);
|
|
24850
24953
|
return calls.map(({ address, name, params }, i) => ({
|
|
@@ -29435,7 +29538,7 @@ function unflattenLenderData(pools) {
|
|
|
29435
29538
|
}
|
|
29436
29539
|
return result;
|
|
29437
29540
|
}
|
|
29438
|
-
var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient16, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false) => {
|
|
29541
|
+
var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient16, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false, concurrency = 1) => {
|
|
29439
29542
|
const queries = organizeUserQueries(queriesRaw);
|
|
29440
29543
|
const builtCalls = await Promise.all(
|
|
29441
29544
|
queries.map(async (query3) => {
|
|
@@ -29451,13 +29554,12 @@ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient16, allowF
|
|
|
29451
29554
|
})
|
|
29452
29555
|
);
|
|
29453
29556
|
const calls = builtCalls.flat();
|
|
29454
|
-
return await
|
|
29557
|
+
return await multicallShardedAbiArray(
|
|
29455
29558
|
chainId,
|
|
29456
29559
|
calls.map((call) => call.abi),
|
|
29457
29560
|
calls.map((call) => call.call),
|
|
29458
29561
|
getEvmClient16,
|
|
29459
|
-
|
|
29460
|
-
0,
|
|
29562
|
+
concurrency,
|
|
29461
29563
|
retries,
|
|
29462
29564
|
allowFailure,
|
|
29463
29565
|
batchSize,
|
|
@@ -32887,6 +32989,62 @@ var coreLstFetcher = {
|
|
|
32887
32989
|
}
|
|
32888
32990
|
};
|
|
32889
32991
|
|
|
32992
|
+
// src/yields/intrinsic/fetchers/hastra.ts
|
|
32993
|
+
var HASTRA_POR_URL = "https://www.hastra.io/hastra-pulse/public/api/v1/por";
|
|
32994
|
+
var HASTRA_PRIME_KEY = "Hastra PRIME::PRIME";
|
|
32995
|
+
var hastraPrimeFetcher = {
|
|
32996
|
+
label: "Hastra",
|
|
32997
|
+
fetch: async () => {
|
|
32998
|
+
const res = await fetch(HASTRA_POR_URL, {
|
|
32999
|
+
method: "GET",
|
|
33000
|
+
headers: { Accept: "application/json" }
|
|
33001
|
+
}).then((r) => r.json());
|
|
33002
|
+
const card = res?.demo_prime_card ?? {};
|
|
33003
|
+
const current = Number(card.current_rate);
|
|
33004
|
+
const fee = Number(card.fee);
|
|
33005
|
+
const lifetimePct = Number(card.lifetime_average_rate) * 100;
|
|
33006
|
+
let apr;
|
|
33007
|
+
if (Number.isFinite(current)) {
|
|
33008
|
+
apr = current - (Number.isFinite(fee) ? fee : 0);
|
|
33009
|
+
} else if (Number.isFinite(lifetimePct)) {
|
|
33010
|
+
apr = lifetimePct;
|
|
33011
|
+
} else {
|
|
33012
|
+
apr = 0;
|
|
33013
|
+
}
|
|
33014
|
+
return { [HASTRA_PRIME_KEY]: Math.max(0, apr) };
|
|
33015
|
+
}
|
|
33016
|
+
};
|
|
33017
|
+
|
|
33018
|
+
// src/yields/intrinsic/fetchers/lombard.ts
|
|
33019
|
+
var LBTC_APY_URL = "https://mainnet.prod.lombard.finance/api/v1/analytics/estimated-apy";
|
|
33020
|
+
var lombardLbtcFetcher = {
|
|
33021
|
+
label: "LBTC",
|
|
33022
|
+
fetch: async () => {
|
|
33023
|
+
const res = await fetch(LBTC_APY_URL, {
|
|
33024
|
+
headers: { accept: "application/json" }
|
|
33025
|
+
}).then((r) => r.json());
|
|
33026
|
+
const frac = Number(res?.lbtc_estimated_apy);
|
|
33027
|
+
return { LBTC: Number.isFinite(frac) ? frac * 100 : 0 };
|
|
33028
|
+
}
|
|
33029
|
+
};
|
|
33030
|
+
var LOMBARD_VAULT_APY_URL = "https://mainnet.prod.lombard.finance/api/v1/analytics/vault/apy/history";
|
|
33031
|
+
var createLombardVaultFetcher = (wrapper, key) => ({
|
|
33032
|
+
label: `LOMBARD_VAULT:${wrapper}`,
|
|
33033
|
+
fetch: async () => {
|
|
33034
|
+
const url = `${LOMBARD_VAULT_APY_URL}?vault_wrapper=${wrapper}&interval=APY_INTERVAL_1M`;
|
|
33035
|
+
const res = await fetch(url, {
|
|
33036
|
+
headers: { accept: "application/json" }
|
|
33037
|
+
}).then((r) => r.json());
|
|
33038
|
+
const latest = Array.isArray(res?.snapshots) ? res.snapshots[0] : void 0;
|
|
33039
|
+
const frac = Number(latest?.total_apy);
|
|
33040
|
+
return { [key]: Number.isFinite(frac) ? frac * 100 : 0 };
|
|
33041
|
+
}
|
|
33042
|
+
});
|
|
33043
|
+
var lombardLbtcvFetcher = createLombardVaultFetcher(
|
|
33044
|
+
"VAULT_WRAPPER_BTCE",
|
|
33045
|
+
"LBTCv"
|
|
33046
|
+
);
|
|
33047
|
+
|
|
32890
33048
|
// src/yields/intrinsic/index.ts
|
|
32891
33049
|
async function fetchIntrinsicYields() {
|
|
32892
33050
|
const wstethPromise = safeFetch(wstethFetcher.label, wstethFetcher.fetch);
|
|
@@ -32955,7 +33113,10 @@ async function fetchIntrinsicYields() {
|
|
|
32955
33113
|
beraEthFetcher,
|
|
32956
33114
|
lbgtFetcher,
|
|
32957
33115
|
psxdcFetcher,
|
|
32958
|
-
coreLstFetcher
|
|
33116
|
+
coreLstFetcher,
|
|
33117
|
+
hastraPrimeFetcher,
|
|
33118
|
+
lombardLbtcFetcher,
|
|
33119
|
+
lombardLbtcvFetcher
|
|
32959
33120
|
];
|
|
32960
33121
|
const results = await Promise.all([
|
|
32961
33122
|
wstethPromise,
|
|
@@ -37994,6 +38155,7 @@ var EULER_EARN_SUBGRAPH_URLS = {
|
|
|
37994
38155
|
[Chain.AVALANCHE_C_CHAIN]: eulerSubgraphUrl("euler-v2-avalanche")
|
|
37995
38156
|
};
|
|
37996
38157
|
var hasEulerEarnVaultSubgraph = (chainId) => chainId in EULER_EARN_SUBGRAPH_URLS;
|
|
38158
|
+
var getEulerEarnSubgraphUrl = (chainId) => EULER_EARN_SUBGRAPH_URLS[chainId];
|
|
37997
38159
|
var EULER_EARN_VAULTS_QUERY = `
|
|
37998
38160
|
{
|
|
37999
38161
|
eulerEarnVaults(first: 200, skip: 0) {
|
|
@@ -38222,10 +38384,176 @@ async function fetchEulerEarnVaultsFromSubgraph(chainId, prices = {}, tokenList
|
|
|
38222
38384
|
}
|
|
38223
38385
|
return out;
|
|
38224
38386
|
}
|
|
38387
|
+
var EULER_DATA_API_BASE2 = "https://v3.euler.finance/v3";
|
|
38388
|
+
var API_TIMEOUT_MS = 1e4;
|
|
38389
|
+
var DETAIL_CONCURRENCY = 8;
|
|
38390
|
+
var BLOCK_TIME_SEC = {
|
|
38391
|
+
"1": 12,
|
|
38392
|
+
"56": 0.75,
|
|
38393
|
+
"130": 1,
|
|
38394
|
+
"146": 0.5,
|
|
38395
|
+
"8453": 2,
|
|
38396
|
+
"1923": 2,
|
|
38397
|
+
"42161": 0.25,
|
|
38398
|
+
"43114": 2
|
|
38399
|
+
};
|
|
38400
|
+
var DEFAULT_BLOCK_TIME_SEC = 2;
|
|
38401
|
+
var MAX_LAG_SECONDS = 30 * 60;
|
|
38402
|
+
function safeBigInt2(v) {
|
|
38403
|
+
if (v == null || v === "") return 0n;
|
|
38404
|
+
try {
|
|
38405
|
+
return BigInt(typeof v === "number" ? Math.trunc(v) : v);
|
|
38406
|
+
} catch {
|
|
38407
|
+
return 0n;
|
|
38408
|
+
}
|
|
38409
|
+
}
|
|
38410
|
+
async function getJson(url) {
|
|
38411
|
+
const controller = new AbortController();
|
|
38412
|
+
const timer = setTimeout(() => controller.abort(), API_TIMEOUT_MS);
|
|
38413
|
+
try {
|
|
38414
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
38415
|
+
if (!res.ok) return void 0;
|
|
38416
|
+
return await res.json();
|
|
38417
|
+
} catch {
|
|
38418
|
+
return void 0;
|
|
38419
|
+
} finally {
|
|
38420
|
+
clearTimeout(timer);
|
|
38421
|
+
}
|
|
38422
|
+
}
|
|
38423
|
+
async function isEulerEarnSubgraphStale(chainId, subgraphUrl) {
|
|
38424
|
+
const [subHead, chainHead] = await Promise.all([
|
|
38425
|
+
fetchSubgraphHead(subgraphUrl),
|
|
38426
|
+
getEvmClientUniversal({ chain: chainId, rpcId: 0 }).getBlockNumber().then((b) => Number(b)).catch(() => null)
|
|
38427
|
+
]);
|
|
38428
|
+
if (subHead == null || chainHead == null) return false;
|
|
38429
|
+
const lagBlocks = chainHead - subHead;
|
|
38430
|
+
if (lagBlocks <= 0) return false;
|
|
38431
|
+
const lagSeconds = lagBlocks * (BLOCK_TIME_SEC[chainId] ?? DEFAULT_BLOCK_TIME_SEC);
|
|
38432
|
+
return lagSeconds > MAX_LAG_SECONDS;
|
|
38433
|
+
}
|
|
38434
|
+
async function fetchSubgraphHead(subgraphUrl) {
|
|
38435
|
+
const controller = new AbortController();
|
|
38436
|
+
const timer = setTimeout(() => controller.abort(), API_TIMEOUT_MS);
|
|
38437
|
+
try {
|
|
38438
|
+
const res = await fetch(subgraphUrl, {
|
|
38439
|
+
method: "POST",
|
|
38440
|
+
headers: { "Content-Type": "application/json" },
|
|
38441
|
+
body: JSON.stringify({ query: "{ _meta { block { number } } }" }),
|
|
38442
|
+
signal: controller.signal
|
|
38443
|
+
});
|
|
38444
|
+
if (!res.ok) return null;
|
|
38445
|
+
const json = await res.json();
|
|
38446
|
+
const n = json?.data?._meta?.block?.number;
|
|
38447
|
+
return typeof n === "number" ? n : null;
|
|
38448
|
+
} catch {
|
|
38449
|
+
return null;
|
|
38450
|
+
} finally {
|
|
38451
|
+
clearTimeout(timer);
|
|
38452
|
+
}
|
|
38453
|
+
}
|
|
38454
|
+
function mapApiDetail(d, chainId, prices, tokenList) {
|
|
38455
|
+
const address = (d.address ?? "").toLowerCase();
|
|
38456
|
+
const underlying = (d.asset?.address ?? "").toLowerCase();
|
|
38457
|
+
if (!address || !underlying) return null;
|
|
38458
|
+
const assetMeta = tokenList[underlying];
|
|
38459
|
+
const decimals = Number(d.decimals ?? d.asset?.decimals ?? 18);
|
|
38460
|
+
const totalAssetsRaw = String(d.totalAssets ?? "0");
|
|
38461
|
+
const totalSupplyRaw = String(d.totalShares ?? "0");
|
|
38462
|
+
const convertToAssets = d.exchangeRate != null ? String(d.exchangeRate) : deriveConvertToAssets(totalAssetsRaw, totalSupplyRaw, decimals);
|
|
38463
|
+
const supplyRate = Number(d.supplyApy ?? d.apyCurrent ?? 0) || 0;
|
|
38464
|
+
const availableRaw = safeBigInt2(d.availableAssets) || safeBigInt2(totalAssetsRaw);
|
|
38465
|
+
const totalAssetsBig = safeBigInt2(totalAssetsRaw);
|
|
38466
|
+
const liquidityRaw = (availableRaw > totalAssetsBig ? totalAssetsBig : availableRaw).toString();
|
|
38467
|
+
const totalAssetsFormatted = Number(parseRawAmount(totalAssetsRaw, decimals));
|
|
38468
|
+
const liquidityFormatted = Number(parseRawAmount(liquidityRaw, decimals));
|
|
38469
|
+
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(underlying, chainId);
|
|
38470
|
+
const priceUsd = prices[oracleKey] ?? prices[underlying] ?? 0;
|
|
38471
|
+
const totalAssetsUsd = priceUsd ? totalAssetsFormatted * priceUsd : Number(d.totalSupplyUsd ?? 0);
|
|
38472
|
+
const liquidityUsd = priceUsd ? liquidityFormatted * priceUsd : Number(d.availableAssetsUsd ?? 0);
|
|
38473
|
+
return {
|
|
38474
|
+
address,
|
|
38475
|
+
underlying,
|
|
38476
|
+
symbol: d.symbol ?? "",
|
|
38477
|
+
name: d.name ?? "",
|
|
38478
|
+
decimals,
|
|
38479
|
+
totalAssets: totalAssetsRaw,
|
|
38480
|
+
totalSupply: totalSupplyRaw,
|
|
38481
|
+
convertToAssets,
|
|
38482
|
+
supplyRate,
|
|
38483
|
+
rewardsRate: 0,
|
|
38484
|
+
depositRate: supplyRate,
|
|
38485
|
+
// The API doesn't surface the performance fee on this endpoint; the
|
|
38486
|
+
// headline APY is already net, so 0 here only affects fee display.
|
|
38487
|
+
fee: 0,
|
|
38488
|
+
owner: d.owner?.toLowerCase(),
|
|
38489
|
+
curator: d.curator?.toLowerCase(),
|
|
38490
|
+
curatorName: curatorNameFromVaultName(d.name, assetMeta?.symbol),
|
|
38491
|
+
guardian: d.guardian?.toLowerCase(),
|
|
38492
|
+
feeRecipient: d.feeReceiver?.toLowerCase() || void 0,
|
|
38493
|
+
asset: assetMeta,
|
|
38494
|
+
priceUsd: priceUsd || void 0,
|
|
38495
|
+
totalAssetsFormatted,
|
|
38496
|
+
totalAssetsUsd,
|
|
38497
|
+
liquidity: liquidityRaw,
|
|
38498
|
+
liquidityFormatted,
|
|
38499
|
+
liquidityUsd
|
|
38500
|
+
};
|
|
38501
|
+
}
|
|
38502
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
38503
|
+
const out = new Array(items.length);
|
|
38504
|
+
let cursor = 0;
|
|
38505
|
+
const worker = async () => {
|
|
38506
|
+
while (true) {
|
|
38507
|
+
const i = cursor++;
|
|
38508
|
+
if (i >= items.length) break;
|
|
38509
|
+
out[i] = await fn(items[i]);
|
|
38510
|
+
}
|
|
38511
|
+
};
|
|
38512
|
+
await Promise.all(
|
|
38513
|
+
Array.from({ length: Math.min(limit, items.length) }, () => worker())
|
|
38514
|
+
);
|
|
38515
|
+
return out;
|
|
38516
|
+
}
|
|
38517
|
+
async function fetchEulerEarnVaultsFromApi(chainId, prices = {}, tokenList = {}) {
|
|
38518
|
+
const list = await getJson(
|
|
38519
|
+
`${EULER_DATA_API_BASE2}/earn/vaults?chainId=${chainId}&limit=200`
|
|
38520
|
+
);
|
|
38521
|
+
if (!list) return void 0;
|
|
38522
|
+
const rows = list.data ?? [];
|
|
38523
|
+
if (rows.length === 0) return {};
|
|
38524
|
+
const details = await mapWithConcurrency(
|
|
38525
|
+
rows,
|
|
38526
|
+
DETAIL_CONCURRENCY,
|
|
38527
|
+
(row) => getJson(
|
|
38528
|
+
`${EULER_DATA_API_BASE2}/earn/vaults/${chainId}/${row.address}?include=strategies`
|
|
38529
|
+
).then((d) => d?.data)
|
|
38530
|
+
);
|
|
38531
|
+
const out = {};
|
|
38532
|
+
for (const d of details) {
|
|
38533
|
+
if (!d) continue;
|
|
38534
|
+
const v = mapApiDetail(d, chainId, prices, tokenList);
|
|
38535
|
+
if (v) out[v.address] = v;
|
|
38536
|
+
}
|
|
38537
|
+
return out;
|
|
38538
|
+
}
|
|
38225
38539
|
|
|
38226
38540
|
// src/vaults/euler-earn/fetchPublic.ts
|
|
38541
|
+
var isNonEmpty = (v) => !!v && Object.keys(v).length > 0;
|
|
38227
38542
|
var fetchEulerEarnVaults = async (chainId, prices = {}, tokenList = {}) => {
|
|
38228
|
-
|
|
38543
|
+
const subgraphUrl = getEulerEarnSubgraphUrl(chainId);
|
|
38544
|
+
if (!subgraphUrl) {
|
|
38545
|
+
return await fetchEulerEarnVaultsFromApi(chainId, prices, tokenList) ?? {};
|
|
38546
|
+
}
|
|
38547
|
+
const [stale, subgraph] = await Promise.all([
|
|
38548
|
+
isEulerEarnSubgraphStale(chainId, subgraphUrl).catch(() => false),
|
|
38549
|
+
fetchEulerEarnVaultsFromSubgraph(chainId, prices, tokenList).then((r) => ({ ok: true, data: r })).catch(() => ({ ok: false, data: void 0 }))
|
|
38550
|
+
]);
|
|
38551
|
+
if (!stale && subgraph.ok && isNonEmpty(subgraph.data)) {
|
|
38552
|
+
return subgraph.data;
|
|
38553
|
+
}
|
|
38554
|
+
const fromApi = await fetchEulerEarnVaultsFromApi(chainId, prices, tokenList);
|
|
38555
|
+
if (isNonEmpty(fromApi)) return fromApi;
|
|
38556
|
+
return subgraph.ok && subgraph.data ? subgraph.data : {};
|
|
38229
38557
|
};
|
|
38230
38558
|
var CHAIN_ID4 = "1";
|
|
38231
38559
|
var SWBTC = "0x8db2350d78abc13f5673a411d4700bcf87864dde";
|
|
@@ -38356,36 +38684,6 @@ var stceloFetcher = {
|
|
|
38356
38684
|
return { STCELO: apr };
|
|
38357
38685
|
}
|
|
38358
38686
|
};
|
|
38359
|
-
|
|
38360
|
-
// src/yields/intrinsic/fetchers/lombard.ts
|
|
38361
|
-
var LBTC_APY_URL = "https://mainnet.prod.lombard.finance/api/v1/analytics/estimated-apy";
|
|
38362
|
-
var lombardLbtcFetcher = {
|
|
38363
|
-
label: "LBTC",
|
|
38364
|
-
fetch: async () => {
|
|
38365
|
-
const res = await fetch(LBTC_APY_URL, {
|
|
38366
|
-
headers: { accept: "application/json" }
|
|
38367
|
-
}).then((r) => r.json());
|
|
38368
|
-
const frac = Number(res?.lbtc_estimated_apy);
|
|
38369
|
-
return { LBTC: Number.isFinite(frac) ? frac * 100 : 0 };
|
|
38370
|
-
}
|
|
38371
|
-
};
|
|
38372
|
-
var LOMBARD_VAULT_APY_URL = "https://mainnet.prod.lombard.finance/api/v1/analytics/vault/apy/history";
|
|
38373
|
-
var createLombardVaultFetcher = (wrapper, key) => ({
|
|
38374
|
-
label: `LOMBARD_VAULT:${wrapper}`,
|
|
38375
|
-
fetch: async () => {
|
|
38376
|
-
const url = `${LOMBARD_VAULT_APY_URL}?vault_wrapper=${wrapper}&interval=APY_INTERVAL_1M`;
|
|
38377
|
-
const res = await fetch(url, {
|
|
38378
|
-
headers: { accept: "application/json" }
|
|
38379
|
-
}).then((r) => r.json());
|
|
38380
|
-
const latest = Array.isArray(res?.snapshots) ? res.snapshots[0] : void 0;
|
|
38381
|
-
const frac = Number(latest?.total_apy);
|
|
38382
|
-
return { [key]: Number.isFinite(frac) ? frac * 100 : 0 };
|
|
38383
|
-
}
|
|
38384
|
-
});
|
|
38385
|
-
var lombardLbtcvFetcher = createLombardVaultFetcher(
|
|
38386
|
-
"VAULT_WRAPPER_BTCE",
|
|
38387
|
-
"LBTCv"
|
|
38388
|
-
);
|
|
38389
38687
|
var CHAIN_ID6 = "1284";
|
|
38390
38688
|
var STDOT = "0xbc7e02c4178a7df7d3e564323a5c359dc96c4db4";
|
|
38391
38689
|
var ONE_E185 = 10n ** 18n;
|
|
@@ -44832,6 +45130,28 @@ var SINGLE_CHAIN_ENTRIES = {
|
|
|
44832
45130
|
withdrawalCooldownSeconds: 604800,
|
|
44833
45131
|
yieldFetcher: mapleFetcher,
|
|
44834
45132
|
yieldKey: "SYRUPUSDT"
|
|
45133
|
+
},
|
|
45134
|
+
{
|
|
45135
|
+
// Hastra Democratized PRIME — ERC-4626 over wYLDS (itself ERC-4626 over
|
|
45136
|
+
// USDC), so the share/asset ratio accrues on-chain (`convertToAssets`).
|
|
45137
|
+
// Solana-primary; the Ethereum deployment exists (verified on-chain:
|
|
45138
|
+
// symbol PRIME, 6 decimals, asset() = wYLDS) but carries no user holders
|
|
45139
|
+
// yet. Deposits are whitelist-gated, so `isMintable` is false — we list
|
|
45140
|
+
// + price it, but don't advertise a permissionless mint that would
|
|
45141
|
+
// revert. Two-phase exit (`requestRedeem` → `completeRedeem`). APR from
|
|
45142
|
+
// the public Proof-of-Reserve feed via `hastraPrimeFetcher`.
|
|
45143
|
+
address: "0x19ebb35279a16207ec4ba82799cc64715065f7f6",
|
|
45144
|
+
underlying: "0x6ad038ca6c04e885630851278ca0a856ad9a66cc",
|
|
45145
|
+
// wYLDS
|
|
45146
|
+
symbol: "PRIME",
|
|
45147
|
+
brand: "Hastra",
|
|
45148
|
+
decimals: 6,
|
|
45149
|
+
underlyingDecimals: 6,
|
|
45150
|
+
isRebasing: false,
|
|
45151
|
+
isMintable: false,
|
|
45152
|
+
withdrawalMode: "request-based",
|
|
45153
|
+
yieldFetcher: hastraPrimeFetcher,
|
|
45154
|
+
yieldKey: "Hastra PRIME::PRIME"
|
|
44835
45155
|
}
|
|
44836
45156
|
],
|
|
44837
45157
|
"8453": [
|
|
@@ -45747,7 +46067,7 @@ var GMX_SUPPORTED_CHAINS = Object.keys(GMX_API_HOSTS);
|
|
|
45747
46067
|
var getGmxApiHost = (chainId) => GMX_API_HOSTS[chainId];
|
|
45748
46068
|
|
|
45749
46069
|
// src/vaults/gmx/api.ts
|
|
45750
|
-
var
|
|
46070
|
+
var getJson2 = async (url) => {
|
|
45751
46071
|
const res = await fetch(url, {
|
|
45752
46072
|
method: "GET",
|
|
45753
46073
|
headers: { Accept: "application/json" }
|
|
@@ -45759,12 +46079,12 @@ var fetchGmxRawData = async (chainId, period, apiUrlOverride) => {
|
|
|
45759
46079
|
const host = apiUrlOverride ?? getGmxApiHost(chainId);
|
|
45760
46080
|
if (!host) throw new Error(`GMX not supported on chain ${chainId}`);
|
|
45761
46081
|
const [apy, marketsRes, glvsRes, tokensRes] = await Promise.all([
|
|
45762
|
-
|
|
45763
|
-
|
|
46082
|
+
getJson2(`${host}/apy?period=${encodeURIComponent(period)}`),
|
|
46083
|
+
getJson2(`${host}/markets`).catch(() => ({
|
|
45764
46084
|
markets: []
|
|
45765
46085
|
})),
|
|
45766
|
-
|
|
45767
|
-
|
|
46086
|
+
getJson2(`${host}/glvs`).catch(() => ({ glvs: [] })),
|
|
46087
|
+
getJson2(`${host}/tokens`).catch(() => ({
|
|
45768
46088
|
tokens: []
|
|
45769
46089
|
}))
|
|
45770
46090
|
]);
|