@1delta/data-sdk 0.0.56 → 0.0.58
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 +144 -28
- package/dist/index.mjs +138 -29
- package/dist/lending/dolomite.d.ts +50 -0
- package/dist/lending/registry.d.ts +2 -1
- package/dist/remoteCache.d.ts +82 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -105,6 +105,7 @@ var LENDER_DATA_DEFAULTS = () => ({
|
|
|
105
105
|
eulerVaults: {},
|
|
106
106
|
dolomiteConfigs: {},
|
|
107
107
|
dolomiteEmode: {},
|
|
108
|
+
dolomiteIsolation: {},
|
|
108
109
|
siloMarkets: {},
|
|
109
110
|
siloPeripherals: {},
|
|
110
111
|
siloMarketsV3: {},
|
|
@@ -298,9 +299,24 @@ function parseGearboxV3LenderKey(lenderKey) {
|
|
|
298
299
|
|
|
299
300
|
// src/lending/dolomite.ts
|
|
300
301
|
var dolomiteConfigs = () => getGlobalData2()?.dolomiteConfigs;
|
|
302
|
+
var DOLOMITE_ROUTER_DEFAULTS = {
|
|
303
|
+
depositWithdrawalRouter: "0xf8b2c637A68cF6A17b1DF9F8992EeBeFf63d2dFf",
|
|
304
|
+
borrowPositionRouter: "0xF579b345cdA0860668b857De10ABD62442133D0F",
|
|
305
|
+
genericTraderRouter: "0x7b61CbA306CfdB02493b94757143132B1b72Bc6b"
|
|
306
|
+
};
|
|
307
|
+
var dolomiteRouters = (chainId) => {
|
|
308
|
+
const cfg = getGlobalData2()?.dolomiteConfigs?.[chainId];
|
|
309
|
+
return {
|
|
310
|
+
depositWithdrawalRouter: cfg?.depositWithdrawalRouter ?? DOLOMITE_ROUTER_DEFAULTS.depositWithdrawalRouter,
|
|
311
|
+
borrowPositionRouter: cfg?.borrowPositionRouter ?? DOLOMITE_ROUTER_DEFAULTS.borrowPositionRouter,
|
|
312
|
+
genericTraderRouter: cfg?.genericTraderRouter ?? DOLOMITE_ROUTER_DEFAULTS.genericTraderRouter
|
|
313
|
+
};
|
|
314
|
+
};
|
|
301
315
|
var dolomiteOdosExecutorShim = (chainId) => getGlobalData2()?.dolomiteConfigs?.[chainId]?.odosExecutor;
|
|
302
316
|
var dolomiteChains = () => Object.keys(getGlobalData2()?.dolomiteConfigs ?? {});
|
|
303
317
|
var dolomiteEmode = () => getGlobalData2()?.dolomiteEmode;
|
|
318
|
+
var dolomiteIsolation = () => getGlobalData2()?.dolomiteIsolation;
|
|
319
|
+
var dolomiteIsolationMarket = (chainId, marketId) => getGlobalData2()?.dolomiteIsolation?.[chainId]?.[String(marketId)];
|
|
304
320
|
var dolomiteMarketIdByToken = (chainId, token) => {
|
|
305
321
|
const markets = getGlobalData2()?.dolomiteConfigs?.[chainId]?.markets;
|
|
306
322
|
if (!markets) return void 0;
|
|
@@ -1034,17 +1050,32 @@ var parseFraxlendPairKey = (lender) => {
|
|
|
1034
1050
|
var FRESH_TTL_MS = 5 * 60 * 1e3;
|
|
1035
1051
|
var STALE_WHILE_REVALIDATE_MS = 12 * 60 * 60 * 1e3;
|
|
1036
1052
|
var REMOTE_CACHE_STORE_TTL_S = 7 * 24 * 60 * 60;
|
|
1053
|
+
var STUCK_REVALIDATE_MS = 60 * 1e3;
|
|
1054
|
+
var MISSING_TTL_MS = FRESH_TTL_MS;
|
|
1037
1055
|
var STATE_KEY = "__1delta_remote_cache__";
|
|
1038
1056
|
function getState() {
|
|
1039
1057
|
const g = globalThis;
|
|
1040
|
-
if (!g[STATE_KEY])
|
|
1058
|
+
if (!g[STATE_KEY]) {
|
|
1059
|
+
g[STATE_KEY] = {
|
|
1060
|
+
memo: /* @__PURE__ */ new Map(),
|
|
1061
|
+
inflight: /* @__PURE__ */ new Map(),
|
|
1062
|
+
revalidating: /* @__PURE__ */ new Map(),
|
|
1063
|
+
missing: /* @__PURE__ */ new Map(),
|
|
1064
|
+
loaders: /* @__PURE__ */ new Map()
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1041
1067
|
const state = g[STATE_KEY];
|
|
1042
|
-
if (!state.revalidating) state.revalidating = /* @__PURE__ */ new
|
|
1068
|
+
if (!(state.revalidating instanceof Map)) state.revalidating = /* @__PURE__ */ new Map();
|
|
1069
|
+
if (!state.missing) state.missing = /* @__PURE__ */ new Map();
|
|
1070
|
+
if (!state.loaders) state.loaders = /* @__PURE__ */ new Map();
|
|
1043
1071
|
return state;
|
|
1044
1072
|
}
|
|
1045
1073
|
function setRemoteCacheStore(next) {
|
|
1046
1074
|
getState().store = next;
|
|
1047
1075
|
}
|
|
1076
|
+
function setRemoteCacheWaitUntil(next) {
|
|
1077
|
+
getState().waitUntil = next;
|
|
1078
|
+
}
|
|
1048
1079
|
function setRemoteCacheGithubToken(token) {
|
|
1049
1080
|
getState().githubToken = token;
|
|
1050
1081
|
}
|
|
@@ -1052,7 +1083,11 @@ function clearRemoteCache() {
|
|
|
1052
1083
|
const state = getState();
|
|
1053
1084
|
state.memo.clear();
|
|
1054
1085
|
state.inflight.clear();
|
|
1086
|
+
state.revalidating.clear();
|
|
1087
|
+
state.missing.clear();
|
|
1088
|
+
state.loaders.clear();
|
|
1055
1089
|
}
|
|
1090
|
+
var tokenListCacheKey = (chainId) => `token-list:${chainId}`;
|
|
1056
1091
|
var RAW_HOST = "https://raw.githubusercontent.com/";
|
|
1057
1092
|
function githubApiMirror(url) {
|
|
1058
1093
|
if (!url.startsWith(RAW_HOST)) return void 0;
|
|
@@ -1100,11 +1135,21 @@ async function readStore(key, isValid) {
|
|
|
1100
1135
|
const { store } = getState();
|
|
1101
1136
|
if (!store) return void 0;
|
|
1102
1137
|
try {
|
|
1103
|
-
|
|
1138
|
+
let raw;
|
|
1139
|
+
let metaAt;
|
|
1140
|
+
if (store.getWithMetadata) {
|
|
1141
|
+
const got = await store.getWithMetadata(storeKey(key));
|
|
1142
|
+
raw = got.value;
|
|
1143
|
+
if (typeof got.metadata?.at === "number") metaAt = got.metadata.at;
|
|
1144
|
+
} else {
|
|
1145
|
+
raw = await store.get(storeKey(key));
|
|
1146
|
+
}
|
|
1104
1147
|
if (!raw) return void 0;
|
|
1105
1148
|
const parsed = JSON.parse(raw);
|
|
1106
|
-
if (
|
|
1107
|
-
|
|
1149
|
+
if (!isValid(parsed?.value)) return void 0;
|
|
1150
|
+
const at = metaAt ?? parsed?.at;
|
|
1151
|
+
if (typeof at !== "number") return void 0;
|
|
1152
|
+
return { at, value: parsed.value };
|
|
1108
1153
|
} catch {
|
|
1109
1154
|
return void 0;
|
|
1110
1155
|
}
|
|
@@ -1113,50 +1158,106 @@ async function writeStore(key, entry) {
|
|
|
1113
1158
|
const { store } = getState();
|
|
1114
1159
|
if (!store) return;
|
|
1115
1160
|
try {
|
|
1116
|
-
|
|
1161
|
+
const body = JSON.stringify(entry);
|
|
1162
|
+
if (store.putWithMetadata) {
|
|
1163
|
+
await store.putWithMetadata(storeKey(key), body, REMOTE_CACHE_STORE_TTL_S, { at: entry.at });
|
|
1164
|
+
} else {
|
|
1165
|
+
await store.put(storeKey(key), body, REMOTE_CACHE_STORE_TTL_S);
|
|
1166
|
+
}
|
|
1167
|
+
} catch {
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
function background(promise) {
|
|
1171
|
+
const { waitUntil } = getState();
|
|
1172
|
+
if (!waitUntil) return;
|
|
1173
|
+
try {
|
|
1174
|
+
waitUntil(promise);
|
|
1117
1175
|
} catch {
|
|
1118
1176
|
}
|
|
1119
1177
|
}
|
|
1178
|
+
function adopt(key, entry) {
|
|
1179
|
+
const { memo } = getState();
|
|
1180
|
+
const current = memo.get(key);
|
|
1181
|
+
if (!current || current.at <= entry.at) memo.set(key, entry);
|
|
1182
|
+
}
|
|
1183
|
+
var negativeCacheError = (entry) => new RemoteFetchError(entry.message, entry.status);
|
|
1184
|
+
function revalidate(key, loader, preferStore) {
|
|
1185
|
+
const state = getState();
|
|
1186
|
+
const existing = state.revalidating.get(key);
|
|
1187
|
+
if (existing && Date.now() - existing.startedAt < STUCK_REVALIDATE_MS) return existing.promise;
|
|
1188
|
+
const entry = { startedAt: Date.now(), promise: Promise.resolve(false) };
|
|
1189
|
+
entry.promise = (async () => {
|
|
1190
|
+
try {
|
|
1191
|
+
const mine = state.memo.get(key);
|
|
1192
|
+
if (preferStore && state.store) {
|
|
1193
|
+
const stored = await readStore(key, loader.isValid);
|
|
1194
|
+
if (stored && stored.at > (mine?.at ?? 0) && Date.now() - stored.at < FRESH_TTL_MS) {
|
|
1195
|
+
adopt(key, stored);
|
|
1196
|
+
return true;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
const value = await loader.load();
|
|
1200
|
+
const fresh = { at: Date.now(), value };
|
|
1201
|
+
adopt(key, fresh);
|
|
1202
|
+
state.missing.delete(key);
|
|
1203
|
+
await writeStore(key, fresh);
|
|
1204
|
+
return true;
|
|
1205
|
+
} catch {
|
|
1206
|
+
return false;
|
|
1207
|
+
} finally {
|
|
1208
|
+
if (state.revalidating.get(key) === entry) state.revalidating.delete(key);
|
|
1209
|
+
}
|
|
1210
|
+
})();
|
|
1211
|
+
state.revalidating.set(key, entry);
|
|
1212
|
+
return entry.promise;
|
|
1213
|
+
}
|
|
1120
1214
|
async function loadCached(key, load, isValid) {
|
|
1121
|
-
const
|
|
1215
|
+
const state = getState();
|
|
1216
|
+
const { memo, inflight } = state;
|
|
1217
|
+
const loader = { load, isValid };
|
|
1218
|
+
state.loaders.set(key, loader);
|
|
1122
1219
|
const cached = memo.get(key);
|
|
1123
|
-
if (cached
|
|
1220
|
+
if (cached) {
|
|
1221
|
+
const age = Date.now() - cached.at;
|
|
1222
|
+
if (age < FRESH_TTL_MS) return cached.value;
|
|
1223
|
+
if (age < STALE_WHILE_REVALIDATE_MS) {
|
|
1224
|
+
background(revalidate(key, loader, true));
|
|
1225
|
+
return cached.value;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
const missing = state.missing.get(key);
|
|
1229
|
+
if (missing && Date.now() - missing.at < MISSING_TTL_MS) throw negativeCacheError(missing);
|
|
1124
1230
|
const pending = inflight.get(key);
|
|
1125
1231
|
if (pending) return pending;
|
|
1126
1232
|
const task = (async () => {
|
|
1127
1233
|
const stored = await readStore(key, isValid);
|
|
1128
1234
|
if (stored && Date.now() - stored.at < FRESH_TTL_MS) {
|
|
1129
|
-
|
|
1235
|
+
adopt(key, stored);
|
|
1130
1236
|
return stored.value;
|
|
1131
1237
|
}
|
|
1132
1238
|
if (stored && Date.now() - stored.at < STALE_WHILE_REVALIDATE_MS) {
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
revalidating.add(key);
|
|
1136
|
-
void (async () => {
|
|
1137
|
-
try {
|
|
1138
|
-
const value = await load();
|
|
1139
|
-
const entry = { at: Date.now(), value };
|
|
1140
|
-
const current = memo.get(key);
|
|
1141
|
-
if (!current || current.at <= entry.at) memo.set(key, entry);
|
|
1142
|
-
await writeStore(key, entry);
|
|
1143
|
-
} catch {
|
|
1144
|
-
} finally {
|
|
1145
|
-
revalidating.delete(key);
|
|
1146
|
-
}
|
|
1147
|
-
})();
|
|
1239
|
+
adopt(key, stored);
|
|
1240
|
+
background(revalidate(key, loader, false));
|
|
1148
1241
|
return stored.value;
|
|
1149
1242
|
}
|
|
1150
1243
|
try {
|
|
1151
1244
|
const value = await load();
|
|
1152
1245
|
const entry = { at: Date.now(), value };
|
|
1153
|
-
|
|
1154
|
-
|
|
1246
|
+
adopt(key, entry);
|
|
1247
|
+
state.missing.delete(key);
|
|
1248
|
+
const put = writeStore(key, entry);
|
|
1249
|
+
if (state.waitUntil) background(put);
|
|
1250
|
+
else await put;
|
|
1155
1251
|
return value;
|
|
1156
1252
|
} catch (error) {
|
|
1157
1253
|
const stale = memo.get(key) ?? stored;
|
|
1158
|
-
if (!stale)
|
|
1159
|
-
|
|
1254
|
+
if (!stale) {
|
|
1255
|
+
if (error instanceof RemoteFetchError && error.isMissing) {
|
|
1256
|
+
state.missing.set(key, { at: Date.now(), status: error.status, message: error.message });
|
|
1257
|
+
}
|
|
1258
|
+
throw error;
|
|
1259
|
+
}
|
|
1260
|
+
adopt(key, stale);
|
|
1160
1261
|
return stale.value;
|
|
1161
1262
|
}
|
|
1162
1263
|
})().finally(() => {
|
|
@@ -1165,6 +1266,14 @@ async function loadCached(key, load, isValid) {
|
|
|
1165
1266
|
inflight.set(key, task);
|
|
1166
1267
|
return task;
|
|
1167
1268
|
}
|
|
1269
|
+
async function refreshRemoteCache(key, opts = {}) {
|
|
1270
|
+
const state = getState();
|
|
1271
|
+
const loader = state.loaders.get(key);
|
|
1272
|
+
if (!loader) return "unknown";
|
|
1273
|
+
const cached = state.memo.get(key);
|
|
1274
|
+
if (cached && opts.maxAgeMs !== void 0 && Date.now() - cached.at < opts.maxAgeMs) return "fresh";
|
|
1275
|
+
return await revalidate(key, loader, false) ? "refreshed" : "failed";
|
|
1276
|
+
}
|
|
1168
1277
|
async function loadCachedJson(key, url, isValid, label = key) {
|
|
1169
1278
|
return loadCached(key, () => fetchRemoteJson(url, label), isValid);
|
|
1170
1279
|
}
|
|
@@ -1215,6 +1324,7 @@ async function fetchMainTokensMap() {
|
|
|
1215
1324
|
|
|
1216
1325
|
exports.COOLER_ETHEREUM_CONFIG = COOLER_ETHEREUM_CONFIG;
|
|
1217
1326
|
exports.CURVANCE_MONAD_CONFIG = CURVANCE_MONAD_CONFIG;
|
|
1327
|
+
exports.DOLOMITE_ROUTER_DEFAULTS = DOLOMITE_ROUTER_DEFAULTS;
|
|
1218
1328
|
exports.FRAXLEND_ETHEREUM_CONFIG = FRAXLEND_ETHEREUM_CONFIG;
|
|
1219
1329
|
exports.GEARBOX_ACCOUNT_COMPRESSOR_V310 = GEARBOX_ACCOUNT_COMPRESSOR_V310;
|
|
1220
1330
|
exports.REMOTE_CACHE_STORE_TTL_S = REMOTE_CACHE_STORE_TTL_S;
|
|
@@ -1256,8 +1366,11 @@ exports.curvancePositionManagersFor = curvancePositionManagersFor;
|
|
|
1256
1366
|
exports.dolomiteChains = dolomiteChains;
|
|
1257
1367
|
exports.dolomiteConfigs = dolomiteConfigs;
|
|
1258
1368
|
exports.dolomiteEmode = dolomiteEmode;
|
|
1369
|
+
exports.dolomiteIsolation = dolomiteIsolation;
|
|
1370
|
+
exports.dolomiteIsolationMarket = dolomiteIsolationMarket;
|
|
1259
1371
|
exports.dolomiteMarketIdByToken = dolomiteMarketIdByToken;
|
|
1260
1372
|
exports.dolomiteOdosExecutorShim = dolomiteOdosExecutorShim;
|
|
1373
|
+
exports.dolomiteRouters = dolomiteRouters;
|
|
1261
1374
|
exports.dssChainData = dssChainData;
|
|
1262
1375
|
exports.dssConfigFor = dssConfigFor;
|
|
1263
1376
|
exports.dssDebtJoin = dssDebtJoin;
|
|
@@ -1372,6 +1485,7 @@ exports.parseMidnightRef = parseMidnightRef;
|
|
|
1372
1485
|
exports.parseSiloV2LenderKey = parseSiloV2LenderKey;
|
|
1373
1486
|
exports.parseSiloV3LenderKey = parseSiloV3LenderKey;
|
|
1374
1487
|
exports.parseTermMaxLenderKey = parseTermMaxLenderKey;
|
|
1488
|
+
exports.refreshRemoteCache = refreshRemoteCache;
|
|
1375
1489
|
exports.resolveMidnightApiBase = resolveMidnightApiBase;
|
|
1376
1490
|
exports.resolveTenorApiUrl = resolveTenorApiUrl;
|
|
1377
1491
|
exports.resolveTermApiBase = resolveTermApiBase;
|
|
@@ -1388,6 +1502,7 @@ exports.riverMarkets = riverMarkets;
|
|
|
1388
1502
|
exports.setMidnightApiBase = setMidnightApiBase;
|
|
1389
1503
|
exports.setRemoteCacheGithubToken = setRemoteCacheGithubToken;
|
|
1390
1504
|
exports.setRemoteCacheStore = setRemoteCacheStore;
|
|
1505
|
+
exports.setRemoteCacheWaitUntil = setRemoteCacheWaitUntil;
|
|
1391
1506
|
exports.setTenorApiUrl = setTenorApiUrl;
|
|
1392
1507
|
exports.setTermApiBase = setTermApiBase;
|
|
1393
1508
|
exports.setTermOrderStoreBase = setTermOrderStoreBase;
|
|
@@ -1419,6 +1534,7 @@ exports.termMaxConfig = termMaxConfig;
|
|
|
1419
1534
|
exports.termMaxConfigByChain = termMaxConfigByChain;
|
|
1420
1535
|
exports.termMaxLenderKey = termMaxLenderKey;
|
|
1421
1536
|
exports.termOrderStoreBaseOverride = termOrderStoreBaseOverride;
|
|
1537
|
+
exports.tokenListCacheKey = tokenListCacheKey;
|
|
1422
1538
|
exports.twyneBaseKey = twyneBaseKey;
|
|
1423
1539
|
exports.twyneBeaconFor = twyneBeaconFor;
|
|
1424
1540
|
exports.twyneChainData = twyneChainData;
|
package/dist/index.mjs
CHANGED
|
@@ -103,6 +103,7 @@ var LENDER_DATA_DEFAULTS = () => ({
|
|
|
103
103
|
eulerVaults: {},
|
|
104
104
|
dolomiteConfigs: {},
|
|
105
105
|
dolomiteEmode: {},
|
|
106
|
+
dolomiteIsolation: {},
|
|
106
107
|
siloMarkets: {},
|
|
107
108
|
siloPeripherals: {},
|
|
108
109
|
siloMarketsV3: {},
|
|
@@ -296,9 +297,24 @@ function parseGearboxV3LenderKey(lenderKey) {
|
|
|
296
297
|
|
|
297
298
|
// src/lending/dolomite.ts
|
|
298
299
|
var dolomiteConfigs = () => getGlobalData2()?.dolomiteConfigs;
|
|
300
|
+
var DOLOMITE_ROUTER_DEFAULTS = {
|
|
301
|
+
depositWithdrawalRouter: "0xf8b2c637A68cF6A17b1DF9F8992EeBeFf63d2dFf",
|
|
302
|
+
borrowPositionRouter: "0xF579b345cdA0860668b857De10ABD62442133D0F",
|
|
303
|
+
genericTraderRouter: "0x7b61CbA306CfdB02493b94757143132B1b72Bc6b"
|
|
304
|
+
};
|
|
305
|
+
var dolomiteRouters = (chainId) => {
|
|
306
|
+
const cfg = getGlobalData2()?.dolomiteConfigs?.[chainId];
|
|
307
|
+
return {
|
|
308
|
+
depositWithdrawalRouter: cfg?.depositWithdrawalRouter ?? DOLOMITE_ROUTER_DEFAULTS.depositWithdrawalRouter,
|
|
309
|
+
borrowPositionRouter: cfg?.borrowPositionRouter ?? DOLOMITE_ROUTER_DEFAULTS.borrowPositionRouter,
|
|
310
|
+
genericTraderRouter: cfg?.genericTraderRouter ?? DOLOMITE_ROUTER_DEFAULTS.genericTraderRouter
|
|
311
|
+
};
|
|
312
|
+
};
|
|
299
313
|
var dolomiteOdosExecutorShim = (chainId) => getGlobalData2()?.dolomiteConfigs?.[chainId]?.odosExecutor;
|
|
300
314
|
var dolomiteChains = () => Object.keys(getGlobalData2()?.dolomiteConfigs ?? {});
|
|
301
315
|
var dolomiteEmode = () => getGlobalData2()?.dolomiteEmode;
|
|
316
|
+
var dolomiteIsolation = () => getGlobalData2()?.dolomiteIsolation;
|
|
317
|
+
var dolomiteIsolationMarket = (chainId, marketId) => getGlobalData2()?.dolomiteIsolation?.[chainId]?.[String(marketId)];
|
|
302
318
|
var dolomiteMarketIdByToken = (chainId, token) => {
|
|
303
319
|
const markets = getGlobalData2()?.dolomiteConfigs?.[chainId]?.markets;
|
|
304
320
|
if (!markets) return void 0;
|
|
@@ -1032,17 +1048,32 @@ var parseFraxlendPairKey = (lender) => {
|
|
|
1032
1048
|
var FRESH_TTL_MS = 5 * 60 * 1e3;
|
|
1033
1049
|
var STALE_WHILE_REVALIDATE_MS = 12 * 60 * 60 * 1e3;
|
|
1034
1050
|
var REMOTE_CACHE_STORE_TTL_S = 7 * 24 * 60 * 60;
|
|
1051
|
+
var STUCK_REVALIDATE_MS = 60 * 1e3;
|
|
1052
|
+
var MISSING_TTL_MS = FRESH_TTL_MS;
|
|
1035
1053
|
var STATE_KEY = "__1delta_remote_cache__";
|
|
1036
1054
|
function getState() {
|
|
1037
1055
|
const g = globalThis;
|
|
1038
|
-
if (!g[STATE_KEY])
|
|
1056
|
+
if (!g[STATE_KEY]) {
|
|
1057
|
+
g[STATE_KEY] = {
|
|
1058
|
+
memo: /* @__PURE__ */ new Map(),
|
|
1059
|
+
inflight: /* @__PURE__ */ new Map(),
|
|
1060
|
+
revalidating: /* @__PURE__ */ new Map(),
|
|
1061
|
+
missing: /* @__PURE__ */ new Map(),
|
|
1062
|
+
loaders: /* @__PURE__ */ new Map()
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1039
1065
|
const state = g[STATE_KEY];
|
|
1040
|
-
if (!state.revalidating) state.revalidating = /* @__PURE__ */ new
|
|
1066
|
+
if (!(state.revalidating instanceof Map)) state.revalidating = /* @__PURE__ */ new Map();
|
|
1067
|
+
if (!state.missing) state.missing = /* @__PURE__ */ new Map();
|
|
1068
|
+
if (!state.loaders) state.loaders = /* @__PURE__ */ new Map();
|
|
1041
1069
|
return state;
|
|
1042
1070
|
}
|
|
1043
1071
|
function setRemoteCacheStore(next) {
|
|
1044
1072
|
getState().store = next;
|
|
1045
1073
|
}
|
|
1074
|
+
function setRemoteCacheWaitUntil(next) {
|
|
1075
|
+
getState().waitUntil = next;
|
|
1076
|
+
}
|
|
1046
1077
|
function setRemoteCacheGithubToken(token) {
|
|
1047
1078
|
getState().githubToken = token;
|
|
1048
1079
|
}
|
|
@@ -1050,7 +1081,11 @@ function clearRemoteCache() {
|
|
|
1050
1081
|
const state = getState();
|
|
1051
1082
|
state.memo.clear();
|
|
1052
1083
|
state.inflight.clear();
|
|
1084
|
+
state.revalidating.clear();
|
|
1085
|
+
state.missing.clear();
|
|
1086
|
+
state.loaders.clear();
|
|
1053
1087
|
}
|
|
1088
|
+
var tokenListCacheKey = (chainId) => `token-list:${chainId}`;
|
|
1054
1089
|
var RAW_HOST = "https://raw.githubusercontent.com/";
|
|
1055
1090
|
function githubApiMirror(url) {
|
|
1056
1091
|
if (!url.startsWith(RAW_HOST)) return void 0;
|
|
@@ -1098,11 +1133,21 @@ async function readStore(key, isValid) {
|
|
|
1098
1133
|
const { store } = getState();
|
|
1099
1134
|
if (!store) return void 0;
|
|
1100
1135
|
try {
|
|
1101
|
-
|
|
1136
|
+
let raw;
|
|
1137
|
+
let metaAt;
|
|
1138
|
+
if (store.getWithMetadata) {
|
|
1139
|
+
const got = await store.getWithMetadata(storeKey(key));
|
|
1140
|
+
raw = got.value;
|
|
1141
|
+
if (typeof got.metadata?.at === "number") metaAt = got.metadata.at;
|
|
1142
|
+
} else {
|
|
1143
|
+
raw = await store.get(storeKey(key));
|
|
1144
|
+
}
|
|
1102
1145
|
if (!raw) return void 0;
|
|
1103
1146
|
const parsed = JSON.parse(raw);
|
|
1104
|
-
if (
|
|
1105
|
-
|
|
1147
|
+
if (!isValid(parsed?.value)) return void 0;
|
|
1148
|
+
const at = metaAt ?? parsed?.at;
|
|
1149
|
+
if (typeof at !== "number") return void 0;
|
|
1150
|
+
return { at, value: parsed.value };
|
|
1106
1151
|
} catch {
|
|
1107
1152
|
return void 0;
|
|
1108
1153
|
}
|
|
@@ -1111,50 +1156,106 @@ async function writeStore(key, entry) {
|
|
|
1111
1156
|
const { store } = getState();
|
|
1112
1157
|
if (!store) return;
|
|
1113
1158
|
try {
|
|
1114
|
-
|
|
1159
|
+
const body = JSON.stringify(entry);
|
|
1160
|
+
if (store.putWithMetadata) {
|
|
1161
|
+
await store.putWithMetadata(storeKey(key), body, REMOTE_CACHE_STORE_TTL_S, { at: entry.at });
|
|
1162
|
+
} else {
|
|
1163
|
+
await store.put(storeKey(key), body, REMOTE_CACHE_STORE_TTL_S);
|
|
1164
|
+
}
|
|
1165
|
+
} catch {
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
function background(promise) {
|
|
1169
|
+
const { waitUntil } = getState();
|
|
1170
|
+
if (!waitUntil) return;
|
|
1171
|
+
try {
|
|
1172
|
+
waitUntil(promise);
|
|
1115
1173
|
} catch {
|
|
1116
1174
|
}
|
|
1117
1175
|
}
|
|
1176
|
+
function adopt(key, entry) {
|
|
1177
|
+
const { memo } = getState();
|
|
1178
|
+
const current = memo.get(key);
|
|
1179
|
+
if (!current || current.at <= entry.at) memo.set(key, entry);
|
|
1180
|
+
}
|
|
1181
|
+
var negativeCacheError = (entry) => new RemoteFetchError(entry.message, entry.status);
|
|
1182
|
+
function revalidate(key, loader, preferStore) {
|
|
1183
|
+
const state = getState();
|
|
1184
|
+
const existing = state.revalidating.get(key);
|
|
1185
|
+
if (existing && Date.now() - existing.startedAt < STUCK_REVALIDATE_MS) return existing.promise;
|
|
1186
|
+
const entry = { startedAt: Date.now(), promise: Promise.resolve(false) };
|
|
1187
|
+
entry.promise = (async () => {
|
|
1188
|
+
try {
|
|
1189
|
+
const mine = state.memo.get(key);
|
|
1190
|
+
if (preferStore && state.store) {
|
|
1191
|
+
const stored = await readStore(key, loader.isValid);
|
|
1192
|
+
if (stored && stored.at > (mine?.at ?? 0) && Date.now() - stored.at < FRESH_TTL_MS) {
|
|
1193
|
+
adopt(key, stored);
|
|
1194
|
+
return true;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
const value = await loader.load();
|
|
1198
|
+
const fresh = { at: Date.now(), value };
|
|
1199
|
+
adopt(key, fresh);
|
|
1200
|
+
state.missing.delete(key);
|
|
1201
|
+
await writeStore(key, fresh);
|
|
1202
|
+
return true;
|
|
1203
|
+
} catch {
|
|
1204
|
+
return false;
|
|
1205
|
+
} finally {
|
|
1206
|
+
if (state.revalidating.get(key) === entry) state.revalidating.delete(key);
|
|
1207
|
+
}
|
|
1208
|
+
})();
|
|
1209
|
+
state.revalidating.set(key, entry);
|
|
1210
|
+
return entry.promise;
|
|
1211
|
+
}
|
|
1118
1212
|
async function loadCached(key, load, isValid) {
|
|
1119
|
-
const
|
|
1213
|
+
const state = getState();
|
|
1214
|
+
const { memo, inflight } = state;
|
|
1215
|
+
const loader = { load, isValid };
|
|
1216
|
+
state.loaders.set(key, loader);
|
|
1120
1217
|
const cached = memo.get(key);
|
|
1121
|
-
if (cached
|
|
1218
|
+
if (cached) {
|
|
1219
|
+
const age = Date.now() - cached.at;
|
|
1220
|
+
if (age < FRESH_TTL_MS) return cached.value;
|
|
1221
|
+
if (age < STALE_WHILE_REVALIDATE_MS) {
|
|
1222
|
+
background(revalidate(key, loader, true));
|
|
1223
|
+
return cached.value;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
const missing = state.missing.get(key);
|
|
1227
|
+
if (missing && Date.now() - missing.at < MISSING_TTL_MS) throw negativeCacheError(missing);
|
|
1122
1228
|
const pending = inflight.get(key);
|
|
1123
1229
|
if (pending) return pending;
|
|
1124
1230
|
const task = (async () => {
|
|
1125
1231
|
const stored = await readStore(key, isValid);
|
|
1126
1232
|
if (stored && Date.now() - stored.at < FRESH_TTL_MS) {
|
|
1127
|
-
|
|
1233
|
+
adopt(key, stored);
|
|
1128
1234
|
return stored.value;
|
|
1129
1235
|
}
|
|
1130
1236
|
if (stored && Date.now() - stored.at < STALE_WHILE_REVALIDATE_MS) {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
revalidating.add(key);
|
|
1134
|
-
void (async () => {
|
|
1135
|
-
try {
|
|
1136
|
-
const value = await load();
|
|
1137
|
-
const entry = { at: Date.now(), value };
|
|
1138
|
-
const current = memo.get(key);
|
|
1139
|
-
if (!current || current.at <= entry.at) memo.set(key, entry);
|
|
1140
|
-
await writeStore(key, entry);
|
|
1141
|
-
} catch {
|
|
1142
|
-
} finally {
|
|
1143
|
-
revalidating.delete(key);
|
|
1144
|
-
}
|
|
1145
|
-
})();
|
|
1237
|
+
adopt(key, stored);
|
|
1238
|
+
background(revalidate(key, loader, false));
|
|
1146
1239
|
return stored.value;
|
|
1147
1240
|
}
|
|
1148
1241
|
try {
|
|
1149
1242
|
const value = await load();
|
|
1150
1243
|
const entry = { at: Date.now(), value };
|
|
1151
|
-
|
|
1152
|
-
|
|
1244
|
+
adopt(key, entry);
|
|
1245
|
+
state.missing.delete(key);
|
|
1246
|
+
const put = writeStore(key, entry);
|
|
1247
|
+
if (state.waitUntil) background(put);
|
|
1248
|
+
else await put;
|
|
1153
1249
|
return value;
|
|
1154
1250
|
} catch (error) {
|
|
1155
1251
|
const stale = memo.get(key) ?? stored;
|
|
1156
|
-
if (!stale)
|
|
1157
|
-
|
|
1252
|
+
if (!stale) {
|
|
1253
|
+
if (error instanceof RemoteFetchError && error.isMissing) {
|
|
1254
|
+
state.missing.set(key, { at: Date.now(), status: error.status, message: error.message });
|
|
1255
|
+
}
|
|
1256
|
+
throw error;
|
|
1257
|
+
}
|
|
1258
|
+
adopt(key, stale);
|
|
1158
1259
|
return stale.value;
|
|
1159
1260
|
}
|
|
1160
1261
|
})().finally(() => {
|
|
@@ -1163,6 +1264,14 @@ async function loadCached(key, load, isValid) {
|
|
|
1163
1264
|
inflight.set(key, task);
|
|
1164
1265
|
return task;
|
|
1165
1266
|
}
|
|
1267
|
+
async function refreshRemoteCache(key, opts = {}) {
|
|
1268
|
+
const state = getState();
|
|
1269
|
+
const loader = state.loaders.get(key);
|
|
1270
|
+
if (!loader) return "unknown";
|
|
1271
|
+
const cached = state.memo.get(key);
|
|
1272
|
+
if (cached && opts.maxAgeMs !== void 0 && Date.now() - cached.at < opts.maxAgeMs) return "fresh";
|
|
1273
|
+
return await revalidate(key, loader, false) ? "refreshed" : "failed";
|
|
1274
|
+
}
|
|
1166
1275
|
async function loadCachedJson(key, url, isValid, label = key) {
|
|
1167
1276
|
return loadCached(key, () => fetchRemoteJson(url, label), isValid);
|
|
1168
1277
|
}
|
|
@@ -1211,4 +1320,4 @@ async function fetchMainTokensMap() {
|
|
|
1211
1320
|
}
|
|
1212
1321
|
}
|
|
1213
1322
|
|
|
1214
|
-
export { COOLER_ETHEREUM_CONFIG, CURVANCE_MONAD_CONFIG, FRAXLEND_ETHEREUM_CONFIG, GEARBOX_ACCOUNT_COMPRESSOR_V310, REMOTE_CACHE_STORE_TTL_S, RESUPPLY_ETHEREUM_CONFIG, RemoteFetchError, aaveOracles, aaveOraclesConfig, aavePools, aaveReserves, aaveTokens, aaveV4Oracles, aaveV4Peripherals, aaveV4SpokeLenderKey, aaveV4Spokes, aaveWethGateway, assertTwyneKeysUnique, chainLogoURI, chains, clearRemoteCache, compoundV2Oracles, compoundV2OraclesConfig, compoundV2Pools, compoundV2Reserves, compoundV2TokenArray, compoundV2Tokens, compoundV3BaseData, compoundV3Bulker, compoundV3OraclesData, compoundV3Pools, compoundV3Reserves, coolerConfig, coolerConfigFor, coolerLendersByChain, curvanceConfig, curvanceConfigFor, curvanceLendersByChain, curvancePositionManager, curvancePositionManagersFor, dolomiteChains, dolomiteConfigs, dolomiteEmode, dolomiteMarketIdByToken, dolomiteOdosExecutorShim, dssChainData, dssConfigFor, dssDebtJoin, dssDebtToken, dssMarketByIlk, eulerConfigs, eulerVaults, exactlyConfig, exactlyMarketByAddress, exactlyMarketByAsset, exactlyMarkets, exactlyMarketsByChain, fetchMainTokensMap, fetchRemoteJson, fetchTokenList, fetchTokenListFile, fetchTokenLists, findAaveV4PositionManager, fluidChains, fluidResolvers, fluidVaultEntries, fluidVaults, flyingTulipAssets, flyingTulipAssetsFor, flyingTulipConfig, flyingTulipConfigFor, flyingTulipLendersByChain, frankencoinChainData, frankencoinConfig, frankencoinConfigFor, frankencoinLendersByChain, frankencoinMarketByPosition, frankencoinMarkets, fraxlendConfig, fraxlendConfigFor, fraxlendLendersByChain, fraxlendPairKey, fraxlendPairsFor, gearboxAccountCompressor, gearboxAddressProviderV310, gearboxBotListV3, gearboxChains, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxResolvers, gearboxV3LenderKey, getAaveV4GatewayAddresses, getAaveV4PositionManagers, getAaveV4SpokeAccess, getAaveV4SpokeEntry, getAaveV4SpokePeripherals, getChainEntries, getSiloV2MarketEntry, getSiloV3MarketEntry, initConfig, initializeChainData, initializeLenderData, inverseChainData, inverseConfig, inverseConfigFor, inverseLendersByChain, inverseMarketByAddress, inverseMarkets, isAaveV4OperationRestricted, isListaSmartLpAsset, isMidnightCollateralRef, liquityBranchByIndex, liquityBranchByTroveManager, liquityBranchesByChain, liquityConfig, liquityConfigFor, liquityLendersByChain, liquityMarkets, listaCollateralProvider, listaCollateralProviders, listaNativeProvider, listaSmartLpByCollateral, llamaLendApiBaseUrl, llamaLendChainData, llamaLendConfig, llamaLendConfigFor, llamaLendLenderKey, llamaLendLendersByChain, llamaLendLeverageZap, llamaLendMarketByController, llamaLendMarketByVault, llamaLendMarkets, llamaLendSupportsDelegation, llamaLendSupportsLeverage, loadCached, loadCachedJson, midnightApiBaseOverride, midnightCollateralRef, midnightConfig, midnightLoanRef, midnightMarketById, midnightMarketIsEnterable, midnightMarkets, midnightMarketsByChain, midnightNotEnterableReason, morphoBundler3, morphoOracles, morphoPools, morphoTypeMarkets, morphoTypeOracles, morphoTypeVaults, parseAaveV4SpokeLenderKey, parseFraxlendPairKey, parseGearboxV3LenderKey, parseLlamaLendLenderKey, parseMidnightRef, parseSiloV2LenderKey, parseSiloV3LenderKey, parseTermMaxLenderKey, resolveMidnightApiBase, resolveTenorApiUrl, resolveTermApiBase, resolveTermOrderStoreBase, resupplyConfig, resupplyConfigFor, resupplyLendersByChain, riverChainData, riverConfig, riverConfigFor, riverLendersByChain, riverMarketByIndex, riverMarkets, setMidnightApiBase, setRemoteCacheGithubToken, setRemoteCacheStore, setTenorApiUrl, setTermApiBase, setTermOrderStoreBase, siloMarkets, siloMarketsV3, siloPeripherals, siloPeripheralsV3, siloV2LenderKey, siloV3LenderKey, skyChainData, skyConfig, skyConfigFor, skyLendersByChain, skyMarkets, tellerConfig, tellerConfigByChain, tellerPoolByAddress, tellerPools, tellerPoolsByChain, tenorApiUrlOverride, termApiBaseOverride, termConfig, termMarketById, termMarkets, termMarketsByChain, termMaxApiBaseUrl, termMaxChainIds, termMaxConfig, termMaxConfigByChain, termMaxLenderKey, termOrderStoreBaseOverride, twyneBaseKey, twyneBeaconFor, twyneChainData, twyneConfig, twyneConfigFor, twyneLendersByChain, twyneMarketByKey, twyneMarketFor, twyneMarketKey, twyneMarkets, twyneMarketsForIntermediateVault, twyneOperator, usddChainData, usddConfig, usddConfigFor, usddLendersByChain, usddMarketByIlk, usddMarkets };
|
|
1323
|
+
export { COOLER_ETHEREUM_CONFIG, CURVANCE_MONAD_CONFIG, DOLOMITE_ROUTER_DEFAULTS, FRAXLEND_ETHEREUM_CONFIG, GEARBOX_ACCOUNT_COMPRESSOR_V310, REMOTE_CACHE_STORE_TTL_S, RESUPPLY_ETHEREUM_CONFIG, RemoteFetchError, aaveOracles, aaveOraclesConfig, aavePools, aaveReserves, aaveTokens, aaveV4Oracles, aaveV4Peripherals, aaveV4SpokeLenderKey, aaveV4Spokes, aaveWethGateway, assertTwyneKeysUnique, chainLogoURI, chains, clearRemoteCache, compoundV2Oracles, compoundV2OraclesConfig, compoundV2Pools, compoundV2Reserves, compoundV2TokenArray, compoundV2Tokens, compoundV3BaseData, compoundV3Bulker, compoundV3OraclesData, compoundV3Pools, compoundV3Reserves, coolerConfig, coolerConfigFor, coolerLendersByChain, curvanceConfig, curvanceConfigFor, curvanceLendersByChain, curvancePositionManager, curvancePositionManagersFor, dolomiteChains, dolomiteConfigs, dolomiteEmode, dolomiteIsolation, dolomiteIsolationMarket, dolomiteMarketIdByToken, dolomiteOdosExecutorShim, dolomiteRouters, dssChainData, dssConfigFor, dssDebtJoin, dssDebtToken, dssMarketByIlk, eulerConfigs, eulerVaults, exactlyConfig, exactlyMarketByAddress, exactlyMarketByAsset, exactlyMarkets, exactlyMarketsByChain, fetchMainTokensMap, fetchRemoteJson, fetchTokenList, fetchTokenListFile, fetchTokenLists, findAaveV4PositionManager, fluidChains, fluidResolvers, fluidVaultEntries, fluidVaults, flyingTulipAssets, flyingTulipAssetsFor, flyingTulipConfig, flyingTulipConfigFor, flyingTulipLendersByChain, frankencoinChainData, frankencoinConfig, frankencoinConfigFor, frankencoinLendersByChain, frankencoinMarketByPosition, frankencoinMarkets, fraxlendConfig, fraxlendConfigFor, fraxlendLendersByChain, fraxlendPairKey, fraxlendPairsFor, gearboxAccountCompressor, gearboxAddressProviderV310, gearboxBotListV3, gearboxChains, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxResolvers, gearboxV3LenderKey, getAaveV4GatewayAddresses, getAaveV4PositionManagers, getAaveV4SpokeAccess, getAaveV4SpokeEntry, getAaveV4SpokePeripherals, getChainEntries, getSiloV2MarketEntry, getSiloV3MarketEntry, initConfig, initializeChainData, initializeLenderData, inverseChainData, inverseConfig, inverseConfigFor, inverseLendersByChain, inverseMarketByAddress, inverseMarkets, isAaveV4OperationRestricted, isListaSmartLpAsset, isMidnightCollateralRef, liquityBranchByIndex, liquityBranchByTroveManager, liquityBranchesByChain, liquityConfig, liquityConfigFor, liquityLendersByChain, liquityMarkets, listaCollateralProvider, listaCollateralProviders, listaNativeProvider, listaSmartLpByCollateral, llamaLendApiBaseUrl, llamaLendChainData, llamaLendConfig, llamaLendConfigFor, llamaLendLenderKey, llamaLendLendersByChain, llamaLendLeverageZap, llamaLendMarketByController, llamaLendMarketByVault, llamaLendMarkets, llamaLendSupportsDelegation, llamaLendSupportsLeverage, loadCached, loadCachedJson, midnightApiBaseOverride, midnightCollateralRef, midnightConfig, midnightLoanRef, midnightMarketById, midnightMarketIsEnterable, midnightMarkets, midnightMarketsByChain, midnightNotEnterableReason, morphoBundler3, morphoOracles, morphoPools, morphoTypeMarkets, morphoTypeOracles, morphoTypeVaults, parseAaveV4SpokeLenderKey, parseFraxlendPairKey, parseGearboxV3LenderKey, parseLlamaLendLenderKey, parseMidnightRef, parseSiloV2LenderKey, parseSiloV3LenderKey, parseTermMaxLenderKey, refreshRemoteCache, resolveMidnightApiBase, resolveTenorApiUrl, resolveTermApiBase, resolveTermOrderStoreBase, resupplyConfig, resupplyConfigFor, resupplyLendersByChain, riverChainData, riverConfig, riverConfigFor, riverLendersByChain, riverMarketByIndex, riverMarkets, setMidnightApiBase, setRemoteCacheGithubToken, setRemoteCacheStore, setRemoteCacheWaitUntil, setTenorApiUrl, setTermApiBase, setTermOrderStoreBase, siloMarkets, siloMarketsV3, siloPeripherals, siloPeripheralsV3, siloV2LenderKey, siloV3LenderKey, skyChainData, skyConfig, skyConfigFor, skyLendersByChain, skyMarkets, tellerConfig, tellerConfigByChain, tellerPoolByAddress, tellerPools, tellerPoolsByChain, tenorApiUrlOverride, termApiBaseOverride, termConfig, termMarketById, termMarkets, termMarketsByChain, termMaxApiBaseUrl, termMaxChainIds, termMaxConfig, termMaxConfigByChain, termMaxLenderKey, termOrderStoreBaseOverride, tokenListCacheKey, twyneBaseKey, twyneBeaconFor, twyneChainData, twyneConfig, twyneConfigFor, twyneLendersByChain, twyneMarketByKey, twyneMarketFor, twyneMarketKey, twyneMarkets, twyneMarketsForIntermediateVault, twyneOperator, usddChainData, usddConfig, usddConfigFor, usddLendersByChain, usddMarketByIlk, usddMarkets };
|
|
@@ -12,6 +12,15 @@ export type DolomiteConfigEntry = {
|
|
|
12
12
|
* ("invalid ETH sender"); ERC-20 deposits/withdrawals still use the proxy.
|
|
13
13
|
*/
|
|
14
14
|
depositWithdrawalRouter?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Modern `BorrowPositionRouter` / `GenericTraderRouter` — ONE address on
|
|
17
|
+
* every Dolomite chain (see `DOLOMITE_ROUTER_DEFAULTS`); the config may
|
|
18
|
+
* override per chain. Both take a leading `isolationModeMarketId` and are
|
|
19
|
+
* the ONLY way to act on an isolation-mode (dGM/dsavETH/…) position, whose
|
|
20
|
+
* DolomiteMargin account is owned by the user's vault.
|
|
21
|
+
*/
|
|
22
|
+
borrowPositionRouter?: string;
|
|
23
|
+
genericTraderRouter?: string;
|
|
15
24
|
borrowPositionProxy?: string;
|
|
16
25
|
genericTraderProxy?: string;
|
|
17
26
|
aggregatorTraders?: {
|
|
@@ -67,7 +76,45 @@ export type DolomiteEmodeChain = {
|
|
|
67
76
|
export type DolomiteEmodeType = {
|
|
68
77
|
[chainId: string]: DolomiteEmodeChain;
|
|
69
78
|
};
|
|
79
|
+
export type DolomiteIsolationMarket = {
|
|
80
|
+
factory: string;
|
|
81
|
+
underlying: string;
|
|
82
|
+
underlyingSymbol: string;
|
|
83
|
+
underlyingDecimals: number;
|
|
84
|
+
allowableDebtMarketIds: string[];
|
|
85
|
+
allowableCollateralMarketIds: string[];
|
|
86
|
+
wrapper: string | null;
|
|
87
|
+
unwrapper: string | null;
|
|
88
|
+
wrapperInputMarketIds: string[];
|
|
89
|
+
unwrapperOutputMarketIds: string[];
|
|
90
|
+
async: boolean;
|
|
91
|
+
executionFeeWei: string | null;
|
|
92
|
+
};
|
|
93
|
+
export type DolomiteIsolationType = {
|
|
94
|
+
[chainId: string]: {
|
|
95
|
+
[marketId: string]: DolomiteIsolationMarket;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
70
98
|
export declare const dolomiteConfigs: () => DolomiteConfigsType;
|
|
99
|
+
/**
|
|
100
|
+
* The three Dolomite routers as deployed by `dolomite-margin-modules`
|
|
101
|
+
* (`packages/deployment/src/deploy/deployments.json`): one CREATE2 address per
|
|
102
|
+
* router on every chain Dolomite runs on (1, 56, 196, 1101, 3637, 5000, 5330,
|
|
103
|
+
* 8453, 42161, 57073, 80094). Probed 2026-09-18 on Arbitrum: all three are
|
|
104
|
+
* `getIsGlobalOperator == true` and `isTokenConverterTrusted == true` on every
|
|
105
|
+
* live isolation factory.
|
|
106
|
+
*/
|
|
107
|
+
export declare const DOLOMITE_ROUTER_DEFAULTS: {
|
|
108
|
+
readonly depositWithdrawalRouter: "0xf8b2c637A68cF6A17b1DF9F8992EeBeFf63d2dFf";
|
|
109
|
+
readonly borrowPositionRouter: "0xF579b345cdA0860668b857De10ABD62442133D0F";
|
|
110
|
+
readonly genericTraderRouter: "0x7b61CbA306CfdB02493b94757143132B1b72Bc6b";
|
|
111
|
+
};
|
|
112
|
+
/** Router addresses for a chain: the config's, else the shared CREATE2 defaults. */
|
|
113
|
+
export declare const dolomiteRouters: (chainId: string) => {
|
|
114
|
+
depositWithdrawalRouter: string;
|
|
115
|
+
borrowPositionRouter: string;
|
|
116
|
+
genericTraderRouter: string;
|
|
117
|
+
};
|
|
71
118
|
/**
|
|
72
119
|
* The `OdosExecutor` deployed on a chain, or `undefined` when the
|
|
73
120
|
* passthrough route is unavailable there. Callers MUST treat `undefined` as
|
|
@@ -76,4 +123,7 @@ export declare const dolomiteConfigs: () => DolomiteConfigsType;
|
|
|
76
123
|
export declare const dolomiteOdosExecutorShim: (chainId: string) => string | undefined;
|
|
77
124
|
export declare const dolomiteChains: () => string[];
|
|
78
125
|
export declare const dolomiteEmode: () => DolomiteEmodeType;
|
|
126
|
+
export declare const dolomiteIsolation: () => DolomiteIsolationType;
|
|
127
|
+
/** The isolation-mode row for a (chain, marketId), or undefined for an ordinary market. */
|
|
128
|
+
export declare const dolomiteIsolationMarket: (chainId: string, marketId: string | number | bigint) => DolomiteIsolationMarket | undefined;
|
|
79
129
|
export declare const dolomiteMarketIdByToken: (chainId: string, token: string) => string | undefined;
|
|
@@ -26,7 +26,7 @@ import type { CompoundV3BaseDataType, CompoundV3BulkerType, CompoundV3OracleData
|
|
|
26
26
|
import type { CurvanceConfigType } from './curvance';
|
|
27
27
|
import type { CoolerConfigType } from './cooler';
|
|
28
28
|
import type { TwyneConfigType, TwyneMarketsType } from './twyne';
|
|
29
|
-
import type { DolomiteConfigsType, DolomiteEmodeType } from './dolomite';
|
|
29
|
+
import type { DolomiteConfigsType, DolomiteEmodeType, DolomiteIsolationType } from './dolomite';
|
|
30
30
|
import type { UsddConfigType, UsddMarketsType } from './dss';
|
|
31
31
|
import type { EulerConfigsType, EulerVaultsType } from './euler';
|
|
32
32
|
import type { ExactlyConfigType, ExactlyMarketsType } from './exactly';
|
|
@@ -118,6 +118,7 @@ export interface GlobalLenderDataRegistry {
|
|
|
118
118
|
eulerVaults: EulerVaultsType;
|
|
119
119
|
dolomiteConfigs: DolomiteConfigsType;
|
|
120
120
|
dolomiteEmode: DolomiteEmodeType;
|
|
121
|
+
dolomiteIsolation: DolomiteIsolationType;
|
|
121
122
|
siloMarkets: SiloMarketsType;
|
|
122
123
|
siloPeripherals: SiloPeripheralsType;
|
|
123
124
|
siloMarketsV3: SiloMarketsType;
|
package/dist/remoteCache.d.ts
CHANGED
|
@@ -11,21 +11,70 @@
|
|
|
11
11
|
* These files change on the order of days, so serving a stale copy is strictly
|
|
12
12
|
* better than failing — hence the stale-on-error fallback, which is the part
|
|
13
13
|
* that actually survives an outage.
|
|
14
|
+
*
|
|
15
|
+
* Read order, and what each layer is for:
|
|
16
|
+
*
|
|
17
|
+
* memory — served IMMEDIATELY whenever a copy exists and is inside the SWR
|
|
18
|
+
* window; older than `FRESH_TTL_MS` it also kicks a background
|
|
19
|
+
* refresh. The request path never awaits the store or the network
|
|
20
|
+
* while memory is warm — a 6.66 MB token list re-read from KV every
|
|
21
|
+
* five minutes used to land on whichever user request crossed the
|
|
22
|
+
* boundary.
|
|
23
|
+
* store — a KV namespace in the workers. Consulted only when memory has
|
|
24
|
+
* nothing usable (a cold isolate), so a fresh isolate never touches
|
|
25
|
+
* GitHub at all.
|
|
26
|
+
* network — raw.githubusercontent.com, then the api.github.com mirror.
|
|
14
27
|
*/
|
|
15
28
|
/** How long a persisted copy is kept around purely as the stale fallback. */
|
|
16
29
|
export declare const REMOTE_CACHE_STORE_TTL_S: number;
|
|
30
|
+
/** What the store carries next to a value, when it can carry anything. */
|
|
31
|
+
export interface RemoteCacheEntryMetadata {
|
|
32
|
+
/** Epoch ms of the upstream fetch that produced the value. */
|
|
33
|
+
at: number;
|
|
34
|
+
}
|
|
17
35
|
/**
|
|
18
36
|
* Durable backing store — a Cloudflare KV namespace in the workers, absent
|
|
19
37
|
* everywhere else. Without one the cache is per-process, which still collapses
|
|
20
38
|
* N requests into one upstream fetch but cannot help a cold start; with one, a
|
|
21
39
|
* fresh isolate never touches GitHub at all.
|
|
40
|
+
*
|
|
41
|
+
* The two `*WithMetadata` members are optional. When present, the fetch
|
|
42
|
+
* timestamp is written as store METADATA as well as inside the value, so a
|
|
43
|
+
* store that can list keys with their metadata (KV's `list()` can) can answer
|
|
44
|
+
* "how old is this entry?" without transferring a multi-MB value. Note that
|
|
45
|
+
* KV's `getWithMetadata` still returns the value — only `list` is
|
|
46
|
+
* metadata-only — so reads through this interface do not get cheaper; what
|
|
47
|
+
* the metadata buys is an inspectable freshness signal for operators and for
|
|
48
|
+
* a future probe that stays off the value read.
|
|
22
49
|
*/
|
|
23
50
|
export interface RemoteCacheStore {
|
|
24
51
|
get(key: string): Promise<string | null>;
|
|
25
52
|
put(key: string, value: string, ttlSeconds: number): Promise<void>;
|
|
53
|
+
getWithMetadata?(key: string): Promise<{
|
|
54
|
+
value: string | null;
|
|
55
|
+
metadata: RemoteCacheEntryMetadata | null;
|
|
56
|
+
}>;
|
|
57
|
+
putWithMetadata?(key: string, value: string, ttlSeconds: number, metadata: RemoteCacheEntryMetadata): Promise<void>;
|
|
26
58
|
}
|
|
59
|
+
/** `ctx.waitUntil`-shaped hook: keeps a background promise alive post-response. */
|
|
60
|
+
export type RemoteCacheWaitUntil = (promise: Promise<unknown>) => void;
|
|
27
61
|
/** Installs (or with `undefined`, removes) the durable store. */
|
|
28
62
|
export declare function setRemoteCacheStore(next: RemoteCacheStore | undefined): void;
|
|
63
|
+
/**
|
|
64
|
+
* Installs (or with `undefined`, removes) the hook that keeps background work
|
|
65
|
+
* alive after a response — `ctx.waitUntil` on Cloudflare Workers.
|
|
66
|
+
*
|
|
67
|
+
* The LATEST hook wins. Workers hand each request its own context, and a
|
|
68
|
+
* module-level slot can only hold one, so a refresh kicked by request A may be
|
|
69
|
+
* registered against request B's context if B arrived in between. That is
|
|
70
|
+
* harmless in the direction that matters (B's context keeps A's refresh alive
|
|
71
|
+
* at least as long as B runs) and the stuck guard covers the other direction
|
|
72
|
+
* (a context that closed before the refresh settled). The hook is called under
|
|
73
|
+
* try/catch for the same reason: a closed context may throw.
|
|
74
|
+
*
|
|
75
|
+
* Without a hook (Node, tests) background work is simply detached.
|
|
76
|
+
*/
|
|
77
|
+
export declare function setRemoteCacheWaitUntil(next: RemoteCacheWaitUntil | undefined): void;
|
|
29
78
|
/**
|
|
30
79
|
* Optional GitHub token for the API mirror below. Unauthenticated it allows 60
|
|
31
80
|
* requests/hour per IP, which is thin for a shared Worker egress; a token
|
|
@@ -34,6 +83,12 @@ export declare function setRemoteCacheStore(next: RemoteCacheStore | undefined):
|
|
|
34
83
|
export declare function setRemoteCacheGithubToken(token: string | undefined): void;
|
|
35
84
|
/** Drops every cached value. Intended for tests. */
|
|
36
85
|
export declare function clearRemoteCache(): void;
|
|
86
|
+
/**
|
|
87
|
+
* The remote-cache key of a chain's token list. `tokens.ts` builds the same
|
|
88
|
+
* string inline; this is exported so a pre-warm can name the key without
|
|
89
|
+
* importing the loader.
|
|
90
|
+
*/
|
|
91
|
+
export declare const tokenListCacheKey: (chainId: string) => string;
|
|
37
92
|
/**
|
|
38
93
|
* A non-2xx from the remote. Carries the ORIGIN status so a caller can tell a
|
|
39
94
|
* settled answer (404/410 — the file is not published) from a transient one
|
|
@@ -57,6 +112,10 @@ export declare function fetchRemoteJson<T>(url: string, label: string): Promise<
|
|
|
57
112
|
* failed `load()` falls back to whatever stale copy either layer holds, only
|
|
58
113
|
* rethrowing when there is nothing to fall back to.
|
|
59
114
|
*
|
|
115
|
+
* Memory is served WITHOUT awaiting anything for as long as the copy is inside
|
|
116
|
+
* the SWR window; past `FRESH_TTL_MS` a refresh runs behind it. The store is
|
|
117
|
+
* consulted only when memory has nothing inside that window.
|
|
118
|
+
*
|
|
60
119
|
* Concurrent callers for the same key share one in-flight load.
|
|
61
120
|
*
|
|
62
121
|
* `isValid` guards the durable layer: a truncated or shape-changed entry is
|
|
@@ -64,5 +123,28 @@ export declare function fetchRemoteJson<T>(url: string, label: string): Promise<
|
|
|
64
123
|
* mis-decimals every balance built from it.
|
|
65
124
|
*/
|
|
66
125
|
export declare function loadCached<T>(key: string, load: () => Promise<T>, isValid: (value: any) => boolean): Promise<T>;
|
|
126
|
+
/** Outcome of {@link refreshRemoteCache}. */
|
|
127
|
+
export type RemoteCacheRefreshResult =
|
|
128
|
+
/** Upstream was fetched and the store written. */
|
|
129
|
+
'refreshed'
|
|
130
|
+
/** The memory copy was younger than `maxAgeMs`; nothing was done. */
|
|
131
|
+
| 'fresh'
|
|
132
|
+
/** Upstream failed; the previous copy (if any) is still served. */
|
|
133
|
+
| 'failed'
|
|
134
|
+
/** Nothing has loaded this key in this process, so there is no loader to run. */
|
|
135
|
+
| 'unknown';
|
|
136
|
+
/**
|
|
137
|
+
* Forces a refresh of `key` from UPSTREAM (never the store), and awaits the
|
|
138
|
+
* store write. For a pre-warm job: the routine path only refreshes once a
|
|
139
|
+
* copy is `FRESH_TTL_MS` old, so a job that runs more often than that would
|
|
140
|
+
* otherwise never write anything.
|
|
141
|
+
*
|
|
142
|
+
* `maxAgeMs` skips the work when the memory copy is younger than that — so a
|
|
143
|
+
* job that has just loaded the key cold does not immediately fetch it again.
|
|
144
|
+
* Joins an in-flight refresh rather than starting a second one.
|
|
145
|
+
*/
|
|
146
|
+
export declare function refreshRemoteCache(key: string, opts?: {
|
|
147
|
+
maxAgeMs?: number;
|
|
148
|
+
}): Promise<RemoteCacheRefreshResult>;
|
|
67
149
|
/** `loadCached` over a JSON URL, failing on any non-2xx so stale can take over. */
|
|
68
150
|
export declare function loadCachedJson<T>(key: string, url: string, isValid: (value: any) => boolean, label?: string): Promise<T>;
|