@morpho-dev/router 0.4.1 → 0.5.0
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/README.md +18 -5
- package/dist/chunk-Bo1DHCg-.mjs +18 -0
- package/dist/cli.js +2654 -2331
- package/dist/index.browser.d.mts +458 -484
- package/dist/index.browser.d.mts.map +1 -1
- package/dist/index.browser.d.ts +458 -484
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +623 -304
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.mjs +592 -294
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.mts +623 -686
- package/dist/index.node.d.mts.map +1 -1
- package/dist/index.node.d.ts +623 -686
- package/dist/index.node.d.ts.map +1 -1
- package/dist/index.node.js +919 -583
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +886 -571
- package/dist/index.node.mjs.map +1 -1
- package/docs/integrator.md +1 -1
- package/package.json +5 -5
- package/dist/chunk-jass6xSI.mjs +0 -13
package/dist/index.node.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as
|
|
1
|
+
import { t as __exportAll } from "./chunk-Bo1DHCg-.mjs";
|
|
2
2
|
import { getBlock, getBlockNumber, getLogs, multicall } from "viem/actions";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
import { bytesToHex, decodeAbiParameters, encodeAbiParameters, erc20Abi, getAddress, hashMessage, hashTypedData, hexToBytes, isAddress, isHex, keccak256, maxUint256, numberToHex, pad, parseAbi, parseEventLogs, publicActions, recoverAddress, stringify, zeroAddress } from "viem";
|
|
@@ -40,7 +40,7 @@ import { Pool } from "pg";
|
|
|
40
40
|
import { and, asc, eq, gt, gte, inArray, lte, ne, sql } from "drizzle-orm";
|
|
41
41
|
|
|
42
42
|
//#region src/logger/Logger.ts
|
|
43
|
-
var Logger_exports = /* @__PURE__ */
|
|
43
|
+
var Logger_exports = /* @__PURE__ */ __exportAll({
|
|
44
44
|
LogLevelValues: () => LogLevelValues,
|
|
45
45
|
defaultLogger: () => defaultLogger,
|
|
46
46
|
getLogger: () => getLogger,
|
|
@@ -75,10 +75,10 @@ function defaultLogger(minLevel, pretty) {
|
|
|
75
75
|
const { msg, ...rest } = entry;
|
|
76
76
|
const stack = typeof rest.stack === "string" ? rest.stack : void 0;
|
|
77
77
|
if (stack) delete rest.stack;
|
|
78
|
-
const timestamp
|
|
78
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
79
79
|
const level = methodLevel.toUpperCase();
|
|
80
80
|
const extras = Object.entries(rest).map(([k, v]) => `${k}=${formatValue(v)}`).join(" ");
|
|
81
|
-
const line = extras.length > 0 ? `${timestamp
|
|
81
|
+
const line = extras.length > 0 ? `${timestamp} [${level}] ${msg} ${extras}` : `${timestamp} [${level}] ${msg}`;
|
|
82
82
|
console[consoleMethod](line);
|
|
83
83
|
if (stack) console[consoleMethod](stack);
|
|
84
84
|
} : () => {};
|
|
@@ -258,7 +258,7 @@ async function batchMulticall(parameters) {
|
|
|
258
258
|
|
|
259
259
|
//#endregion
|
|
260
260
|
//#region src/utils/Errors.ts
|
|
261
|
-
var Errors_exports = /* @__PURE__ */
|
|
261
|
+
var Errors_exports = /* @__PURE__ */ __exportAll({
|
|
262
262
|
BaseError: () => BaseError,
|
|
263
263
|
ReorgError: () => ReorgError
|
|
264
264
|
});
|
|
@@ -315,7 +315,7 @@ var ReorgError = class extends BaseError {
|
|
|
315
315
|
|
|
316
316
|
//#endregion
|
|
317
317
|
//#region src/utils/Format.ts
|
|
318
|
-
var Format_exports = /* @__PURE__ */
|
|
318
|
+
var Format_exports = /* @__PURE__ */ __exportAll({
|
|
319
319
|
fromSnakeCase: () => fromSnakeCase$3,
|
|
320
320
|
stringifyBigint: () => stringifyBigint,
|
|
321
321
|
toSnakeCase: () => toSnakeCase$1
|
|
@@ -327,7 +327,7 @@ var Format_exports = /* @__PURE__ */ __export({
|
|
|
327
327
|
* Stringifies bigint values to strings.
|
|
328
328
|
*/
|
|
329
329
|
function toSnakeCase$1(obj) {
|
|
330
|
-
return stringifyBigint(processObject(obj, (s
|
|
330
|
+
return stringifyBigint(processObject(obj, (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? getAddress(value.toLowerCase()) : value));
|
|
331
331
|
}
|
|
332
332
|
/**
|
|
333
333
|
* Formats a snake case object to its camel case type.
|
|
@@ -336,7 +336,7 @@ function toSnakeCase$1(obj) {
|
|
|
336
336
|
* @warning Does not unstringify bigint values.
|
|
337
337
|
*/
|
|
338
338
|
function fromSnakeCase$3(obj) {
|
|
339
|
-
return processObject(obj, (s
|
|
339
|
+
return processObject(obj, (s) => isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? value.toLowerCase() : value);
|
|
340
340
|
}
|
|
341
341
|
function processObject(obj, fnKey, fnValue) {
|
|
342
342
|
if (typeof obj !== "object" || obj === null) return obj;
|
|
@@ -360,7 +360,7 @@ function stringifyBigint(value) {
|
|
|
360
360
|
|
|
361
361
|
//#endregion
|
|
362
362
|
//#region src/utils/Group.ts
|
|
363
|
-
var Group_exports = /* @__PURE__ */
|
|
363
|
+
var Group_exports = /* @__PURE__ */ __exportAll({ fromNumber: () => fromNumber });
|
|
364
364
|
/**
|
|
365
365
|
* Creates a bytes32 group identifier from a number.
|
|
366
366
|
* @param n - A non-negative integer.
|
|
@@ -384,8 +384,8 @@ function lazy(pollFn) {
|
|
|
384
384
|
let active = true;
|
|
385
385
|
let resolveNext = null;
|
|
386
386
|
const queue = [];
|
|
387
|
-
const wait
|
|
388
|
-
resolveNext = resolve
|
|
387
|
+
const wait = () => new Promise((resolve) => {
|
|
388
|
+
resolveNext = resolve;
|
|
389
389
|
});
|
|
390
390
|
const emit = (item) => {
|
|
391
391
|
queue.push(item);
|
|
@@ -402,7 +402,7 @@ function lazy(pollFn) {
|
|
|
402
402
|
unpoll = pollFn(emit, { stop });
|
|
403
403
|
try {
|
|
404
404
|
while (active) {
|
|
405
|
-
if (queue.length === 0) await wait
|
|
405
|
+
if (queue.length === 0) await wait();
|
|
406
406
|
while (queue.length > 0 && active) yield queue.shift();
|
|
407
407
|
}
|
|
408
408
|
} finally {
|
|
@@ -441,7 +441,7 @@ function poll(fn, { interval }) {
|
|
|
441
441
|
|
|
442
442
|
//#endregion
|
|
443
443
|
//#region src/utils/Random.ts
|
|
444
|
-
var Random_exports = /* @__PURE__ */
|
|
444
|
+
var Random_exports = /* @__PURE__ */ __exportAll({
|
|
445
445
|
address: () => address,
|
|
446
446
|
bool: () => bool,
|
|
447
447
|
bytes: () => bytes,
|
|
@@ -454,16 +454,16 @@ var Random_exports = /* @__PURE__ */ __export({
|
|
|
454
454
|
let currentRng = Math.random;
|
|
455
455
|
const FNV_OFFSET_BASIS = 2166136261;
|
|
456
456
|
const FNV_PRIME = 16777619;
|
|
457
|
-
const hashSeed = (seed
|
|
458
|
-
let hash
|
|
459
|
-
for (let i = 0; i < seed
|
|
460
|
-
hash
|
|
461
|
-
hash
|
|
457
|
+
const hashSeed = (seed) => {
|
|
458
|
+
let hash = FNV_OFFSET_BASIS;
|
|
459
|
+
for (let i = 0; i < seed.length; i += 1) {
|
|
460
|
+
hash ^= seed.charCodeAt(i);
|
|
461
|
+
hash = Math.imul(hash, FNV_PRIME);
|
|
462
462
|
}
|
|
463
|
-
return hash
|
|
463
|
+
return hash >>> 0;
|
|
464
464
|
};
|
|
465
|
-
const createSeededRng = (seed
|
|
466
|
-
let state = hashSeed(seed
|
|
465
|
+
const createSeededRng = (seed) => {
|
|
466
|
+
let state = hashSeed(seed);
|
|
467
467
|
return () => {
|
|
468
468
|
state += 1831565813;
|
|
469
469
|
let t = Math.imul(state ^ state >>> 15, state | 1);
|
|
@@ -474,9 +474,9 @@ const createSeededRng = (seed$1) => {
|
|
|
474
474
|
/**
|
|
475
475
|
* Runs a function with a deterministic RNG derived from the given seed.
|
|
476
476
|
*/
|
|
477
|
-
function withSeed(seed
|
|
477
|
+
function withSeed(seed, fn) {
|
|
478
478
|
const previous = currentRng;
|
|
479
|
-
currentRng = createSeededRng(seed
|
|
479
|
+
currentRng = createSeededRng(seed);
|
|
480
480
|
try {
|
|
481
481
|
return fn();
|
|
482
482
|
} finally {
|
|
@@ -486,8 +486,8 @@ function withSeed(seed$1, fn) {
|
|
|
486
486
|
/**
|
|
487
487
|
* Seeds the global RNG for deterministic test runs.
|
|
488
488
|
*/
|
|
489
|
-
function seed(seed
|
|
490
|
-
currentRng = createSeededRng(seed
|
|
489
|
+
function seed(seed) {
|
|
490
|
+
currentRng = createSeededRng(seed);
|
|
491
491
|
}
|
|
492
492
|
/**
|
|
493
493
|
* Returns a deterministic random float in [0, 1).
|
|
@@ -498,8 +498,8 @@ function float() {
|
|
|
498
498
|
/**
|
|
499
499
|
* Returns a deterministic random integer in [min, maxExclusive).
|
|
500
500
|
*/
|
|
501
|
-
function int(maxExclusive, min
|
|
502
|
-
return Math.floor(float() * (maxExclusive - min
|
|
501
|
+
function int(maxExclusive, min = 0) {
|
|
502
|
+
return Math.floor(float() * (maxExclusive - min)) + min;
|
|
503
503
|
}
|
|
504
504
|
/**
|
|
505
505
|
* Returns a deterministic random boolean.
|
|
@@ -531,7 +531,7 @@ function address() {
|
|
|
531
531
|
|
|
532
532
|
//#endregion
|
|
533
533
|
//#region src/utils/time.ts
|
|
534
|
-
var time_exports = /* @__PURE__ */
|
|
534
|
+
var time_exports = /* @__PURE__ */ __exportAll({
|
|
535
535
|
max: () => max,
|
|
536
536
|
now: () => now
|
|
537
537
|
});
|
|
@@ -544,7 +544,7 @@ function max() {
|
|
|
544
544
|
|
|
545
545
|
//#endregion
|
|
546
546
|
//#region src/utils/index.ts
|
|
547
|
-
var utils_exports = /* @__PURE__ */
|
|
547
|
+
var utils_exports = /* @__PURE__ */ __exportAll({
|
|
548
548
|
BaseError: () => BaseError,
|
|
549
549
|
Group: () => Group_exports,
|
|
550
550
|
Random: () => Random_exports,
|
|
@@ -687,14 +687,14 @@ const reconcile = async (parameters) => {
|
|
|
687
687
|
if (block.hash === null || block.number === null || block.parentHash === null) throw new Error("Failed to get block");
|
|
688
688
|
const latestBlock = unfinalizedBlocks[unfinalizedBlocks.length - 1];
|
|
689
689
|
if (latestBlock === void 0) {
|
|
690
|
-
const newBlock
|
|
690
|
+
const newBlock = {
|
|
691
691
|
hash: block.hash,
|
|
692
692
|
number: block.number,
|
|
693
693
|
parentHash: block.parentHash
|
|
694
694
|
};
|
|
695
|
-
unfinalizedBlocks.push(newBlock
|
|
695
|
+
unfinalizedBlocks.push(newBlock);
|
|
696
696
|
return {
|
|
697
|
-
block: newBlock
|
|
697
|
+
block: newBlock,
|
|
698
698
|
didReorgHappened: false,
|
|
699
699
|
unfinalizedBlocks
|
|
700
700
|
};
|
|
@@ -729,14 +729,14 @@ const reconcile = async (parameters) => {
|
|
|
729
729
|
msg: `Missing blocks`
|
|
730
730
|
});
|
|
731
731
|
const missingBlockNumbers = (() => {
|
|
732
|
-
const missingBlockNumbers
|
|
733
|
-
let start
|
|
732
|
+
const missingBlockNumbers = [];
|
|
733
|
+
let start = latestBlock.number + 1n;
|
|
734
734
|
const threshold = latestBlock.number + BigInt(maxBatchSize) > block.number ? block.number : latestBlock.number + BigInt(maxBatchSize);
|
|
735
|
-
while (start
|
|
736
|
-
missingBlockNumbers
|
|
737
|
-
start
|
|
735
|
+
while (start < threshold) {
|
|
736
|
+
missingBlockNumbers.push(start);
|
|
737
|
+
start = start + 1n;
|
|
738
738
|
}
|
|
739
|
-
return missingBlockNumbers
|
|
739
|
+
return missingBlockNumbers;
|
|
740
740
|
})();
|
|
741
741
|
const missingBlocks = await Promise.all(missingBlockNumbers.map((blockNumber) => retry(async () => await client.getBlock({
|
|
742
742
|
blockNumber,
|
|
@@ -853,10 +853,10 @@ function create$16({ name, collect, client, db, options }) {
|
|
|
853
853
|
}) && options.maxBlockNumber !== void 0 && lastBlockNumber !== void 0 && options.maxBlockNumber === lastBlockNumber) return;
|
|
854
854
|
const { blockNumber, done } = await startActiveSpan(tracer, `${collectorId}.next`, async () => {
|
|
855
855
|
if (iterator === null) throw new Error("Iterator is not initialized");
|
|
856
|
-
const { value: blockNumber
|
|
856
|
+
const { value: blockNumber, done } = await iterator.next();
|
|
857
857
|
return {
|
|
858
|
-
blockNumber
|
|
859
|
-
done
|
|
858
|
+
blockNumber,
|
|
859
|
+
done
|
|
860
860
|
};
|
|
861
861
|
});
|
|
862
862
|
if (done) iterator = null;
|
|
@@ -951,7 +951,7 @@ const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed meta
|
|
|
951
951
|
|
|
952
952
|
//#endregion
|
|
953
953
|
//#region src/core/Abi/index.ts
|
|
954
|
-
var Abi_exports = /* @__PURE__ */
|
|
954
|
+
var Abi_exports = /* @__PURE__ */ __exportAll({
|
|
955
955
|
ERC4626: () => ERC4626,
|
|
956
956
|
MetaMorpho: () => MetaMorpho,
|
|
957
957
|
MetaMorphoFactory: () => MetaMorphoFactory,
|
|
@@ -1102,41 +1102,77 @@ const Morpho = [
|
|
|
1102
1102
|
|
|
1103
1103
|
//#endregion
|
|
1104
1104
|
//#region src/core/Callback.ts
|
|
1105
|
-
var Callback_exports = /* @__PURE__ */
|
|
1106
|
-
|
|
1105
|
+
var Callback_exports = /* @__PURE__ */ __exportAll({
|
|
1106
|
+
Type: () => Type$1,
|
|
1107
1107
|
decode: () => decode$2,
|
|
1108
|
+
decodeBuyERC20: () => decodeBuyERC20,
|
|
1108
1109
|
decodeBuyVaultV1Callback: () => decodeBuyVaultV1Callback,
|
|
1109
1110
|
decodeSellERC20Callback: () => decodeSellERC20Callback,
|
|
1110
1111
|
encode: () => encode$2,
|
|
1112
|
+
encodeBuyERC20: () => encodeBuyERC20,
|
|
1111
1113
|
encodeBuyVaultV1Callback: () => encodeBuyVaultV1Callback,
|
|
1112
1114
|
encodeSellERC20Callback: () => encodeSellERC20Callback,
|
|
1113
1115
|
isEmptyCallback: () => isEmptyCallback
|
|
1114
1116
|
});
|
|
1115
|
-
let
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1117
|
+
let Type$1 = /* @__PURE__ */ function(Type) {
|
|
1118
|
+
Type["BuyWithEmptyCallback"] = "buy_with_empty_callback";
|
|
1119
|
+
Type["BuyERC20"] = "buy_erc20";
|
|
1120
|
+
Type["BuyVaultV1Callback"] = "buy_vault_v1_callback";
|
|
1121
|
+
Type["SellERC20Callback"] = "sell_erc20_callback";
|
|
1122
|
+
return Type;
|
|
1120
1123
|
}({});
|
|
1121
1124
|
const isEmptyCallback = (offer) => offer.callback.data === "0x";
|
|
1122
1125
|
function decode$2(type, data) {
|
|
1123
1126
|
switch (type) {
|
|
1124
|
-
case
|
|
1125
|
-
case
|
|
1127
|
+
case Type$1.BuyERC20: return decodeBuyERC20(data);
|
|
1128
|
+
case Type$1.BuyVaultV1Callback: return decodeBuyVaultV1Callback(data);
|
|
1129
|
+
case Type$1.SellERC20Callback: return decodeSellERC20Callback(data);
|
|
1126
1130
|
default: throw new Error("Invalid callback type");
|
|
1127
1131
|
}
|
|
1128
1132
|
}
|
|
1129
1133
|
function encode$2(type, data) {
|
|
1130
1134
|
switch (type) {
|
|
1131
|
-
case
|
|
1135
|
+
case Type$1.BuyERC20:
|
|
1136
|
+
if (!("tokens" in data)) throw new Error("Invalid callback data");
|
|
1137
|
+
return encodeBuyERC20(data);
|
|
1138
|
+
case Type$1.BuyVaultV1Callback:
|
|
1132
1139
|
if (!("vaults" in data)) throw new Error("Invalid callback data");
|
|
1133
1140
|
return encodeBuyVaultV1Callback(data);
|
|
1134
|
-
case
|
|
1141
|
+
case Type$1.SellERC20Callback:
|
|
1135
1142
|
if (!("collaterals" in data)) throw new Error("Invalid callback data");
|
|
1136
1143
|
return encodeSellERC20Callback(data);
|
|
1137
1144
|
default: throw new Error("Invalid callback type");
|
|
1138
1145
|
}
|
|
1139
1146
|
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Decodes BuyERC20 callback data into positions.
|
|
1149
|
+
* @param data - The ABI-encoded callback data containing token addresses and amounts.
|
|
1150
|
+
* @returns Array of positions with contract address and amount.
|
|
1151
|
+
* @throws If data is empty, malformed, or arrays have mismatched lengths.
|
|
1152
|
+
*/
|
|
1153
|
+
function decodeBuyERC20(data) {
|
|
1154
|
+
if (!data || data === "0x") throw new Error("Empty callback data");
|
|
1155
|
+
let tokens;
|
|
1156
|
+
let amounts;
|
|
1157
|
+
try {
|
|
1158
|
+
[tokens, amounts] = decodeAbiParameters([{ type: "address[]" }, { type: "uint256[]" }], data);
|
|
1159
|
+
} catch (_) {
|
|
1160
|
+
throw new Error("Invalid BuyERC20 callback data");
|
|
1161
|
+
}
|
|
1162
|
+
if (tokens.length !== amounts.length) throw new Error("Mismatched array lengths");
|
|
1163
|
+
return tokens.map((token, index) => ({
|
|
1164
|
+
contract: token,
|
|
1165
|
+
amount: amounts[index]
|
|
1166
|
+
}));
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Encodes BuyERC20 callback parameters into ABI-encoded data.
|
|
1170
|
+
* @param parameters - The tokens and amounts to encode.
|
|
1171
|
+
* @returns ABI-encoded hex string.
|
|
1172
|
+
*/
|
|
1173
|
+
function encodeBuyERC20(parameters) {
|
|
1174
|
+
return encodeAbiParameters([{ type: "address[]" }, { type: "uint256[]" }], [parameters.tokens, parameters.amounts]);
|
|
1175
|
+
}
|
|
1140
1176
|
function decodeBuyVaultV1Callback(data) {
|
|
1141
1177
|
if (!data || data === "0x") throw new Error("Empty callback data");
|
|
1142
1178
|
try {
|
|
@@ -1172,7 +1208,7 @@ function encodeSellERC20Callback(parameters) {
|
|
|
1172
1208
|
|
|
1173
1209
|
//#endregion
|
|
1174
1210
|
//#region src/core/Chain.ts
|
|
1175
|
-
var Chain_exports = /* @__PURE__ */
|
|
1211
|
+
var Chain_exports = /* @__PURE__ */ __exportAll({
|
|
1176
1212
|
ChainId: () => ChainId,
|
|
1177
1213
|
InvalidBatchSizeError: () => InvalidBatchSizeError,
|
|
1178
1214
|
InvalidBlockRangeError: () => InvalidBlockRangeError,
|
|
@@ -1234,7 +1270,8 @@ const chains$2 = {
|
|
|
1234
1270
|
address: "0x1897A8997241C1cD4bD0698647e4EB7213535c24",
|
|
1235
1271
|
blockCreated: 21439510
|
|
1236
1272
|
}
|
|
1237
|
-
} }
|
|
1273
|
+
} },
|
|
1274
|
+
callbacks: []
|
|
1238
1275
|
}
|
|
1239
1276
|
},
|
|
1240
1277
|
base: {
|
|
@@ -1263,7 +1300,8 @@ const chains$2 = {
|
|
|
1263
1300
|
address: "0xFf62A7c278C62eD665133147129245053Bbf5918",
|
|
1264
1301
|
blockCreated: 23928808
|
|
1265
1302
|
}
|
|
1266
|
-
} }
|
|
1303
|
+
} },
|
|
1304
|
+
callbacks: []
|
|
1267
1305
|
}
|
|
1268
1306
|
},
|
|
1269
1307
|
"ethereum-virtual-testnet": {
|
|
@@ -1292,7 +1330,8 @@ const chains$2 = {
|
|
|
1292
1330
|
address: "0x1897A8997241C1cD4bD0698647e4EB7213535c24",
|
|
1293
1331
|
blockCreated: 21439510
|
|
1294
1332
|
}
|
|
1295
|
-
} }
|
|
1333
|
+
} },
|
|
1334
|
+
callbacks: []
|
|
1296
1335
|
}
|
|
1297
1336
|
},
|
|
1298
1337
|
anvil: {
|
|
@@ -1321,7 +1360,8 @@ const chains$2 = {
|
|
|
1321
1360
|
address: "0x0000000000000000000000000000000000000000",
|
|
1322
1361
|
blockCreated: 0
|
|
1323
1362
|
}
|
|
1324
|
-
} }
|
|
1363
|
+
} },
|
|
1364
|
+
callbacks: []
|
|
1325
1365
|
}
|
|
1326
1366
|
}
|
|
1327
1367
|
};
|
|
@@ -1417,10 +1457,15 @@ var MissingBlockNumberError = class extends BaseError {
|
|
|
1417
1457
|
|
|
1418
1458
|
//#endregion
|
|
1419
1459
|
//#region src/core/ChainRegistry.ts
|
|
1420
|
-
var ChainRegistry_exports = /* @__PURE__ */
|
|
1421
|
-
|
|
1460
|
+
var ChainRegistry_exports = /* @__PURE__ */ __exportAll({ create: () => create$15 });
|
|
1461
|
+
/**
|
|
1462
|
+
* Creates a chain registry from a list of chains.
|
|
1463
|
+
* @param chains - Array of chain objects to register.
|
|
1464
|
+
* @returns A registry for looking up chains by ID. {@link ChainRegistry}
|
|
1465
|
+
*/
|
|
1466
|
+
function create$15(chains) {
|
|
1422
1467
|
const byId = /* @__PURE__ */ new Map();
|
|
1423
|
-
for (const chain of chains
|
|
1468
|
+
for (const chain of chains) byId.set(chain.id, chain);
|
|
1424
1469
|
return {
|
|
1425
1470
|
getById: (chainId) => byId.get(chainId),
|
|
1426
1471
|
list: () => Array.from(byId.values())
|
|
@@ -1510,12 +1555,12 @@ const transformAddress = (val, ctx) => {
|
|
|
1510
1555
|
|
|
1511
1556
|
//#endregion
|
|
1512
1557
|
//#region src/core/LLTV.ts
|
|
1513
|
-
var LLTV_exports = /* @__PURE__ */
|
|
1558
|
+
var LLTV_exports = /* @__PURE__ */ __exportAll({
|
|
1514
1559
|
InvalidLLTVError: () => InvalidLLTVError,
|
|
1515
1560
|
InvalidOptionError: () => InvalidOptionError$1,
|
|
1516
1561
|
LLTVSchema: () => LLTVSchema,
|
|
1517
1562
|
Options: () => Options,
|
|
1518
|
-
from: () => from$
|
|
1563
|
+
from: () => from$18
|
|
1519
1564
|
});
|
|
1520
1565
|
const Options = [
|
|
1521
1566
|
.385,
|
|
@@ -1534,7 +1579,7 @@ const LLTV_SCALED = Options.map((lltv) => BigInt(lltv * 10 ** 18));
|
|
|
1534
1579
|
* @param lltv - The LLTV option or the scaled LLTV.
|
|
1535
1580
|
* @returns The LLTV.
|
|
1536
1581
|
*/
|
|
1537
|
-
function from$
|
|
1582
|
+
function from$18(lltv) {
|
|
1538
1583
|
if (typeof lltv === "bigint" && !LLTV_SCALED.includes(lltv)) throw new InvalidLLTVError(lltv);
|
|
1539
1584
|
if (typeof lltv === "bigint") return lltv;
|
|
1540
1585
|
if (typeof lltv === "number" && !Options.includes(lltv)) throw new InvalidOptionError$1(lltv);
|
|
@@ -1554,21 +1599,21 @@ var InvalidLLTVError = class extends BaseError {
|
|
|
1554
1599
|
};
|
|
1555
1600
|
const LLTVSchema = z$1.bigint({ coerce: true }).refine((lltv) => {
|
|
1556
1601
|
try {
|
|
1557
|
-
from$
|
|
1602
|
+
from$18(lltv);
|
|
1558
1603
|
return true;
|
|
1559
1604
|
} catch (_) {
|
|
1560
1605
|
return false;
|
|
1561
1606
|
}
|
|
1562
1607
|
}, { error: () => {
|
|
1563
1608
|
return "Invalid LLTV: must be one of 0.385, 0.625, 0.77, 0.86, 0.915, 0.945, 0.965 or 0.98 (scaled by 1e18)";
|
|
1564
|
-
} }).transform((lltv) => from$
|
|
1609
|
+
} }).transform((lltv) => from$18(lltv));
|
|
1565
1610
|
|
|
1566
1611
|
//#endregion
|
|
1567
1612
|
//#region src/core/Collateral.ts
|
|
1568
|
-
var Collateral_exports = /* @__PURE__ */
|
|
1613
|
+
var Collateral_exports = /* @__PURE__ */ __exportAll({
|
|
1569
1614
|
CollateralSchema: () => CollateralSchema,
|
|
1570
1615
|
CollateralsSchema: () => CollateralsSchema,
|
|
1571
|
-
from: () => from$
|
|
1616
|
+
from: () => from$17,
|
|
1572
1617
|
random: () => random$3
|
|
1573
1618
|
});
|
|
1574
1619
|
const CollateralSchema = z$1.object({
|
|
@@ -1588,10 +1633,10 @@ const CollateralsSchema = z$1.array(CollateralSchema).min(1, { message: "At leas
|
|
|
1588
1633
|
}
|
|
1589
1634
|
return true;
|
|
1590
1635
|
}, { message: "Collaterals must not contain duplicate assets" });
|
|
1591
|
-
const from$
|
|
1636
|
+
const from$17 = (parameters) => {
|
|
1592
1637
|
return {
|
|
1593
1638
|
asset: parameters.asset.toLowerCase(),
|
|
1594
|
-
lltv: from$
|
|
1639
|
+
lltv: from$18(parameters.lltv),
|
|
1595
1640
|
oracle: parameters.oracle.toLowerCase()
|
|
1596
1641
|
};
|
|
1597
1642
|
};
|
|
@@ -1605,7 +1650,7 @@ const from$16 = (parameters) => {
|
|
|
1605
1650
|
* ```
|
|
1606
1651
|
*/
|
|
1607
1652
|
function random$3() {
|
|
1608
|
-
return from$
|
|
1653
|
+
return from$17({
|
|
1609
1654
|
asset: address(),
|
|
1610
1655
|
oracle: address(),
|
|
1611
1656
|
lltv: .965
|
|
@@ -1614,7 +1659,7 @@ function random$3() {
|
|
|
1614
1659
|
|
|
1615
1660
|
//#endregion
|
|
1616
1661
|
//#region src/core/ERC4626.ts
|
|
1617
|
-
var ERC4626_exports = /* @__PURE__ */
|
|
1662
|
+
var ERC4626_exports = /* @__PURE__ */ __exportAll({
|
|
1618
1663
|
DenominatorIsZeroError: () => DenominatorIsZeroError,
|
|
1619
1664
|
convertToAssets: () => convertToAssets,
|
|
1620
1665
|
convertToShares: () => convertToShares,
|
|
@@ -1677,7 +1722,7 @@ var DenominatorIsZeroError = class extends BaseError {
|
|
|
1677
1722
|
|
|
1678
1723
|
//#endregion
|
|
1679
1724
|
//#region src/core/Liquidity.ts
|
|
1680
|
-
var Liquidity_exports = /* @__PURE__ */
|
|
1725
|
+
var Liquidity_exports = /* @__PURE__ */ __exportAll({
|
|
1681
1726
|
calculateMaxDebt: () => calculateMaxDebt,
|
|
1682
1727
|
generateAllowancePoolId: () => generateAllowancePoolId,
|
|
1683
1728
|
generateBalancePoolId: () => generateBalancePoolId,
|
|
@@ -1703,23 +1748,23 @@ function calculateMaxDebt(amount, oraclePrice, lltv) {
|
|
|
1703
1748
|
* Generate pool ID for balance pools.
|
|
1704
1749
|
*/
|
|
1705
1750
|
function generateBalancePoolId(parameters) {
|
|
1706
|
-
const { user, chainId, token
|
|
1707
|
-
return `${user}-${chainId.toString()}-${token
|
|
1751
|
+
const { user, chainId, token } = parameters;
|
|
1752
|
+
return `${user}-${chainId.toString()}-${token}-balance`.toLowerCase();
|
|
1708
1753
|
}
|
|
1709
1754
|
/**
|
|
1710
1755
|
* Generate pool ID for allowance pools.
|
|
1711
1756
|
*/
|
|
1712
1757
|
function generateAllowancePoolId(parameters) {
|
|
1713
|
-
const { user, chainId, token
|
|
1714
|
-
return `${user}-${chainId.toString()}-${token
|
|
1758
|
+
const { user, chainId, token } = parameters;
|
|
1759
|
+
return `${user}-${chainId.toString()}-${token}-allowance`.toLowerCase();
|
|
1715
1760
|
}
|
|
1716
1761
|
/**
|
|
1717
1762
|
* Generate pool ID for sell ERC20 callback pools.
|
|
1718
1763
|
* Each offer has its own callback pool to prevent liquidity conflicts.
|
|
1719
1764
|
*/
|
|
1720
1765
|
function generateSellERC20CallbackPoolId(parameters) {
|
|
1721
|
-
const { user, chainId, obligationId
|
|
1722
|
-
return `${user}-${chainId.toString()}-${obligationId
|
|
1766
|
+
const { user, chainId, obligationId, token, offerHash } = parameters;
|
|
1767
|
+
return `${user}-${chainId.toString()}-${obligationId}-${token}-${offerHash}-sell_erc20_callback`.toLowerCase();
|
|
1723
1768
|
}
|
|
1724
1769
|
/**
|
|
1725
1770
|
* Generate pool ID for obligation collateral pools.
|
|
@@ -1727,22 +1772,22 @@ function generateSellERC20CallbackPoolId(parameters) {
|
|
|
1727
1772
|
* These pools are shared across all offers with the same obligation.
|
|
1728
1773
|
*/
|
|
1729
1774
|
function generateObligationCollateralPoolId(parameters) {
|
|
1730
|
-
const { user, chainId, obligationId
|
|
1731
|
-
return `${user}-${chainId.toString()}-${obligationId
|
|
1775
|
+
const { user, chainId, obligationId, token } = parameters;
|
|
1776
|
+
return `${user}-${chainId.toString()}-${obligationId}-${token}-obligation-collateral`.toLowerCase();
|
|
1732
1777
|
}
|
|
1733
1778
|
/**
|
|
1734
1779
|
* Generate pool ID for buy vault callback pools.
|
|
1735
1780
|
*/
|
|
1736
1781
|
function generateBuyVaultCallbackPoolId(parameters) {
|
|
1737
1782
|
const { user, chainId, vault, offerHash } = parameters;
|
|
1738
|
-
return `${user}-${chainId.toString()}-${vault}-${offerHash}-${
|
|
1783
|
+
return `${user}-${chainId.toString()}-${vault}-${offerHash}-${Type$1.BuyVaultV1Callback}`.toLowerCase();
|
|
1739
1784
|
}
|
|
1740
1785
|
/**
|
|
1741
1786
|
* Generate pool ID for debt pools.
|
|
1742
1787
|
*/
|
|
1743
1788
|
function generateDebtPoolId(parameters) {
|
|
1744
|
-
const { user, chainId, obligationId
|
|
1745
|
-
return `${user}-${chainId.toString()}-${obligationId
|
|
1789
|
+
const { user, chainId, obligationId } = parameters;
|
|
1790
|
+
return `${user}-${chainId.toString()}-${obligationId}-debt`.toLowerCase();
|
|
1746
1791
|
}
|
|
1747
1792
|
/**
|
|
1748
1793
|
* Generate pool ID for user position in a vault.
|
|
@@ -1768,17 +1813,17 @@ function generateMarketLiquidityPoolId(parameters) {
|
|
|
1768
1813
|
|
|
1769
1814
|
//#endregion
|
|
1770
1815
|
//#region src/core/Maturity.ts
|
|
1771
|
-
var Maturity_exports = /* @__PURE__ */
|
|
1816
|
+
var Maturity_exports = /* @__PURE__ */ __exportAll({
|
|
1772
1817
|
InvalidDateError: () => InvalidDateError,
|
|
1773
1818
|
InvalidFormatError: () => InvalidFormatError,
|
|
1774
1819
|
InvalidOptionError: () => InvalidOptionError,
|
|
1775
1820
|
MaturitySchema: () => MaturitySchema,
|
|
1776
1821
|
MaturityType: () => MaturityType,
|
|
1777
|
-
from: () => from$
|
|
1822
|
+
from: () => from$16
|
|
1778
1823
|
});
|
|
1779
|
-
const MaturitySchema = z$1.number().int().refine((maturity
|
|
1824
|
+
const MaturitySchema = z$1.number().int().refine((maturity) => {
|
|
1780
1825
|
try {
|
|
1781
|
-
from$
|
|
1826
|
+
from$16(maturity);
|
|
1782
1827
|
return true;
|
|
1783
1828
|
} catch (_e) {
|
|
1784
1829
|
return false;
|
|
@@ -1789,15 +1834,15 @@ const MaturitySchema = z$1.number().int().refine((maturity$1) => {
|
|
|
1789
1834
|
} catch (_) {
|
|
1790
1835
|
return `The maturity is set to ${issue.input}. It must fall on the allowed settlement cycles (Friday 15:00 UTC at the end of week/month/quarter).`;
|
|
1791
1836
|
}
|
|
1792
|
-
} }).transform((maturity
|
|
1793
|
-
let MaturityType = /* @__PURE__ */ function(MaturityType
|
|
1794
|
-
MaturityType
|
|
1795
|
-
MaturityType
|
|
1796
|
-
MaturityType
|
|
1797
|
-
MaturityType
|
|
1798
|
-
MaturityType
|
|
1799
|
-
MaturityType
|
|
1800
|
-
return MaturityType
|
|
1837
|
+
} }).transform((maturity) => maturity);
|
|
1838
|
+
let MaturityType = /* @__PURE__ */ function(MaturityType) {
|
|
1839
|
+
MaturityType["EndOfWeek"] = "end_of_week";
|
|
1840
|
+
MaturityType["EndOfNextWeek"] = "end_of_next_week";
|
|
1841
|
+
MaturityType["EndOfMonth"] = "end_of_month";
|
|
1842
|
+
MaturityType["EndOfNextMonth"] = "end_of_next_month";
|
|
1843
|
+
MaturityType["EndOfQuarter"] = "end_of_quarter";
|
|
1844
|
+
MaturityType["EndOfNextQuarter"] = "end_of_next_quarter";
|
|
1845
|
+
return MaturityType;
|
|
1801
1846
|
}({});
|
|
1802
1847
|
const MaturityOptions = {
|
|
1803
1848
|
end_of_week: () => endOfWeek(),
|
|
@@ -1813,7 +1858,7 @@ const MaturityOptions = {
|
|
|
1813
1858
|
* @throws {InvalidDateError} If the maturity is in seconds but not a valid date.
|
|
1814
1859
|
* @throws {InvalidOptionError} If the maturity is not a valid option.
|
|
1815
1860
|
*/
|
|
1816
|
-
function from$
|
|
1861
|
+
function from$16(ts) {
|
|
1817
1862
|
if (typeof ts === "string") {
|
|
1818
1863
|
if (ts in MaturityOptions) return MaturityOptions[ts]();
|
|
1819
1864
|
throw new InvalidOptionError(ts);
|
|
@@ -1831,23 +1876,23 @@ const endOfNextWeek = () => fridayOfWeek(1);
|
|
|
1831
1876
|
* on that Friday), roll to the next month's last Friday.
|
|
1832
1877
|
*/
|
|
1833
1878
|
const endOfMonth = () => {
|
|
1834
|
-
const now
|
|
1835
|
-
const year = now
|
|
1836
|
-
const month = now
|
|
1837
|
-
const endOfMonth
|
|
1838
|
-
if (now
|
|
1839
|
-
return endOfMonth
|
|
1879
|
+
const now = /* @__PURE__ */ new Date();
|
|
1880
|
+
const year = now.getUTCFullYear();
|
|
1881
|
+
const month = now.getUTCMonth();
|
|
1882
|
+
const endOfMonth = lastFridayOfMonth(year, month);
|
|
1883
|
+
if (now.getTime() > endOfMonth * 1e3) return lastFridayOfMonth(year, month + 1);
|
|
1884
|
+
return endOfMonth;
|
|
1840
1885
|
};
|
|
1841
1886
|
/** Returns the end of the next month (last friday of the next month at 15:00:00 UTC)
|
|
1842
1887
|
* Business rule: if we are after the last Friday of the current month (strictly after 15:00 UTC
|
|
1843
1888
|
* on that Friday), we consider being in the next month already, so "next month" becomes month+2.
|
|
1844
1889
|
*/
|
|
1845
1890
|
const endOfNextMonth = () => {
|
|
1846
|
-
const now
|
|
1847
|
-
const year = now
|
|
1848
|
-
const month = now
|
|
1849
|
-
const endOfMonth
|
|
1850
|
-
if (now
|
|
1891
|
+
const now = /* @__PURE__ */ new Date();
|
|
1892
|
+
const year = now.getUTCFullYear();
|
|
1893
|
+
const month = now.getUTCMonth();
|
|
1894
|
+
const endOfMonth = lastFridayOfMonth(year, month);
|
|
1895
|
+
if (now.getTime() > endOfMonth * 1e3) return lastFridayOfMonth(year, month + 2);
|
|
1851
1896
|
return lastFridayOfMonth(year, month + 1);
|
|
1852
1897
|
};
|
|
1853
1898
|
/** Returns the end of the current quarter (last friday of the quarter at 15:00:00 UTC) */
|
|
@@ -1855,10 +1900,10 @@ const endOfQuarter = () => lastFridayOfQuarter(0);
|
|
|
1855
1900
|
/** Returns the end of the next quarter (last friday of the next quarter at 15:00:00 UTC) */
|
|
1856
1901
|
const endOfNextQuarter = () => lastFridayOfQuarter(1);
|
|
1857
1902
|
const fridayOfWeek = (weeksAhead = 0) => {
|
|
1858
|
-
const now
|
|
1859
|
-
const today15H = new Date(Date.UTC(now
|
|
1903
|
+
const now = /* @__PURE__ */ new Date();
|
|
1904
|
+
const today15H = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 15));
|
|
1860
1905
|
let daysUntilFriday = (5 - today15H.getUTCDay() + 7) % 7;
|
|
1861
|
-
if (daysUntilFriday === 0 && now
|
|
1906
|
+
if (daysUntilFriday === 0 && now.getTime() >= today15H.getTime()) daysUntilFriday = 7;
|
|
1862
1907
|
const friday = new Date(today15H);
|
|
1863
1908
|
friday.setUTCDate(friday.getUTCDate() + daysUntilFriday + weeksAhead * 7);
|
|
1864
1909
|
return friday.getTime() / 1e3;
|
|
@@ -1869,9 +1914,9 @@ const lastFridayOfMonth = (year, month) => {
|
|
|
1869
1914
|
return lastDayOfMonth15H.setUTCDate(lastDayOfMonth15H.getUTCDate()) / 1e3;
|
|
1870
1915
|
};
|
|
1871
1916
|
const lastFridayOfQuarter = (quartersAhead = 0) => {
|
|
1872
|
-
const now
|
|
1873
|
-
const quarterIndex = Math.floor(now
|
|
1874
|
-
return lastFridayOfMonth(now
|
|
1917
|
+
const now = /* @__PURE__ */ new Date();
|
|
1918
|
+
const quarterIndex = Math.floor(now.getUTCMonth() / 3) + quartersAhead;
|
|
1919
|
+
return lastFridayOfMonth(now.getUTCFullYear() + Math.floor(quarterIndex / 4), quarterIndex % 4 * 3 + 2);
|
|
1875
1920
|
};
|
|
1876
1921
|
var InvalidFormatError = class extends BaseError {
|
|
1877
1922
|
name = "Maturity.InvalidFormatError";
|
|
@@ -1894,11 +1939,11 @@ var InvalidOptionError = class extends BaseError {
|
|
|
1894
1939
|
|
|
1895
1940
|
//#endregion
|
|
1896
1941
|
//#region src/core/Obligation.ts
|
|
1897
|
-
var Obligation_exports = /* @__PURE__ */
|
|
1942
|
+
var Obligation_exports = /* @__PURE__ */ __exportAll({
|
|
1898
1943
|
CollateralsAreNotSortedError: () => CollateralsAreNotSortedError,
|
|
1899
1944
|
InvalidObligationError: () => InvalidObligationError,
|
|
1900
1945
|
ObligationSchema: () => ObligationSchema,
|
|
1901
|
-
from: () => from$
|
|
1946
|
+
from: () => from$15,
|
|
1902
1947
|
fromSnakeCase: () => fromSnakeCase$2,
|
|
1903
1948
|
id: () => id,
|
|
1904
1949
|
random: () => random$2
|
|
@@ -1932,11 +1977,11 @@ const ObligationSchema = z$1.object({
|
|
|
1932
1977
|
* });
|
|
1933
1978
|
* ```
|
|
1934
1979
|
*/
|
|
1935
|
-
function from$
|
|
1980
|
+
function from$15(parameters) {
|
|
1936
1981
|
try {
|
|
1937
1982
|
const parsedObligation = ObligationSchema.parse({
|
|
1938
1983
|
...parameters,
|
|
1939
|
-
maturity: from$
|
|
1984
|
+
maturity: from$16(parameters.maturity)
|
|
1940
1985
|
});
|
|
1941
1986
|
return {
|
|
1942
1987
|
chainId: parsedObligation.chainId,
|
|
@@ -1955,7 +2000,7 @@ function from$14(parameters) {
|
|
|
1955
2000
|
* @returns The created obligation. {@link fromSnakeCase.ReturnType}
|
|
1956
2001
|
*/
|
|
1957
2002
|
function fromSnakeCase$2(input) {
|
|
1958
|
-
return from$
|
|
2003
|
+
return from$15(fromSnakeCase$3(input));
|
|
1959
2004
|
}
|
|
1960
2005
|
/**
|
|
1961
2006
|
* Calculates the obligation id based on the smart contract's Obligation struct.
|
|
@@ -2020,11 +2065,11 @@ function id(parameters) {
|
|
|
2020
2065
|
* ```
|
|
2021
2066
|
*/
|
|
2022
2067
|
function random$2() {
|
|
2023
|
-
return from$
|
|
2068
|
+
return from$15({
|
|
2024
2069
|
chainId: 1,
|
|
2025
2070
|
loanToken: address(),
|
|
2026
2071
|
collaterals: [random$3()],
|
|
2027
|
-
maturity: from$
|
|
2072
|
+
maturity: from$16("end_of_next_quarter")
|
|
2028
2073
|
});
|
|
2029
2074
|
}
|
|
2030
2075
|
var InvalidObligationError = class extends BaseError {
|
|
@@ -2042,7 +2087,7 @@ var CollateralsAreNotSortedError = class extends BaseError {
|
|
|
2042
2087
|
|
|
2043
2088
|
//#endregion
|
|
2044
2089
|
//#region src/core/Tree.ts
|
|
2045
|
-
var Tree_exports = /* @__PURE__ */
|
|
2090
|
+
var Tree_exports = /* @__PURE__ */ __exportAll({
|
|
2046
2091
|
DecodeError: () => DecodeError,
|
|
2047
2092
|
EncodeError: () => EncodeError,
|
|
2048
2093
|
TreeError: () => TreeError,
|
|
@@ -2050,11 +2095,11 @@ var Tree_exports = /* @__PURE__ */ __export({
|
|
|
2050
2095
|
decode: () => decode$1,
|
|
2051
2096
|
encode: () => encode$1,
|
|
2052
2097
|
encodeUnsigned: () => encodeUnsigned,
|
|
2053
|
-
from: () => from$
|
|
2098
|
+
from: () => from$14,
|
|
2054
2099
|
proofs: () => proofs
|
|
2055
2100
|
});
|
|
2056
2101
|
const VERSION$1 = 1;
|
|
2057
|
-
const normalizeHash = (hash
|
|
2102
|
+
const normalizeHash = (hash) => hash.toLowerCase();
|
|
2058
2103
|
/**
|
|
2059
2104
|
* Builds a Merkle tree from a list of offers.
|
|
2060
2105
|
*
|
|
@@ -2066,19 +2111,19 @@ const normalizeHash = (hash$1) => hash$1.toLowerCase();
|
|
|
2066
2111
|
* @returns A `StandardMerkleTree` of `bytes32` leaves representing the offers.
|
|
2067
2112
|
* @throws {TreeError} If tree building fails due to offer inconsistencies.
|
|
2068
2113
|
*/
|
|
2069
|
-
const from$
|
|
2070
|
-
const leaves = offers
|
|
2114
|
+
const from$14 = (offers) => {
|
|
2115
|
+
const leaves = offers.map((offer) => [hash(offer)]);
|
|
2071
2116
|
const tree = StandardMerkleTree.of(leaves, ["bytes32"]);
|
|
2072
|
-
const orderedOffers = orderOffers(tree, offers
|
|
2117
|
+
const orderedOffers = orderOffers(tree, offers);
|
|
2073
2118
|
return Object.assign(tree, { offers: orderedOffers });
|
|
2074
2119
|
};
|
|
2075
|
-
const orderOffers = (tree, offers
|
|
2120
|
+
const orderOffers = (tree, offers) => {
|
|
2076
2121
|
const offerByHash = /* @__PURE__ */ new Map();
|
|
2077
|
-
for (const offer of offers
|
|
2122
|
+
for (const offer of offers) offerByHash.set(normalizeHash(hash(offer)), offer);
|
|
2078
2123
|
const entries = tree.dump().values.map((value) => {
|
|
2079
|
-
const hash
|
|
2080
|
-
const offer = offerByHash.get(hash
|
|
2081
|
-
if (!offer) throw new TreeError(`missing offer for leaf ${hash
|
|
2124
|
+
const hash = normalizeHash(value.value[0]);
|
|
2125
|
+
const offer = offerByHash.get(hash);
|
|
2126
|
+
if (!offer) throw new TreeError(`missing offer for leaf ${hash}`);
|
|
2082
2127
|
return {
|
|
2083
2128
|
offer,
|
|
2084
2129
|
treeIndex: value.treeIndex
|
|
@@ -2111,10 +2156,10 @@ const assertHex = (value, expectedBytes, name) => {
|
|
|
2111
2156
|
const verifySignatureAndRecoverAddress = async (params) => {
|
|
2112
2157
|
const { root, signature } = params;
|
|
2113
2158
|
assertHex(signature, 65, "signature");
|
|
2114
|
-
const hash
|
|
2159
|
+
const hash = hashMessage({ raw: root });
|
|
2115
2160
|
try {
|
|
2116
2161
|
return await recoverAddress({
|
|
2117
|
-
hash
|
|
2162
|
+
hash,
|
|
2118
2163
|
signature
|
|
2119
2164
|
});
|
|
2120
2165
|
} catch {
|
|
@@ -2188,7 +2233,7 @@ const encodeUnsigned = (tree) => {
|
|
|
2188
2233
|
};
|
|
2189
2234
|
const validateTreeForEncoding = (tree) => {
|
|
2190
2235
|
if (VERSION$1 > 255) throw new EncodeError(`version overflow: ${VERSION$1} exceeds 255`);
|
|
2191
|
-
const computed = from$
|
|
2236
|
+
const computed = from$14(tree.offers);
|
|
2192
2237
|
if (tree.root !== computed.root) throw new EncodeError(`root mismatch: expected ${computed.root}, got ${tree.root}`);
|
|
2193
2238
|
};
|
|
2194
2239
|
const encodeUnsignedBytes = (tree) => {
|
|
@@ -2224,19 +2269,19 @@ const encodeUnsignedBytes = (tree) => {
|
|
|
2224
2269
|
* @throws {DecodeError} If version invalid, signature invalid, or root mismatch
|
|
2225
2270
|
*/
|
|
2226
2271
|
const decode$1 = async (encoded) => {
|
|
2227
|
-
const bytes
|
|
2228
|
-
if (bytes
|
|
2229
|
-
const version = bytes
|
|
2272
|
+
const bytes = hexToBytes(encoded);
|
|
2273
|
+
if (bytes.length < 98) throw new DecodeError("payload too short");
|
|
2274
|
+
const version = bytes[0];
|
|
2230
2275
|
if (version !== (VERSION$1 & 255)) throw new DecodeError(`invalid version: expected ${VERSION$1}, got ${version ?? 0}`);
|
|
2231
|
-
const signature = bytesToHex(bytes
|
|
2232
|
-
const root = bytesToHex(bytes
|
|
2276
|
+
const signature = bytesToHex(bytes.slice(-65));
|
|
2277
|
+
const root = bytesToHex(bytes.slice(-97, -65));
|
|
2233
2278
|
assertHex(root, 32, "root");
|
|
2234
2279
|
assertHex(signature, 65, "signature");
|
|
2235
2280
|
const signer = await verifySignatureAndRecoverAddress({
|
|
2236
2281
|
root,
|
|
2237
2282
|
signature
|
|
2238
2283
|
});
|
|
2239
|
-
const compressed = bytes
|
|
2284
|
+
const compressed = bytes.slice(1, -97);
|
|
2240
2285
|
let decoded;
|
|
2241
2286
|
try {
|
|
2242
2287
|
decoded = ungzip(compressed, { to: "string" });
|
|
@@ -2249,7 +2294,7 @@ const decode$1 = async (encoded) => {
|
|
|
2249
2294
|
} catch {
|
|
2250
2295
|
throw new DecodeError("JSON parse failed");
|
|
2251
2296
|
}
|
|
2252
|
-
const tree = from$
|
|
2297
|
+
const tree = from$14(rawOffers.map((o) => OfferSchema().parse(o)));
|
|
2253
2298
|
if (root !== tree.root) throw new DecodeError(`root mismatch: expected ${tree.root}, got ${root}`);
|
|
2254
2299
|
return {
|
|
2255
2300
|
tree,
|
|
@@ -2290,7 +2335,7 @@ var DecodeError = class extends BaseError {
|
|
|
2290
2335
|
|
|
2291
2336
|
//#endregion
|
|
2292
2337
|
//#region src/core/Offer.ts
|
|
2293
|
-
var Offer_exports = /* @__PURE__ */
|
|
2338
|
+
var Offer_exports = /* @__PURE__ */ __exportAll({
|
|
2294
2339
|
AccountNotSetError: () => AccountNotSetError,
|
|
2295
2340
|
InvalidOfferError: () => InvalidOfferError,
|
|
2296
2341
|
OfferSchema: () => OfferSchema,
|
|
@@ -2299,7 +2344,7 @@ var Offer_exports = /* @__PURE__ */ __export({
|
|
|
2299
2344
|
decode: () => decode,
|
|
2300
2345
|
domain: () => domain,
|
|
2301
2346
|
encode: () => encode,
|
|
2302
|
-
from: () => from$
|
|
2347
|
+
from: () => from$13,
|
|
2303
2348
|
fromSnakeCase: () => fromSnakeCase$1,
|
|
2304
2349
|
hash: () => hash,
|
|
2305
2350
|
obligationId: () => obligationId,
|
|
@@ -2312,10 +2357,10 @@ var Offer_exports = /* @__PURE__ */ __export({
|
|
|
2312
2357
|
});
|
|
2313
2358
|
/** Internal symbol for caching the computed hash. */
|
|
2314
2359
|
const HASH_CACHE = Symbol("offer.hash");
|
|
2315
|
-
let Status = /* @__PURE__ */ function(Status
|
|
2316
|
-
Status
|
|
2317
|
-
Status
|
|
2318
|
-
return Status
|
|
2360
|
+
let Status = /* @__PURE__ */ function(Status) {
|
|
2361
|
+
Status["VALID"] = "VALID";
|
|
2362
|
+
Status["SIMULATION_ERROR"] = "SIMULATION_ERROR";
|
|
2363
|
+
return Status;
|
|
2319
2364
|
}({});
|
|
2320
2365
|
const OfferSchema = () => {
|
|
2321
2366
|
return z$1.object({
|
|
@@ -2359,7 +2404,7 @@ const OfferSchema = () => {
|
|
|
2359
2404
|
* @param input - The offer to create.
|
|
2360
2405
|
* @returns The created offer.
|
|
2361
2406
|
*/
|
|
2362
|
-
function from$
|
|
2407
|
+
function from$13(input) {
|
|
2363
2408
|
try {
|
|
2364
2409
|
return OfferSchema().parse(input);
|
|
2365
2410
|
} catch (error) {
|
|
@@ -2373,7 +2418,7 @@ function from$12(input) {
|
|
|
2373
2418
|
* @returns The created offer.
|
|
2374
2419
|
*/
|
|
2375
2420
|
function fromSnakeCase$1(input) {
|
|
2376
|
-
return from$
|
|
2421
|
+
return from$13(fromSnakeCase$3(input));
|
|
2377
2422
|
}
|
|
2378
2423
|
/**
|
|
2379
2424
|
* Converts an offer to a snake case object.
|
|
@@ -2427,8 +2472,8 @@ function random$1(config) {
|
|
|
2427
2472
|
const collateralCandidates = config?.collateralTokens ? config.collateralTokens.filter((a) => a !== loanToken) : [address()];
|
|
2428
2473
|
const collateralAsset = collateralCandidates[int(collateralCandidates.length)];
|
|
2429
2474
|
const maturityOption = weightedChoice([["end_of_month", 1], ["end_of_next_month", 1]]);
|
|
2430
|
-
const maturity
|
|
2431
|
-
const lltv = from$
|
|
2475
|
+
const maturity = config?.maturity ?? from$16(maturityOption);
|
|
2476
|
+
const lltv = from$18(weightedChoice([
|
|
2432
2477
|
[.385, 1],
|
|
2433
2478
|
[.5, 1],
|
|
2434
2479
|
[.625, 2],
|
|
@@ -2467,15 +2512,15 @@ function random$1(config) {
|
|
|
2467
2512
|
})
|
|
2468
2513
|
};
|
|
2469
2514
|
})();
|
|
2470
|
-
return from$
|
|
2515
|
+
return from$13({
|
|
2471
2516
|
maker: config?.maker ?? address(),
|
|
2472
2517
|
assets: assetsScaled,
|
|
2473
2518
|
obligationUnits: config?.obligationUnits ?? 0n,
|
|
2474
2519
|
obligationShares: config?.obligationShares ?? 0n,
|
|
2475
2520
|
price,
|
|
2476
|
-
maturity
|
|
2477
|
-
expiry: config?.expiry ?? maturity
|
|
2478
|
-
start: config?.start ?? maturity
|
|
2521
|
+
maturity,
|
|
2522
|
+
expiry: config?.expiry ?? maturity - 1,
|
|
2523
|
+
start: config?.start ?? maturity - 10,
|
|
2479
2524
|
group: config?.group ?? hex(32),
|
|
2480
2525
|
session: config?.session ?? hex(32),
|
|
2481
2526
|
buy,
|
|
@@ -2602,15 +2647,15 @@ const types = {
|
|
|
2602
2647
|
* @param wallet - The wallet to sign the offers with.
|
|
2603
2648
|
* @returns The signed offers.
|
|
2604
2649
|
*/
|
|
2605
|
-
async function sign(offers
|
|
2650
|
+
async function sign(offers, wallet) {
|
|
2606
2651
|
if (!wallet.account) throw new AccountNotSetError();
|
|
2607
2652
|
return wallet.signMessage({
|
|
2608
2653
|
account: wallet.account,
|
|
2609
|
-
message: { raw: signatureMsg(offers
|
|
2654
|
+
message: { raw: signatureMsg(offers) }
|
|
2610
2655
|
});
|
|
2611
2656
|
}
|
|
2612
|
-
function signatureMsg(offers
|
|
2613
|
-
return from$
|
|
2657
|
+
function signatureMsg(offers) {
|
|
2658
|
+
return from$14(offers).root;
|
|
2614
2659
|
}
|
|
2615
2660
|
function hash(offer) {
|
|
2616
2661
|
const cached = offer[HASH_CACHE];
|
|
@@ -2648,7 +2693,7 @@ function hash(offer) {
|
|
|
2648
2693
|
* @returns The obligation id as a 32-byte hex string.
|
|
2649
2694
|
*/
|
|
2650
2695
|
function obligationId(offer) {
|
|
2651
|
-
return id(from$
|
|
2696
|
+
return id(from$15({
|
|
2652
2697
|
chainId: offer.chainId,
|
|
2653
2698
|
loanToken: offer.loanToken,
|
|
2654
2699
|
collaterals: offer.collaterals,
|
|
@@ -2764,13 +2809,13 @@ function decode(data) {
|
|
|
2764
2809
|
} catch (error) {
|
|
2765
2810
|
throw new InvalidOfferError(error);
|
|
2766
2811
|
}
|
|
2767
|
-
return from$
|
|
2812
|
+
return from$13({
|
|
2768
2813
|
maker: decoded[0],
|
|
2769
2814
|
assets: decoded[1],
|
|
2770
2815
|
obligationUnits: decoded[2],
|
|
2771
2816
|
obligationShares: decoded[3],
|
|
2772
2817
|
price: decoded[4],
|
|
2773
|
-
maturity: from$
|
|
2818
|
+
maturity: from$16(Number(decoded[5])),
|
|
2774
2819
|
expiry: Number(decoded[6]),
|
|
2775
2820
|
group: decoded[7],
|
|
2776
2821
|
session: decoded[8],
|
|
@@ -2779,7 +2824,7 @@ function decode(data) {
|
|
|
2779
2824
|
loanToken: decoded[11],
|
|
2780
2825
|
start: Number(decoded[12]),
|
|
2781
2826
|
collaterals: decoded[13].map((c) => {
|
|
2782
|
-
return from$
|
|
2827
|
+
return from$17({
|
|
2783
2828
|
asset: c.asset,
|
|
2784
2829
|
oracle: c.oracle,
|
|
2785
2830
|
lltv: c.lltv
|
|
@@ -2852,16 +2897,16 @@ var AccountNotSetError = class extends BaseError {
|
|
|
2852
2897
|
|
|
2853
2898
|
//#endregion
|
|
2854
2899
|
//#region src/core/Oracle.ts
|
|
2855
|
-
var Oracle_exports = /* @__PURE__ */
|
|
2900
|
+
var Oracle_exports = /* @__PURE__ */ __exportAll({
|
|
2856
2901
|
Conversion: () => Conversion,
|
|
2857
|
-
from: () => from$
|
|
2902
|
+
from: () => from$12
|
|
2858
2903
|
});
|
|
2859
2904
|
/**
|
|
2860
2905
|
* Create an Oracle from a plain object.
|
|
2861
2906
|
* @param data - The data to create the oracle from.
|
|
2862
2907
|
* @returns The created oracle.
|
|
2863
2908
|
*/
|
|
2864
|
-
function from$
|
|
2909
|
+
function from$12(data) {
|
|
2865
2910
|
return {
|
|
2866
2911
|
chainId: data.chainId,
|
|
2867
2912
|
address: data.address.toLowerCase(),
|
|
@@ -2884,14 +2929,14 @@ let Conversion;
|
|
|
2884
2929
|
|
|
2885
2930
|
//#endregion
|
|
2886
2931
|
//#region src/core/Position.ts
|
|
2887
|
-
var Position_exports = /* @__PURE__ */
|
|
2932
|
+
var Position_exports = /* @__PURE__ */ __exportAll({
|
|
2888
2933
|
Type: () => Type,
|
|
2889
|
-
from: () => from$
|
|
2934
|
+
from: () => from$11
|
|
2890
2935
|
});
|
|
2891
|
-
let Type = /* @__PURE__ */ function(Type
|
|
2892
|
-
Type
|
|
2893
|
-
Type
|
|
2894
|
-
return Type
|
|
2936
|
+
let Type = /* @__PURE__ */ function(Type) {
|
|
2937
|
+
Type["ERC20"] = "erc20";
|
|
2938
|
+
Type["VAULT_V1"] = "vault_v1";
|
|
2939
|
+
return Type;
|
|
2895
2940
|
}({});
|
|
2896
2941
|
/**
|
|
2897
2942
|
* @constructor
|
|
@@ -2899,7 +2944,7 @@ let Type = /* @__PURE__ */ function(Type$1) {
|
|
|
2899
2944
|
* @param parameters - {@link from.Parameters}
|
|
2900
2945
|
* @returns The created Position. {@link from.ReturnType}
|
|
2901
2946
|
*/
|
|
2902
|
-
function from$
|
|
2947
|
+
function from$11(parameters) {
|
|
2903
2948
|
return {
|
|
2904
2949
|
chainId: parameters.chainId,
|
|
2905
2950
|
contract: parameters.contract.toLowerCase(),
|
|
@@ -2913,10 +2958,10 @@ function from$10(parameters) {
|
|
|
2913
2958
|
|
|
2914
2959
|
//#endregion
|
|
2915
2960
|
//#region src/core/Quote.ts
|
|
2916
|
-
var Quote_exports = /* @__PURE__ */
|
|
2961
|
+
var Quote_exports = /* @__PURE__ */ __exportAll({
|
|
2917
2962
|
InvalidQuoteError: () => InvalidQuoteError,
|
|
2918
2963
|
QuoteSchema: () => QuoteSchema,
|
|
2919
|
-
from: () => from$
|
|
2964
|
+
from: () => from$10,
|
|
2920
2965
|
fromSnakeCase: () => fromSnakeCase,
|
|
2921
2966
|
random: () => random
|
|
2922
2967
|
});
|
|
@@ -2937,7 +2982,7 @@ const QuoteSchema = z$1.object({
|
|
|
2937
2982
|
* const quote = Quote.from({ obligationId: "0x123", ask: { price: 100n }, bid: { price: 100n } });
|
|
2938
2983
|
* ```
|
|
2939
2984
|
*/
|
|
2940
|
-
function from$
|
|
2985
|
+
function from$10(parameters) {
|
|
2941
2986
|
try {
|
|
2942
2987
|
const parsedQuote = QuoteSchema.parse(parameters);
|
|
2943
2988
|
return {
|
|
@@ -2956,7 +3001,7 @@ function from$9(parameters) {
|
|
|
2956
3001
|
* @returns The created quote. {@link fromSnakeCase.ReturnType}
|
|
2957
3002
|
*/
|
|
2958
3003
|
function fromSnakeCase(snake) {
|
|
2959
|
-
return from$
|
|
3004
|
+
return from$10(fromSnakeCase$3(snake));
|
|
2960
3005
|
}
|
|
2961
3006
|
/**
|
|
2962
3007
|
* Generates a random quote.
|
|
@@ -2968,7 +3013,7 @@ function fromSnakeCase(snake) {
|
|
|
2968
3013
|
* ```
|
|
2969
3014
|
*/
|
|
2970
3015
|
function random() {
|
|
2971
|
-
return from$
|
|
3016
|
+
return from$10({
|
|
2972
3017
|
obligationId: id(random$2()),
|
|
2973
3018
|
ask: { price: BigInt(int(1e6)) },
|
|
2974
3019
|
bid: { price: BigInt(int(1e6)) }
|
|
@@ -2981,9 +3026,158 @@ var InvalidQuoteError = class extends BaseError {
|
|
|
2981
3026
|
}
|
|
2982
3027
|
};
|
|
2983
3028
|
|
|
3029
|
+
//#endregion
|
|
3030
|
+
//#region src/core/TradingFee.ts
|
|
3031
|
+
var TradingFee_exports = /* @__PURE__ */ __exportAll({
|
|
3032
|
+
BREAKPOINTS: () => BREAKPOINTS,
|
|
3033
|
+
InvalidFeeError: () => InvalidFeeError,
|
|
3034
|
+
InvalidFeesLengthError: () => InvalidFeesLengthError,
|
|
3035
|
+
WAD: () => WAD,
|
|
3036
|
+
activate: () => activate,
|
|
3037
|
+
compute: () => compute,
|
|
3038
|
+
deactivate: () => deactivate,
|
|
3039
|
+
from: () => from$9,
|
|
3040
|
+
getFees: () => getFees,
|
|
3041
|
+
isActivated: () => isActivated
|
|
3042
|
+
});
|
|
3043
|
+
/**
|
|
3044
|
+
* Time breakpoints in seconds for piecewise linear fee interpolation.
|
|
3045
|
+
* Matches on-chain constants: 0d, 1d, 7d, 30d, 90d, 180d.
|
|
3046
|
+
*/
|
|
3047
|
+
const BREAKPOINTS = [
|
|
3048
|
+
0n,
|
|
3049
|
+
86400n,
|
|
3050
|
+
604800n,
|
|
3051
|
+
2592000n,
|
|
3052
|
+
7776000n,
|
|
3053
|
+
15552000n
|
|
3054
|
+
];
|
|
3055
|
+
/** WAD constant (1e18) for fee scaling. */
|
|
3056
|
+
const WAD = 10n ** 18n;
|
|
3057
|
+
/**
|
|
3058
|
+
* Create a TradingFee from an activation flag and 6 fee values.
|
|
3059
|
+
* @param activated - Whether the fee is active.
|
|
3060
|
+
* @param fees - Tuple of 6 fee values in WAD (one per breakpoint: 0d, 1d, 7d, 30d, 90d, 180d).
|
|
3061
|
+
* @returns A new TradingFee instance.
|
|
3062
|
+
* @throws {@link InvalidFeeError} if any fee exceeds WAD (100%).
|
|
3063
|
+
* @throws {@link InvalidFeesLengthError} if fees array doesn't have exactly 6 elements.
|
|
3064
|
+
*/
|
|
3065
|
+
function from$9(activated, fees) {
|
|
3066
|
+
if (fees.length !== 6) throw new InvalidFeesLengthError(fees.length);
|
|
3067
|
+
for (let i = 0; i < 6; i++) {
|
|
3068
|
+
const fee = fees[i];
|
|
3069
|
+
if (fee < 0n || fee > WAD) throw new InvalidFeeError(fee, i);
|
|
3070
|
+
}
|
|
3071
|
+
const frozenFees = Object.freeze([...fees]);
|
|
3072
|
+
return Object.freeze({
|
|
3073
|
+
_activated: activated,
|
|
3074
|
+
_fees: frozenFees
|
|
3075
|
+
});
|
|
3076
|
+
}
|
|
3077
|
+
/**
|
|
3078
|
+
* Compute the trading fee for a given time to maturity using piecewise linear interpolation.
|
|
3079
|
+
* @param tradingFee - The TradingFee instance.
|
|
3080
|
+
* @param timeToMaturity - Time to maturity in seconds.
|
|
3081
|
+
* @returns The interpolated fee in WAD. Returns 0n if not activated.
|
|
3082
|
+
*/
|
|
3083
|
+
function compute(tradingFee, timeToMaturity) {
|
|
3084
|
+
if (!tradingFee._activated) return 0n;
|
|
3085
|
+
const time = BigInt(Math.max(0, Math.floor(timeToMaturity)));
|
|
3086
|
+
if (time >= BREAKPOINTS[5]) return tradingFee._fees[5];
|
|
3087
|
+
const { index, start, end } = getSegment(time);
|
|
3088
|
+
const feeLower = tradingFee._fees[index];
|
|
3089
|
+
const feeUpper = tradingFee._fees[index + 1];
|
|
3090
|
+
const segmentLength = end - start;
|
|
3091
|
+
return (feeLower * (end - time) + feeUpper * (time - start)) / segmentLength;
|
|
3092
|
+
}
|
|
3093
|
+
/**
|
|
3094
|
+
* Check if the trading fee is activated.
|
|
3095
|
+
* @param tradingFee - The TradingFee instance.
|
|
3096
|
+
* @returns True if activated, false otherwise.
|
|
3097
|
+
*/
|
|
3098
|
+
function isActivated(tradingFee) {
|
|
3099
|
+
return tradingFee._activated;
|
|
3100
|
+
}
|
|
3101
|
+
/**
|
|
3102
|
+
* Create a new TradingFee with activation enabled.
|
|
3103
|
+
* @param tradingFee - The TradingFee instance.
|
|
3104
|
+
* @returns A new TradingFee with activated set to true.
|
|
3105
|
+
*/
|
|
3106
|
+
function activate(tradingFee) {
|
|
3107
|
+
return Object.freeze({
|
|
3108
|
+
_activated: true,
|
|
3109
|
+
_fees: tradingFee._fees
|
|
3110
|
+
});
|
|
3111
|
+
}
|
|
3112
|
+
/**
|
|
3113
|
+
* Create a new TradingFee with activation disabled.
|
|
3114
|
+
* @param tradingFee - The TradingFee instance.
|
|
3115
|
+
* @returns A new TradingFee with activated set to false.
|
|
3116
|
+
*/
|
|
3117
|
+
function deactivate(tradingFee) {
|
|
3118
|
+
return Object.freeze({
|
|
3119
|
+
_activated: false,
|
|
3120
|
+
_fees: tradingFee._fees
|
|
3121
|
+
});
|
|
3122
|
+
}
|
|
3123
|
+
/**
|
|
3124
|
+
* Get the fee values at each breakpoint.
|
|
3125
|
+
* @param tradingFee - The TradingFee instance.
|
|
3126
|
+
* @returns The tuple of 6 fee values.
|
|
3127
|
+
*/
|
|
3128
|
+
function getFees(tradingFee) {
|
|
3129
|
+
return tradingFee._fees;
|
|
3130
|
+
}
|
|
3131
|
+
/**
|
|
3132
|
+
* Determine which segment a timeToMaturity falls into for interpolation.
|
|
3133
|
+
* @param timeToMaturity - Time to maturity in seconds.
|
|
3134
|
+
* @returns Object with index, start, and end of the segment.
|
|
3135
|
+
*/
|
|
3136
|
+
function getSegment(timeToMaturity) {
|
|
3137
|
+
if (timeToMaturity < BREAKPOINTS[1]) return {
|
|
3138
|
+
index: 0,
|
|
3139
|
+
start: BREAKPOINTS[0],
|
|
3140
|
+
end: BREAKPOINTS[1]
|
|
3141
|
+
};
|
|
3142
|
+
if (timeToMaturity < BREAKPOINTS[2]) return {
|
|
3143
|
+
index: 1,
|
|
3144
|
+
start: BREAKPOINTS[1],
|
|
3145
|
+
end: BREAKPOINTS[2]
|
|
3146
|
+
};
|
|
3147
|
+
if (timeToMaturity < BREAKPOINTS[3]) return {
|
|
3148
|
+
index: 2,
|
|
3149
|
+
start: BREAKPOINTS[2],
|
|
3150
|
+
end: BREAKPOINTS[3]
|
|
3151
|
+
};
|
|
3152
|
+
if (timeToMaturity < BREAKPOINTS[4]) return {
|
|
3153
|
+
index: 3,
|
|
3154
|
+
start: BREAKPOINTS[3],
|
|
3155
|
+
end: BREAKPOINTS[4]
|
|
3156
|
+
};
|
|
3157
|
+
return {
|
|
3158
|
+
index: 4,
|
|
3159
|
+
start: BREAKPOINTS[4],
|
|
3160
|
+
end: BREAKPOINTS[5]
|
|
3161
|
+
};
|
|
3162
|
+
}
|
|
3163
|
+
/** Error thrown when a fee value is invalid (negative or exceeds WAD). */
|
|
3164
|
+
var InvalidFeeError = class extends BaseError {
|
|
3165
|
+
name = "TradingFee.InvalidFeeError";
|
|
3166
|
+
constructor(fee, index) {
|
|
3167
|
+
super(`Invalid fee at index ${index}: ${fee}. Fee must be between 0 and ${WAD} (WAD).`);
|
|
3168
|
+
}
|
|
3169
|
+
};
|
|
3170
|
+
/** Error thrown when fees array doesn't have exactly 6 elements. */
|
|
3171
|
+
var InvalidFeesLengthError = class extends BaseError {
|
|
3172
|
+
name = "TradingFee.InvalidFeesLengthError";
|
|
3173
|
+
constructor(length) {
|
|
3174
|
+
super(`Invalid fees length: ${length}. Expected exactly 6 fee values.`);
|
|
3175
|
+
}
|
|
3176
|
+
};
|
|
3177
|
+
|
|
2984
3178
|
//#endregion
|
|
2985
3179
|
//#region src/core/Transfer.ts
|
|
2986
|
-
var Transfer_exports = /* @__PURE__ */
|
|
3180
|
+
var Transfer_exports = /* @__PURE__ */ __exportAll({ from: () => from$8 });
|
|
2987
3181
|
/**
|
|
2988
3182
|
* @constructor
|
|
2989
3183
|
*
|
|
@@ -3218,10 +3412,13 @@ async function* collectOffersV2(parameters) {
|
|
|
3218
3412
|
});
|
|
3219
3413
|
totalValidOffers += tree.offers.length;
|
|
3220
3414
|
} catch (err) {
|
|
3415
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
3221
3416
|
logger.error({
|
|
3222
|
-
err,
|
|
3223
|
-
msg: "
|
|
3417
|
+
err: error,
|
|
3418
|
+
msg: "Gatekeeper validation failed",
|
|
3419
|
+
chain_id: client.chain.id
|
|
3224
3420
|
});
|
|
3421
|
+
throw new Error("Gatekeeper validation failed", { cause: error });
|
|
3225
3422
|
}
|
|
3226
3423
|
if (treesToInsert.length > 0) await dbTx.trees.create(treesToInsert);
|
|
3227
3424
|
try {
|
|
@@ -3295,14 +3492,14 @@ async function* collectOffersV2(parameters) {
|
|
|
3295
3492
|
* @returns {@link fetchOraclePrices.ReturnType} mapping {@link Address} to `bigint` price.
|
|
3296
3493
|
*/
|
|
3297
3494
|
async function fetchOraclePrices(parameters) {
|
|
3298
|
-
const { client, oracles
|
|
3299
|
-
if (oracles
|
|
3495
|
+
const { client, oracles, options } = parameters;
|
|
3496
|
+
if (oracles.length === 0) return /* @__PURE__ */ new Map();
|
|
3300
3497
|
const batchSize = Math.max(1, options?.batchSize ?? 5e3);
|
|
3301
3498
|
const retryAttempts = Math.max(1, options?.retryAttempts ?? 3);
|
|
3302
3499
|
const retryDelayMs = Math.max(0, options?.retryDelayMs ?? 50);
|
|
3303
3500
|
const blockNumber = options?.blockNumber ? BigInt(options.blockNumber) : void 0;
|
|
3304
3501
|
const out = /* @__PURE__ */ new Map();
|
|
3305
|
-
for (const oraclesBatch of batch$1(oracles
|
|
3502
|
+
for (const oraclesBatch of batch$1(oracles, batchSize)) {
|
|
3306
3503
|
const priceCalls = [];
|
|
3307
3504
|
for (const oracle of oraclesBatch) priceCalls.push({
|
|
3308
3505
|
address: oracle,
|
|
@@ -3354,17 +3551,17 @@ async function snapshotERC20Positions(parameters) {
|
|
|
3354
3551
|
retryAttempts,
|
|
3355
3552
|
retryDelayMs
|
|
3356
3553
|
});
|
|
3357
|
-
const positions
|
|
3554
|
+
const positions = [];
|
|
3358
3555
|
for (let i = 0; i < balances.length; i++) {
|
|
3359
3556
|
const oldPosition = oldPositions[i];
|
|
3360
3557
|
if (!oldPosition) continue;
|
|
3361
|
-
positions
|
|
3558
|
+
positions.push({
|
|
3362
3559
|
...oldPosition,
|
|
3363
3560
|
balance: balances[i],
|
|
3364
3561
|
blockNumber
|
|
3365
3562
|
});
|
|
3366
3563
|
}
|
|
3367
|
-
return positions
|
|
3564
|
+
return positions;
|
|
3368
3565
|
}
|
|
3369
3566
|
|
|
3370
3567
|
//#endregion
|
|
@@ -3381,8 +3578,8 @@ async function snapshotVaultPositions(parameters) {
|
|
|
3381
3578
|
const { client, positions: oldPositions, blockNumber, options: { maxBatchSize = 1e3, retryAttempts = 5, retryDelayMs = 500 } = {} } = parameters;
|
|
3382
3579
|
const calls = [];
|
|
3383
3580
|
const contracts = /* @__PURE__ */ new Map();
|
|
3384
|
-
const positions
|
|
3385
|
-
for (const position of positions
|
|
3581
|
+
const positions = structuredClone(oldPositions);
|
|
3582
|
+
for (const position of positions) {
|
|
3386
3583
|
calls.push({
|
|
3387
3584
|
address: position.contract,
|
|
3388
3585
|
abi: MetaMorpho,
|
|
@@ -3479,8 +3676,8 @@ async function snapshotVaultPositions(parameters) {
|
|
|
3479
3676
|
break;
|
|
3480
3677
|
}
|
|
3481
3678
|
}
|
|
3482
|
-
for (const convertToAssets
|
|
3483
|
-
return positions
|
|
3679
|
+
for (const convertToAssets of convertToAssetsList) convertToAssets();
|
|
3680
|
+
return positions;
|
|
3484
3681
|
}
|
|
3485
3682
|
|
|
3486
3683
|
//#endregion
|
|
@@ -3529,7 +3726,7 @@ async function* collectPositions(parameters) {
|
|
|
3529
3726
|
abi: [TransferEvent],
|
|
3530
3727
|
logs
|
|
3531
3728
|
});
|
|
3532
|
-
const transfers
|
|
3729
|
+
const transfers = [];
|
|
3533
3730
|
for (const log of parsedLogs) {
|
|
3534
3731
|
if (log.blockNumber === null || log.logIndex === null || log.transactionHash === null) {
|
|
3535
3732
|
logger.debug({
|
|
@@ -3539,7 +3736,7 @@ async function* collectPositions(parameters) {
|
|
|
3539
3736
|
});
|
|
3540
3737
|
continue;
|
|
3541
3738
|
}
|
|
3542
|
-
transfers
|
|
3739
|
+
transfers.push(from$8({
|
|
3543
3740
|
id: `${client.chain.id}-${log.blockNumber.toString()}-${log.transactionHash}-${log.logIndex.toString()}`,
|
|
3544
3741
|
chainId: client.chain.id,
|
|
3545
3742
|
contract: log.address,
|
|
@@ -3549,14 +3746,14 @@ async function* collectPositions(parameters) {
|
|
|
3549
3746
|
blockNumber: Number(log.blockNumber)
|
|
3550
3747
|
}));
|
|
3551
3748
|
}
|
|
3552
|
-
const { positions
|
|
3749
|
+
const { positions } = await db.positions.get({
|
|
3553
3750
|
chainId: client.chain.id,
|
|
3554
3751
|
filled: false
|
|
3555
3752
|
});
|
|
3556
3753
|
const newPositions = [];
|
|
3557
3754
|
try {
|
|
3558
3755
|
newPositions.push(...(await _snapshot({
|
|
3559
|
-
positions
|
|
3756
|
+
positions,
|
|
3560
3757
|
blockNumber: latestBlockNumberChain,
|
|
3561
3758
|
client,
|
|
3562
3759
|
maxBatchSize,
|
|
@@ -3595,9 +3792,9 @@ async function* collectPositions(parameters) {
|
|
|
3595
3792
|
}
|
|
3596
3793
|
};
|
|
3597
3794
|
const insertTransfers = async () => {
|
|
3598
|
-
if (transfers
|
|
3795
|
+
if (transfers.length === 0) return;
|
|
3599
3796
|
try {
|
|
3600
|
-
const created = await dbTx.transfers.create(transfers
|
|
3797
|
+
const created = await dbTx.transfers.create(transfers);
|
|
3601
3798
|
logger.info({
|
|
3602
3799
|
msg: `New transfers`,
|
|
3603
3800
|
collector,
|
|
@@ -3651,7 +3848,7 @@ async function* collectPositions(parameters) {
|
|
|
3651
3848
|
logger.error({
|
|
3652
3849
|
msg: "Failed to insert transfers",
|
|
3653
3850
|
collector,
|
|
3654
|
-
count: transfers
|
|
3851
|
+
count: transfers.length,
|
|
3655
3852
|
chain_id: client.chain.id,
|
|
3656
3853
|
block_number: blockNumber,
|
|
3657
3854
|
err
|
|
@@ -3661,7 +3858,7 @@ async function* collectPositions(parameters) {
|
|
|
3661
3858
|
}
|
|
3662
3859
|
if (!reorgDetected) {
|
|
3663
3860
|
startBlock = blockNumber;
|
|
3664
|
-
if (newPositions.length === 0 && transfers
|
|
3861
|
+
if (newPositions.length === 0 && transfers.length === 0 && lastStreamBlockNumber !== latestBlockNumberChain) continue;
|
|
3665
3862
|
yield blockNumber;
|
|
3666
3863
|
continue;
|
|
3667
3864
|
}
|
|
@@ -3711,10 +3908,10 @@ async function* collectPositions(parameters) {
|
|
|
3711
3908
|
* @returns The new positions. {@link _snapshot.ReturnType}
|
|
3712
3909
|
*/
|
|
3713
3910
|
async function _snapshot(parameters) {
|
|
3714
|
-
const { positions
|
|
3911
|
+
const { positions, blockNumber, client, maxBatchSize, retryAttempts, retryDelayMs } = parameters;
|
|
3715
3912
|
const vaultV1Positions = [];
|
|
3716
3913
|
const erc20Positions = [];
|
|
3717
|
-
for (const position of positions
|
|
3914
|
+
for (const position of positions) switch (position.type) {
|
|
3718
3915
|
case Type.VAULT_V1:
|
|
3719
3916
|
vaultV1Positions.push(position);
|
|
3720
3917
|
break;
|
|
@@ -3773,12 +3970,12 @@ async function* collectPrices(parameters) {
|
|
|
3773
3970
|
const { db, collector, client, options: { maxBatchSize = 5e3, retryAttempts = 5, retryDelayMs = 500 } = {} } = parameters;
|
|
3774
3971
|
const logger = getLogger();
|
|
3775
3972
|
let blockNumber = parameters.lastBlockNumber;
|
|
3776
|
-
const [oracles
|
|
3973
|
+
const [oracles, { blockNumber: latestBlockNumberChain, epoch }] = await Promise.all([db.oracles.get({ chainId: client.chain.id }), db.blocks.getChain(client.chain.id)]);
|
|
3777
3974
|
const updatedOracles = [];
|
|
3778
3975
|
try {
|
|
3779
3976
|
const pricesMap = await fetchOraclePrices({
|
|
3780
3977
|
client,
|
|
3781
|
-
oracles: oracles
|
|
3978
|
+
oracles: oracles.map((oracle) => oracle.address),
|
|
3782
3979
|
options: {
|
|
3783
3980
|
batchSize: maxBatchSize,
|
|
3784
3981
|
blockNumber: latestBlockNumberChain,
|
|
@@ -3786,7 +3983,7 @@ async function* collectPrices(parameters) {
|
|
|
3786
3983
|
retryDelayMs
|
|
3787
3984
|
}
|
|
3788
3985
|
});
|
|
3789
|
-
for (const oracle of oracles
|
|
3986
|
+
for (const oracle of oracles) {
|
|
3790
3987
|
const price = pricesMap.get(oracle.address);
|
|
3791
3988
|
if (price !== void 0) updatedOracles.push({
|
|
3792
3989
|
chainId: client.chain.id,
|
|
@@ -3969,7 +4166,7 @@ const from$7 = (parameters) => {
|
|
|
3969
4166
|
|
|
3970
4167
|
//#endregion
|
|
3971
4168
|
//#region src/indexer/Indexer.ts
|
|
3972
|
-
var Indexer_exports = /* @__PURE__ */
|
|
4169
|
+
var Indexer_exports = /* @__PURE__ */ __exportAll({
|
|
3973
4170
|
create: () => create$14,
|
|
3974
4171
|
from: () => from$6
|
|
3975
4172
|
});
|
|
@@ -3997,10 +4194,10 @@ function from$6(config) {
|
|
|
3997
4194
|
});
|
|
3998
4195
|
}
|
|
3999
4196
|
function create$14(params) {
|
|
4000
|
-
const { collectors
|
|
4197
|
+
const { collectors, client } = params;
|
|
4001
4198
|
const indexerId = `${client.chain.id.toString()}.indexer`;
|
|
4002
4199
|
const tracer = getTracer(`router.${indexerId}`);
|
|
4003
|
-
const iterators = collectors
|
|
4200
|
+
const iterators = collectors.map((collector) => collector.collect());
|
|
4004
4201
|
const next = async () => {
|
|
4005
4202
|
await startActiveSpan(tracer, `${indexerId}.next`, async () => {
|
|
4006
4203
|
await Promise.all(iterators.map((iterator) => iterator.next()));
|
|
@@ -4011,7 +4208,7 @@ function create$14(params) {
|
|
|
4011
4208
|
};
|
|
4012
4209
|
return {
|
|
4013
4210
|
start: () => {
|
|
4014
|
-
const stops = collectors
|
|
4211
|
+
const stops = collectors.map((collector) => start(collector));
|
|
4015
4212
|
return () => {
|
|
4016
4213
|
stops.forEach((stop) => {
|
|
4017
4214
|
stop();
|
|
@@ -4025,7 +4222,7 @@ function create$14(params) {
|
|
|
4025
4222
|
|
|
4026
4223
|
//#endregion
|
|
4027
4224
|
//#region src/api/Health.ts
|
|
4028
|
-
var Health_exports = /* @__PURE__ */
|
|
4225
|
+
var Health_exports = /* @__PURE__ */ __exportAll({ create: () => create$13 });
|
|
4029
4226
|
const DEFAULT_MAX_ALLOWED_LAG = 5;
|
|
4030
4227
|
/**
|
|
4031
4228
|
* Create a health service that exposes collector and chain block numbers.
|
|
@@ -4063,26 +4260,26 @@ function create$13(parameters) {
|
|
|
4063
4260
|
name
|
|
4064
4261
|
}))).sort((a, b) => a.chainId === b.chainId ? a.name.localeCompare(b.name) : a.chainId - b.chainId);
|
|
4065
4262
|
const initialized = knownChainIds.size > 0 && missingChains.length === 0 && missingCollectors.length === 0;
|
|
4066
|
-
const collectors
|
|
4263
|
+
const collectors = Array.from(knownChainIds).sort((a, b) => a - b > 0 ? 1 : -1).flatMap((chainId) => [...names].sort().map((name) => {
|
|
4067
4264
|
const row = collectorsByKey.get(collectorKey(chainId, name));
|
|
4068
4265
|
const chain = chainById.get(chainId);
|
|
4069
4266
|
const blockNumber = row?.blockNumber ?? null;
|
|
4070
4267
|
const chainBlockNumber = chain?.blockNumber ?? null;
|
|
4071
4268
|
const lag = blockNumber !== null && chainBlockNumber !== null ? Math.max(chainBlockNumber - blockNumber, 0) : null;
|
|
4072
|
-
let status
|
|
4073
|
-
if (lag !== null) status
|
|
4074
|
-
else if (chainBlockNumber !== null) status
|
|
4269
|
+
let status = "unknown";
|
|
4270
|
+
if (lag !== null) status = lag <= maxAllowedLag ? "live" : "lagging";
|
|
4271
|
+
else if (chainBlockNumber !== null) status = "lagging";
|
|
4075
4272
|
return {
|
|
4076
4273
|
name,
|
|
4077
4274
|
chainId,
|
|
4078
4275
|
blockNumber,
|
|
4079
4276
|
updatedAt: row ? row.updatedAt.toISOString() : null,
|
|
4080
4277
|
lag,
|
|
4081
|
-
status
|
|
4278
|
+
status,
|
|
4082
4279
|
initialized: row !== void 0
|
|
4083
4280
|
};
|
|
4084
4281
|
}));
|
|
4085
|
-
const chains
|
|
4282
|
+
const chains = Array.from(knownChainIds).sort((a, b) => a - b > 0 ? 1 : -1).map((chainId) => {
|
|
4086
4283
|
const chain = chainById.get(chainId);
|
|
4087
4284
|
return {
|
|
4088
4285
|
chainId,
|
|
@@ -4094,12 +4291,12 @@ function create$13(parameters) {
|
|
|
4094
4291
|
};
|
|
4095
4292
|
});
|
|
4096
4293
|
return {
|
|
4097
|
-
status: collectors
|
|
4294
|
+
status: collectors.length > 0 && collectors.every((collector) => collector.status === "live") ? "live" : "syncing",
|
|
4098
4295
|
initialized,
|
|
4099
4296
|
missingChains,
|
|
4100
4297
|
missingCollectors,
|
|
4101
|
-
collectors
|
|
4102
|
-
chains
|
|
4298
|
+
collectors,
|
|
4299
|
+
chains
|
|
4103
4300
|
};
|
|
4104
4301
|
};
|
|
4105
4302
|
return {
|
|
@@ -4142,7 +4339,7 @@ async function getRemoteBlockNumbers(healthClients) {
|
|
|
4142
4339
|
|
|
4143
4340
|
//#endregion
|
|
4144
4341
|
//#region src/api/Schema/BookResponse.ts
|
|
4145
|
-
var BookResponse_exports = /* @__PURE__ */
|
|
4342
|
+
var BookResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$5 });
|
|
4146
4343
|
function from$5(level) {
|
|
4147
4344
|
return {
|
|
4148
4345
|
price: level.price.toString(),
|
|
@@ -4187,7 +4384,7 @@ const RouterStatusResponse = z.object({
|
|
|
4187
4384
|
|
|
4188
4385
|
//#endregion
|
|
4189
4386
|
//#region src/api/Schema/ObligationResponse.ts
|
|
4190
|
-
var ObligationResponse_exports = /* @__PURE__ */
|
|
4387
|
+
var ObligationResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$4 });
|
|
4191
4388
|
/**
|
|
4192
4389
|
* Creates an `ObligationResponse` from a `Obligation`.
|
|
4193
4390
|
* @constructor
|
|
@@ -4212,7 +4409,7 @@ function from$4(obligation, quote) {
|
|
|
4212
4409
|
|
|
4213
4410
|
//#endregion
|
|
4214
4411
|
//#region src/api/Schema/OfferResponse.ts
|
|
4215
|
-
var OfferResponse_exports = /* @__PURE__ */
|
|
4412
|
+
var OfferResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$3 });
|
|
4216
4413
|
/**
|
|
4217
4414
|
* Creates an `OfferResponse` matching the Solidity Offer struct layout.
|
|
4218
4415
|
* @constructor
|
|
@@ -4220,7 +4417,7 @@ var OfferResponse_exports = /* @__PURE__ */ __export({ from: () => from$3 });
|
|
|
4220
4417
|
* @returns The created `OfferResponse`. {@link OfferResponse}
|
|
4221
4418
|
*/
|
|
4222
4419
|
function from$3(input) {
|
|
4223
|
-
const base
|
|
4420
|
+
const base = {
|
|
4224
4421
|
offer: {
|
|
4225
4422
|
obligation: {
|
|
4226
4423
|
loan_token: input.loanToken,
|
|
@@ -4257,13 +4454,13 @@ function from$3(input) {
|
|
|
4257
4454
|
block_number: input.blockNumber
|
|
4258
4455
|
};
|
|
4259
4456
|
if (!input.proof || !input.root || !input.signature) return {
|
|
4260
|
-
...base
|
|
4457
|
+
...base,
|
|
4261
4458
|
root: null,
|
|
4262
4459
|
proof: null,
|
|
4263
4460
|
signature: null
|
|
4264
4461
|
};
|
|
4265
4462
|
return {
|
|
4266
|
-
...base
|
|
4463
|
+
...base,
|
|
4267
4464
|
root: input.root.toLowerCase(),
|
|
4268
4465
|
proof: input.proof.map((p) => p.toLowerCase()),
|
|
4269
4466
|
signature: input.signature.toLowerCase()
|
|
@@ -4278,12 +4475,12 @@ const API_ERROR_CODES = [
|
|
|
4278
4475
|
"INTERNAL_SERVER_ERROR",
|
|
4279
4476
|
"BAD_REQUEST"
|
|
4280
4477
|
];
|
|
4281
|
-
let STATUS_CODE = /* @__PURE__ */ function(STATUS_CODE
|
|
4282
|
-
STATUS_CODE
|
|
4283
|
-
STATUS_CODE
|
|
4284
|
-
STATUS_CODE
|
|
4285
|
-
STATUS_CODE
|
|
4286
|
-
return STATUS_CODE
|
|
4478
|
+
let STATUS_CODE = /* @__PURE__ */ function(STATUS_CODE) {
|
|
4479
|
+
STATUS_CODE[STATUS_CODE["SUCCESS"] = 200] = "SUCCESS";
|
|
4480
|
+
STATUS_CODE[STATUS_CODE["BAD_REQUEST"] = 400] = "BAD_REQUEST";
|
|
4481
|
+
STATUS_CODE[STATUS_CODE["NOT_FOUND"] = 404] = "NOT_FOUND";
|
|
4482
|
+
STATUS_CODE[STATUS_CODE["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
|
|
4483
|
+
return STATUS_CODE;
|
|
4287
4484
|
}({});
|
|
4288
4485
|
var APIError = class extends Error {
|
|
4289
4486
|
constructor(statusCode, message, code, details) {
|
|
@@ -4369,7 +4566,7 @@ function handleZodError(error) {
|
|
|
4369
4566
|
}
|
|
4370
4567
|
|
|
4371
4568
|
//#endregion
|
|
4372
|
-
//#region \0@oxc-project+runtime@0.
|
|
4569
|
+
//#region \0@oxc-project+runtime@0.110.0/helpers/decorate.js
|
|
4373
4570
|
function __decorate(decorators, target, key, desc) {
|
|
4374
4571
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4375
4572
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -4990,7 +5187,7 @@ __decorate([ApiProperty({
|
|
|
4990
5187
|
type: () => [BookLevelResponse],
|
|
4991
5188
|
description: "Aggregated book levels grouped by computed price."
|
|
4992
5189
|
})], BookListResponse.prototype, "data", void 0);
|
|
4993
|
-
let BooksController = class BooksController
|
|
5190
|
+
let BooksController = class BooksController {
|
|
4994
5191
|
async getBook() {}
|
|
4995
5192
|
};
|
|
4996
5193
|
__decorate([
|
|
@@ -5036,7 +5233,7 @@ BooksController = __decorate([ApiTags("Markets"), ApiResponse({
|
|
|
5036
5233
|
description: "Bad Request",
|
|
5037
5234
|
type: BadRequestResponse
|
|
5038
5235
|
})], BooksController);
|
|
5039
|
-
let ValidateController = class ValidateController
|
|
5236
|
+
let ValidateController = class ValidateController {
|
|
5040
5237
|
async validateOffers() {}
|
|
5041
5238
|
};
|
|
5042
5239
|
__decorate([
|
|
@@ -5063,7 +5260,7 @@ ValidateController = __decorate([ApiTags("Make"), ApiResponse({
|
|
|
5063
5260
|
description: "Bad Request",
|
|
5064
5261
|
type: BadRequestResponse
|
|
5065
5262
|
})], ValidateController);
|
|
5066
|
-
let OffersController = class OffersController
|
|
5263
|
+
let OffersController = class OffersController {
|
|
5067
5264
|
async getOffers() {}
|
|
5068
5265
|
};
|
|
5069
5266
|
__decorate([
|
|
@@ -5118,7 +5315,7 @@ OffersController = __decorate([ApiTags("Markets"), ApiResponse({
|
|
|
5118
5315
|
description: "Bad Request",
|
|
5119
5316
|
type: BadRequestResponse
|
|
5120
5317
|
})], OffersController);
|
|
5121
|
-
let HealthController = class HealthController
|
|
5318
|
+
let HealthController = class HealthController {
|
|
5122
5319
|
async getRouterStatus() {}
|
|
5123
5320
|
async getCollectorsHealth() {}
|
|
5124
5321
|
async getChainsHealth() {}
|
|
@@ -5184,31 +5381,17 @@ __decorate([
|
|
|
5184
5381
|
})
|
|
5185
5382
|
], HealthController.prototype, "getChainsHealth", null);
|
|
5186
5383
|
HealthController = __decorate([ApiTags("System")], HealthController);
|
|
5187
|
-
const
|
|
5188
|
-
end_of_month: 1738335600,
|
|
5189
|
-
end_of_next_month: 1740754800
|
|
5190
|
-
};
|
|
5384
|
+
const callbacksExample = [Type$1.BuyWithEmptyCallback];
|
|
5191
5385
|
const chainConfigExample = {
|
|
5192
5386
|
chain_id: 505050505,
|
|
5193
5387
|
contracts: { mempool: "0xD946246695A9259F3B33a78629026F61B3Ab40aF" },
|
|
5194
|
-
|
|
5388
|
+
callbacks: callbacksExample
|
|
5195
5389
|
};
|
|
5196
5390
|
var ConfigContractsResponse = class {};
|
|
5197
5391
|
__decorate([ApiProperty({
|
|
5198
5392
|
type: "string",
|
|
5199
5393
|
example: chainConfigExample.contracts.mempool
|
|
5200
5394
|
})], ConfigContractsResponse.prototype, "mempool", void 0);
|
|
5201
|
-
var MaturitiesResponse = class {};
|
|
5202
|
-
__decorate([ApiProperty({
|
|
5203
|
-
type: "number",
|
|
5204
|
-
description: "Unix timestamp for end of current month maturity (last Friday 15:00 UTC).",
|
|
5205
|
-
example: maturitiesExample.end_of_month
|
|
5206
|
-
})], MaturitiesResponse.prototype, "end_of_month", void 0);
|
|
5207
|
-
__decorate([ApiProperty({
|
|
5208
|
-
type: "number",
|
|
5209
|
-
description: "Unix timestamp for end of next month maturity (last Friday 15:00 UTC).",
|
|
5210
|
-
example: maturitiesExample.end_of_next_month
|
|
5211
|
-
})], MaturitiesResponse.prototype, "end_of_next_month", void 0);
|
|
5212
5395
|
var ConfigDataResponse = class {};
|
|
5213
5396
|
__decorate([ApiProperty({
|
|
5214
5397
|
type: "number",
|
|
@@ -5216,10 +5399,11 @@ __decorate([ApiProperty({
|
|
|
5216
5399
|
})], ConfigDataResponse.prototype, "chain_id", void 0);
|
|
5217
5400
|
__decorate([ApiProperty({ type: () => ConfigContractsResponse })], ConfigDataResponse.prototype, "contracts", void 0);
|
|
5218
5401
|
__decorate([ApiProperty({
|
|
5219
|
-
type: () =>
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5402
|
+
type: () => [String],
|
|
5403
|
+
enum: Object.values(Type$1),
|
|
5404
|
+
description: "Supported callback types for this chain.",
|
|
5405
|
+
example: callbacksExample
|
|
5406
|
+
})], ConfigDataResponse.prototype, "callbacks", void 0);
|
|
5223
5407
|
var ConfigSuccessResponse = class extends SuccessResponse {};
|
|
5224
5408
|
__decorate([ApiProperty({
|
|
5225
5409
|
type: "string",
|
|
@@ -5231,21 +5415,21 @@ __decorate([ApiProperty({
|
|
|
5231
5415
|
description: "Array of chain configurations for all indexed chains.",
|
|
5232
5416
|
example: [chainConfigExample]
|
|
5233
5417
|
})], ConfigSuccessResponse.prototype, "data", void 0);
|
|
5234
|
-
let ConfigController = class ConfigController
|
|
5418
|
+
let ConfigController = class ConfigController {
|
|
5235
5419
|
async getConfig() {}
|
|
5236
5420
|
};
|
|
5237
5421
|
__decorate([ApiOperation({
|
|
5238
5422
|
methods: ["get"],
|
|
5239
5423
|
path: "/v1/config",
|
|
5240
5424
|
summary: "Get router configuration",
|
|
5241
|
-
description: "Returns chain configurations including contract addresses and supported
|
|
5425
|
+
description: "Returns chain configurations including contract addresses and supported callback types."
|
|
5242
5426
|
}), ApiResponse({
|
|
5243
5427
|
status: 200,
|
|
5244
5428
|
description: "Success",
|
|
5245
5429
|
type: ConfigSuccessResponse
|
|
5246
5430
|
})], ConfigController.prototype, "getConfig", null);
|
|
5247
5431
|
ConfigController = __decorate([ApiTags("System")], ConfigController);
|
|
5248
|
-
let ObligationsController = class ObligationsController
|
|
5432
|
+
let ObligationsController = class ObligationsController {
|
|
5249
5433
|
async getObligations() {}
|
|
5250
5434
|
async getObligation() {}
|
|
5251
5435
|
};
|
|
@@ -5269,32 +5453,40 @@ __decorate([
|
|
|
5269
5453
|
description: "Maximum number of obligations to return."
|
|
5270
5454
|
}),
|
|
5271
5455
|
ApiQuery({
|
|
5272
|
-
name: "
|
|
5273
|
-
type: "number",
|
|
5456
|
+
name: "chains",
|
|
5457
|
+
type: ["number"],
|
|
5274
5458
|
required: false,
|
|
5275
|
-
example: 1,
|
|
5276
|
-
description: "Filter by chain
|
|
5459
|
+
example: "1,8453",
|
|
5460
|
+
description: "Filter by chain IDs (comma-separated).",
|
|
5461
|
+
style: "form",
|
|
5462
|
+
explode: false
|
|
5277
5463
|
}),
|
|
5278
5464
|
ApiQuery({
|
|
5279
|
-
name: "
|
|
5280
|
-
type: "string",
|
|
5465
|
+
name: "loan_tokens",
|
|
5466
|
+
type: ["string"],
|
|
5281
5467
|
required: false,
|
|
5282
|
-
example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
5283
|
-
description: "Filter by loan token
|
|
5468
|
+
example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078,0x34Cf890dB685FC536E05652FB41f02090c3fb751",
|
|
5469
|
+
description: "Filter by loan token addresses (comma-separated).",
|
|
5470
|
+
style: "form",
|
|
5471
|
+
explode: false
|
|
5284
5472
|
}),
|
|
5285
5473
|
ApiQuery({
|
|
5286
|
-
name: "
|
|
5287
|
-
type: "string",
|
|
5474
|
+
name: "collateral_tokens",
|
|
5475
|
+
type: ["string"],
|
|
5288
5476
|
required: false,
|
|
5289
|
-
example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
|
|
5290
|
-
description: "Filter by collateral
|
|
5477
|
+
example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751,0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
5478
|
+
description: "Filter by collateral tokens (comma-separated, matches any collateral).",
|
|
5479
|
+
style: "form",
|
|
5480
|
+
explode: false
|
|
5291
5481
|
}),
|
|
5292
5482
|
ApiQuery({
|
|
5293
|
-
name: "
|
|
5294
|
-
type: "number",
|
|
5483
|
+
name: "maturities",
|
|
5484
|
+
type: ["number"],
|
|
5295
5485
|
required: false,
|
|
5296
|
-
example: 1761922800,
|
|
5297
|
-
description: "Filter by exact maturity
|
|
5486
|
+
example: "1761922800,1764524800",
|
|
5487
|
+
description: "Filter by exact maturity timestamps (comma-separated, unix seconds).",
|
|
5488
|
+
style: "form",
|
|
5489
|
+
explode: false
|
|
5298
5490
|
}),
|
|
5299
5491
|
ApiResponse({
|
|
5300
5492
|
status: 200,
|
|
@@ -5326,7 +5518,7 @@ ObligationsController = __decorate([ApiTags("Markets"), ApiResponse({
|
|
|
5326
5518
|
description: "Bad Request",
|
|
5327
5519
|
type: BadRequestResponse
|
|
5328
5520
|
})], ObligationsController);
|
|
5329
|
-
let UsersController = class UsersController
|
|
5521
|
+
let UsersController = class UsersController {
|
|
5330
5522
|
async getUserPositions() {}
|
|
5331
5523
|
};
|
|
5332
5524
|
__decorate([
|
|
@@ -5416,7 +5608,7 @@ const OpenApi = async (options = {}) => {
|
|
|
5416
5608
|
|
|
5417
5609
|
//#endregion
|
|
5418
5610
|
//#region src/api/Schema/PositionResponse.ts
|
|
5419
|
-
var PositionResponse_exports = /* @__PURE__ */
|
|
5611
|
+
var PositionResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$2 });
|
|
5420
5612
|
/**
|
|
5421
5613
|
* Creates a `PositionResponse` from a `PositionWithReserved`.
|
|
5422
5614
|
* @param position - {@link PositionWithReserved}
|
|
@@ -5447,6 +5639,15 @@ function isValidBase64urlJson(val) {
|
|
|
5447
5639
|
return false;
|
|
5448
5640
|
}
|
|
5449
5641
|
}
|
|
5642
|
+
const csvArray = (schema) => z$1.preprocess((value) => {
|
|
5643
|
+
if (value === void 0) return void 0;
|
|
5644
|
+
if (Array.isArray(value)) {
|
|
5645
|
+
if (value.some((item) => typeof item !== "string")) return value;
|
|
5646
|
+
return value.flatMap((item) => item.split(",")).map((item) => item.trim()).filter((item) => item.length > 0);
|
|
5647
|
+
}
|
|
5648
|
+
if (typeof value === "string") return value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
5649
|
+
return value;
|
|
5650
|
+
}, z$1.array(schema)).optional();
|
|
5450
5651
|
const PaginationQueryParams = z$1.object({
|
|
5451
5652
|
cursor: z$1.string().optional().refine((val) => {
|
|
5452
5653
|
if (!val) return true;
|
|
@@ -5497,21 +5698,21 @@ const GetObligationsQueryParams = z$1.object({
|
|
|
5497
5698
|
description: "Obligation id cursor",
|
|
5498
5699
|
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
5499
5700
|
}),
|
|
5500
|
-
|
|
5501
|
-
description: "Filter by chain
|
|
5502
|
-
example: "1"
|
|
5701
|
+
chains: csvArray(z$1.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
|
|
5702
|
+
description: "Filter by chain IDs (comma-separated).",
|
|
5703
|
+
example: "1,8453"
|
|
5503
5704
|
}),
|
|
5504
|
-
|
|
5505
|
-
description: "Filter by loan token
|
|
5506
|
-
example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
|
|
5705
|
+
loan_tokens: csvArray(z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Loan token must be a valid 20-byte address" }).transform((val) => val.toLowerCase())).meta({
|
|
5706
|
+
description: "Filter by loan token addresses (comma-separated).",
|
|
5707
|
+
example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078,0x34Cf890dB685FC536E05652FB41f02090c3fb751"
|
|
5507
5708
|
}),
|
|
5508
|
-
|
|
5509
|
-
description: "Filter by collateral
|
|
5510
|
-
example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751"
|
|
5709
|
+
collateral_tokens: csvArray(z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Collateral token must be a valid 20-byte address" }).transform((val) => val.toLowerCase())).meta({
|
|
5710
|
+
description: "Filter by collateral tokens (comma-separated, matches any collateral).",
|
|
5711
|
+
example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751,0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
|
|
5511
5712
|
}),
|
|
5512
|
-
|
|
5513
|
-
description: "Filter by exact maturity
|
|
5514
|
-
example: "1761922800"
|
|
5713
|
+
maturities: csvArray(z$1.string().regex(/^[1-9]\d*$/, { message: "Maturity must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
|
|
5714
|
+
description: "Filter by exact maturity timestamps (comma-separated, unix seconds).",
|
|
5715
|
+
example: "1761922800,1764524800"
|
|
5515
5716
|
})
|
|
5516
5717
|
});
|
|
5517
5718
|
const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
@@ -5624,18 +5825,14 @@ async function getBook(params, db) {
|
|
|
5624
5825
|
* @returns The configuration for all chains the router is indexing. {@link ApiPayload.Payload<ChainConfig[]>}
|
|
5625
5826
|
*/
|
|
5626
5827
|
async function getConfig(chainRegistry) {
|
|
5627
|
-
const
|
|
5628
|
-
|
|
5629
|
-
end_of_next_month: from$15(MaturityType.EndOfNextMonth)
|
|
5630
|
-
};
|
|
5631
|
-
const configs$1 = [];
|
|
5632
|
-
for (const chain of chainRegistry.list()) configs$1.push({
|
|
5828
|
+
const configs = [];
|
|
5829
|
+
for (const chain of chainRegistry.list()) configs.push({
|
|
5633
5830
|
chain_id: chain.id,
|
|
5634
5831
|
contracts: { mempool: chain.custom.mempool.address },
|
|
5635
|
-
|
|
5832
|
+
callbacks: chain.custom.callbacks.map((c) => c.type)
|
|
5636
5833
|
});
|
|
5637
|
-
configs
|
|
5638
|
-
return success({ data: configs
|
|
5834
|
+
configs.sort((a, b) => a.chain_id - b.chain_id);
|
|
5835
|
+
return success({ data: configs });
|
|
5639
5836
|
}
|
|
5640
5837
|
|
|
5641
5838
|
//#endregion
|
|
@@ -5651,17 +5848,24 @@ const parse_error_Description = {
|
|
|
5651
5848
|
name: "parse_error",
|
|
5652
5849
|
description: "Returns when an offer fails to parse due to invalid format or missing required fields"
|
|
5653
5850
|
};
|
|
5654
|
-
const getGatekeeperRules = (gatekeeper) => {
|
|
5655
|
-
return [parse_error_Description, ...gatekeeper.
|
|
5656
|
-
name: rule.name,
|
|
5657
|
-
description: rule.description
|
|
5658
|
-
}))];
|
|
5851
|
+
const getGatekeeperRules = async (gatekeeper) => {
|
|
5852
|
+
return [parse_error_Description, ...await gatekeeper.getRules()];
|
|
5659
5853
|
};
|
|
5854
|
+
/**
|
|
5855
|
+
* Build the OpenAPI document for the router.
|
|
5856
|
+
* @param parameters - Includes a {@link RulesProvider} to fetch gatekeeper rules.
|
|
5857
|
+
* @returns OpenAPI document. {@link OpenAPIDocument}
|
|
5858
|
+
*/
|
|
5660
5859
|
async function getSwaggerJson({ gatekeeper }) {
|
|
5661
|
-
return OpenApi({ rules: getGatekeeperRules(gatekeeper) });
|
|
5860
|
+
return OpenApi({ rules: await getGatekeeperRules(gatekeeper) });
|
|
5662
5861
|
}
|
|
5862
|
+
/**
|
|
5863
|
+
* Render the API documentation HTML page.
|
|
5864
|
+
* @param parameters - Includes a {@link RulesProvider} to fetch gatekeeper rules.
|
|
5865
|
+
* @returns HTML page as string.
|
|
5866
|
+
*/
|
|
5663
5867
|
async function getDocsHtml({ gatekeeper }) {
|
|
5664
|
-
const spec = await OpenApi({ rules: getGatekeeperRules(gatekeeper) });
|
|
5868
|
+
const spec = await OpenApi({ rules: await getGatekeeperRules(gatekeeper) });
|
|
5665
5869
|
return `<!DOCTYPE html>
|
|
5666
5870
|
<html>
|
|
5667
5871
|
<head>
|
|
@@ -5766,8 +5970,8 @@ async function getHealthChains(query, db, healthClients, chainRegistry) {
|
|
|
5766
5970
|
missingChains: snapshot.missingChains,
|
|
5767
5971
|
missingCollectors: snapshot.missingCollectors
|
|
5768
5972
|
})));
|
|
5769
|
-
const chains
|
|
5770
|
-
return success({ data: chains
|
|
5973
|
+
const chains = snapshot.chains;
|
|
5974
|
+
return success({ data: chains.map(({ chainId, localBlockNumber, remoteBlockNumber, updatedAt, initialized }) => toSnakeCase$1({
|
|
5771
5975
|
chainId,
|
|
5772
5976
|
localBlockNumber,
|
|
5773
5977
|
remoteBlockNumber,
|
|
@@ -5797,14 +6001,14 @@ async function getHealthCollectors(query, db, chainRegistry) {
|
|
|
5797
6001
|
missingChains: snapshot.missingChains,
|
|
5798
6002
|
missingCollectors: snapshot.missingCollectors
|
|
5799
6003
|
})));
|
|
5800
|
-
const collectors
|
|
5801
|
-
return success({ data: collectors
|
|
6004
|
+
const collectors = snapshot.collectors;
|
|
6005
|
+
return success({ data: collectors.map(({ name, chainId, blockNumber, updatedAt, lag, status, initialized }) => toSnakeCase$1({
|
|
5802
6006
|
name,
|
|
5803
6007
|
chainId,
|
|
5804
6008
|
blockNumber,
|
|
5805
6009
|
updatedAt,
|
|
5806
6010
|
lag,
|
|
5807
|
-
status
|
|
6011
|
+
status,
|
|
5808
6012
|
initialized
|
|
5809
6013
|
})) });
|
|
5810
6014
|
} catch (err) {
|
|
@@ -5826,9 +6030,9 @@ async function getObligation(params, db) {
|
|
|
5826
6030
|
if (!result.success) return failure(result.error);
|
|
5827
6031
|
const query = result.data;
|
|
5828
6032
|
try {
|
|
5829
|
-
const { obligations
|
|
5830
|
-
if (obligations
|
|
5831
|
-
const obligation = obligations
|
|
6033
|
+
const { obligations } = await db.offers.getObligations({ ids: [query.obligation_id] });
|
|
6034
|
+
if (obligations.length === 0) return failure(new NotFoundError("Obligation not found"));
|
|
6035
|
+
const obligation = obligations[0];
|
|
5832
6036
|
const [quote] = await db.offers.getQuotes({ obligationIds: [id(obligation)] });
|
|
5833
6037
|
return success({
|
|
5834
6038
|
data: from$4(obligation, quote ?? {
|
|
@@ -5857,17 +6061,21 @@ async function getObligations$1(queryParameters, db) {
|
|
|
5857
6061
|
if (!result.success) return failure(result.error);
|
|
5858
6062
|
const query = result.data;
|
|
5859
6063
|
try {
|
|
5860
|
-
const
|
|
6064
|
+
const chainIds = query.chains?.length ? query.chains : void 0;
|
|
6065
|
+
const loanTokens = query.loan_tokens?.length ? query.loan_tokens : void 0;
|
|
6066
|
+
const collateralTokens = query.collateral_tokens?.length ? query.collateral_tokens : void 0;
|
|
6067
|
+
const maturities = query.maturities?.length ? query.maturities : void 0;
|
|
6068
|
+
const { obligations, nextCursor } = await db.offers.getObligations({
|
|
5861
6069
|
cursor: query.cursor,
|
|
5862
6070
|
limit: query.limit,
|
|
5863
|
-
chainId:
|
|
5864
|
-
loanToken:
|
|
5865
|
-
collateralToken:
|
|
5866
|
-
maturity:
|
|
6071
|
+
chainId: chainIds,
|
|
6072
|
+
loanToken: loanTokens,
|
|
6073
|
+
collateralToken: collateralTokens,
|
|
6074
|
+
maturity: maturities
|
|
5867
6075
|
});
|
|
5868
|
-
const quotes = await db.offers.getQuotes({ obligationIds: obligations
|
|
6076
|
+
const quotes = await db.offers.getQuotes({ obligationIds: obligations.map((o) => id(o)) });
|
|
5869
6077
|
return success({
|
|
5870
|
-
data: obligations
|
|
6078
|
+
data: obligations.map((o) => from$4(o, quotes.find((q) => q.obligationId === id(o)) ?? {
|
|
5871
6079
|
obligationId: id(o),
|
|
5872
6080
|
ask: { price: 0n },
|
|
5873
6081
|
bid: { price: 0n }
|
|
@@ -5907,8 +6115,8 @@ async function getOffers$1(queryParameters, db) {
|
|
|
5907
6115
|
const attestationMap = await db.trees.getAttestations(hashes);
|
|
5908
6116
|
return success({
|
|
5909
6117
|
data: rows.map((row) => {
|
|
5910
|
-
const hash$
|
|
5911
|
-
const attestation = attestationMap.get(hash$
|
|
6118
|
+
const hash$2 = hash(row);
|
|
6119
|
+
const attestation = attestationMap.get(hash$2);
|
|
5912
6120
|
return from$3({
|
|
5913
6121
|
...row,
|
|
5914
6122
|
...attestation
|
|
@@ -5941,13 +6149,13 @@ async function getUserPositions(queryParameters, db) {
|
|
|
5941
6149
|
if (!result.success) return failure(result.error);
|
|
5942
6150
|
const query = result.data;
|
|
5943
6151
|
try {
|
|
5944
|
-
const { positions
|
|
6152
|
+
const { positions, nextCursor } = await db.positions.getByUser({
|
|
5945
6153
|
user: query.user_address,
|
|
5946
6154
|
cursor: query.cursor,
|
|
5947
6155
|
limit: query.limit
|
|
5948
6156
|
});
|
|
5949
6157
|
return success({
|
|
5950
|
-
data: positions
|
|
6158
|
+
data: positions.map((position) => from$2(position)),
|
|
5951
6159
|
cursor: nextCursor ?? null
|
|
5952
6160
|
});
|
|
5953
6161
|
} catch (err) {
|
|
@@ -5989,10 +6197,10 @@ async function validateOffers(body, gatekeeper) {
|
|
|
5989
6197
|
const { issues } = await gatekeeper.isAllowed(parsedOffers);
|
|
5990
6198
|
if (issues.length > 0) {
|
|
5991
6199
|
const mappedIssues = issues.map((issue) => {
|
|
5992
|
-
const index
|
|
5993
|
-
if (index
|
|
6200
|
+
const index = offerIndexByHash.get(hash(issue.item));
|
|
6201
|
+
if (index === void 0) return null;
|
|
5994
6202
|
return {
|
|
5995
|
-
index
|
|
6203
|
+
index,
|
|
5996
6204
|
rule: issue.ruleName,
|
|
5997
6205
|
message: issue.message
|
|
5998
6206
|
};
|
|
@@ -6002,7 +6210,7 @@ async function validateOffers(body, gatekeeper) {
|
|
|
6002
6210
|
cursor: null
|
|
6003
6211
|
});
|
|
6004
6212
|
}
|
|
6005
|
-
const tree = from$
|
|
6213
|
+
const tree = from$14(parsedOffers);
|
|
6006
6214
|
const payload = encodeUnsigned(tree);
|
|
6007
6215
|
return success({
|
|
6008
6216
|
data: {
|
|
@@ -6024,7 +6232,7 @@ async function validateOffers(body, gatekeeper) {
|
|
|
6024
6232
|
|
|
6025
6233
|
//#endregion
|
|
6026
6234
|
//#region src/api/Controllers/index.ts
|
|
6027
|
-
var Controllers_exports = /* @__PURE__ */
|
|
6235
|
+
var Controllers_exports = /* @__PURE__ */ __exportAll({
|
|
6028
6236
|
getBook: () => getBook,
|
|
6029
6237
|
getConfig: () => getConfig,
|
|
6030
6238
|
getDocsHtml: () => getDocsHtml,
|
|
@@ -6089,8 +6297,8 @@ function serve$1(parameters) {
|
|
|
6089
6297
|
return c.json(body, statusCode);
|
|
6090
6298
|
});
|
|
6091
6299
|
app.get("/v1/obligations/:obligationId", async (c) => {
|
|
6092
|
-
const id
|
|
6093
|
-
const { statusCode, body } = await getObligation({ obligation_id: id
|
|
6300
|
+
const id = c.req.param("obligationId");
|
|
6301
|
+
const { statusCode, body } = await getObligation({ obligation_id: id }, db);
|
|
6094
6302
|
return c.json(body, statusCode);
|
|
6095
6303
|
});
|
|
6096
6304
|
app.get("/v1/books/:obligationId/:side", async (c) => {
|
|
@@ -6104,9 +6312,14 @@ function serve$1(parameters) {
|
|
|
6104
6312
|
return c.json(body, statusCode);
|
|
6105
6313
|
});
|
|
6106
6314
|
app.post("/v1/validate", async (c) => {
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6315
|
+
try {
|
|
6316
|
+
const reqBody = await c.req.json();
|
|
6317
|
+
const { statusCode, body } = await gatekeeper.validate(reqBody);
|
|
6318
|
+
return c.json(body, statusCode);
|
|
6319
|
+
} catch (err) {
|
|
6320
|
+
const failure$1 = failure(err);
|
|
6321
|
+
return c.json(failure$1.body, failure$1.statusCode);
|
|
6322
|
+
}
|
|
6110
6323
|
});
|
|
6111
6324
|
app.get("/v1/users/:userAddress/positions", async (c) => {
|
|
6112
6325
|
const query = c.req.query();
|
|
@@ -6144,7 +6357,7 @@ function serve$1(parameters) {
|
|
|
6144
6357
|
|
|
6145
6358
|
//#endregion
|
|
6146
6359
|
//#region src/api/RouterApi.ts
|
|
6147
|
-
var RouterApi_exports = /* @__PURE__ */
|
|
6360
|
+
var RouterApi_exports = /* @__PURE__ */ __exportAll({
|
|
6148
6361
|
BookResponse: () => BookResponse_exports,
|
|
6149
6362
|
BooksController: () => BooksController,
|
|
6150
6363
|
ChainHealth: () => ChainHealth,
|
|
@@ -6171,7 +6384,7 @@ var RouterApi_exports = /* @__PURE__ */ __export({
|
|
|
6171
6384
|
|
|
6172
6385
|
//#endregion
|
|
6173
6386
|
//#region src/client/Client.ts
|
|
6174
|
-
var Client_exports = /* @__PURE__ */
|
|
6387
|
+
var Client_exports$1 = /* @__PURE__ */ __exportAll({
|
|
6175
6388
|
HttpForbiddenError: () => HttpForbiddenError,
|
|
6176
6389
|
HttpGetApiFailedError: () => HttpGetApiFailedError,
|
|
6177
6390
|
HttpRateLimitError: () => HttpRateLimitError,
|
|
@@ -6204,12 +6417,16 @@ function connect$2(parameters) {
|
|
|
6204
6417
|
};
|
|
6205
6418
|
const apiClient = createOpenApiFetchClient({
|
|
6206
6419
|
baseUrl: config.url.toString(),
|
|
6207
|
-
headers: config.headers
|
|
6420
|
+
headers: config.headers,
|
|
6421
|
+
querySerializer: { array: {
|
|
6422
|
+
style: "form",
|
|
6423
|
+
explode: false
|
|
6424
|
+
} }
|
|
6208
6425
|
});
|
|
6209
6426
|
return {
|
|
6210
6427
|
...config,
|
|
6211
|
-
getOffers: (parameters
|
|
6212
|
-
getObligations: (parameters
|
|
6428
|
+
getOffers: (parameters) => getOffers(apiClient, parameters),
|
|
6429
|
+
getObligations: (parameters) => getObligations(apiClient, parameters)
|
|
6213
6430
|
};
|
|
6214
6431
|
}
|
|
6215
6432
|
async function getOffers(apiClient, parameters) {
|
|
@@ -6227,7 +6444,7 @@ async function getOffers(apiClient, parameters) {
|
|
|
6227
6444
|
}
|
|
6228
6445
|
throw new HttpGetApiFailedError(`GET request returned ${response.status}`, { details: JSON.stringify(error) });
|
|
6229
6446
|
}
|
|
6230
|
-
const offers
|
|
6447
|
+
const offers = data?.data.map((item) => {
|
|
6231
6448
|
const { root, proof, signature, offer: offerData } = item;
|
|
6232
6449
|
return {
|
|
6233
6450
|
...fromSnakeCase$1({
|
|
@@ -6236,7 +6453,7 @@ async function getOffers(apiClient, parameters) {
|
|
|
6236
6453
|
obligation_units: offerData.obligation_units,
|
|
6237
6454
|
obligation_shares: offerData.obligation_shares,
|
|
6238
6455
|
price: offerData.price,
|
|
6239
|
-
maturity: from$
|
|
6456
|
+
maturity: from$16(offerData.obligation.maturity),
|
|
6240
6457
|
expiry: offerData.expiry,
|
|
6241
6458
|
start: offerData.start,
|
|
6242
6459
|
group: offerData.group,
|
|
@@ -6265,17 +6482,17 @@ async function getOffers(apiClient, parameters) {
|
|
|
6265
6482
|
}) ?? [];
|
|
6266
6483
|
return {
|
|
6267
6484
|
cursor: data?.cursor ?? null,
|
|
6268
|
-
offers
|
|
6485
|
+
offers
|
|
6269
6486
|
};
|
|
6270
6487
|
}
|
|
6271
6488
|
async function getObligations(apiClient, parameters) {
|
|
6272
6489
|
const { data, error, response } = await apiClient.GET("/v1/obligations", { params: { query: {
|
|
6273
6490
|
cursor: parameters?.cursor,
|
|
6274
6491
|
limit: parameters?.limit,
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6492
|
+
chains: parameters?.chainIds,
|
|
6493
|
+
loan_tokens: parameters?.loanTokens,
|
|
6494
|
+
collateral_tokens: parameters?.collateralTokens,
|
|
6495
|
+
maturities: parameters?.maturities
|
|
6279
6496
|
} } });
|
|
6280
6497
|
if (error !== void 0) {
|
|
6281
6498
|
switch (response.status) {
|
|
@@ -6285,7 +6502,7 @@ async function getObligations(apiClient, parameters) {
|
|
|
6285
6502
|
}
|
|
6286
6503
|
throw new HttpGetApiFailedError(`GET request returned ${response.status}`, { details: JSON.stringify(error) });
|
|
6287
6504
|
}
|
|
6288
|
-
const obligations
|
|
6505
|
+
const obligations = data?.data.map((item) => {
|
|
6289
6506
|
const obligation = fromSnakeCase$2({
|
|
6290
6507
|
chain_id: item.chain_id,
|
|
6291
6508
|
loan_token: item.loan_token,
|
|
@@ -6294,7 +6511,7 @@ async function getObligations(apiClient, parameters) {
|
|
|
6294
6511
|
oracle: collateral.oracle,
|
|
6295
6512
|
lltv: collateral.lltv
|
|
6296
6513
|
})),
|
|
6297
|
-
maturity: from$
|
|
6514
|
+
maturity: from$16(item.maturity)
|
|
6298
6515
|
});
|
|
6299
6516
|
const { obligationId: _, ...returned } = {
|
|
6300
6517
|
id: () => id(obligation),
|
|
@@ -6309,7 +6526,7 @@ async function getObligations(apiClient, parameters) {
|
|
|
6309
6526
|
}) ?? [];
|
|
6310
6527
|
return {
|
|
6311
6528
|
cursor: data?.cursor ?? null,
|
|
6312
|
-
obligations
|
|
6529
|
+
obligations
|
|
6313
6530
|
};
|
|
6314
6531
|
}
|
|
6315
6532
|
var InvalidUrlError = class extends BaseError {
|
|
@@ -6349,7 +6566,7 @@ const VERSION = "router_v1.6";
|
|
|
6349
6566
|
|
|
6350
6567
|
//#endregion
|
|
6351
6568
|
//#region src/database/drizzle/schema.ts
|
|
6352
|
-
var schema_exports = /* @__PURE__ */
|
|
6569
|
+
var schema_exports = /* @__PURE__ */ __exportAll({
|
|
6353
6570
|
PositionTypes: () => PositionTypes,
|
|
6354
6571
|
StatusCode: () => StatusCode,
|
|
6355
6572
|
TABLE_NAMES: () => TABLE_NAMES,
|
|
@@ -6375,25 +6592,25 @@ var schema_exports = /* @__PURE__ */ __export({
|
|
|
6375
6592
|
validations: () => validations
|
|
6376
6593
|
});
|
|
6377
6594
|
const s = pgSchema(VERSION);
|
|
6378
|
-
var EnumTableName = /* @__PURE__ */ function(EnumTableName
|
|
6379
|
-
EnumTableName
|
|
6380
|
-
EnumTableName
|
|
6381
|
-
EnumTableName
|
|
6382
|
-
EnumTableName
|
|
6383
|
-
EnumTableName
|
|
6384
|
-
EnumTableName
|
|
6385
|
-
EnumTableName
|
|
6386
|
-
EnumTableName
|
|
6387
|
-
EnumTableName
|
|
6388
|
-
EnumTableName
|
|
6389
|
-
EnumTableName
|
|
6390
|
-
EnumTableName
|
|
6391
|
-
EnumTableName
|
|
6392
|
-
EnumTableName
|
|
6393
|
-
EnumTableName
|
|
6394
|
-
EnumTableName
|
|
6395
|
-
EnumTableName
|
|
6396
|
-
return EnumTableName
|
|
6595
|
+
var EnumTableName = /* @__PURE__ */ function(EnumTableName) {
|
|
6596
|
+
EnumTableName["OBLIGATIONS"] = "obligations";
|
|
6597
|
+
EnumTableName["GROUPS"] = "groups";
|
|
6598
|
+
EnumTableName["CONSUMED_EVENTS"] = "consumed_events";
|
|
6599
|
+
EnumTableName["OBLIGATION_COLLATERALS_V2"] = "obligation_collaterals_v2";
|
|
6600
|
+
EnumTableName["ORACLES"] = "oracles";
|
|
6601
|
+
EnumTableName["OFFERS"] = "offers";
|
|
6602
|
+
EnumTableName["OFFERS_CALLBACKS"] = "offers_callbacks";
|
|
6603
|
+
EnumTableName["CALLBACKS"] = "callbacks";
|
|
6604
|
+
EnumTableName["POSITIONS"] = "positions";
|
|
6605
|
+
EnumTableName["TRANSFERS"] = "transfers";
|
|
6606
|
+
EnumTableName["VALIDATIONS"] = "validations";
|
|
6607
|
+
EnumTableName["COLLECTORS"] = "collectors";
|
|
6608
|
+
EnumTableName["CHAINS"] = "chains";
|
|
6609
|
+
EnumTableName["LOTS"] = "lots";
|
|
6610
|
+
EnumTableName["OFFSETS"] = "offsets";
|
|
6611
|
+
EnumTableName["TREES"] = "trees";
|
|
6612
|
+
EnumTableName["MERKLE_PATHS"] = "merkle_paths";
|
|
6613
|
+
return EnumTableName;
|
|
6397
6614
|
}(EnumTableName || {});
|
|
6398
6615
|
const TABLE_NAMES = Object.values(EnumTableName);
|
|
6399
6616
|
const VERSIONED_TABLE_NAMES = TABLE_NAMES.map((table) => `"${VERSION}"."${table}"`);
|
|
@@ -6750,7 +6967,7 @@ const merklePaths = s.table(EnumTableName.MERKLE_PATHS, {
|
|
|
6750
6967
|
|
|
6751
6968
|
//#endregion
|
|
6752
6969
|
//#region src/database/drizzle/index.ts
|
|
6753
|
-
var drizzle_exports = /* @__PURE__ */
|
|
6970
|
+
var drizzle_exports = /* @__PURE__ */ __exportAll({
|
|
6754
6971
|
PositionTypes: () => PositionTypes,
|
|
6755
6972
|
StatusCode: () => StatusCode,
|
|
6756
6973
|
TABLE_NAMES: () => TABLE_NAMES,
|
|
@@ -6782,7 +6999,7 @@ var drizzle_exports = /* @__PURE__ */ __export({
|
|
|
6782
6999
|
/** Postgres implementation. */
|
|
6783
7000
|
const create$11 = (config) => {
|
|
6784
7001
|
const { db, chainRegistry } = config;
|
|
6785
|
-
const getChain
|
|
7002
|
+
const getChain = async (chainId) => {
|
|
6786
7003
|
const rows = await db.select({
|
|
6787
7004
|
chainId: chains$1.chainId,
|
|
6788
7005
|
blockNumber: chains$1.blockNumber,
|
|
@@ -6928,26 +7145,26 @@ const create$11 = (config) => {
|
|
|
6928
7145
|
epoch
|
|
6929
7146
|
});
|
|
6930
7147
|
const collectorStates = await Promise.all(collectorNames.map(async (collectorName) => {
|
|
6931
|
-
const { blockNumber
|
|
7148
|
+
const { blockNumber, epoch } = await getCollector({
|
|
6932
7149
|
chainId,
|
|
6933
7150
|
collectorName
|
|
6934
7151
|
});
|
|
6935
7152
|
return {
|
|
6936
7153
|
collectorName,
|
|
6937
|
-
blockNumber
|
|
6938
|
-
epoch
|
|
7154
|
+
blockNumber,
|
|
7155
|
+
epoch
|
|
6939
7156
|
};
|
|
6940
7157
|
}));
|
|
6941
|
-
await Promise.all(collectorStates.map(({ collectorName, blockNumber
|
|
7158
|
+
await Promise.all(collectorStates.map(({ collectorName, blockNumber }) => advanceCollector({
|
|
6942
7159
|
collectorName,
|
|
6943
7160
|
chainId,
|
|
6944
|
-
blockNumber: Math.min(blockNumber
|
|
7161
|
+
blockNumber: Math.min(blockNumber, parameters.blockNumber),
|
|
6945
7162
|
epoch: parameters.epoch
|
|
6946
7163
|
})));
|
|
6947
7164
|
};
|
|
6948
7165
|
return {
|
|
6949
7166
|
init,
|
|
6950
|
-
getChain
|
|
7167
|
+
getChain,
|
|
6951
7168
|
getCollector,
|
|
6952
7169
|
getChains,
|
|
6953
7170
|
getCollectors,
|
|
@@ -6964,8 +7181,8 @@ const MAX_TOTAL_OFFERS = 500;
|
|
|
6964
7181
|
function create$10(config) {
|
|
6965
7182
|
const db = config.db;
|
|
6966
7183
|
const logger = getLogger();
|
|
6967
|
-
const getOffers
|
|
6968
|
-
const { side, obligationId
|
|
7184
|
+
const getOffers = async (parameters) => {
|
|
7185
|
+
const { side, obligationId, cursor: cursorString } = parameters;
|
|
6969
7186
|
const requestedLimit = parameters.limit ?? DEFAULT_LIMIT$3;
|
|
6970
7187
|
const priceSortDirection = side === "sell" ? "asc" : "desc";
|
|
6971
7188
|
const inputCursor = Cursor.decode(cursorString, logger);
|
|
@@ -6974,16 +7191,16 @@ function create$10(config) {
|
|
|
6974
7191
|
nextCursor: null
|
|
6975
7192
|
};
|
|
6976
7193
|
if (inputCursor != null && inputCursor.side !== side) throw new Error("Cursor does not match the current sort parameters");
|
|
6977
|
-
const now
|
|
7194
|
+
const now = inputCursor?.now ?? Math.floor(Date.now() / 1e3);
|
|
6978
7195
|
const previouslyReturned = inputCursor?.totalReturned ?? 0;
|
|
6979
7196
|
if (previouslyReturned >= MAX_TOTAL_OFFERS) return {
|
|
6980
7197
|
rows: [],
|
|
6981
7198
|
nextCursor: null
|
|
6982
7199
|
};
|
|
6983
7200
|
const { rows, hasMore } = await _getOffers(db, {
|
|
6984
|
-
obligationId
|
|
7201
|
+
obligationId,
|
|
6985
7202
|
side,
|
|
6986
|
-
now
|
|
7203
|
+
now,
|
|
6987
7204
|
priceSortDirection,
|
|
6988
7205
|
cursor: inputCursor,
|
|
6989
7206
|
limit: Math.min(requestedLimit, MAX_TOTAL_OFFERS - previouslyReturned)
|
|
@@ -6993,23 +7210,23 @@ function create$10(config) {
|
|
|
6993
7210
|
const hasHitHardLimit = newTotalReturned >= MAX_TOTAL_OFFERS;
|
|
6994
7211
|
return {
|
|
6995
7212
|
rows,
|
|
6996
|
-
nextCursor: rows.length > 0 && lastReturnedOffer && !hasHitHardLimit && hasMore ? Cursor.encode(lastReturnedOffer, newTotalReturned, now
|
|
7213
|
+
nextCursor: rows.length > 0 && lastReturnedOffer && !hasHitHardLimit && hasMore ? Cursor.encode(lastReturnedOffer, newTotalReturned, now, side) : null
|
|
6997
7214
|
};
|
|
6998
7215
|
};
|
|
6999
7216
|
return {
|
|
7000
7217
|
get: async (parameters) => {
|
|
7001
|
-
const { side, obligationId
|
|
7218
|
+
const { side, obligationId, cursor: cursorString, limit = DEFAULT_LIMIT$3 } = parameters;
|
|
7002
7219
|
const inputCursor = LevelCursor.decode(cursorString, logger);
|
|
7003
7220
|
if (cursorString != null && inputCursor === null) return {
|
|
7004
7221
|
levels: [],
|
|
7005
7222
|
nextCursor: null
|
|
7006
7223
|
};
|
|
7007
7224
|
if (inputCursor != null && inputCursor.side !== side) throw new Error("Cursor does not match the current sort parameters");
|
|
7008
|
-
const now
|
|
7225
|
+
const now = inputCursor?.now ?? Math.floor(Date.now() / 1e3);
|
|
7009
7226
|
const fetchLimit = limit * 10;
|
|
7010
|
-
const { rows, nextCursor: offersNextCursor } = await getOffers
|
|
7227
|
+
const { rows, nextCursor: offersNextCursor } = await getOffers({
|
|
7011
7228
|
side,
|
|
7012
|
-
obligationId
|
|
7229
|
+
obligationId,
|
|
7013
7230
|
cursor: inputCursor?.offersCursor ?? void 0,
|
|
7014
7231
|
limit: fetchLimit
|
|
7015
7232
|
});
|
|
@@ -7035,15 +7252,15 @@ function create$10(config) {
|
|
|
7035
7252
|
const lastLevel = paginatedLevels[paginatedLevels.length - 1];
|
|
7036
7253
|
return {
|
|
7037
7254
|
levels: paginatedLevels,
|
|
7038
|
-
nextCursor: hasMore && lastLevel ? LevelCursor.encode(lastLevel, offersNextCursor, side, now
|
|
7255
|
+
nextCursor: hasMore && lastLevel ? LevelCursor.encode(lastLevel, offersNextCursor, side, now) : null
|
|
7039
7256
|
};
|
|
7040
7257
|
},
|
|
7041
|
-
getOffers
|
|
7258
|
+
getOffers
|
|
7042
7259
|
};
|
|
7043
7260
|
}
|
|
7044
7261
|
/** Get offers with computed takeable based on lot balance. */
|
|
7045
7262
|
async function _getOffers(db, params) {
|
|
7046
|
-
const { obligationId
|
|
7263
|
+
const { obligationId, side, now, priceSortDirection, cursor, limit } = params;
|
|
7047
7264
|
const raw = await db.execute(sql`
|
|
7048
7265
|
WITH collats AS MATERIALIZED (
|
|
7049
7266
|
SELECT oc.obligation_id,
|
|
@@ -7056,7 +7273,7 @@ async function _getOffers(db, params) {
|
|
|
7056
7273
|
JOIN ${oracles} oracle
|
|
7057
7274
|
ON oracle.chain_id = oc.oracle_chain_id
|
|
7058
7275
|
AND oracle.address = oc.oracle_address
|
|
7059
|
-
WHERE oc.obligation_id = ${obligationId
|
|
7276
|
+
WHERE oc.obligation_id = ${obligationId}
|
|
7060
7277
|
GROUP BY oc.obligation_id
|
|
7061
7278
|
),
|
|
7062
7279
|
winners AS (
|
|
@@ -7067,11 +7284,11 @@ async function _getOffers(db, params) {
|
|
|
7067
7284
|
ON v.offer_hash = o.hash
|
|
7068
7285
|
LEFT JOIN ${status} s
|
|
7069
7286
|
ON s.id = v.status_id
|
|
7070
|
-
WHERE o.obligation_id = ${obligationId
|
|
7287
|
+
WHERE o.obligation_id = ${obligationId}
|
|
7071
7288
|
AND o.buy = ${side === "buy"}
|
|
7072
|
-
AND o.expiry > ${now
|
|
7073
|
-
AND o.maturity > ${now
|
|
7074
|
-
AND o.start <= ${now
|
|
7289
|
+
AND o.expiry > ${now}
|
|
7290
|
+
AND o.maturity > ${now}
|
|
7291
|
+
AND o.start <= ${now}
|
|
7075
7292
|
AND (s.code IS NULL OR s.code = ${Status.VALID})
|
|
7076
7293
|
ORDER BY
|
|
7077
7294
|
o.group_chain_id, o.group_maker, o."group_group",
|
|
@@ -7350,7 +7567,7 @@ async function _getOffers(db, params) {
|
|
|
7350
7567
|
}
|
|
7351
7568
|
let Cursor;
|
|
7352
7569
|
(function(_Cursor) {
|
|
7353
|
-
function encode
|
|
7570
|
+
function encode(row, totalReturned, now, side) {
|
|
7354
7571
|
return Buffer.from(JSON.stringify({
|
|
7355
7572
|
side,
|
|
7356
7573
|
price: row.price.toString(),
|
|
@@ -7358,11 +7575,11 @@ let Cursor;
|
|
|
7358
7575
|
assets: row.assets.toString(),
|
|
7359
7576
|
hash: row.hash,
|
|
7360
7577
|
totalReturned,
|
|
7361
|
-
now
|
|
7578
|
+
now
|
|
7362
7579
|
})).toString("base64url");
|
|
7363
7580
|
}
|
|
7364
|
-
_Cursor.encode = encode
|
|
7365
|
-
function decode
|
|
7581
|
+
_Cursor.encode = encode;
|
|
7582
|
+
function decode(cursorString, logger) {
|
|
7366
7583
|
if (cursorString == null) return null;
|
|
7367
7584
|
const isNumericString = (value) => typeof value === "string" && /^-?\d+$/.test(value);
|
|
7368
7585
|
try {
|
|
@@ -7378,20 +7595,20 @@ let Cursor;
|
|
|
7378
7595
|
return null;
|
|
7379
7596
|
}
|
|
7380
7597
|
}
|
|
7381
|
-
_Cursor.decode = decode
|
|
7598
|
+
_Cursor.decode = decode;
|
|
7382
7599
|
})(Cursor || (Cursor = {}));
|
|
7383
7600
|
let LevelCursor;
|
|
7384
7601
|
(function(_LevelCursor) {
|
|
7385
|
-
function encode
|
|
7602
|
+
function encode(lastLevel, offersCursor, side, now) {
|
|
7386
7603
|
return Buffer.from(JSON.stringify({
|
|
7387
7604
|
side,
|
|
7388
7605
|
lastPrice: lastLevel.price.toString(),
|
|
7389
|
-
now
|
|
7606
|
+
now,
|
|
7390
7607
|
offersCursor
|
|
7391
7608
|
})).toString("base64url");
|
|
7392
7609
|
}
|
|
7393
|
-
_LevelCursor.encode = encode
|
|
7394
|
-
function decode
|
|
7610
|
+
_LevelCursor.encode = encode;
|
|
7611
|
+
function decode(cursorString, logger) {
|
|
7395
7612
|
if (cursorString == null) return null;
|
|
7396
7613
|
const isNumericString = (value) => typeof value === "string" && /^-?\d+$/.test(value);
|
|
7397
7614
|
try {
|
|
@@ -7407,7 +7624,7 @@ let LevelCursor;
|
|
|
7407
7624
|
return null;
|
|
7408
7625
|
}
|
|
7409
7626
|
}
|
|
7410
|
-
_LevelCursor.decode = decode
|
|
7627
|
+
_LevelCursor.decode = decode;
|
|
7411
7628
|
})(LevelCursor || (LevelCursor = {}));
|
|
7412
7629
|
|
|
7413
7630
|
//#endregion
|
|
@@ -7449,7 +7666,7 @@ function create$9(db) {
|
|
|
7449
7666
|
consumed: "0",
|
|
7450
7667
|
blockNumber: group.blockNumber
|
|
7451
7668
|
}));
|
|
7452
|
-
for (const batch
|
|
7669
|
+
for (const batch of batch$1(groupsRows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(groups).values(batch).onConflictDoNothing();
|
|
7453
7670
|
const eventsRows = events.map((event) => ({
|
|
7454
7671
|
eventId: event.id,
|
|
7455
7672
|
chainId: event.chainId,
|
|
@@ -7458,7 +7675,7 @@ function create$9(db) {
|
|
|
7458
7675
|
amount: event.amount.toString(),
|
|
7459
7676
|
blockNumber: event.blockNumber
|
|
7460
7677
|
}));
|
|
7461
|
-
for (const batch
|
|
7678
|
+
for (const batch of batch$1(eventsRows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(consumedEvents).values(batch).onConflictDoNothing();
|
|
7462
7679
|
});
|
|
7463
7680
|
},
|
|
7464
7681
|
delete: async (parameters) => {
|
|
@@ -7513,9 +7730,96 @@ function create$8(db) {
|
|
|
7513
7730
|
};
|
|
7514
7731
|
}
|
|
7515
7732
|
|
|
7733
|
+
//#endregion
|
|
7734
|
+
//#region src/gatekeeper/Client.ts
|
|
7735
|
+
var Client_exports = /* @__PURE__ */ __exportAll({ createHttpClient: () => createHttpClient });
|
|
7736
|
+
const DEFAULT_TIMEOUT_MS = 1e4;
|
|
7737
|
+
/**
|
|
7738
|
+
* Create an HTTP client for a gatekeeper service.
|
|
7739
|
+
* @param config - Gatekeeper client configuration. {@link ClientConfig}
|
|
7740
|
+
* @returns An HTTP-backed gatekeeper client. {@link GatekeeperClient}
|
|
7741
|
+
*/
|
|
7742
|
+
function createHttpClient(config) {
|
|
7743
|
+
const fetchFn = config.fetchFn ?? fetch;
|
|
7744
|
+
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
7745
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
7746
|
+
const request = async (path, init) => {
|
|
7747
|
+
const controller = new AbortController();
|
|
7748
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
7749
|
+
try {
|
|
7750
|
+
return await fetchFn(`${baseUrl}${path}`, {
|
|
7751
|
+
...init,
|
|
7752
|
+
signal: controller.signal
|
|
7753
|
+
});
|
|
7754
|
+
} finally {
|
|
7755
|
+
clearTimeout(timeout);
|
|
7756
|
+
}
|
|
7757
|
+
};
|
|
7758
|
+
const validate = async (body) => {
|
|
7759
|
+
const response = await request("/v1/validate", {
|
|
7760
|
+
method: "POST",
|
|
7761
|
+
headers: { "content-type": "application/json" },
|
|
7762
|
+
body: JSON.stringify(body)
|
|
7763
|
+
});
|
|
7764
|
+
const json = await response.json();
|
|
7765
|
+
return {
|
|
7766
|
+
statusCode: response.status,
|
|
7767
|
+
body: json
|
|
7768
|
+
};
|
|
7769
|
+
};
|
|
7770
|
+
const getRules = async () => {
|
|
7771
|
+
const response = await request("/v1/rules", { method: "GET" });
|
|
7772
|
+
const json = await response.json();
|
|
7773
|
+
if (!response.ok) throw new Error(`Gatekeeper rules request failed: ${extractErrorMessage(json) ?? response.statusText}`);
|
|
7774
|
+
if (!("data" in json) || !Array.isArray(json.data)) throw new Error("Gatekeeper rules response is invalid.");
|
|
7775
|
+
return json.data;
|
|
7776
|
+
};
|
|
7777
|
+
const isAllowed = async (offers) => {
|
|
7778
|
+
const { statusCode, body } = await validate({ offers: offers.map((offer) => toSnakeCase(offer)) });
|
|
7779
|
+
if (statusCode !== 200) {
|
|
7780
|
+
const errorMessage = extractErrorMessage(body);
|
|
7781
|
+
throw new Error(`Gatekeeper validation failed: ${errorMessage ?? `status ${statusCode}`}`);
|
|
7782
|
+
}
|
|
7783
|
+
const data = body.data;
|
|
7784
|
+
if (!data || typeof data !== "object") throw new Error("Gatekeeper validation response is invalid.");
|
|
7785
|
+
if ("issues" in data) {
|
|
7786
|
+
const issues = data.issues.map((issue) => ({
|
|
7787
|
+
ruleName: issue.rule,
|
|
7788
|
+
message: issue.message,
|
|
7789
|
+
item: offers[issue.index]
|
|
7790
|
+
}));
|
|
7791
|
+
const invalidIndices = new Set(data.issues.map((issue) => issue.index));
|
|
7792
|
+
return {
|
|
7793
|
+
valid: offers.filter((_, index) => !invalidIndices.has(index)),
|
|
7794
|
+
issues
|
|
7795
|
+
};
|
|
7796
|
+
}
|
|
7797
|
+
if (!("payload" in data) || !("root" in data)) throw new Error("Gatekeeper validation response is missing payload data.");
|
|
7798
|
+
return {
|
|
7799
|
+
valid: offers.slice(),
|
|
7800
|
+
issues: []
|
|
7801
|
+
};
|
|
7802
|
+
};
|
|
7803
|
+
return {
|
|
7804
|
+
baseUrl,
|
|
7805
|
+
validate,
|
|
7806
|
+
isAllowed,
|
|
7807
|
+
getRules
|
|
7808
|
+
};
|
|
7809
|
+
}
|
|
7810
|
+
function normalizeBaseUrl(url) {
|
|
7811
|
+
return url.trim().replace(/\/+$/, "");
|
|
7812
|
+
}
|
|
7813
|
+
function extractErrorMessage(payload) {
|
|
7814
|
+
if (!payload || typeof payload !== "object") return void 0;
|
|
7815
|
+
const error = payload.error;
|
|
7816
|
+
if (!error || typeof error !== "object") return void 0;
|
|
7817
|
+
return typeof error.message === "string" ? error.message : void 0;
|
|
7818
|
+
}
|
|
7819
|
+
|
|
7516
7820
|
//#endregion
|
|
7517
7821
|
//#region src/gatekeeper/Gate.ts
|
|
7518
|
-
var Gate_exports = /* @__PURE__ */
|
|
7822
|
+
var Gate_exports = /* @__PURE__ */ __exportAll({
|
|
7519
7823
|
batch: () => batch,
|
|
7520
7824
|
run: () => run,
|
|
7521
7825
|
single: () => single
|
|
@@ -7527,12 +7831,12 @@ var Gate_exports = /* @__PURE__ */ __export({
|
|
|
7527
7831
|
* @param run - The function that validates the rule.
|
|
7528
7832
|
* @returns The created rule.
|
|
7529
7833
|
*/
|
|
7530
|
-
function single(name, description, run
|
|
7834
|
+
function single(name, description, run) {
|
|
7531
7835
|
return {
|
|
7532
7836
|
kind: "single",
|
|
7533
7837
|
name,
|
|
7534
7838
|
description,
|
|
7535
|
-
run
|
|
7839
|
+
run
|
|
7536
7840
|
};
|
|
7537
7841
|
}
|
|
7538
7842
|
/**
|
|
@@ -7542,12 +7846,12 @@ function single(name, description, run$1) {
|
|
|
7542
7846
|
* @param run - The function that validates the rule.
|
|
7543
7847
|
* @returns The created rule.
|
|
7544
7848
|
*/
|
|
7545
|
-
function batch(name, description, run
|
|
7849
|
+
function batch(name, description, run) {
|
|
7546
7850
|
return {
|
|
7547
7851
|
kind: "batch",
|
|
7548
7852
|
name,
|
|
7549
7853
|
description,
|
|
7550
|
-
run
|
|
7854
|
+
run
|
|
7551
7855
|
};
|
|
7552
7856
|
}
|
|
7553
7857
|
async function run(parameters) {
|
|
@@ -7600,7 +7904,7 @@ async function run(parameters) {
|
|
|
7600
7904
|
|
|
7601
7905
|
//#endregion
|
|
7602
7906
|
//#region src/gatekeeper/GateConfig.ts
|
|
7603
|
-
var GateConfig_exports = /* @__PURE__ */
|
|
7907
|
+
var GateConfig_exports = /* @__PURE__ */ __exportAll({
|
|
7604
7908
|
assets: () => assets,
|
|
7605
7909
|
configs: () => configs,
|
|
7606
7910
|
getCallback: () => getCallback,
|
|
@@ -7626,8 +7930,8 @@ function getCallback(chain, type) {
|
|
|
7626
7930
|
* @param address - Callback contract address
|
|
7627
7931
|
* @returns The callback type when found, otherwise undefined
|
|
7628
7932
|
*/
|
|
7629
|
-
function getCallbackType(chain, address
|
|
7630
|
-
return configs[chain].callbacks?.find((c) => c.type !==
|
|
7933
|
+
function getCallbackType(chain, address) {
|
|
7934
|
+
return configs[chain].callbacks?.find((c) => c.type !== Type$1.BuyWithEmptyCallback && c.addresses.includes(address?.toLowerCase()))?.type;
|
|
7631
7935
|
}
|
|
7632
7936
|
/**
|
|
7633
7937
|
* Returns the callback addresses for a given chain and callback type, if it exists.
|
|
@@ -7636,7 +7940,7 @@ function getCallbackType(chain, address$1) {
|
|
|
7636
7940
|
* @returns The matching callback addresses or an empty array if not configured
|
|
7637
7941
|
*/
|
|
7638
7942
|
function getCallbackTypeAddresses(chain, type) {
|
|
7639
|
-
if (type ===
|
|
7943
|
+
if (type === Type$1.BuyWithEmptyCallback) return [];
|
|
7640
7944
|
const match = configs[chain].callbacks?.find((c) => c.type === type);
|
|
7641
7945
|
return match && "addresses" in match ? match.addresses : [];
|
|
7642
7946
|
}
|
|
@@ -7647,7 +7951,7 @@ function getCallbackTypeAddresses(chain, type) {
|
|
|
7647
7951
|
* @returns Array of allowed callback addresses (lowercased). Empty when none configured
|
|
7648
7952
|
*/
|
|
7649
7953
|
const getCallbackAddresses = (chain) => {
|
|
7650
|
-
return configs[chain].callbacks?.filter((c) => c.type !==
|
|
7954
|
+
return configs[chain].callbacks?.filter((c) => c.type !== Type$1.BuyWithEmptyCallback).flatMap((c) => c.addresses) ?? [];
|
|
7651
7955
|
};
|
|
7652
7956
|
const assets = {
|
|
7653
7957
|
[ChainId.ETHEREUM.toString()]: [
|
|
@@ -7680,60 +7984,60 @@ const configs = {
|
|
|
7680
7984
|
ethereum: {
|
|
7681
7985
|
callbacks: [
|
|
7682
7986
|
{
|
|
7683
|
-
type:
|
|
7987
|
+
type: Type$1.BuyVaultV1Callback,
|
|
7684
7988
|
addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
|
|
7685
7989
|
vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
|
|
7686
7990
|
},
|
|
7687
7991
|
{
|
|
7688
|
-
type:
|
|
7992
|
+
type: Type$1.SellERC20Callback,
|
|
7689
7993
|
addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
|
|
7690
7994
|
},
|
|
7691
|
-
{ type:
|
|
7995
|
+
{ type: Type$1.BuyWithEmptyCallback }
|
|
7692
7996
|
],
|
|
7693
7997
|
maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
|
|
7694
7998
|
},
|
|
7695
7999
|
base: {
|
|
7696
8000
|
callbacks: [
|
|
7697
8001
|
{
|
|
7698
|
-
type:
|
|
8002
|
+
type: Type$1.BuyVaultV1Callback,
|
|
7699
8003
|
addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
|
|
7700
8004
|
vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0xFf62A7c278C62eD665133147129245053Bbf5918"]
|
|
7701
8005
|
},
|
|
7702
8006
|
{
|
|
7703
|
-
type:
|
|
8007
|
+
type: Type$1.SellERC20Callback,
|
|
7704
8008
|
addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
|
|
7705
8009
|
},
|
|
7706
|
-
{ type:
|
|
8010
|
+
{ type: Type$1.BuyWithEmptyCallback }
|
|
7707
8011
|
],
|
|
7708
8012
|
maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
|
|
7709
8013
|
},
|
|
7710
8014
|
"ethereum-virtual-testnet": {
|
|
7711
8015
|
callbacks: [
|
|
7712
8016
|
{
|
|
7713
|
-
type:
|
|
8017
|
+
type: Type$1.BuyVaultV1Callback,
|
|
7714
8018
|
addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
|
|
7715
8019
|
vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
|
|
7716
8020
|
},
|
|
7717
8021
|
{
|
|
7718
|
-
type:
|
|
8022
|
+
type: Type$1.SellERC20Callback,
|
|
7719
8023
|
addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
|
|
7720
8024
|
},
|
|
7721
|
-
{ type:
|
|
8025
|
+
{ type: Type$1.BuyWithEmptyCallback }
|
|
7722
8026
|
],
|
|
7723
8027
|
maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
|
|
7724
8028
|
},
|
|
7725
8029
|
anvil: {
|
|
7726
8030
|
callbacks: [
|
|
7727
8031
|
{
|
|
7728
|
-
type:
|
|
8032
|
+
type: Type$1.BuyVaultV1Callback,
|
|
7729
8033
|
addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
|
|
7730
8034
|
vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
|
|
7731
8035
|
},
|
|
7732
8036
|
{
|
|
7733
|
-
type:
|
|
8037
|
+
type: Type$1.SellERC20Callback,
|
|
7734
8038
|
addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
|
|
7735
8039
|
},
|
|
7736
|
-
{ type:
|
|
8040
|
+
{ type: Type$1.BuyWithEmptyCallback }
|
|
7737
8041
|
],
|
|
7738
8042
|
maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
|
|
7739
8043
|
}
|
|
@@ -7741,22 +8045,31 @@ const configs = {
|
|
|
7741
8045
|
|
|
7742
8046
|
//#endregion
|
|
7743
8047
|
//#region src/gatekeeper/Gatekeeper.ts
|
|
7744
|
-
var Gatekeeper_exports = /* @__PURE__ */
|
|
8048
|
+
var Gatekeeper_exports = /* @__PURE__ */ __exportAll({ create: () => create$7 });
|
|
8049
|
+
/**
|
|
8050
|
+
* Create a gatekeeper instance with the provided rules.
|
|
8051
|
+
* @param parameters - Gatekeeper parameters. {@link GatekeeperParameters}
|
|
8052
|
+
* @returns Gatekeeper instance. {@link Gatekeeper}
|
|
8053
|
+
*/
|
|
7745
8054
|
function create$7(parameters) {
|
|
8055
|
+
const { rules } = parameters;
|
|
7746
8056
|
return {
|
|
7747
|
-
|
|
7748
|
-
isAllowed: async (offers$1) => {
|
|
8057
|
+
isAllowed: async (offers) => {
|
|
7749
8058
|
return await run({
|
|
7750
|
-
items: offers
|
|
7751
|
-
rules
|
|
8059
|
+
items: offers,
|
|
8060
|
+
rules
|
|
7752
8061
|
});
|
|
7753
|
-
}
|
|
8062
|
+
},
|
|
8063
|
+
getRules: async () => rules.map((rule) => ({
|
|
8064
|
+
name: rule.name,
|
|
8065
|
+
description: rule.description
|
|
8066
|
+
}))
|
|
7754
8067
|
};
|
|
7755
8068
|
}
|
|
7756
8069
|
|
|
7757
8070
|
//#endregion
|
|
7758
8071
|
//#region src/gatekeeper/Rules.ts
|
|
7759
|
-
var Rules_exports = /* @__PURE__ */
|
|
8072
|
+
var Rules_exports = /* @__PURE__ */ __exportAll({
|
|
7760
8073
|
amountMutualExclusivity: () => amountMutualExclusivity,
|
|
7761
8074
|
callback: () => callback,
|
|
7762
8075
|
chains: () => chains,
|
|
@@ -7775,21 +8088,21 @@ function validity(parameters) {
|
|
|
7775
8088
|
const { client } = parameters;
|
|
7776
8089
|
const sellErc20CallbackInvalid = single("sell_erc20_callback_invalid", "Validates that sell offers have valid ERC20 callback data matching offer collaterals", (offer) => {
|
|
7777
8090
|
const callbackType = getCallbackType(client.chain.name, offer.callback.address);
|
|
7778
|
-
if (callbackType !==
|
|
8091
|
+
if (callbackType !== Type$1.SellERC20Callback) return;
|
|
7779
8092
|
const decoded = decode$2(callbackType, offer.callback.data);
|
|
7780
8093
|
if (decoded.length === 0) return { message: "Callback data cannot be decoded or is empty." };
|
|
7781
|
-
if (callbackType ===
|
|
8094
|
+
if (callbackType === Type$1.SellERC20Callback) {
|
|
7782
8095
|
const offerCollaterals = new Set(offer.collaterals.map((c) => c.asset.toLowerCase()));
|
|
7783
8096
|
if (decoded.length !== offer.collaterals.length) return { message: `Sell callback collateral length mismatch. Expected ${offer.collaterals.length}, got ${decoded.length}.` };
|
|
7784
8097
|
for (const { contract } of decoded) if (!offerCollaterals.has(contract.toLowerCase())) return { message: "Sell callback collateral is not part of offer collaterals." };
|
|
7785
8098
|
}
|
|
7786
8099
|
});
|
|
7787
|
-
const buyCallbackVaultInvalid = batch("buy_offers_callback_vault_invalid", "Validates that buy offers have valid vault callbacks registered in allowed factories with matching assets", async (offers
|
|
8100
|
+
const buyCallbackVaultInvalid = batch("buy_offers_callback_vault_invalid", "Validates that buy offers have valid vault callbacks registered in allowed factories with matching assets", async (offers) => {
|
|
7788
8101
|
const validationIssues = /* @__PURE__ */ new Map();
|
|
7789
8102
|
const offersByVaultAddress = /* @__PURE__ */ new Map();
|
|
7790
|
-
for (let i = 0; i < offers
|
|
7791
|
-
const offer = offers
|
|
7792
|
-
if (getCallbackType(client.chain.name, offer.callback.address) !==
|
|
8103
|
+
for (let i = 0; i < offers.length; i++) {
|
|
8104
|
+
const offer = offers[i];
|
|
8105
|
+
if (getCallbackType(client.chain.name, offer.callback.address) !== Type$1.BuyVaultV1Callback) continue;
|
|
7793
8106
|
try {
|
|
7794
8107
|
const callbackVaults = decodeBuyVaultV1Callback(offer.callback.data);
|
|
7795
8108
|
for (const { contract } of callbackVaults) {
|
|
@@ -7804,7 +8117,7 @@ function validity(parameters) {
|
|
|
7804
8117
|
}
|
|
7805
8118
|
const uniqueVaultAddresses = Array.from(offersByVaultAddress.keys());
|
|
7806
8119
|
if (uniqueVaultAddresses.length === 0) return validationIssues;
|
|
7807
|
-
const allowedFactories = getCallback(client.chain.name,
|
|
8120
|
+
const allowedFactories = getCallback(client.chain.name, Type$1.BuyVaultV1Callback)?.vaultFactories.map((f) => f.toLowerCase());
|
|
7808
8121
|
if (!allowedFactories) return validationIssues;
|
|
7809
8122
|
const multicallContracts = [];
|
|
7810
8123
|
for (const vaultAddress of uniqueVaultAddresses) {
|
|
@@ -7840,8 +8153,8 @@ function validity(parameters) {
|
|
|
7840
8153
|
if (isRegisteredInFactory) registeredVaults.add(vaultAddress);
|
|
7841
8154
|
}
|
|
7842
8155
|
const uniqueOffers = /* @__PURE__ */ new Map();
|
|
7843
|
-
for (const offersArray of offersByVaultAddress.values()) for (const { index
|
|
7844
|
-
for (const [index
|
|
8156
|
+
for (const offersArray of offersByVaultAddress.values()) for (const { index, offer } of offersArray) uniqueOffers.set(index, offer);
|
|
8157
|
+
for (const [index, offer] of uniqueOffers) try {
|
|
7845
8158
|
const callbackVaults = decodeBuyVaultV1Callback(offer.callback.data);
|
|
7846
8159
|
const vaultsWithIssues = [];
|
|
7847
8160
|
for (const { contract } of callbackVaults) {
|
|
@@ -7859,7 +8172,7 @@ function validity(parameters) {
|
|
|
7859
8172
|
}
|
|
7860
8173
|
if (vaultsWithIssues.length > 0) {
|
|
7861
8174
|
const failureDetails = vaultsWithIssues.map((v) => `${v.vaultAddress} (${v.failureReasons})`).join("; ");
|
|
7862
|
-
validationIssues.set(index
|
|
8175
|
+
validationIssues.set(index, { message: `Buy offer callback vaults are invalid: ${failureDetails}` });
|
|
7863
8176
|
}
|
|
7864
8177
|
} catch (_) {}
|
|
7865
8178
|
return validationIssues;
|
|
@@ -7872,16 +8185,16 @@ function validity(parameters) {
|
|
|
7872
8185
|
buyCallbackVaultInvalid
|
|
7873
8186
|
];
|
|
7874
8187
|
}
|
|
7875
|
-
const chains = ({ chains
|
|
7876
|
-
const allowedChainIds = chains
|
|
7877
|
-
if (!allowedChainIds.some((id
|
|
8188
|
+
const chains = ({ chains }) => single("chain_ids", `Validates that offer chain is one of: [${chains.map((c) => c.id).join(", ")}]`, (offer) => {
|
|
8189
|
+
const allowedChainIds = chains.map((c) => c.id);
|
|
8190
|
+
if (!allowedChainIds.some((id) => id === offer.chainId)) return { message: `Chain ID ${offer.chainId} is not in the allowed chains (${allowedChainIds.join(", ")})` };
|
|
7878
8191
|
});
|
|
7879
8192
|
const maturity = ({ maturities }) => single("maturity", `Validates that offer maturity is one of: [${maturities.join(", ")}]`, (offer) => {
|
|
7880
|
-
const allowedMaturities = maturities.map((m) => from$
|
|
8193
|
+
const allowedMaturities = maturities.map((m) => from$16(m));
|
|
7881
8194
|
if (!allowedMaturities.includes(offer.maturity)) return { message: `Maturity must be end of current month (${allowedMaturities[0]}) or end of next month (${allowedMaturities[1]}). Got: ${offer.maturity}` };
|
|
7882
8195
|
});
|
|
7883
|
-
const callback = ({ callbacks
|
|
7884
|
-
if (isEmptyCallback(offer) && offer.buy && !callbacks
|
|
8196
|
+
const callback = ({ callbacks, allowedAddresses }) => single("callback", `Validates callbacks: buy empty callback is ${callbacks.includes(Type$1.BuyWithEmptyCallback) ? "allowed" : "not allowed"}; sell offers must use a non-empty callback; non-empty callbacks must target one of [${allowedAddresses.map((a) => a.toLowerCase()).join(", ")}]`, (offer) => {
|
|
8197
|
+
if (isEmptyCallback(offer) && offer.buy && !callbacks?.find((c) => c === Type$1.BuyWithEmptyCallback)) return { message: "Buy offers with empty callback not allowed." };
|
|
7885
8198
|
if (isEmptyCallback(offer) && !offer.buy) return { message: "Sell offers require a non-empty callback." };
|
|
7886
8199
|
if (!isEmptyCallback(offer)) {
|
|
7887
8200
|
if (!allowedAddresses.includes(offer.callback.address?.toLowerCase())) return { message: `Callback address ${offer.callback.address} is not allowed.` };
|
|
@@ -7903,14 +8216,14 @@ const token = ({ assetsByChainId }) => single("token", "Validates that offer loa
|
|
|
7903
8216
|
* Returns an issue only for the first non-conforming offer.
|
|
7904
8217
|
* This rule is signing-agnostic; signer verification is handled at the collector level.
|
|
7905
8218
|
*/
|
|
7906
|
-
const sameMaker = () => batch("mixed_maker", "Validates that all offers in a batch have the same maker address", (offers
|
|
8219
|
+
const sameMaker = () => batch("mixed_maker", "Validates that all offers in a batch have the same maker address", (offers) => {
|
|
7907
8220
|
const issues = /* @__PURE__ */ new Map();
|
|
7908
|
-
if (offers
|
|
7909
|
-
const firstMaker = offers
|
|
7910
|
-
for (let i = 1; i < offers
|
|
7911
|
-
const offer = offers
|
|
8221
|
+
if (offers.length === 0) return issues;
|
|
8222
|
+
const firstMaker = offers[0].maker.toLowerCase();
|
|
8223
|
+
for (let i = 1; i < offers.length; i++) {
|
|
8224
|
+
const offer = offers[i];
|
|
7912
8225
|
if (offer.maker.toLowerCase() !== firstMaker) {
|
|
7913
|
-
issues.set(i, { message: `Offer has different maker ${offer.maker} than first offer ${offers
|
|
8226
|
+
issues.set(i, { message: `Offer has different maker ${offer.maker} than first offer ${offers[0].maker}` });
|
|
7914
8227
|
return issues;
|
|
7915
8228
|
}
|
|
7916
8229
|
}
|
|
@@ -7937,9 +8250,9 @@ const morphoRules = (chains$3) => {
|
|
|
7937
8250
|
maturity({ maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth] }),
|
|
7938
8251
|
callback({
|
|
7939
8252
|
callbacks: [
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
8253
|
+
Type$1.BuyWithEmptyCallback,
|
|
8254
|
+
Type$1.BuyVaultV1Callback,
|
|
8255
|
+
Type$1.SellERC20Callback
|
|
7943
8256
|
],
|
|
7944
8257
|
allowedAddresses: chains$3.flatMap((c) => getCallbackAddresses(c.name))
|
|
7945
8258
|
}),
|
|
@@ -7955,7 +8268,7 @@ function create$6(config) {
|
|
|
7955
8268
|
return {
|
|
7956
8269
|
create: async (batches) => {
|
|
7957
8270
|
if (batches.length === 0) return [];
|
|
7958
|
-
const offersWithBlock = batches.flatMap(({ blockNumber, offers
|
|
8271
|
+
const offersWithBlock = batches.flatMap(({ blockNumber, offers }) => offers.map((offer) => ({
|
|
7959
8272
|
offer,
|
|
7960
8273
|
blockNumber
|
|
7961
8274
|
})));
|
|
@@ -7967,7 +8280,7 @@ function create$6(config) {
|
|
|
7967
8280
|
for (const { offer, blockNumber } of offersWithBlock) {
|
|
7968
8281
|
const obligationId$1 = obligationId(offer);
|
|
7969
8282
|
if (!obligationsMap.has(obligationId$1)) {
|
|
7970
|
-
obligationsMap.set(obligationId$1, from$
|
|
8283
|
+
obligationsMap.set(obligationId$1, from$15({
|
|
7971
8284
|
chainId: offer.chainId,
|
|
7972
8285
|
loanToken: offer.loanToken,
|
|
7973
8286
|
maturity: offer.maturity,
|
|
@@ -7995,28 +8308,28 @@ function create$6(config) {
|
|
|
7995
8308
|
});
|
|
7996
8309
|
}
|
|
7997
8310
|
return await db.transaction(async (dbTx) => {
|
|
7998
|
-
const obligationsRows = Array.from(obligationsMap.entries()).map(([obligationId
|
|
7999
|
-
obligationId
|
|
8311
|
+
const obligationsRows = Array.from(obligationsMap.entries()).map(([obligationId, obligation]) => ({
|
|
8312
|
+
obligationId,
|
|
8000
8313
|
chainId: obligation.chainId,
|
|
8001
8314
|
loanToken: obligation.loanToken.toLowerCase(),
|
|
8002
8315
|
maturity: obligation.maturity
|
|
8003
8316
|
}));
|
|
8004
|
-
for (const batch
|
|
8317
|
+
for (const batch of batch$1(obligationsRows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(obligations).values(batch).onConflictDoNothing();
|
|
8005
8318
|
const oraclesRows = Array.from(oraclesMap.values()).map((oracle) => ({
|
|
8006
8319
|
chainId: oracle.chainId,
|
|
8007
8320
|
address: oracle.address.toLowerCase(),
|
|
8008
8321
|
blockNumber: oracle.blockNumber
|
|
8009
8322
|
}));
|
|
8010
|
-
for (const batch
|
|
8011
|
-
const collateralsRows = Array.from(collateralsMap.entries()).flatMap(([obligationId
|
|
8012
|
-
obligationId
|
|
8323
|
+
for (const batch of batch$1(oraclesRows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(oracles).values(batch).onConflictDoNothing();
|
|
8324
|
+
const collateralsRows = Array.from(collateralsMap.entries()).flatMap(([obligationId, items]) => items.collaterals.map((collateral) => ({
|
|
8325
|
+
obligationId,
|
|
8013
8326
|
asset: collateral.asset.toLowerCase(),
|
|
8014
|
-
oracleChainId: obligationsMap.get(obligationId
|
|
8327
|
+
oracleChainId: obligationsMap.get(obligationId).chainId,
|
|
8015
8328
|
oracleAddress: collateral.oracle.toLowerCase(),
|
|
8016
8329
|
lltv: collateral.lltv,
|
|
8017
8330
|
blockNumber: items.blockNumber
|
|
8018
8331
|
})));
|
|
8019
|
-
for (const batch
|
|
8332
|
+
for (const batch of batch$1(collateralsRows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(obligationCollateralsV2).values(batch).onConflictDoNothing();
|
|
8020
8333
|
const groupsRows = Array.from(groupsMap.values()).map((group) => ({
|
|
8021
8334
|
chainId: group.chainId,
|
|
8022
8335
|
maker: group.maker.toLowerCase(),
|
|
@@ -8024,7 +8337,7 @@ function create$6(config) {
|
|
|
8024
8337
|
consumed: "0",
|
|
8025
8338
|
blockNumber: group.blockNumber
|
|
8026
8339
|
}));
|
|
8027
|
-
for (const batch
|
|
8340
|
+
for (const batch of batch$1(groupsRows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(groups).values(batch).onConflictDoNothing();
|
|
8028
8341
|
const offersRows = offersWithBlock.map(({ offer, blockNumber }) => ({
|
|
8029
8342
|
...serialize(offer),
|
|
8030
8343
|
obligationId: obligationId(offer),
|
|
@@ -8035,17 +8348,17 @@ function create$6(config) {
|
|
|
8035
8348
|
blockNumber
|
|
8036
8349
|
}));
|
|
8037
8350
|
const inserted = [];
|
|
8038
|
-
for (const batch
|
|
8039
|
-
const result = await dbTx.insert(offers).values(batch
|
|
8351
|
+
for (const batch of batch$1(offersRows, DEFAULT_BATCH_SIZE$1)) {
|
|
8352
|
+
const result = await dbTx.insert(offers).values(batch).onConflictDoNothing().returning();
|
|
8040
8353
|
inserted.push(...result);
|
|
8041
8354
|
}
|
|
8042
8355
|
if (inserted.length === 0) return [];
|
|
8043
8356
|
const idCached = /* @__PURE__ */ new Map();
|
|
8044
|
-
const id
|
|
8357
|
+
const id = (params) => {
|
|
8045
8358
|
const preimage = `0x${params.chainId}${params.contract}${params.user}${params.amount}`.toLowerCase();
|
|
8046
|
-
const id
|
|
8047
|
-
idCached.set(preimage, id
|
|
8048
|
-
return id
|
|
8359
|
+
const id = idCached.get(preimage) ?? keccak256(preimage);
|
|
8360
|
+
idCached.set(preimage, id);
|
|
8361
|
+
return id;
|
|
8049
8362
|
};
|
|
8050
8363
|
const offersCallbacksMap = /* @__PURE__ */ new Map();
|
|
8051
8364
|
for (const offer of inserted) {
|
|
@@ -8056,21 +8369,21 @@ function create$6(config) {
|
|
|
8056
8369
|
if (!chain) continue;
|
|
8057
8370
|
const callbackType = getCallbackType(chain.name, offer.callbackAddress);
|
|
8058
8371
|
if (!callbackType) continue;
|
|
8059
|
-
const callbacks
|
|
8372
|
+
const callbacks = decode$2(callbackType, offer.callbackData).map((callback) => ({
|
|
8060
8373
|
chainId: offer.groupChainId,
|
|
8061
|
-
contract: callback
|
|
8374
|
+
contract: callback.contract.toLowerCase(),
|
|
8062
8375
|
user: user.toLowerCase(),
|
|
8063
|
-
amount: callback
|
|
8064
|
-
type: callbackType ===
|
|
8065
|
-
asset: callbackType ===
|
|
8376
|
+
amount: callback.amount.toString(),
|
|
8377
|
+
type: callbackType === Type$1.BuyVaultV1Callback ? Type.VAULT_V1 : Type.ERC20,
|
|
8378
|
+
asset: callbackType === Type$1.BuyVaultV1Callback ? void 0 : callback.contract.toLowerCase(),
|
|
8066
8379
|
blockNumber: offer.blockNumber
|
|
8067
8380
|
}));
|
|
8068
8381
|
try {
|
|
8069
|
-
await dbTx.insert(offersCallbacks).values(callbacks
|
|
8382
|
+
await dbTx.insert(offersCallbacks).values(callbacks.map((callback) => ({
|
|
8070
8383
|
offerHash: offer.hash,
|
|
8071
|
-
callbackId: id
|
|
8384
|
+
callbackId: id(callback)
|
|
8072
8385
|
}))).onConflictDoNothing();
|
|
8073
|
-
offersCallbacksMap.get(offer.hash).push(...callbacks
|
|
8386
|
+
offersCallbacksMap.get(offer.hash).push(...callbacks);
|
|
8074
8387
|
} catch (_) {
|
|
8075
8388
|
offersCallbacksMap.delete(offer.hash);
|
|
8076
8389
|
}
|
|
@@ -8084,34 +8397,34 @@ function create$6(config) {
|
|
|
8084
8397
|
idCached.clear();
|
|
8085
8398
|
return inserted.map((offer) => offer.hash);
|
|
8086
8399
|
}
|
|
8087
|
-
await dbTx.positions.upsert(Array.from(offersCallbacksMap.values()).flatMap((callbacks
|
|
8088
|
-
chainId: callback
|
|
8089
|
-
contract: callback
|
|
8090
|
-
user: callback
|
|
8091
|
-
type: callback
|
|
8092
|
-
asset: callback
|
|
8093
|
-
blockNumber: callback
|
|
8400
|
+
await dbTx.positions.upsert(Array.from(offersCallbacksMap.values()).flatMap((callbacks) => callbacks.map((callback) => ({
|
|
8401
|
+
chainId: callback.chainId,
|
|
8402
|
+
contract: callback.contract,
|
|
8403
|
+
user: callback.user,
|
|
8404
|
+
type: callback.type,
|
|
8405
|
+
asset: callback.asset,
|
|
8406
|
+
blockNumber: callback.blockNumber
|
|
8094
8407
|
}))));
|
|
8095
|
-
const callbacksRows = Array.from(offersCallbacksMap.values()).flatMap((callbacks
|
|
8096
|
-
id: id
|
|
8097
|
-
positionChainId: callback
|
|
8098
|
-
positionContract: callback
|
|
8099
|
-
positionUser: callback
|
|
8100
|
-
amount: callback
|
|
8408
|
+
const callbacksRows = Array.from(offersCallbacksMap.values()).flatMap((callbacks) => callbacks.map((callback) => ({
|
|
8409
|
+
id: id(callback),
|
|
8410
|
+
positionChainId: callback.chainId,
|
|
8411
|
+
positionContract: callback.contract,
|
|
8412
|
+
positionUser: callback.user,
|
|
8413
|
+
amount: callback.amount
|
|
8101
8414
|
})));
|
|
8102
|
-
for (const batch
|
|
8415
|
+
for (const batch of batch$1(callbacksRows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(callbacks).values(batch).onConflictDoNothing();
|
|
8103
8416
|
const lotInfos = [];
|
|
8104
|
-
for (const [offerHash, callbacks
|
|
8417
|
+
for (const [offerHash, callbacks] of offersCallbacksMap.entries()) {
|
|
8105
8418
|
const offer = inserted.find((o) => o.hash === offerHash);
|
|
8106
8419
|
if (!offer) continue;
|
|
8107
|
-
for (const callback
|
|
8108
|
-
const isLoanPosition = obligationsMap.get(offer.obligationId)?.loanToken.toLowerCase() === callback
|
|
8420
|
+
for (const callback of callbacks) {
|
|
8421
|
+
const isLoanPosition = obligationsMap.get(offer.obligationId)?.loanToken.toLowerCase() === callback.asset?.toLowerCase();
|
|
8109
8422
|
lotInfos.push({
|
|
8110
|
-
positionChainId: callback
|
|
8111
|
-
positionContract: callback
|
|
8112
|
-
positionUser: callback
|
|
8423
|
+
positionChainId: callback.chainId,
|
|
8424
|
+
positionContract: callback.contract,
|
|
8425
|
+
positionUser: callback.user,
|
|
8113
8426
|
group: offer.group,
|
|
8114
|
-
size: isLoanPosition ? BigInt(offer.assets) : BigInt(callback
|
|
8427
|
+
size: isLoanPosition ? BigInt(offer.assets) : BigInt(callback.amount)
|
|
8115
8428
|
});
|
|
8116
8429
|
}
|
|
8117
8430
|
}
|
|
@@ -8205,7 +8518,7 @@ function create$6(config) {
|
|
|
8205
8518
|
obligationUnits: BigInt(row.obligationUnits),
|
|
8206
8519
|
obligationShares: BigInt(row.obligationShares),
|
|
8207
8520
|
price: BigInt(row.price),
|
|
8208
|
-
maturity: from$
|
|
8521
|
+
maturity: from$16(row.maturity),
|
|
8209
8522
|
expiry: row.expiry,
|
|
8210
8523
|
start: row.start,
|
|
8211
8524
|
group: row.group,
|
|
@@ -8241,7 +8554,7 @@ function create$6(config) {
|
|
|
8241
8554
|
if ("hashes" in parameters) {
|
|
8242
8555
|
const { hashes } = parameters;
|
|
8243
8556
|
if (hashes.length === 0) return 0;
|
|
8244
|
-
const normalizedHashes = hashes.map((hash
|
|
8557
|
+
const normalizedHashes = hashes.map((hash) => hash.toLowerCase());
|
|
8245
8558
|
return (await db.delete(offers).where(inArray(offers.hash, normalizedHashes))).affectedRows;
|
|
8246
8559
|
}
|
|
8247
8560
|
if ("blockNumberGte" in parameters) {
|
|
@@ -8251,12 +8564,13 @@ function create$6(config) {
|
|
|
8251
8564
|
throw new Error("Invalid parameters");
|
|
8252
8565
|
},
|
|
8253
8566
|
getObligations: async (parameters) => {
|
|
8254
|
-
const { ids, chainId, loanToken, collateralToken, maturity:
|
|
8567
|
+
const { ids, chainId: chainIds, loanToken: loanTokens, collateralToken: collateralTokens, maturity: maturities, cursor, limit = DEFAULT_LIMIT$2 } = parameters ?? {};
|
|
8255
8568
|
const now$1 = now();
|
|
8256
|
-
const
|
|
8569
|
+
const loanTokenFilter = loanTokens !== void 0 && loanTokens.length > 0 ? sql`(${sql.join(loanTokens.map((token) => sql`LOWER(${obligations.loanToken}) = ${token.toLowerCase()}`), sql` OR `)})` : void 0;
|
|
8570
|
+
const collateralFilter = collateralTokens !== void 0 && collateralTokens.length > 0 ? sql`EXISTS (
|
|
8257
8571
|
SELECT 1 FROM ${obligationCollateralsV2} oc
|
|
8258
8572
|
WHERE oc.obligation_id = ${obligations.obligationId}
|
|
8259
|
-
AND LOWER(oc.asset) = ${
|
|
8573
|
+
AND (${sql.join(collateralTokens.map((token) => sql`LOWER(oc.asset) = ${token.toLowerCase()}`), sql` OR `)})
|
|
8260
8574
|
)` : void 0;
|
|
8261
8575
|
const result = await db.select({
|
|
8262
8576
|
obligationId: obligations.obligationId,
|
|
@@ -8265,15 +8579,15 @@ function create$6(config) {
|
|
|
8265
8579
|
collaterals: sql`ARRAY_AGG(jsonb_build_object('asset', ${obligationCollateralsV2.asset}, 'oracle', ${oracles.address}, 'lltv', ${obligationCollateralsV2.lltv}))`.as("collaterals"),
|
|
8266
8580
|
maturity: obligations.maturity
|
|
8267
8581
|
}).from(obligations).innerJoin(obligationCollateralsV2, eq(obligations.obligationId, obligationCollateralsV2.obligationId)).innerJoin(oracles, sql`${obligationCollateralsV2.oracleChainId} = ${oracles.chainId}
|
|
8268
|
-
AND ${obligationCollateralsV2.oracleAddress} = ${oracles.address}`).groupBy(obligations.obligationId).where(and(cursor !== null && cursor !== void 0 ? gt(obligations.obligationId, cursor) : sql`true`, ids !== void 0 && ids.length > 0 ? inArray(obligations.obligationId, ids) : void 0,
|
|
8582
|
+
AND ${obligationCollateralsV2.oracleAddress} = ${oracles.address}`).groupBy(obligations.obligationId).where(and(cursor !== null && cursor !== void 0 ? gt(obligations.obligationId, cursor) : sql`true`, ids !== void 0 && ids.length > 0 ? inArray(obligations.obligationId, ids) : void 0, chainIds !== void 0 && chainIds.length > 0 ? inArray(obligations.chainId, chainIds) : void 0, loanTokenFilter, maturities !== void 0 && maturities.length > 0 ? inArray(obligations.maturity, maturities) : gte(obligations.maturity, now$1), collateralFilter)).orderBy(asc(obligations.obligationId)).limit(limit);
|
|
8269
8583
|
const items = [];
|
|
8270
|
-
for (const row of result) items.push(from$
|
|
8584
|
+
for (const row of result) items.push(from$15({
|
|
8271
8585
|
chainId: row.chainId,
|
|
8272
8586
|
loanToken: row.loanToken,
|
|
8273
|
-
collaterals: row.collaterals.sort((a, b) => a.asset.localeCompare(b.asset)).map((c) => from$
|
|
8587
|
+
collaterals: row.collaterals.sort((a, b) => a.asset.localeCompare(b.asset)).map((c) => from$17({
|
|
8274
8588
|
asset: c.asset,
|
|
8275
8589
|
oracle: c.oracle,
|
|
8276
|
-
lltv: from$
|
|
8590
|
+
lltv: from$18(BigInt(c.lltv))
|
|
8277
8591
|
})),
|
|
8278
8592
|
maturity: row.maturity
|
|
8279
8593
|
}));
|
|
@@ -8286,11 +8600,11 @@ function create$6(config) {
|
|
|
8286
8600
|
getQuotes: async (parameters) => {
|
|
8287
8601
|
const { obligationIds } = parameters;
|
|
8288
8602
|
if (obligationIds.length === 0) return [];
|
|
8289
|
-
const now$
|
|
8603
|
+
const now$2 = now();
|
|
8290
8604
|
const query = ({ side }) => db.selectDistinctOn([offers.obligationId], {
|
|
8291
8605
|
obligationId: offers.obligationId,
|
|
8292
8606
|
price: offers.price
|
|
8293
|
-
}).from(offers).innerJoin(groups, and(eq(offers.groupChainId, groups.chainId), eq(offers.groupMaker, groups.maker), eq(offers.group, groups.group))).leftJoin(validations, eq(offers.hash, validations.offerHash)).leftJoin(status, eq(validations.statusId, status.id)).where(and(inArray(offers.obligationId, obligationIds), eq(offers.buy, side === "buy"), gte(offers.expiry, now$
|
|
8607
|
+
}).from(offers).innerJoin(groups, and(eq(offers.groupChainId, groups.chainId), eq(offers.groupMaker, groups.maker), eq(offers.group, groups.group))).leftJoin(validations, eq(offers.hash, validations.offerHash)).leftJoin(status, eq(validations.statusId, status.id)).where(and(inArray(offers.obligationId, obligationIds), eq(offers.buy, side === "buy"), gte(offers.expiry, now$2), gte(offers.maturity, now$2), lte(offers.start, now$2), sql`(${status.code} IS NULL OR ${status.code} = ${Status.VALID})`)).orderBy(offers.obligationId, side === "buy" ? sql`${offers.price}::numeric ASC` : sql`${offers.price}::numeric DESC`);
|
|
8294
8608
|
const [bestBuys, bestSells] = await Promise.all([query({ side: "buy" }), query({ side: "sell" })]);
|
|
8295
8609
|
const quotes = /* @__PURE__ */ new Map();
|
|
8296
8610
|
for (const row of bestSells) quotes.set(row.obligationId, {
|
|
@@ -8308,9 +8622,9 @@ function create$6(config) {
|
|
|
8308
8622
|
}
|
|
8309
8623
|
quote.bid = { price: BigInt(row.price) };
|
|
8310
8624
|
}
|
|
8311
|
-
return Array.from(quotes.entries()).map(([id
|
|
8312
|
-
return from$
|
|
8313
|
-
obligationId: id
|
|
8625
|
+
return Array.from(quotes.entries()).map(([id, quote]) => {
|
|
8626
|
+
return from$10({
|
|
8627
|
+
obligationId: id,
|
|
8314
8628
|
ask: quote.ask,
|
|
8315
8629
|
bid: quote.bid
|
|
8316
8630
|
});
|
|
@@ -8351,7 +8665,7 @@ function create$4(db) {
|
|
|
8351
8665
|
price: oracles.price,
|
|
8352
8666
|
blockNumber: oracles.blockNumber,
|
|
8353
8667
|
chainId: oracles.chainId
|
|
8354
|
-
}).from(oracles).where(eq(oracles.chainId, chainId))).map((r) => from$
|
|
8668
|
+
}).from(oracles).where(eq(oracles.chainId, chainId))).map((r) => from$12({
|
|
8355
8669
|
chainId: r.chainId,
|
|
8356
8670
|
address: r.address,
|
|
8357
8671
|
price: r.price,
|
|
@@ -8367,7 +8681,7 @@ function create$4(db) {
|
|
|
8367
8681
|
blockNumber: o.blockNumber
|
|
8368
8682
|
}));
|
|
8369
8683
|
db.transaction(async (dbTx) => {
|
|
8370
|
-
for (const batch
|
|
8684
|
+
for (const batch of batch$1(rows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(oracles).values(batch).onConflictDoUpdate({
|
|
8371
8685
|
target: [oracles.chainId, oracles.address],
|
|
8372
8686
|
set: {
|
|
8373
8687
|
price: sql`EXCLUDED.price`,
|
|
@@ -8418,8 +8732,8 @@ const create$3 = (db) => {
|
|
|
8418
8732
|
};
|
|
8419
8733
|
});
|
|
8420
8734
|
let totalUpdated = 0;
|
|
8421
|
-
for (const batch
|
|
8422
|
-
const updated = await db.insert(positions).values(batch
|
|
8735
|
+
for (const batch of batch$1(rows, DEFAULT_BATCH_SIZE$1)) {
|
|
8736
|
+
const updated = await db.insert(positions).values(batch).onConflictDoUpdate({
|
|
8423
8737
|
target: [
|
|
8424
8738
|
positions.chainId,
|
|
8425
8739
|
positions.contract,
|
|
@@ -8449,20 +8763,20 @@ const create$3 = (db) => {
|
|
|
8449
8763
|
user: parsed.user
|
|
8450
8764
|
};
|
|
8451
8765
|
}
|
|
8452
|
-
const positions$
|
|
8766
|
+
const positions$2 = await db.select().from(positions).where(and(ne(positions.user, zeroAddress), filled === void 0 ? sql`true` : sql`${positions.balance} IS ${filled === true ? sql`NOT` : sql``} NULL`, type !== void 0 ? eq(positions.positionTypeId, Object.values(Type).indexOf(type) + 1) : sql`true`, chainId !== void 0 ? eq(positions.chainId, chainId) : sql`true`, (() => {
|
|
8453
8767
|
if (cursor === null || cursor === void 0) return sql`true`;
|
|
8454
8768
|
return sql`
|
|
8455
8769
|
(${chainId === void 0 ? sql`"chain_id", ` : sql``}"contract", "user") > (${chainId === void 0 ? sql`${cursor.chainId}, ` : sql``}${cursor.contract}, ${cursor.user})
|
|
8456
8770
|
`;
|
|
8457
8771
|
})())).orderBy(asc(positions.chainId), asc(positions.contract), asc(positions.user), asc(positions.blockNumber)).limit(limit);
|
|
8458
|
-
const nextCursor = positions$
|
|
8459
|
-
chainId: positions$
|
|
8460
|
-
contract: positions$
|
|
8461
|
-
user: positions$
|
|
8462
|
-
blockNumber: positions$
|
|
8772
|
+
const nextCursor = positions$2.length === limit ? Buffer.from(JSON.stringify({
|
|
8773
|
+
chainId: positions$2[positions$2.length - 1].chainId.toString(),
|
|
8774
|
+
contract: positions$2[positions$2.length - 1].contract,
|
|
8775
|
+
user: positions$2[positions$2.length - 1].user,
|
|
8776
|
+
blockNumber: positions$2[positions$2.length - 1].blockNumber.toString()
|
|
8463
8777
|
})).toString("base64url") : null;
|
|
8464
8778
|
return {
|
|
8465
|
-
positions: positions$
|
|
8779
|
+
positions: positions$2.map((p) => ({
|
|
8466
8780
|
chainId: p.chainId,
|
|
8467
8781
|
contract: p.contract,
|
|
8468
8782
|
user: p.user,
|
|
@@ -8741,7 +9055,7 @@ function create$1(config) {
|
|
|
8741
9055
|
treeRoot: root,
|
|
8742
9056
|
proofNodes: concatenateProofs(proof.path)
|
|
8743
9057
|
}));
|
|
8744
|
-
for (const batch
|
|
9058
|
+
for (const batch of batch$1(pathRows, DEFAULT_BATCH_SIZE$1)) await dbTx.insert(merklePaths).values(batch).onConflictDoUpdate({
|
|
8745
9059
|
target: [merklePaths.offerHash],
|
|
8746
9060
|
set: {
|
|
8747
9061
|
treeRoot: sql`excluded.tree_root`,
|
|
@@ -8776,9 +9090,9 @@ function create$1(config) {
|
|
|
8776
9090
|
* Concatenates an array of 32-byte hex hashes into a single hex string.
|
|
8777
9091
|
* Empty arrays return "0x".
|
|
8778
9092
|
*/
|
|
8779
|
-
function concatenateProofs(proofs
|
|
8780
|
-
if (proofs
|
|
8781
|
-
return `0x${proofs
|
|
9093
|
+
function concatenateProofs(proofs) {
|
|
9094
|
+
if (proofs.length === 0) return "0x";
|
|
9095
|
+
return `0x${proofs.map((p) => p.slice(2)).join("")}`;
|
|
8782
9096
|
}
|
|
8783
9097
|
/**
|
|
8784
9098
|
* Splits a concatenated hex string back into an array of 32-byte hex hashes.
|
|
@@ -8786,10 +9100,10 @@ function concatenateProofs(proofs$1) {
|
|
|
8786
9100
|
*/
|
|
8787
9101
|
function splitProofs(concatenated) {
|
|
8788
9102
|
if (!concatenated || concatenated === "0x" || concatenated.length <= 2) return [];
|
|
8789
|
-
const hex
|
|
8790
|
-
const proofs
|
|
8791
|
-
for (let i = 0; i < hex
|
|
8792
|
-
return proofs
|
|
9103
|
+
const hex = concatenated.slice(2);
|
|
9104
|
+
const proofs = [];
|
|
9105
|
+
for (let i = 0; i < hex.length; i += 64) proofs.push(`0x${hex.slice(i, i + 64)}`);
|
|
9106
|
+
return proofs;
|
|
8793
9107
|
}
|
|
8794
9108
|
|
|
8795
9109
|
//#endregion
|
|
@@ -8824,7 +9138,7 @@ function create(db) {
|
|
|
8824
9138
|
upsert: async (results) => {
|
|
8825
9139
|
if (results.length === 0) return;
|
|
8826
9140
|
const allowedStatuses = new Set(Object.values(Status));
|
|
8827
|
-
const invalidStatuses = Array.from(new Set(results.map((r) => r.status).filter((s
|
|
9141
|
+
const invalidStatuses = Array.from(new Set(results.map((r) => r.status).filter((s) => !allowedStatuses.has(s))));
|
|
8828
9142
|
if (invalidStatuses.length > 0) throw new Error(`Unknown validation status: ${invalidStatuses.join(", ")}`);
|
|
8829
9143
|
const normalized = results.map((r) => ({
|
|
8830
9144
|
offerHash: r.offerHash.toLowerCase(),
|
|
@@ -8836,12 +9150,12 @@ function create(db) {
|
|
|
8836
9150
|
code: status.code
|
|
8837
9151
|
}).from(status).where(inArray(status.code, uniqueStatuses));
|
|
8838
9152
|
const statusMap = new Map(statusRows.map((row) => [row.code, row.id]));
|
|
8839
|
-
for (const status
|
|
9153
|
+
for (const status of uniqueStatuses) if (!statusMap.has(status)) throw new Error(`Unknown validation status: ${status}`);
|
|
8840
9154
|
const values = normalized.map((row) => ({
|
|
8841
9155
|
offerHash: row.offerHash,
|
|
8842
9156
|
statusId: statusMap.get(row.status)
|
|
8843
9157
|
}));
|
|
8844
|
-
for (const batch
|
|
9158
|
+
for (const batch of batch$1(values, DEFAULT_BATCH_SIZE$1)) await db.insert(validations).values(batch).onConflictDoUpdate({
|
|
8845
9159
|
target: [validations.offerHash],
|
|
8846
9160
|
set: {
|
|
8847
9161
|
statusId: sql`excluded.status_id`,
|
|
@@ -8854,7 +9168,7 @@ function create(db) {
|
|
|
8854
9168
|
|
|
8855
9169
|
//#endregion
|
|
8856
9170
|
//#region src/database/Database.ts
|
|
8857
|
-
var Database_exports = /* @__PURE__ */
|
|
9171
|
+
var Database_exports = /* @__PURE__ */ __exportAll({ connect: () => connect$1 });
|
|
8858
9172
|
function createDomains(core, chainRegistry) {
|
|
8859
9173
|
return {
|
|
8860
9174
|
book: create$10({ db: core }),
|
|
@@ -8877,12 +9191,12 @@ function createDomains(core, chainRegistry) {
|
|
|
8877
9191
|
};
|
|
8878
9192
|
}
|
|
8879
9193
|
const AUGMENT_CACHE = /* @__PURE__ */ new WeakMap();
|
|
8880
|
-
function augmentWithDomains(base
|
|
8881
|
-
const cached = AUGMENT_CACHE.get(base
|
|
9194
|
+
function augmentWithDomains(base, chainRegistry) {
|
|
9195
|
+
const cached = AUGMENT_CACHE.get(base)?.get(chainRegistry);
|
|
8882
9196
|
if (cached) return cached;
|
|
8883
|
-
const wrapped = Object.create(base
|
|
9197
|
+
const wrapped = Object.create(base);
|
|
8884
9198
|
wrapped.transaction = async (fn) => {
|
|
8885
|
-
return base
|
|
9199
|
+
return base.transaction(async (tx) => {
|
|
8886
9200
|
return fn(augmentWithDomains(tx, chainRegistry));
|
|
8887
9201
|
});
|
|
8888
9202
|
};
|
|
@@ -8933,8 +9247,8 @@ function augmentWithDomains(base$1, chainRegistry) {
|
|
|
8933
9247
|
enumerable: true
|
|
8934
9248
|
}
|
|
8935
9249
|
});
|
|
8936
|
-
const chainRegistryMap = AUGMENT_CACHE.get(base
|
|
8937
|
-
if (!chainRegistryMap) AUGMENT_CACHE.set(base
|
|
9250
|
+
const chainRegistryMap = AUGMENT_CACHE.get(base);
|
|
9251
|
+
if (!chainRegistryMap) AUGMENT_CACHE.set(base, new Map([[chainRegistry, wrapped]]));
|
|
8938
9252
|
else chainRegistryMap.set(chainRegistry, wrapped);
|
|
8939
9253
|
return wrapped;
|
|
8940
9254
|
}
|
|
@@ -8946,22 +9260,23 @@ const InMemoryDbMap = /* @__PURE__ */ new Map();
|
|
|
8946
9260
|
* @returns The database client {@link connect.ReturnType}
|
|
8947
9261
|
*/
|
|
8948
9262
|
function connect$1(chainRegistry, connectionString) {
|
|
8949
|
-
const clean = async (driver
|
|
9263
|
+
const clean = async (driver) => {
|
|
8950
9264
|
if (TABLE_NAMES.length === 0) return;
|
|
8951
|
-
await driver
|
|
9265
|
+
await driver.execute(`TRUNCATE TABLE ${VERSIONED_TABLE_NAMES.join(", ")} RESTART IDENTITY CASCADE;`);
|
|
8952
9266
|
};
|
|
8953
9267
|
if (connectionString !== void 0) {
|
|
8954
|
-
const pool
|
|
8955
|
-
const driver
|
|
8956
|
-
const core
|
|
8957
|
-
return Object.assign(core
|
|
9268
|
+
const pool = new Pool({ connectionString });
|
|
9269
|
+
const driver = drizzle(pool, { schema: schema_exports });
|
|
9270
|
+
const core = augmentWithDomains(driver, chainRegistry);
|
|
9271
|
+
return Object.assign(core, {
|
|
8958
9272
|
name: "pg",
|
|
8959
|
-
pool
|
|
8960
|
-
applyMigrations: applyMigrations("pg", driver
|
|
8961
|
-
clean: async () => await clean(driver
|
|
9273
|
+
pool,
|
|
9274
|
+
applyMigrations: applyMigrations("pg", driver),
|
|
9275
|
+
clean: async () => await clean(driver)
|
|
8962
9276
|
});
|
|
8963
9277
|
}
|
|
8964
|
-
const
|
|
9278
|
+
const poolId = process.env.VITEST_POOL_ID ?? "";
|
|
9279
|
+
const key = crypto.createHash("md5").update(JSON.stringify(chainRegistry.list()) + poolId).digest("hex");
|
|
8965
9280
|
const cached = InMemoryDbMap.get(key);
|
|
8966
9281
|
if (cached) return cached;
|
|
8967
9282
|
const pool = new PGlite();
|
|
@@ -9324,9 +9639,9 @@ function from(parameters) {
|
|
|
9324
9639
|
blockWindow: parameters.blockWindow
|
|
9325
9640
|
};
|
|
9326
9641
|
return {
|
|
9327
|
-
add: (parameters
|
|
9328
|
-
get: (parameters
|
|
9329
|
-
stream: (parameters
|
|
9642
|
+
add: (parameters) => add(config, parameters),
|
|
9643
|
+
get: (parameters) => get(config, parameters),
|
|
9644
|
+
stream: (parameters) => streamOffers(config, parameters)
|
|
9330
9645
|
};
|
|
9331
9646
|
}
|
|
9332
9647
|
/**
|
|
@@ -9336,9 +9651,9 @@ function from(parameters) {
|
|
|
9336
9651
|
* @throws ViemClientError if the viem client throws an error.
|
|
9337
9652
|
* @throws Offer.InvalidOfferError if the offer is invalid.
|
|
9338
9653
|
*/
|
|
9339
|
-
async function add(config, offers
|
|
9654
|
+
async function add(config, offers) {
|
|
9340
9655
|
if (!config.client.account) throw new WalletAccountNotSetError();
|
|
9341
|
-
const tree = from$
|
|
9656
|
+
const tree = from$14(offers.map((o) => from$13(o)));
|
|
9342
9657
|
const chainId = await getChainId(config.client);
|
|
9343
9658
|
for (const offer of tree.offers) if (chainId !== offer.chainId) throw new ChainIdMismatchError(offer.chainId, chainId);
|
|
9344
9659
|
const signature = await sign(tree.offers, config.client);
|
|
@@ -9407,7 +9722,7 @@ async function* streamOffers(config, parameters) {
|
|
|
9407
9722
|
for await (const { logs, blockNumber: newBlockNumber } of stream) {
|
|
9408
9723
|
blockNumber = newBlockNumber;
|
|
9409
9724
|
if (logs.length === 0) continue;
|
|
9410
|
-
const offers
|
|
9725
|
+
const offers = [];
|
|
9411
9726
|
for (const log of logs) {
|
|
9412
9727
|
if (!log) continue;
|
|
9413
9728
|
const [payload] = decodeAbiParameters([{ type: "bytes" }], log.data);
|
|
@@ -9415,12 +9730,12 @@ async function* streamOffers(config, parameters) {
|
|
|
9415
9730
|
const { tree } = await decode$1(payload);
|
|
9416
9731
|
for (const offer of tree.offers) {
|
|
9417
9732
|
if (loanToken && offer.loanToken.toLowerCase() !== loanToken.toLowerCase()) continue;
|
|
9418
|
-
offers
|
|
9733
|
+
offers.push(offer);
|
|
9419
9734
|
}
|
|
9420
9735
|
} catch (_) {}
|
|
9421
9736
|
}
|
|
9422
9737
|
yield {
|
|
9423
|
-
offers
|
|
9738
|
+
offers,
|
|
9424
9739
|
blockNumber
|
|
9425
9740
|
};
|
|
9426
9741
|
}
|
|
@@ -9456,7 +9771,7 @@ function connect(parameters) {
|
|
|
9456
9771
|
|
|
9457
9772
|
//#endregion
|
|
9458
9773
|
//#region src/mempool/index.ts
|
|
9459
|
-
var mempool_exports = /* @__PURE__ */
|
|
9774
|
+
var mempool_exports = /* @__PURE__ */ __exportAll({
|
|
9460
9775
|
ChainIdMismatchError: () => ChainIdMismatchError,
|
|
9461
9776
|
ViemClientError: () => ViemClientError,
|
|
9462
9777
|
WalletAccountNotSetError: () => WalletAccountNotSetError,
|
|
@@ -9467,5 +9782,5 @@ var mempool_exports = /* @__PURE__ */ __export({
|
|
|
9467
9782
|
});
|
|
9468
9783
|
|
|
9469
9784
|
//#endregion
|
|
9470
|
-
export { Abi_exports as Abi, BookResponse_exports as BookResponse, BooksController, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainHealth, ChainRegistry_exports as ChainRegistry, ChainsHealthResponse, Collateral_exports as Collateral, CollectorHealth, CollectorsHealthResponse, ConfigController, Database_exports as Database, ERC4626_exports as ERC4626, Errors_exports as Errors, Format_exports as Format, GateConfig_exports as GateConfig, Gatekeeper_exports as Gatekeeper, Health_exports as Health, HealthController, Indexer_exports as Indexer, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Logger_exports as Logger, Maturity_exports as Maturity, mempool_exports as Mempool, Obligation_exports as Obligation, ObligationResponse_exports as ObligationResponse, ObligationsController, Offer_exports as Offer, OfferResponse_exports as OfferResponse, OffersController, drizzle_exports as OffersSchema, OpenApi, Oracle_exports as Oracle, Position_exports as Position, PositionResponse_exports as PositionResponse, Quote_exports as Quote, RouterApi_exports as RouterApi, Client_exports as RouterClient, RouterStatusResponse, Rules_exports as Rules, time_exports as Time, Transfer_exports as Transfer, Tree_exports as Tree, UsersController, utils_exports as Utils, ValidateController, Gate_exports as Validation, morphoRules, parse, safeParse };
|
|
9785
|
+
export { Abi_exports as Abi, BookResponse_exports as BookResponse, BooksController, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainHealth, ChainRegistry_exports as ChainRegistry, ChainsHealthResponse, Collateral_exports as Collateral, CollectorHealth, CollectorsHealthResponse, ConfigController, Database_exports as Database, ERC4626_exports as ERC4626, Errors_exports as Errors, Format_exports as Format, GateConfig_exports as GateConfig, Gatekeeper_exports as Gatekeeper, Client_exports as GatekeeperClient, Health_exports as Health, HealthController, Indexer_exports as Indexer, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Logger_exports as Logger, Maturity_exports as Maturity, mempool_exports as Mempool, Obligation_exports as Obligation, ObligationResponse_exports as ObligationResponse, ObligationsController, Offer_exports as Offer, OfferResponse_exports as OfferResponse, OffersController, drizzle_exports as OffersSchema, OpenApi, Oracle_exports as Oracle, Position_exports as Position, PositionResponse_exports as PositionResponse, Quote_exports as Quote, RouterApi_exports as RouterApi, Client_exports$1 as RouterClient, RouterStatusResponse, Rules_exports as Rules, time_exports as Time, TradingFee_exports as TradingFee, Transfer_exports as Transfer, Tree_exports as Tree, UsersController, utils_exports as Utils, ValidateController, Gate_exports as Validation, morphoRules, parse, safeParse };
|
|
9471
9786
|
//# sourceMappingURL=index.node.mjs.map
|