@1delta/margin-fetcher-sol 0.0.2 → 0.0.4
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.d.mts +344 -217
- package/dist/index.d.ts +344 -217
- package/dist/index.js +274 -143
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +135 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -7855,6 +7855,8 @@ var RESERVE = {
|
|
|
7855
7855
|
maxLiquidationBonusBps: 4876,
|
|
7856
7856
|
originationFeeSf: 4896,
|
|
7857
7857
|
flashLoanFeeSf: 4904,
|
|
7858
|
+
// config.borrowRateCurve — 11 × CurvePoint { utilizationRateBps u32, borrowRateBps u32 }, after fees' 8 padding bytes
|
|
7859
|
+
borrowRateCurve: 4920,
|
|
7858
7860
|
borrowFactorPct: 5008,
|
|
7859
7861
|
depositLimit: 5016,
|
|
7860
7862
|
borrowLimit: 5024,
|
|
@@ -7997,6 +7999,14 @@ function readKlendReserveChain(reserve, data) {
|
|
|
7997
7999
|
debtWithdrawalCap: withdrawalCap(data, RESERVE.debtWithdrawalCap),
|
|
7998
8000
|
disableUsageAsCollOutsideEmode: data[RESERVE.disableUsageAsCollOutsideEmode] !== 0,
|
|
7999
8001
|
utilizationLimitBlockBorrowingAbovePct: data[RESERVE.utilizationLimitBlockBorrowingAbovePct],
|
|
8002
|
+
borrowRateCurve: Array.from({ length: 11 }, (_, i) => {
|
|
8003
|
+
const v = new DataView(data.buffer, data.byteOffset);
|
|
8004
|
+
const off = RESERVE.borrowRateCurve + 8 * i;
|
|
8005
|
+
return [
|
|
8006
|
+
v.getUint32(off, true) / 1e4,
|
|
8007
|
+
v.getUint32(off + 4, true) / 1e4
|
|
8008
|
+
];
|
|
8009
|
+
}),
|
|
8000
8010
|
borrowLimitOutsideElevationGroup: u64(
|
|
8001
8011
|
data,
|
|
8002
8012
|
RESERVE.borrowLimitOutsideElevationGroup
|
|
@@ -8487,6 +8497,15 @@ function exchangeRateOf(inp) {
|
|
|
8487
8497
|
if (!t || !s || t.num <= 0n || s.num <= 0n) return { num: 1n, den: 1n };
|
|
8488
8498
|
return { num: t.num * s.den, den: t.den * s.num };
|
|
8489
8499
|
}
|
|
8500
|
+
function dedupeKnots(knots) {
|
|
8501
|
+
const out = [];
|
|
8502
|
+
for (const k of knots) {
|
|
8503
|
+
const last = out[out.length - 1];
|
|
8504
|
+
if (last && last[0] === k[0] && last[1] === k[1]) continue;
|
|
8505
|
+
out.push(k);
|
|
8506
|
+
}
|
|
8507
|
+
return out;
|
|
8508
|
+
}
|
|
8490
8509
|
function convertKaminoReserve(inp, ctx) {
|
|
8491
8510
|
const { stats, metrics, detail, chain } = inp;
|
|
8492
8511
|
const mint = chain?.mint ?? stats.token;
|
|
@@ -8584,7 +8603,12 @@ function convertKaminoReserve(inp, ctx) {
|
|
|
8584
8603
|
interestRateBasis: stats.interestRateBasis,
|
|
8585
8604
|
protocolTakeRatePct: stats.protocolTakeRatePct,
|
|
8586
8605
|
hostFixedInterestRateBps: stats.hostFixedInterestRateBps,
|
|
8587
|
-
borrowCurve: detail.borrowCurve,
|
|
8606
|
+
borrowCurve: chain ? dedupeKnots(chain.borrowRateCurve) : detail.borrowCurve,
|
|
8607
|
+
borrowCurveSource: chain ? "chain" : "api",
|
|
8608
|
+
...stats.interestRateBasis === "legacy" && ctx.slotSeconds ? { slotSeconds: ctx.slotSeconds } : {},
|
|
8609
|
+
...chain ? {
|
|
8610
|
+
utilizationLimitBlockBorrowingAbovePct: chain.utilizationLimitBlockBorrowingAbovePct
|
|
8611
|
+
} : {},
|
|
8588
8612
|
autoDeleverage: stats.autoDeleverage,
|
|
8589
8613
|
source: chain ? "chain" : "api",
|
|
8590
8614
|
maxLiquidationBonus: chain ? chain.maxLiquidationBonusBps / 1e4 : num(detail.maxLiquidationBonus),
|
|
@@ -8630,6 +8654,7 @@ function convertKaminoMarket(inp) {
|
|
|
8630
8654
|
closeFactor,
|
|
8631
8655
|
chainMarket: inp.chainMarket,
|
|
8632
8656
|
slot: inp.slot,
|
|
8657
|
+
slotSeconds: inp.slotSeconds,
|
|
8633
8658
|
tokenList: inp.tokenList
|
|
8634
8659
|
});
|
|
8635
8660
|
data[row.marketUid] = row;
|
|
@@ -8645,6 +8670,7 @@ function convertKaminoMarket(inp) {
|
|
|
8645
8670
|
}
|
|
8646
8671
|
|
|
8647
8672
|
// src/lending/public-data/kamino/fetchPublic.ts
|
|
8673
|
+
import { measureSlotSeconds } from "@1delta/svm-kit";
|
|
8648
8674
|
async function fetchKaminoPublic(opts = {}) {
|
|
8649
8675
|
const api = createKaminoApi(opts);
|
|
8650
8676
|
const { markets, metricsByMarket } = await listServedMarkets(api, opts);
|
|
@@ -8711,6 +8737,7 @@ async function fetchKaminoPublic(opts = {}) {
|
|
|
8711
8737
|
return false;
|
|
8712
8738
|
});
|
|
8713
8739
|
const rpc = opts.rpc;
|
|
8740
|
+
const slotSeconds = opts.slotSeconds ?? (rpc ? await measureSlotSeconds(rpc) : void 0);
|
|
8714
8741
|
const chainReads = await Promise.all(
|
|
8715
8742
|
served.map(async (mr) => {
|
|
8716
8743
|
if (!rpc) return void 0;
|
|
@@ -8743,7 +8770,8 @@ async function fetchKaminoPublic(opts = {}) {
|
|
|
8743
8770
|
reserves,
|
|
8744
8771
|
...chain?.market ? { chainMarket: chain.market, slot: chain.slot } : {},
|
|
8745
8772
|
leveragePairs: mr.leveragePairs,
|
|
8746
|
-
tokenList: opts.tokenList
|
|
8773
|
+
tokenList: opts.tokenList,
|
|
8774
|
+
slotSeconds
|
|
8747
8775
|
});
|
|
8748
8776
|
out[conv.lenderKey] = {
|
|
8749
8777
|
chainId: conv.chainId,
|
|
@@ -10879,6 +10907,68 @@ async function readJupiterLendVaultsOnchain(rpc, market, vaultIds, opts = {}) {
|
|
|
10879
10907
|
}
|
|
10880
10908
|
return out;
|
|
10881
10909
|
}
|
|
10910
|
+
function decodeJlRateModel(data) {
|
|
10911
|
+
if (data.length < 53)
|
|
10912
|
+
throw new Error(`RateModel is ${data.length} bytes, expected 53`);
|
|
10913
|
+
const v = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
10914
|
+
const u16 = (o) => v.getUint16(o, true);
|
|
10915
|
+
const version = data[40];
|
|
10916
|
+
if (version !== 1 && version !== 2)
|
|
10917
|
+
throw new Error(`RateModel version ${version} not supported`);
|
|
10918
|
+
return {
|
|
10919
|
+
version,
|
|
10920
|
+
rateAtZero: u16(41),
|
|
10921
|
+
kink1: u16(43),
|
|
10922
|
+
rateAtKink1: u16(45),
|
|
10923
|
+
rateAtMax: u16(47),
|
|
10924
|
+
...version === 2 ? { kink2: u16(49), rateAtKink2: u16(51) } : {}
|
|
10925
|
+
};
|
|
10926
|
+
}
|
|
10927
|
+
async function readJlLayerIrms(rpc, market, mints, now = BigInt(Math.floor(Date.now() / 1e3))) {
|
|
10928
|
+
const uniq = [...new Set(mints)];
|
|
10929
|
+
const keys = await Promise.all(
|
|
10930
|
+
uniq.map(async (m2) => ({
|
|
10931
|
+
mint: m2,
|
|
10932
|
+
model: await liq([utf83("rate_model"), await pk3(m2)], market),
|
|
10933
|
+
reserve: await liq([utf83("reserve"), await pk3(m2)], market)
|
|
10934
|
+
}))
|
|
10935
|
+
);
|
|
10936
|
+
const { m } = await read(
|
|
10937
|
+
rpc,
|
|
10938
|
+
keys.flatMap((k) => [k.model, k.reserve])
|
|
10939
|
+
);
|
|
10940
|
+
const out = /* @__PURE__ */ new Map();
|
|
10941
|
+
for (const k of keys) {
|
|
10942
|
+
const ma = m.get(k.model);
|
|
10943
|
+
const ra = m.get(k.reserve);
|
|
10944
|
+
if (!ma || !ra) continue;
|
|
10945
|
+
try {
|
|
10946
|
+
const model = decodeJlRateModel(fromBase643(ma.data[0]));
|
|
10947
|
+
const r = dec("TokenReserve", ra.data[0]);
|
|
10948
|
+
const o = jlOverallTokenData(r, now);
|
|
10949
|
+
const P = JL_EXCHANGE_PRICES_PRECISION;
|
|
10950
|
+
const bWi = Number(big(r.total_borrow_with_interest) * o.borrowEx / P);
|
|
10951
|
+
const sWi = Number(big(r.total_supply_with_interest) * o.supplyEx / P);
|
|
10952
|
+
const tb = Number(o.totalBorrow);
|
|
10953
|
+
const ts = Number(o.totalSupply);
|
|
10954
|
+
const u = ts > 0 ? tb / ts : 0;
|
|
10955
|
+
const ratio2 = u > 0 && sWi > 0 ? bWi / sWi / u : 1;
|
|
10956
|
+
out.set(k.mint, {
|
|
10957
|
+
...model,
|
|
10958
|
+
feeOnInterest: Number(r.fee_on_interest),
|
|
10959
|
+
maxUtilization: Number(o.maxUtilization),
|
|
10960
|
+
supplyWithInterestRatio: Number.isFinite(ratio2) ? ratio2 : 1,
|
|
10961
|
+
lastUtilization: Number(r.last_utilization),
|
|
10962
|
+
borrowRate: Number(r.borrow_rate)
|
|
10963
|
+
});
|
|
10964
|
+
} catch (e) {
|
|
10965
|
+
console.warn(
|
|
10966
|
+
`[jupiter-lend] rate model for ${k.mint} not read: ${e.message}`
|
|
10967
|
+
);
|
|
10968
|
+
}
|
|
10969
|
+
}
|
|
10970
|
+
return out;
|
|
10971
|
+
}
|
|
10882
10972
|
|
|
10883
10973
|
// src/lending/public-data/jupiter-lend/convertPublic.ts
|
|
10884
10974
|
var JL_FACTOR_SCALE = 1e3;
|
|
@@ -11197,6 +11287,22 @@ async function fetchJupiterLendPublic(opts = {}) {
|
|
|
11197
11287
|
}
|
|
11198
11288
|
}
|
|
11199
11289
|
const fromChain = new Map(chain.map((c) => [c.vault.id, c]));
|
|
11290
|
+
let irms = /* @__PURE__ */ new Map();
|
|
11291
|
+
if (opts.rpc) {
|
|
11292
|
+
const mints = /* @__PURE__ */ new Set();
|
|
11293
|
+
for (const v of [...vaults, ...chain.map((c) => c.vault)]) {
|
|
11294
|
+
const cv = fromChain.get(v.id);
|
|
11295
|
+
if (!cv?.smartCol) mints.add(v.supplyToken.address);
|
|
11296
|
+
if (!cv?.smartDebt) mints.add(v.borrowToken.address);
|
|
11297
|
+
}
|
|
11298
|
+
try {
|
|
11299
|
+
irms = await readJlLayerIrms(opts.rpc, market, [...mints]);
|
|
11300
|
+
} catch (e) {
|
|
11301
|
+
console.warn(
|
|
11302
|
+
`[jupiter-lend] layer rate models for ${market} not read: ${e.message}`
|
|
11303
|
+
);
|
|
11304
|
+
}
|
|
11305
|
+
}
|
|
11200
11306
|
for (const v of [...vaults, ...chain.map((c) => c.vault)]) {
|
|
11201
11307
|
if (only && !only.includes(v.id)) continue;
|
|
11202
11308
|
const conv = convertJupiterLendVault(market, v, {
|
|
@@ -11205,6 +11311,15 @@ async function fetchJupiterLendPublic(opts = {}) {
|
|
|
11205
11311
|
layer
|
|
11206
11312
|
});
|
|
11207
11313
|
const cv = fromChain.get(v.id);
|
|
11314
|
+
const mags = {
|
|
11315
|
+
supplyMagnifier: Number(v.supplyRateMagnifier) || 0,
|
|
11316
|
+
borrowMagnifier: Number(v.borrowRateMagnifier) || 0
|
|
11317
|
+
};
|
|
11318
|
+
for (const row of Object.values(conv.data)) {
|
|
11319
|
+
const smart = row.underlying === v.supplyToken.address ? cv?.smartCol : cv?.smartDebt;
|
|
11320
|
+
const irm = smart ? void 0 : irms.get(row.underlying);
|
|
11321
|
+
if (irm) row.jupiterLend = { irm: { ...irm, ...mags } };
|
|
11322
|
+
}
|
|
11208
11323
|
const meta = conv.params.jupiterLendVault;
|
|
11209
11324
|
meta.source = cv ? "chain" : "api";
|
|
11210
11325
|
if (cv) {
|
|
@@ -11256,7 +11371,7 @@ var SAVE_API_BASE = "https://api.save.finance";
|
|
|
11256
11371
|
var SAVE_WAD = 10n ** 18n;
|
|
11257
11372
|
var SAVE_U64_MAX = "18446744073709551615";
|
|
11258
11373
|
var SAVE_SLOTS_PER_YEAR = 63072e3;
|
|
11259
|
-
var SAVE_DEFAULT_AVG_SLOT_SECONDS = 0.
|
|
11374
|
+
var SAVE_DEFAULT_AVG_SLOT_SECONDS = 0.2665;
|
|
11260
11375
|
var SAVE_LIQUIDATION_CLOSE_FACTOR = 0.2;
|
|
11261
11376
|
var SAVE_MAX_LIQUIDATABLE_VALUE_USD = 5e5;
|
|
11262
11377
|
var SAVE_FULL_LIQUIDATION_VALUE_USD = 1;
|
|
@@ -12203,7 +12318,12 @@ function convertLoopscalePair(pair, opts) {
|
|
|
12203
12318
|
termId: t.termId,
|
|
12204
12319
|
durationDays: t.durationDays,
|
|
12205
12320
|
durationSecs: t.durationDays * 86400,
|
|
12206
|
-
apr: t.apr
|
|
12321
|
+
apr: t.apr,
|
|
12322
|
+
ladder: t.ladder.map((l) => ({
|
|
12323
|
+
apr: l.apr,
|
|
12324
|
+
assets: fmt2(l.sum, pDec),
|
|
12325
|
+
fill: "single"
|
|
12326
|
+
}))
|
|
12207
12327
|
}));
|
|
12208
12328
|
const common = {
|
|
12209
12329
|
totalDebtStable: "0",
|
|
@@ -36403,6 +36523,9 @@ async function getLenderPublicData(chainId, opts = {}) {
|
|
|
36403
36523
|
return Object.assign({}, ...parts);
|
|
36404
36524
|
}
|
|
36405
36525
|
|
|
36526
|
+
// src/lending/public-data/getLenderPublicDataAll.ts
|
|
36527
|
+
import { measureSlotSeconds as measureSlotSeconds2 } from "@1delta/svm-kit";
|
|
36528
|
+
|
|
36406
36529
|
// src/lending/public-data/basket.ts
|
|
36407
36530
|
function describeBasket(lenderKey, bundle) {
|
|
36408
36531
|
const brand = lenderBrandKey(lenderKey) ?? lenderKey;
|
|
@@ -36522,12 +36645,15 @@ async function getLenderPublicDataAll(chainId, lenders, opts = {}) {
|
|
|
36522
36645
|
if (chainId !== SOLANA_CHAIN_ID)
|
|
36523
36646
|
throw new Error(`getLenderPublicDataAll: unsupported chain ${chainId}`);
|
|
36524
36647
|
const out = {};
|
|
36648
|
+
const needsSlot = opts.rpc && (lenders.some(isSave) && opts.save?.avgSlotSeconds === void 0 || lenders.some(isKamino) && opts.kamino?.slotSeconds === void 0);
|
|
36649
|
+
const slotSeconds = needsSlot ? await measureSlotSeconds2(opts.rpc) : void 0;
|
|
36525
36650
|
const kaminoKeys = lenders.filter(isKamino);
|
|
36526
36651
|
if (kaminoKeys.length) {
|
|
36527
36652
|
const explicit = kaminoKeys.map(kaminoMarketFromKey).filter((m) => !!m);
|
|
36528
36653
|
const wantsAll = kaminoKeys.some((k) => !kaminoMarketFromKey(k));
|
|
36529
36654
|
const res = await fetchKaminoPublic({
|
|
36530
36655
|
...opts.kamino,
|
|
36656
|
+
slotSeconds: opts.kamino?.slotSeconds ?? slotSeconds,
|
|
36531
36657
|
rpc: opts.kamino?.rpc ?? opts.rpc,
|
|
36532
36658
|
tokenList: opts.tokenList ?? opts.kamino?.tokenList,
|
|
36533
36659
|
...wantsAll ? {} : { markets: explicit }
|
|
@@ -36567,6 +36693,7 @@ async function getLenderPublicDataAll(chainId, lenders, opts = {}) {
|
|
|
36567
36693
|
const wantsAll = saveKeys.some((k) => !saveMarketFromKey(k));
|
|
36568
36694
|
const res = await fetchSavePublic({
|
|
36569
36695
|
...opts.save,
|
|
36696
|
+
avgSlotSeconds: opts.save?.avgSlotSeconds ?? slotSeconds,
|
|
36570
36697
|
tokenList: opts.tokenList ?? opts.save?.tokenList,
|
|
36571
36698
|
...wantsAll ? {} : { markets: explicit }
|
|
36572
36699
|
});
|
|
@@ -36863,6 +36990,8 @@ async function fetchJupiterPrices(mints, tokenList = {}, opts = {}) {
|
|
|
36863
36990
|
for (const [mint, r] of Object.entries(res ?? {})) {
|
|
36864
36991
|
const p = num(r?.usdPrice);
|
|
36865
36992
|
if (!(p > 0)) continue;
|
|
36993
|
+
if (opts.minLiquidityUsd !== void 0 && !(num(r?.liquidity) >= opts.minLiquidityUsd))
|
|
36994
|
+
continue;
|
|
36866
36995
|
byMint[mint] = p;
|
|
36867
36996
|
const stock = num(r?.stockData?.price);
|
|
36868
36997
|
if (stock > 0) stockPriceByMint[mint] = stock;
|
|
@@ -68890,6 +69019,7 @@ export {
|
|
|
68890
69019
|
decodeHumaPoolConfig,
|
|
68891
69020
|
decodeHumaPoolState,
|
|
68892
69021
|
decodeHumaRedemptionRequest,
|
|
69022
|
+
decodeJlRateModel,
|
|
68893
69023
|
decodeJuniorUnlockShare,
|
|
68894
69024
|
decodeJupFlashloanAdmin,
|
|
68895
69025
|
decodeKaminoObligation,
|
|
@@ -69089,6 +69219,7 @@ export {
|
|
|
69089
69219
|
readHumaChainState,
|
|
69090
69220
|
readHumaLenderState,
|
|
69091
69221
|
readHumaRedemptionRequests,
|
|
69222
|
+
readJlLayerIrms,
|
|
69092
69223
|
readJlNextVaultId,
|
|
69093
69224
|
readJupFlashAssets,
|
|
69094
69225
|
readJupFlashAvailable,
|