@morpho-dev/router 0.4.2 → 0.6.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.
@@ -5,21 +5,30 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (all) => {
8
+ var __exportAll = (all, symbols) => {
9
9
  let target = {};
10
- for (var name in all) __defProp(target, name, {
11
- get: all[name],
12
- enumerable: true
13
- });
10
+ for (var name in all) {
11
+ __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ }
16
+ if (symbols) {
17
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
18
+ }
14
19
  return target;
15
20
  };
16
- var __copyProps = (to, from$15, except, desc) => {
17
- if (from$15 && typeof from$15 === "object" || typeof from$15 === "function") for (var keys = __getOwnPropNames(from$15), i = 0, n = keys.length, key; i < n; i++) {
18
- key = keys[i];
19
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
20
- get: ((k) => from$15[k]).bind(null, key),
21
- enumerable: !(desc = __getOwnPropDesc(from$15, key)) || desc.enumerable
22
- });
21
+ var __copyProps = (to, from, except, desc) => {
22
+ if (from && typeof from === "object" || typeof from === "function") {
23
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
24
+ key = keys[i];
25
+ if (!__hasOwnProp.call(to, key) && key !== except) {
26
+ __defProp(to, key, {
27
+ get: ((k) => from[k]).bind(null, key),
28
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
29
+ });
30
+ }
31
+ }
23
32
  }
24
33
  return to;
25
34
  };
@@ -35,7 +44,7 @@ let viem_actions = require("viem/actions");
35
44
  let viem_chains = require("viem/chains");
36
45
  let zod = require("zod");
37
46
  zod = __toESM(zod);
38
- let __openzeppelin_merkle_tree = require("@openzeppelin/merkle-tree");
47
+ let _openzeppelin_merkle_tree = require("@openzeppelin/merkle-tree");
39
48
  let pako = require("pako");
40
49
  require("reflect-metadata");
41
50
  let openapi_metadata = require("openapi-metadata");
@@ -44,8 +53,8 @@ let openapi_fetch = require("openapi-fetch");
44
53
  openapi_fetch = __toESM(openapi_fetch);
45
54
 
46
55
  //#region src/api/Schema/BookResponse.ts
47
- var BookResponse_exports = /* @__PURE__ */ __export({ from: () => from$14 });
48
- function from$14(level) {
56
+ var BookResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$15 });
57
+ function from$15(level) {
49
58
  return {
50
59
  price: level.price.toString(),
51
60
  assets: level.assets.toString(),
@@ -89,14 +98,14 @@ const RouterStatusResponse = zod_v4.z.object({
89
98
 
90
99
  //#endregion
91
100
  //#region src/api/Schema/ObligationResponse.ts
92
- var ObligationResponse_exports = /* @__PURE__ */ __export({ from: () => from$13 });
101
+ var ObligationResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$14 });
93
102
  /**
94
103
  * Creates an `ObligationResponse` from a `Obligation`.
95
104
  * @constructor
96
105
  * @param obligation - {@link Obligation}
97
106
  * @returns The created `ObligationResponse`. {@link ObligationResponse}
98
107
  */
99
- function from$13(obligation, quote) {
108
+ function from$14(obligation, quote) {
100
109
  return {
101
110
  id: quote.obligationId,
102
111
  chain_id: obligation.chainId,
@@ -132,7 +141,7 @@ const MetaMorphoFactory = (0, viem.parseAbi)(["event CreateMetaMorpho(address in
132
141
 
133
142
  //#endregion
134
143
  //#region src/core/Abi/index.ts
135
- var Abi_exports = /* @__PURE__ */ __export({
144
+ var Abi_exports = /* @__PURE__ */ __exportAll({
136
145
  ERC4626: () => ERC4626,
137
146
  MetaMorpho: () => MetaMorpho,
138
147
  MetaMorphoFactory: () => MetaMorphoFactory,
@@ -283,41 +292,77 @@ const Morpho = [
283
292
 
284
293
  //#endregion
285
294
  //#region src/core/Callback.ts
286
- var Callback_exports = /* @__PURE__ */ __export({
287
- CallbackType: () => CallbackType,
295
+ var Callback_exports = /* @__PURE__ */ __exportAll({
296
+ Type: () => Type$1,
288
297
  decode: () => decode$2,
298
+ decodeBuyERC20: () => decodeBuyERC20,
289
299
  decodeBuyVaultV1Callback: () => decodeBuyVaultV1Callback,
290
300
  decodeSellERC20Callback: () => decodeSellERC20Callback,
291
301
  encode: () => encode$2,
302
+ encodeBuyERC20: () => encodeBuyERC20,
292
303
  encodeBuyVaultV1Callback: () => encodeBuyVaultV1Callback,
293
304
  encodeSellERC20Callback: () => encodeSellERC20Callback,
294
305
  isEmptyCallback: () => isEmptyCallback
295
306
  });
296
- let CallbackType = /* @__PURE__ */ function(CallbackType$1) {
297
- CallbackType$1["BuyWithEmptyCallback"] = "buy_with_empty_callback";
298
- CallbackType$1["BuyVaultV1Callback"] = "buy_vault_v1_callback";
299
- CallbackType$1["SellERC20Callback"] = "sell_erc20_callback";
300
- return CallbackType$1;
307
+ let Type$1 = /* @__PURE__ */ function(Type) {
308
+ Type["BuyWithEmptyCallback"] = "buy_with_empty_callback";
309
+ Type["BuyERC20"] = "buy_erc20";
310
+ Type["BuyVaultV1Callback"] = "buy_vault_v1_callback";
311
+ Type["SellERC20Callback"] = "sell_erc20_callback";
312
+ return Type;
301
313
  }({});
302
314
  const isEmptyCallback = (offer) => offer.callback.data === "0x";
303
315
  function decode$2(type, data) {
304
316
  switch (type) {
305
- case CallbackType.BuyVaultV1Callback: return decodeBuyVaultV1Callback(data);
306
- case CallbackType.SellERC20Callback: return decodeSellERC20Callback(data);
317
+ case Type$1.BuyERC20: return decodeBuyERC20(data);
318
+ case Type$1.BuyVaultV1Callback: return decodeBuyVaultV1Callback(data);
319
+ case Type$1.SellERC20Callback: return decodeSellERC20Callback(data);
307
320
  default: throw new Error("Invalid callback type");
308
321
  }
309
322
  }
310
323
  function encode$2(type, data) {
311
324
  switch (type) {
312
- case CallbackType.BuyVaultV1Callback:
325
+ case Type$1.BuyERC20:
326
+ if (!("tokens" in data)) throw new Error("Invalid callback data");
327
+ return encodeBuyERC20(data);
328
+ case Type$1.BuyVaultV1Callback:
313
329
  if (!("vaults" in data)) throw new Error("Invalid callback data");
314
330
  return encodeBuyVaultV1Callback(data);
315
- case CallbackType.SellERC20Callback:
331
+ case Type$1.SellERC20Callback:
316
332
  if (!("collaterals" in data)) throw new Error("Invalid callback data");
317
333
  return encodeSellERC20Callback(data);
318
334
  default: throw new Error("Invalid callback type");
319
335
  }
320
336
  }
337
+ /**
338
+ * Decodes BuyERC20 callback data into positions.
339
+ * @param data - The ABI-encoded callback data containing token addresses and amounts.
340
+ * @returns Array of positions with contract address and amount.
341
+ * @throws If data is empty, malformed, or arrays have mismatched lengths.
342
+ */
343
+ function decodeBuyERC20(data) {
344
+ if (!data || data === "0x") throw new Error("Empty callback data");
345
+ let tokens;
346
+ let amounts;
347
+ try {
348
+ [tokens, amounts] = (0, viem.decodeAbiParameters)([{ type: "address[]" }, { type: "uint256[]" }], data);
349
+ } catch (_) {
350
+ throw new Error("Invalid BuyERC20 callback data");
351
+ }
352
+ if (tokens.length !== amounts.length) throw new Error("Mismatched array lengths");
353
+ return tokens.map((token, index) => ({
354
+ contract: token,
355
+ amount: amounts[index]
356
+ }));
357
+ }
358
+ /**
359
+ * Encodes BuyERC20 callback parameters into ABI-encoded data.
360
+ * @param parameters - The tokens and amounts to encode.
361
+ * @returns ABI-encoded hex string.
362
+ */
363
+ function encodeBuyERC20(parameters) {
364
+ return (0, viem.encodeAbiParameters)([{ type: "address[]" }, { type: "uint256[]" }], [parameters.tokens, parameters.amounts]);
365
+ }
321
366
  function decodeBuyVaultV1Callback(data) {
322
367
  if (!data || data === "0x") throw new Error("Empty callback data");
323
368
  try {
@@ -392,23 +437,23 @@ function atMostOneNonZero(...values) {
392
437
  * // [5]
393
438
  * ```
394
439
  */
395
- function* batch(array, batchSize) {
440
+ function* batch$1(array, batchSize) {
396
441
  for (let i = 0; i < array.length; i += batchSize) yield array.slice(i, i + batchSize);
397
442
  }
398
443
 
399
444
  //#endregion
400
- //#region \0@oxc-project+runtime@0.97.0/helpers/typeof.js
445
+ //#region \0@oxc-project+runtime@0.110.0/helpers/typeof.js
401
446
  function _typeof(o) {
402
447
  "@babel/helpers - typeof";
403
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
404
- return typeof o$1;
405
- } : function(o$1) {
406
- return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
448
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
449
+ return typeof o;
450
+ } : function(o) {
451
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
407
452
  }, _typeof(o);
408
453
  }
409
454
 
410
455
  //#endregion
411
- //#region \0@oxc-project+runtime@0.97.0/helpers/toPrimitive.js
456
+ //#region \0@oxc-project+runtime@0.110.0/helpers/toPrimitive.js
412
457
  function toPrimitive(t, r) {
413
458
  if ("object" != _typeof(t) || !t) return t;
414
459
  var e = t[Symbol.toPrimitive];
@@ -421,14 +466,14 @@ function toPrimitive(t, r) {
421
466
  }
422
467
 
423
468
  //#endregion
424
- //#region \0@oxc-project+runtime@0.97.0/helpers/toPropertyKey.js
469
+ //#region \0@oxc-project+runtime@0.110.0/helpers/toPropertyKey.js
425
470
  function toPropertyKey(t) {
426
471
  var i = toPrimitive(t, "string");
427
472
  return "symbol" == _typeof(i) ? i : i + "";
428
473
  }
429
474
 
430
475
  //#endregion
431
- //#region \0@oxc-project+runtime@0.97.0/helpers/defineProperty.js
476
+ //#region \0@oxc-project+runtime@0.110.0/helpers/defineProperty.js
432
477
  function _defineProperty(e, r, t) {
433
478
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
434
479
  value: t,
@@ -440,7 +485,7 @@ function _defineProperty(e, r, t) {
440
485
 
441
486
  //#endregion
442
487
  //#region src/utils/Errors.ts
443
- var Errors_exports = /* @__PURE__ */ __export({
488
+ var Errors_exports = /* @__PURE__ */ __exportAll({
444
489
  BaseError: () => BaseError,
445
490
  ReorgError: () => ReorgError
446
491
  });
@@ -497,7 +542,7 @@ var ReorgError = class extends BaseError {
497
542
 
498
543
  //#endregion
499
544
  //#region src/core/Chain.ts
500
- var Chain_exports = /* @__PURE__ */ __export({
545
+ var Chain_exports = /* @__PURE__ */ __exportAll({
501
546
  ChainId: () => ChainId,
502
547
  InvalidBatchSizeError: () => InvalidBatchSizeError,
503
548
  InvalidBlockRangeError: () => InvalidBlockRangeError,
@@ -559,7 +604,8 @@ const chains$1 = {
559
604
  address: "0x1897A8997241C1cD4bD0698647e4EB7213535c24",
560
605
  blockCreated: 21439510
561
606
  }
562
- } }
607
+ } },
608
+ callbacks: []
563
609
  }
564
610
  },
565
611
  base: {
@@ -588,7 +634,8 @@ const chains$1 = {
588
634
  address: "0xFf62A7c278C62eD665133147129245053Bbf5918",
589
635
  blockCreated: 23928808
590
636
  }
591
- } }
637
+ } },
638
+ callbacks: []
592
639
  }
593
640
  },
594
641
  "ethereum-virtual-testnet": {
@@ -617,7 +664,8 @@ const chains$1 = {
617
664
  address: "0x1897A8997241C1cD4bD0698647e4EB7213535c24",
618
665
  blockCreated: 21439510
619
666
  }
620
- } }
667
+ } },
668
+ callbacks: []
621
669
  }
622
670
  },
623
671
  anvil: {
@@ -646,7 +694,8 @@ const chains$1 = {
646
694
  address: "0x0000000000000000000000000000000000000000",
647
695
  blockCreated: 0
648
696
  }
649
- } }
697
+ } },
698
+ callbacks: []
650
699
  }
651
700
  }
652
701
  };
@@ -691,7 +740,7 @@ async function* streamLogs(parameters) {
691
740
  if (a.transactionIndex !== b.transactionIndex) return order === "asc" ? a.transactionIndex - b.transactionIndex : b.transactionIndex - a.transactionIndex;
692
741
  return order === "asc" ? a.logIndex - b.logIndex : b.logIndex - a.logIndex;
693
742
  });
694
- for (const logBatch of batch(logs, maxBatchSize)) yield {
743
+ for (const logBatch of batch$1(logs, maxBatchSize)) yield {
695
744
  logs: logBatch,
696
745
  blockNumber: logBatch.length === maxBatchSize ? Number(logBatch[logBatch.length - 1]?.blockNumber) : order === "asc" ? Number(toBlock) : Number(fromBlock)
697
746
  };
@@ -742,10 +791,15 @@ var MissingBlockNumberError = class extends BaseError {
742
791
 
743
792
  //#endregion
744
793
  //#region src/core/ChainRegistry.ts
745
- var ChainRegistry_exports = /* @__PURE__ */ __export({ create: () => create$1 });
746
- function create$1(chains$2) {
794
+ var ChainRegistry_exports = /* @__PURE__ */ __exportAll({ create: () => create$1 });
795
+ /**
796
+ * Creates a chain registry from a list of chains.
797
+ * @param chains - Array of chain objects to register.
798
+ * @returns A registry for looking up chains by ID. {@link ChainRegistry}
799
+ */
800
+ function create$1(chains) {
747
801
  const byId = /* @__PURE__ */ new Map();
748
- for (const chain of chains$2) byId.set(chain.id, chain);
802
+ for (const chain of chains) byId.set(chain.id, chain);
749
803
  return {
750
804
  getById: (chainId) => byId.get(chainId),
751
805
  list: () => Array.from(byId.values())
@@ -754,7 +808,7 @@ function create$1(chains$2) {
754
808
 
755
809
  //#endregion
756
810
  //#region src/utils/Random.ts
757
- var Random_exports = /* @__PURE__ */ __export({
811
+ var Random_exports = /* @__PURE__ */ __exportAll({
758
812
  address: () => address,
759
813
  bool: () => bool,
760
814
  bytes: () => bytes,
@@ -767,16 +821,16 @@ var Random_exports = /* @__PURE__ */ __export({
767
821
  let currentRng = Math.random;
768
822
  const FNV_OFFSET_BASIS = 2166136261;
769
823
  const FNV_PRIME = 16777619;
770
- const hashSeed = (seed$1) => {
771
- let hash$1 = FNV_OFFSET_BASIS;
772
- for (let i = 0; i < seed$1.length; i += 1) {
773
- hash$1 ^= seed$1.charCodeAt(i);
774
- hash$1 = Math.imul(hash$1, FNV_PRIME);
824
+ const hashSeed = (seed) => {
825
+ let hash = FNV_OFFSET_BASIS;
826
+ for (let i = 0; i < seed.length; i += 1) {
827
+ hash ^= seed.charCodeAt(i);
828
+ hash = Math.imul(hash, FNV_PRIME);
775
829
  }
776
- return hash$1 >>> 0;
830
+ return hash >>> 0;
777
831
  };
778
- const createSeededRng = (seed$1) => {
779
- let state = hashSeed(seed$1);
832
+ const createSeededRng = (seed) => {
833
+ let state = hashSeed(seed);
780
834
  return () => {
781
835
  state += 1831565813;
782
836
  let t = Math.imul(state ^ state >>> 15, state | 1);
@@ -787,9 +841,9 @@ const createSeededRng = (seed$1) => {
787
841
  /**
788
842
  * Runs a function with a deterministic RNG derived from the given seed.
789
843
  */
790
- function withSeed(seed$1, fn) {
844
+ function withSeed(seed, fn) {
791
845
  const previous = currentRng;
792
- currentRng = createSeededRng(seed$1);
846
+ currentRng = createSeededRng(seed);
793
847
  try {
794
848
  return fn();
795
849
  } finally {
@@ -799,8 +853,8 @@ function withSeed(seed$1, fn) {
799
853
  /**
800
854
  * Seeds the global RNG for deterministic test runs.
801
855
  */
802
- function seed(seed$1) {
803
- currentRng = createSeededRng(seed$1);
856
+ function seed(seed) {
857
+ currentRng = createSeededRng(seed);
804
858
  }
805
859
  /**
806
860
  * Returns a deterministic random float in [0, 1).
@@ -811,8 +865,8 @@ function float() {
811
865
  /**
812
866
  * Returns a deterministic random integer in [min, maxExclusive).
813
867
  */
814
- function int(maxExclusive, min$1 = 0) {
815
- return Math.floor(float() * (maxExclusive - min$1)) + min$1;
868
+ function int(maxExclusive, min = 0) {
869
+ return Math.floor(float() * (maxExclusive - min)) + min;
816
870
  }
817
871
  /**
818
872
  * Returns a deterministic random boolean.
@@ -925,12 +979,12 @@ const transformAddress = (val, ctx) => {
925
979
 
926
980
  //#endregion
927
981
  //#region src/core/LLTV.ts
928
- var LLTV_exports = /* @__PURE__ */ __export({
982
+ var LLTV_exports = /* @__PURE__ */ __exportAll({
929
983
  InvalidLLTVError: () => InvalidLLTVError,
930
984
  InvalidOptionError: () => InvalidOptionError$1,
931
985
  LLTVSchema: () => LLTVSchema,
932
986
  Options: () => Options,
933
- from: () => from$12
987
+ from: () => from$13
934
988
  });
935
989
  const Options = [
936
990
  .385,
@@ -949,7 +1003,7 @@ const LLTV_SCALED = Options.map((lltv) => BigInt(lltv * 10 ** 18));
949
1003
  * @param lltv - The LLTV option or the scaled LLTV.
950
1004
  * @returns The LLTV.
951
1005
  */
952
- function from$12(lltv) {
1006
+ function from$13(lltv) {
953
1007
  if (typeof lltv === "bigint" && !LLTV_SCALED.includes(lltv)) throw new InvalidLLTVError(lltv);
954
1008
  if (typeof lltv === "bigint") return lltv;
955
1009
  if (typeof lltv === "number" && !Options.includes(lltv)) throw new InvalidOptionError$1(lltv);
@@ -969,21 +1023,21 @@ var InvalidLLTVError = class extends BaseError {
969
1023
  };
970
1024
  const LLTVSchema = zod.bigint({ coerce: true }).refine((lltv) => {
971
1025
  try {
972
- from$12(lltv);
1026
+ from$13(lltv);
973
1027
  return true;
974
1028
  } catch (_) {
975
1029
  return false;
976
1030
  }
977
1031
  }, { error: () => {
978
1032
  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)";
979
- } }).transform((lltv) => from$12(lltv));
1033
+ } }).transform((lltv) => from$13(lltv));
980
1034
 
981
1035
  //#endregion
982
1036
  //#region src/core/Collateral.ts
983
- var Collateral_exports = /* @__PURE__ */ __export({
1037
+ var Collateral_exports = /* @__PURE__ */ __exportAll({
984
1038
  CollateralSchema: () => CollateralSchema,
985
1039
  CollateralsSchema: () => CollateralsSchema,
986
- from: () => from$11,
1040
+ from: () => from$12,
987
1041
  random: () => random$3
988
1042
  });
989
1043
  const CollateralSchema = zod.object({
@@ -1003,10 +1057,10 @@ const CollateralsSchema = zod.array(CollateralSchema).min(1, { message: "At leas
1003
1057
  }
1004
1058
  return true;
1005
1059
  }, { message: "Collaterals must not contain duplicate assets" });
1006
- const from$11 = (parameters) => {
1060
+ const from$12 = (parameters) => {
1007
1061
  return {
1008
1062
  asset: parameters.asset.toLowerCase(),
1009
- lltv: from$12(parameters.lltv),
1063
+ lltv: from$13(parameters.lltv),
1010
1064
  oracle: parameters.oracle.toLowerCase()
1011
1065
  };
1012
1066
  };
@@ -1020,7 +1074,7 @@ const from$11 = (parameters) => {
1020
1074
  * ```
1021
1075
  */
1022
1076
  function random$3() {
1023
- return from$11({
1077
+ return from$12({
1024
1078
  asset: address(),
1025
1079
  oracle: address(),
1026
1080
  lltv: .965
@@ -1029,7 +1083,7 @@ function random$3() {
1029
1083
 
1030
1084
  //#endregion
1031
1085
  //#region src/core/ERC4626.ts
1032
- var ERC4626_exports = /* @__PURE__ */ __export({
1086
+ var ERC4626_exports = /* @__PURE__ */ __exportAll({
1033
1087
  DenominatorIsZeroError: () => DenominatorIsZeroError,
1034
1088
  convertToAssets: () => convertToAssets,
1035
1089
  convertToShares: () => convertToShares,
@@ -1092,7 +1146,7 @@ var DenominatorIsZeroError = class extends BaseError {
1092
1146
 
1093
1147
  //#endregion
1094
1148
  //#region src/core/Liquidity.ts
1095
- var Liquidity_exports = /* @__PURE__ */ __export({
1149
+ var Liquidity_exports = /* @__PURE__ */ __exportAll({
1096
1150
  calculateMaxDebt: () => calculateMaxDebt,
1097
1151
  generateAllowancePoolId: () => generateAllowancePoolId,
1098
1152
  generateBalancePoolId: () => generateBalancePoolId,
@@ -1118,23 +1172,23 @@ function calculateMaxDebt(amount, oraclePrice, lltv) {
1118
1172
  * Generate pool ID for balance pools.
1119
1173
  */
1120
1174
  function generateBalancePoolId(parameters) {
1121
- const { user, chainId, token: token$1 } = parameters;
1122
- return `${user}-${chainId.toString()}-${token$1}-balance`.toLowerCase();
1175
+ const { user, chainId, token } = parameters;
1176
+ return `${user}-${chainId.toString()}-${token}-balance`.toLowerCase();
1123
1177
  }
1124
1178
  /**
1125
1179
  * Generate pool ID for allowance pools.
1126
1180
  */
1127
1181
  function generateAllowancePoolId(parameters) {
1128
- const { user, chainId, token: token$1 } = parameters;
1129
- return `${user}-${chainId.toString()}-${token$1}-allowance`.toLowerCase();
1182
+ const { user, chainId, token } = parameters;
1183
+ return `${user}-${chainId.toString()}-${token}-allowance`.toLowerCase();
1130
1184
  }
1131
1185
  /**
1132
1186
  * Generate pool ID for sell ERC20 callback pools.
1133
1187
  * Each offer has its own callback pool to prevent liquidity conflicts.
1134
1188
  */
1135
1189
  function generateSellERC20CallbackPoolId(parameters) {
1136
- const { user, chainId, obligationId: obligationId$1, token: token$1, offerHash } = parameters;
1137
- return `${user}-${chainId.toString()}-${obligationId$1}-${token$1}-${offerHash}-sell_erc20_callback`.toLowerCase();
1190
+ const { user, chainId, obligationId, token, offerHash } = parameters;
1191
+ return `${user}-${chainId.toString()}-${obligationId}-${token}-${offerHash}-sell_erc20_callback`.toLowerCase();
1138
1192
  }
1139
1193
  /**
1140
1194
  * Generate pool ID for obligation collateral pools.
@@ -1142,22 +1196,22 @@ function generateSellERC20CallbackPoolId(parameters) {
1142
1196
  * These pools are shared across all offers with the same obligation.
1143
1197
  */
1144
1198
  function generateObligationCollateralPoolId(parameters) {
1145
- const { user, chainId, obligationId: obligationId$1, token: token$1 } = parameters;
1146
- return `${user}-${chainId.toString()}-${obligationId$1}-${token$1}-obligation-collateral`.toLowerCase();
1199
+ const { user, chainId, obligationId, token } = parameters;
1200
+ return `${user}-${chainId.toString()}-${obligationId}-${token}-obligation-collateral`.toLowerCase();
1147
1201
  }
1148
1202
  /**
1149
1203
  * Generate pool ID for buy vault callback pools.
1150
1204
  */
1151
1205
  function generateBuyVaultCallbackPoolId(parameters) {
1152
1206
  const { user, chainId, vault, offerHash } = parameters;
1153
- return `${user}-${chainId.toString()}-${vault}-${offerHash}-${CallbackType.BuyVaultV1Callback}`.toLowerCase();
1207
+ return `${user}-${chainId.toString()}-${vault}-${offerHash}-${Type$1.BuyVaultV1Callback}`.toLowerCase();
1154
1208
  }
1155
1209
  /**
1156
1210
  * Generate pool ID for debt pools.
1157
1211
  */
1158
1212
  function generateDebtPoolId(parameters) {
1159
- const { user, chainId, obligationId: obligationId$1 } = parameters;
1160
- return `${user}-${chainId.toString()}-${obligationId$1}-debt`.toLowerCase();
1213
+ const { user, chainId, obligationId } = parameters;
1214
+ return `${user}-${chainId.toString()}-${obligationId}-debt`.toLowerCase();
1161
1215
  }
1162
1216
  /**
1163
1217
  * Generate pool ID for user position in a vault.
@@ -1183,17 +1237,17 @@ function generateMarketLiquidityPoolId(parameters) {
1183
1237
 
1184
1238
  //#endregion
1185
1239
  //#region src/core/Maturity.ts
1186
- var Maturity_exports = /* @__PURE__ */ __export({
1240
+ var Maturity_exports = /* @__PURE__ */ __exportAll({
1187
1241
  InvalidDateError: () => InvalidDateError,
1188
1242
  InvalidFormatError: () => InvalidFormatError,
1189
1243
  InvalidOptionError: () => InvalidOptionError,
1190
1244
  MaturitySchema: () => MaturitySchema,
1191
1245
  MaturityType: () => MaturityType,
1192
- from: () => from$10
1246
+ from: () => from$11
1193
1247
  });
1194
- const MaturitySchema = zod.number().int().refine((maturity$1) => {
1248
+ const MaturitySchema = zod.number().int().refine((maturity) => {
1195
1249
  try {
1196
- from$10(maturity$1);
1250
+ from$11(maturity);
1197
1251
  return true;
1198
1252
  } catch (_e) {
1199
1253
  return false;
@@ -1204,15 +1258,15 @@ const MaturitySchema = zod.number().int().refine((maturity$1) => {
1204
1258
  } catch (_) {
1205
1259
  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).`;
1206
1260
  }
1207
- } }).transform((maturity$1) => maturity$1);
1208
- let MaturityType = /* @__PURE__ */ function(MaturityType$1) {
1209
- MaturityType$1["EndOfWeek"] = "end_of_week";
1210
- MaturityType$1["EndOfNextWeek"] = "end_of_next_week";
1211
- MaturityType$1["EndOfMonth"] = "end_of_month";
1212
- MaturityType$1["EndOfNextMonth"] = "end_of_next_month";
1213
- MaturityType$1["EndOfQuarter"] = "end_of_quarter";
1214
- MaturityType$1["EndOfNextQuarter"] = "end_of_next_quarter";
1215
- return MaturityType$1;
1261
+ } }).transform((maturity) => maturity);
1262
+ let MaturityType = /* @__PURE__ */ function(MaturityType) {
1263
+ MaturityType["EndOfWeek"] = "end_of_week";
1264
+ MaturityType["EndOfNextWeek"] = "end_of_next_week";
1265
+ MaturityType["EndOfMonth"] = "end_of_month";
1266
+ MaturityType["EndOfNextMonth"] = "end_of_next_month";
1267
+ MaturityType["EndOfQuarter"] = "end_of_quarter";
1268
+ MaturityType["EndOfNextQuarter"] = "end_of_next_quarter";
1269
+ return MaturityType;
1216
1270
  }({});
1217
1271
  const MaturityOptions = {
1218
1272
  end_of_week: () => endOfWeek(),
@@ -1228,7 +1282,7 @@ const MaturityOptions = {
1228
1282
  * @throws {InvalidDateError} If the maturity is in seconds but not a valid date.
1229
1283
  * @throws {InvalidOptionError} If the maturity is not a valid option.
1230
1284
  */
1231
- function from$10(ts) {
1285
+ function from$11(ts) {
1232
1286
  if (typeof ts === "string") {
1233
1287
  if (ts in MaturityOptions) return MaturityOptions[ts]();
1234
1288
  throw new InvalidOptionError(ts);
@@ -1246,23 +1300,23 @@ const endOfNextWeek = () => fridayOfWeek(1);
1246
1300
  * on that Friday), roll to the next month's last Friday.
1247
1301
  */
1248
1302
  const endOfMonth = () => {
1249
- const now$1 = /* @__PURE__ */ new Date();
1250
- const year = now$1.getUTCFullYear();
1251
- const month = now$1.getUTCMonth();
1252
- const endOfMonth$1 = lastFridayOfMonth(year, month);
1253
- if (now$1.getTime() > endOfMonth$1 * 1e3) return lastFridayOfMonth(year, month + 1);
1254
- return endOfMonth$1;
1303
+ const now = /* @__PURE__ */ new Date();
1304
+ const year = now.getUTCFullYear();
1305
+ const month = now.getUTCMonth();
1306
+ const endOfMonth = lastFridayOfMonth(year, month);
1307
+ if (now.getTime() > endOfMonth * 1e3) return lastFridayOfMonth(year, month + 1);
1308
+ return endOfMonth;
1255
1309
  };
1256
1310
  /** Returns the end of the next month (last friday of the next month at 15:00:00 UTC)
1257
1311
  * Business rule: if we are after the last Friday of the current month (strictly after 15:00 UTC
1258
1312
  * on that Friday), we consider being in the next month already, so "next month" becomes month+2.
1259
1313
  */
1260
1314
  const endOfNextMonth = () => {
1261
- const now$1 = /* @__PURE__ */ new Date();
1262
- const year = now$1.getUTCFullYear();
1263
- const month = now$1.getUTCMonth();
1264
- const endOfMonth$1 = lastFridayOfMonth(year, month);
1265
- if (now$1.getTime() > endOfMonth$1 * 1e3) return lastFridayOfMonth(year, month + 2);
1315
+ const now = /* @__PURE__ */ new Date();
1316
+ const year = now.getUTCFullYear();
1317
+ const month = now.getUTCMonth();
1318
+ const endOfMonth = lastFridayOfMonth(year, month);
1319
+ if (now.getTime() > endOfMonth * 1e3) return lastFridayOfMonth(year, month + 2);
1266
1320
  return lastFridayOfMonth(year, month + 1);
1267
1321
  };
1268
1322
  /** Returns the end of the current quarter (last friday of the quarter at 15:00:00 UTC) */
@@ -1270,10 +1324,10 @@ const endOfQuarter = () => lastFridayOfQuarter(0);
1270
1324
  /** Returns the end of the next quarter (last friday of the next quarter at 15:00:00 UTC) */
1271
1325
  const endOfNextQuarter = () => lastFridayOfQuarter(1);
1272
1326
  const fridayOfWeek = (weeksAhead = 0) => {
1273
- const now$1 = /* @__PURE__ */ new Date();
1274
- const today15H = new Date(Date.UTC(now$1.getUTCFullYear(), now$1.getUTCMonth(), now$1.getUTCDate(), 15));
1327
+ const now = /* @__PURE__ */ new Date();
1328
+ const today15H = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 15));
1275
1329
  let daysUntilFriday = (5 - today15H.getUTCDay() + 7) % 7;
1276
- if (daysUntilFriday === 0 && now$1.getTime() >= today15H.getTime()) daysUntilFriday = 7;
1330
+ if (daysUntilFriday === 0 && now.getTime() >= today15H.getTime()) daysUntilFriday = 7;
1277
1331
  const friday = new Date(today15H);
1278
1332
  friday.setUTCDate(friday.getUTCDate() + daysUntilFriday + weeksAhead * 7);
1279
1333
  return friday.getTime() / 1e3;
@@ -1284,9 +1338,9 @@ const lastFridayOfMonth = (year, month) => {
1284
1338
  return lastDayOfMonth15H.setUTCDate(lastDayOfMonth15H.getUTCDate()) / 1e3;
1285
1339
  };
1286
1340
  const lastFridayOfQuarter = (quartersAhead = 0) => {
1287
- const now$1 = /* @__PURE__ */ new Date();
1288
- const quarterIndex = Math.floor(now$1.getUTCMonth() / 3) + quartersAhead;
1289
- return lastFridayOfMonth(now$1.getUTCFullYear() + Math.floor(quarterIndex / 4), quarterIndex % 4 * 3 + 2);
1341
+ const now = /* @__PURE__ */ new Date();
1342
+ const quarterIndex = Math.floor(now.getUTCMonth() / 3) + quartersAhead;
1343
+ return lastFridayOfMonth(now.getUTCFullYear() + Math.floor(quarterIndex / 4), quarterIndex % 4 * 3 + 2);
1290
1344
  };
1291
1345
  var InvalidFormatError = class extends BaseError {
1292
1346
  constructor() {
@@ -1309,7 +1363,7 @@ var InvalidOptionError = class extends BaseError {
1309
1363
 
1310
1364
  //#endregion
1311
1365
  //#region src/utils/Format.ts
1312
- var Format_exports = /* @__PURE__ */ __export({
1366
+ var Format_exports = /* @__PURE__ */ __exportAll({
1313
1367
  fromSnakeCase: () => fromSnakeCase$3,
1314
1368
  stringifyBigint: () => stringifyBigint,
1315
1369
  toSnakeCase: () => toSnakeCase$1
@@ -1354,11 +1408,12 @@ function stringifyBigint(value) {
1354
1408
 
1355
1409
  //#endregion
1356
1410
  //#region src/core/Obligation.ts
1357
- var Obligation_exports = /* @__PURE__ */ __export({
1411
+ var Obligation_exports = /* @__PURE__ */ __exportAll({
1358
1412
  CollateralsAreNotSortedError: () => CollateralsAreNotSortedError,
1359
1413
  InvalidObligationError: () => InvalidObligationError,
1360
1414
  ObligationSchema: () => ObligationSchema,
1361
- from: () => from$9,
1415
+ from: () => from$10,
1416
+ fromOffer: () => fromOffer$1,
1362
1417
  fromSnakeCase: () => fromSnakeCase$2,
1363
1418
  id: () => id,
1364
1419
  random: () => random$2
@@ -1392,11 +1447,11 @@ const ObligationSchema = zod.object({
1392
1447
  * });
1393
1448
  * ```
1394
1449
  */
1395
- function from$9(parameters) {
1450
+ function from$10(parameters) {
1396
1451
  try {
1397
1452
  const parsedObligation = ObligationSchema.parse({
1398
1453
  ...parameters,
1399
- maturity: from$10(parameters.maturity)
1454
+ maturity: from$11(parameters.maturity)
1400
1455
  });
1401
1456
  return {
1402
1457
  chainId: parsedObligation.chainId,
@@ -1415,7 +1470,7 @@ function from$9(parameters) {
1415
1470
  * @returns The created obligation. {@link fromSnakeCase.ReturnType}
1416
1471
  */
1417
1472
  function fromSnakeCase$2(input) {
1418
- return from$9(fromSnakeCase$3(input));
1473
+ return from$10(fromSnakeCase$3(input));
1419
1474
  }
1420
1475
  /**
1421
1476
  * Calculates the obligation id based on the smart contract's Obligation struct.
@@ -1480,11 +1535,26 @@ function id(parameters) {
1480
1535
  * ```
1481
1536
  */
1482
1537
  function random$2() {
1483
- return from$9({
1538
+ return from$10({
1484
1539
  chainId: 1,
1485
1540
  loanToken: address(),
1486
1541
  collaterals: [random$3()],
1487
- maturity: from$10("end_of_next_quarter")
1542
+ maturity: from$11("end_of_next_quarter")
1543
+ });
1544
+ }
1545
+ /**
1546
+ * Creates an obligation from an offer.
1547
+ * @constructor
1548
+ *
1549
+ * @param offer - The offer to create the obligation from.
1550
+ * @returns The created obligation. {@link fromOffer.ReturnType}
1551
+ */
1552
+ function fromOffer$1(offer) {
1553
+ return from$10({
1554
+ chainId: offer.chainId,
1555
+ loanToken: offer.loanToken,
1556
+ collaterals: offer.collaterals,
1557
+ maturity: offer.maturity
1488
1558
  });
1489
1559
  }
1490
1560
  var InvalidObligationError = class extends BaseError {
@@ -1500,282 +1570,31 @@ var CollateralsAreNotSortedError = class extends BaseError {
1500
1570
  }
1501
1571
  };
1502
1572
 
1503
- //#endregion
1504
- //#region src/core/Tree.ts
1505
- var Tree_exports = /* @__PURE__ */ __export({
1506
- DecodeError: () => DecodeError,
1507
- EncodeError: () => EncodeError,
1508
- TreeError: () => TreeError,
1509
- VERSION: () => VERSION,
1510
- decode: () => decode$1,
1511
- encode: () => encode$1,
1512
- encodeUnsigned: () => encodeUnsigned,
1513
- from: () => from$8,
1514
- proofs: () => proofs
1515
- });
1516
- const VERSION = 1;
1517
- const normalizeHash = (hash$1) => hash$1.toLowerCase();
1518
- /**
1519
- * Builds a Merkle tree from a list of offers.
1520
- *
1521
- * Leaves are the offer `hash` values as `bytes32` and are deterministically
1522
- * ordered following the StandardMerkleTree leaf ordering so that the resulting
1523
- * root is stable regardless of the input order.
1524
- *
1525
- * @param offers - Offers to include in the tree.
1526
- * @returns A `StandardMerkleTree` of `bytes32` leaves representing the offers.
1527
- * @throws {TreeError} If tree building fails due to offer inconsistencies.
1528
- */
1529
- const from$8 = (offers) => {
1530
- const leaves = offers.map((offer) => [hash(offer)]);
1531
- const tree = __openzeppelin_merkle_tree.StandardMerkleTree.of(leaves, ["bytes32"]);
1532
- const orderedOffers = orderOffers(tree, offers);
1533
- return Object.assign(tree, { offers: orderedOffers });
1534
- };
1535
- const orderOffers = (tree, offers) => {
1536
- const offerByHash = /* @__PURE__ */ new Map();
1537
- for (const offer of offers) offerByHash.set(normalizeHash(hash(offer)), offer);
1538
- const entries = tree.dump().values.map((value) => {
1539
- const hash$1 = normalizeHash(value.value[0]);
1540
- const offer = offerByHash.get(hash$1);
1541
- if (!offer) throw new TreeError(`missing offer for leaf ${hash$1}`);
1542
- return {
1543
- offer,
1544
- treeIndex: value.treeIndex
1545
- };
1546
- });
1547
- entries.sort((a, b) => b.treeIndex - a.treeIndex);
1548
- return entries.map((item) => item.offer);
1549
- };
1550
- /**
1551
- * Generates merkle proofs for all offers in a tree.
1552
- *
1553
- * Each proof allows independent verification that an offer is included in the tree
1554
- * without requiring the full tree. Proofs are ordered by StandardMerkleTree leaf ordering.
1555
- *
1556
- * @param tree - The {@link Tree} to generate proofs for.
1557
- * @returns Array of proofs - {@link Proof}
1558
- */
1559
- const proofs = (tree) => {
1560
- return tree.offers.map((offer) => {
1561
- return {
1562
- offer,
1563
- path: tree.getProof([hash(offer)])
1564
- };
1565
- });
1566
- };
1567
- const assertHex = (value, expectedBytes, name) => {
1568
- if (typeof value !== "string" || !(0, viem.isHex)(value)) throw new DecodeError(`${name} is not a valid hex string`);
1569
- if ((0, viem.hexToBytes)(value).length !== expectedBytes) throw new DecodeError(`${name}: expected ${expectedBytes} bytes`);
1570
- };
1571
- const verifySignatureAndRecoverAddress = async (params) => {
1572
- const { root, signature } = params;
1573
- assertHex(signature, 65, "signature");
1574
- const hash$1 = (0, viem.hashMessage)({ raw: root });
1575
- try {
1576
- return await (0, viem.recoverAddress)({
1577
- hash: hash$1,
1578
- signature
1579
- });
1580
- } catch {
1581
- throw new DecodeError("signature recovery failed");
1582
- }
1583
- };
1584
- /**
1585
- * Encodes a merkle tree with signature into hex calldata for onchain broadcast.
1586
- *
1587
- * Layout: `0x{vv}{gzip([...offers])}{root}{signature}` where:
1588
- * - `{vv}`: 1-byte version (currently 0x01)
1589
- * - `{gzip([...offers])}`: gzipped JSON array of serialized offers
1590
- * - `{root}`: 32-byte merkle root
1591
- * - `{signature}`: 65-byte EIP-191 signature over raw root bytes
1592
- *
1593
- * Validates signature authenticity and root integrity before encoding.
1594
- *
1595
- * @example
1596
- * ```typescript
1597
- * const tree = Tree.from(offers);
1598
- * const signature = await wallet.signMessage({ message: { raw: tree.root } });
1599
- * const calldata = await Tree.encode(tree, signature);
1600
- * await broadcast(calldata);
1601
- * ```
1602
- *
1603
- * @example
1604
- * Manual construction (for advanced users):
1605
- * ```typescript
1606
- * const tree = Tree.from(offers);
1607
- * const compressed = gzip(JSON.stringify(tree.offers.map(Offer.serialize)));
1608
- * const partial = `0x01${bytesToHex(compressed)}${tree.root.slice(2)}`;
1609
- * const signature = await wallet.signMessage({ message: { raw: tree.root } });
1610
- * const calldata = `${partial}${signature.slice(2)}`;
1611
- * ```
1612
- *
1613
- * @param tree - Merkle tree of offers
1614
- * @param signature - EIP-191 signature over raw root bytes
1615
- * @returns Hex-encoded calldata ready for onchain broadcast
1616
- * @throws {EncodeError} If signature verification fails or root mismatch
1617
- */
1618
- const encode$1 = async (tree, signature) => {
1619
- validateTreeForEncoding(tree);
1620
- await verifySignatureAndRecoverAddress({
1621
- root: tree.root,
1622
- signature
1623
- });
1624
- const unsigned = encodeUnsignedBytes(tree);
1625
- const sigBytes = (0, viem.hexToBytes)(signature);
1626
- const encoded = new Uint8Array(unsigned.length + sigBytes.length);
1627
- encoded.set(unsigned, 0);
1628
- encoded.set(sigBytes, unsigned.length);
1629
- return (0, viem.bytesToHex)(encoded);
1630
- };
1631
- /**
1632
- * Encodes a merkle tree without a signature into hex payload for client-side signing.
1633
- *
1634
- * Layout: `0x{vv}{gzip([...offers])}{root}` where:
1635
- * - `{vv}`: 1-byte version (currently 0x01)
1636
- * - `{gzip([...offers])}`: gzipped JSON array of serialized offers
1637
- * - `{root}`: 32-byte merkle root
1638
- *
1639
- * Validates root integrity before encoding.
1640
- *
1641
- * @param tree - Merkle tree of offers
1642
- * @returns Hex-encoded unsigned payload
1643
- * @throws {EncodeError} If root mismatch
1644
- */
1645
- const encodeUnsigned = (tree) => {
1646
- validateTreeForEncoding(tree);
1647
- return (0, viem.bytesToHex)(encodeUnsignedBytes(tree));
1648
- };
1649
- const validateTreeForEncoding = (tree) => {
1650
- if (VERSION > 255) throw new EncodeError(`version overflow: ${VERSION} exceeds 255`);
1651
- const computed = from$8(tree.offers);
1652
- if (tree.root !== computed.root) throw new EncodeError(`root mismatch: expected ${computed.root}, got ${tree.root}`);
1653
- };
1654
- const encodeUnsignedBytes = (tree) => {
1655
- const offersPayload = tree.offers.map(serialize);
1656
- const compressed = (0, pako.gzip)(JSON.stringify(offersPayload));
1657
- const rootBytes = (0, viem.hexToBytes)(tree.root);
1658
- const encoded = new Uint8Array(1 + compressed.length + 32);
1659
- encoded[0] = VERSION;
1660
- encoded.set(compressed, 1);
1661
- encoded.set(rootBytes, 1 + compressed.length);
1662
- return encoded;
1663
- };
1664
- /**
1665
- * Decodes hex calldata into a validated merkle tree.
1666
- *
1667
- * Validates signature before decompression for fail-fast rejection of invalid payloads.
1668
- * Returns the tree with separately validated signature and recovered signer address.
1669
- *
1670
- * Validation order:
1671
- * 1. Version check
1672
- * 2. Signature verification (fail-fast, before decompression)
1673
- * 3. Decompression (only if signature valid)
1674
- * 4. Root verification (computed from offers vs embedded root)
1675
- *
1676
- * @example
1677
- * ```typescript
1678
- * const { tree, signature, signer } = await Tree.decode(calldata);
1679
- * console.log(`Tree signed by ${signer} with ${tree.offers.length} offers`);
1680
- * ```
1681
- *
1682
- * @param encoded - Hex calldata in format `0x{vv}{gzip}{root}{signature}`
1683
- * @returns Validated tree, signature, and recovered signer address
1684
- * @throws {DecodeError} If version invalid, signature invalid, or root mismatch
1685
- */
1686
- const decode$1 = async (encoded) => {
1687
- const bytes$1 = (0, viem.hexToBytes)(encoded);
1688
- if (bytes$1.length < 98) throw new DecodeError("payload too short");
1689
- const version = bytes$1[0];
1690
- if (version !== (VERSION & 255)) throw new DecodeError(`invalid version: expected ${VERSION}, got ${version ?? 0}`);
1691
- const signature = (0, viem.bytesToHex)(bytes$1.slice(-65));
1692
- const root = (0, viem.bytesToHex)(bytes$1.slice(-97, -65));
1693
- assertHex(root, 32, "root");
1694
- assertHex(signature, 65, "signature");
1695
- const signer = await verifySignatureAndRecoverAddress({
1696
- root,
1697
- signature
1698
- });
1699
- const compressed = bytes$1.slice(1, -97);
1700
- let decoded;
1701
- try {
1702
- decoded = (0, pako.ungzip)(compressed, { to: "string" });
1703
- } catch {
1704
- throw new DecodeError("decompression failed");
1705
- }
1706
- let rawOffers;
1707
- try {
1708
- rawOffers = JSON.parse(decoded);
1709
- } catch {
1710
- throw new DecodeError("JSON parse failed");
1711
- }
1712
- const tree = from$8(rawOffers.map((o) => OfferSchema().parse(o)));
1713
- if (root !== tree.root) throw new DecodeError(`root mismatch: expected ${tree.root}, got ${root}`);
1714
- return {
1715
- tree,
1716
- signature,
1717
- signer
1718
- };
1719
- };
1720
- /**
1721
- * Error thrown during tree building operations.
1722
- * Indicates structural issues with the tree (missing offers, inconsistent state).
1723
- */
1724
- var TreeError = class extends BaseError {
1725
- constructor(reason) {
1726
- super(`Tree error: ${reason}`);
1727
- _defineProperty(this, "name", "Tree.TreeError");
1728
- }
1729
- };
1730
- /**
1731
- * Error thrown during tree encoding.
1732
- * Indicates validation failures (signature, root mismatch, mixed makers).
1733
- */
1734
- var EncodeError = class extends BaseError {
1735
- constructor(reason) {
1736
- super(`Failed to encode tree: ${reason}`);
1737
- _defineProperty(this, "name", "Tree.EncodeError");
1738
- }
1739
- };
1740
- /**
1741
- * Error thrown during tree decoding.
1742
- * Indicates payload corruption, version mismatch, or validation failures.
1743
- */
1744
- var DecodeError = class extends BaseError {
1745
- constructor(reason) {
1746
- super(`Failed to decode tree: ${reason}`);
1747
- _defineProperty(this, "name", "Tree.DecodeError");
1748
- }
1749
- };
1750
-
1751
1573
  //#endregion
1752
1574
  //#region src/core/Offer.ts
1753
- var Offer_exports = /* @__PURE__ */ __export({
1754
- AccountNotSetError: () => AccountNotSetError,
1575
+ var Offer_exports = /* @__PURE__ */ __exportAll({
1755
1576
  InvalidOfferError: () => InvalidOfferError,
1756
1577
  OfferSchema: () => OfferSchema,
1757
1578
  Status: () => Status,
1758
1579
  consumedEvent: () => consumedEvent,
1759
- decode: () => decode,
1580
+ decode: () => decode$1,
1760
1581
  domain: () => domain,
1761
- encode: () => encode,
1762
- from: () => from$7,
1582
+ encode: () => encode$1,
1583
+ from: () => from$9,
1763
1584
  fromSnakeCase: () => fromSnakeCase$1,
1764
1585
  hash: () => hash,
1765
1586
  obligationId: () => obligationId,
1766
1587
  random: () => random$1,
1767
1588
  serialize: () => serialize,
1768
- sign: () => sign,
1769
- signatureMsg: () => signatureMsg,
1770
1589
  toSnakeCase: () => toSnakeCase,
1771
1590
  types: () => types
1772
1591
  });
1773
1592
  /** Internal symbol for caching the computed hash. */
1774
1593
  const HASH_CACHE = Symbol("offer.hash");
1775
- let Status = /* @__PURE__ */ function(Status$1) {
1776
- Status$1["VALID"] = "VALID";
1777
- Status$1["SIMULATION_ERROR"] = "SIMULATION_ERROR";
1778
- return Status$1;
1594
+ let Status = /* @__PURE__ */ function(Status) {
1595
+ Status["VALID"] = "VALID";
1596
+ Status["SIMULATION_ERROR"] = "SIMULATION_ERROR";
1597
+ return Status;
1779
1598
  }({});
1780
1599
  const OfferSchema = () => {
1781
1600
  return zod.object({
@@ -1819,7 +1638,7 @@ const OfferSchema = () => {
1819
1638
  * @param input - The offer to create.
1820
1639
  * @returns The created offer.
1821
1640
  */
1822
- function from$7(input) {
1641
+ function from$9(input) {
1823
1642
  try {
1824
1643
  return OfferSchema().parse(input);
1825
1644
  } catch (error) {
@@ -1833,7 +1652,7 @@ function from$7(input) {
1833
1652
  * @returns The created offer.
1834
1653
  */
1835
1654
  function fromSnakeCase$1(input) {
1836
- return from$7(fromSnakeCase$3(input));
1655
+ return from$9(fromSnakeCase$3(input));
1837
1656
  }
1838
1657
  /**
1839
1658
  * Converts an offer to a snake case object.
@@ -1887,8 +1706,8 @@ function random$1(config) {
1887
1706
  const collateralCandidates = config?.collateralTokens ? config.collateralTokens.filter((a) => a !== loanToken) : [address()];
1888
1707
  const collateralAsset = collateralCandidates[int(collateralCandidates.length)];
1889
1708
  const maturityOption = weightedChoice([["end_of_month", 1], ["end_of_next_month", 1]]);
1890
- const maturity$1 = config?.maturity ?? from$10(maturityOption);
1891
- const lltv = from$12(weightedChoice([
1709
+ const maturity = config?.maturity ?? from$11(maturityOption);
1710
+ const lltv = from$13(weightedChoice([
1892
1711
  [.385, 1],
1893
1712
  [.5, 1],
1894
1713
  [.625, 2],
@@ -1927,15 +1746,15 @@ function random$1(config) {
1927
1746
  })
1928
1747
  };
1929
1748
  })();
1930
- return from$7({
1749
+ return from$9({
1931
1750
  maker: config?.maker ?? address(),
1932
1751
  assets: assetsScaled,
1933
1752
  obligationUnits: config?.obligationUnits ?? 0n,
1934
1753
  obligationShares: config?.obligationShares ?? 0n,
1935
1754
  price,
1936
- maturity: maturity$1,
1937
- expiry: config?.expiry ?? maturity$1 - 1,
1938
- start: config?.start ?? maturity$1 - 10,
1755
+ maturity,
1756
+ expiry: config?.expiry ?? maturity - 1,
1757
+ start: config?.start ?? maturity - 10,
1939
1758
  group: config?.group ?? hex(32),
1940
1759
  session: config?.session ?? hex(32),
1941
1760
  buy,
@@ -2055,23 +1874,6 @@ const types = {
2055
1874
  type: "bytes"
2056
1875
  }]
2057
1876
  };
2058
- /**
2059
- * Signs an array of offers.
2060
- * @throws {Error} If the wallet account is not set.
2061
- * @param offers - The offers to sign.
2062
- * @param wallet - The wallet to sign the offers with.
2063
- * @returns The signed offers.
2064
- */
2065
- async function sign(offers, wallet) {
2066
- if (!wallet.account) throw new AccountNotSetError();
2067
- return wallet.signMessage({
2068
- account: wallet.account,
2069
- message: { raw: signatureMsg(offers) }
2070
- });
2071
- }
2072
- function signatureMsg(offers) {
2073
- return from$8(offers).root;
2074
- }
2075
1877
  function hash(offer) {
2076
1878
  const cached = offer[HASH_CACHE];
2077
1879
  if (cached) return cached;
@@ -2108,7 +1910,7 @@ function hash(offer) {
2108
1910
  * @returns The obligation id as a 32-byte hex string.
2109
1911
  */
2110
1912
  function obligationId(offer) {
2111
- return id(from$9({
1913
+ return id(from$10({
2112
1914
  chainId: offer.chainId,
2113
1915
  loanToken: offer.loanToken,
2114
1916
  collaterals: offer.collaterals,
@@ -2198,7 +2000,7 @@ const OfferAbi = [
2198
2000
  }]
2199
2001
  }
2200
2002
  ];
2201
- function encode(offer) {
2003
+ function encode$1(offer) {
2202
2004
  return (0, viem.encodeAbiParameters)(OfferAbi, [
2203
2005
  offer.maker,
2204
2006
  offer.assets,
@@ -2217,20 +2019,20 @@ function encode(offer) {
2217
2019
  offer.callback
2218
2020
  ]);
2219
2021
  }
2220
- function decode(data) {
2022
+ function decode$1(data) {
2221
2023
  let decoded;
2222
2024
  try {
2223
2025
  decoded = (0, viem.decodeAbiParameters)(OfferAbi, data);
2224
2026
  } catch (error) {
2225
2027
  throw new InvalidOfferError(error);
2226
2028
  }
2227
- return from$7({
2029
+ return from$9({
2228
2030
  maker: decoded[0],
2229
2031
  assets: decoded[1],
2230
2032
  obligationUnits: decoded[2],
2231
2033
  obligationShares: decoded[3],
2232
2034
  price: decoded[4],
2233
- maturity: from$10(Number(decoded[5])),
2035
+ maturity: from$11(Number(decoded[5])),
2234
2036
  expiry: Number(decoded[6]),
2235
2037
  group: decoded[7],
2236
2038
  session: decoded[8],
@@ -2239,7 +2041,7 @@ function decode(data) {
2239
2041
  loanToken: decoded[11],
2240
2042
  start: Number(decoded[12]),
2241
2043
  collaterals: decoded[13].map((c) => {
2242
- return from$11({
2044
+ return from$12({
2243
2045
  asset: c.asset,
2244
2046
  oracle: c.oracle,
2245
2047
  lltv: c.lltv
@@ -2303,25 +2105,22 @@ var InvalidOfferError = class InvalidOfferError extends BaseError {
2303
2105
  return `Invalid offer. ${InvalidOfferError.formatDetails(this.cause)}`;
2304
2106
  }
2305
2107
  };
2306
- var AccountNotSetError = class extends BaseError {
2307
- constructor() {
2308
- super("Account not set.");
2309
- _defineProperty(this, "name", "Offer.AccountNotSetError");
2310
- }
2311
- };
2312
2108
 
2313
2109
  //#endregion
2314
2110
  //#region src/core/Oracle.ts
2315
- var Oracle_exports = /* @__PURE__ */ __export({
2111
+ var Oracle_exports = /* @__PURE__ */ __exportAll({
2316
2112
  Conversion: () => Conversion,
2317
- from: () => from$6
2113
+ from: () => from$8,
2114
+ fromCollateral: () => fromCollateral,
2115
+ fromOffer: () => fromOffer,
2116
+ fromOffers: () => fromOffers
2318
2117
  });
2319
2118
  /**
2320
2119
  * Create an Oracle from a plain object.
2321
2120
  * @param data - The data to create the oracle from.
2322
2121
  * @returns The created oracle.
2323
2122
  */
2324
- function from$6(data) {
2123
+ function from$8(data) {
2325
2124
  return {
2326
2125
  chainId: data.chainId,
2327
2126
  address: data.address.toLowerCase(),
@@ -2329,6 +2128,59 @@ function from$6(data) {
2329
2128
  blockNumber: data.blockNumber
2330
2129
  };
2331
2130
  }
2131
+ /**
2132
+ * Creates an oracle from a collateral.
2133
+ * @constructor
2134
+ *
2135
+ * @param parameters - {@link fromCollateral.Parameters}
2136
+ * @returns The created oracle. {@link fromCollateral.ReturnType}
2137
+ */
2138
+ function fromCollateral(parameters) {
2139
+ const { chainId, collateral, blockNumber, price = null } = parameters;
2140
+ return {
2141
+ chainId,
2142
+ address: collateral.oracle.toLowerCase(),
2143
+ price,
2144
+ blockNumber
2145
+ };
2146
+ }
2147
+ /**
2148
+ * Creates oracles from a single offer.
2149
+ * @constructor
2150
+ *
2151
+ * @param parameters - {@link fromOffer.Parameters}
2152
+ * @returns The created oracles. {@link fromOffer.ReturnType}
2153
+ */
2154
+ function fromOffer(parameters) {
2155
+ const { offer, blockNumber, price = null } = parameters;
2156
+ return fromOffers({
2157
+ offers: [offer],
2158
+ blockNumber,
2159
+ price
2160
+ });
2161
+ }
2162
+ /**
2163
+ * Creates oracles from a list of offers.
2164
+ * @constructor
2165
+ *
2166
+ * @param parameters - {@link fromOffers.Parameters}
2167
+ * @returns The created oracles. {@link fromOffers.ReturnType}
2168
+ */
2169
+ function fromOffers(parameters) {
2170
+ const { offers, blockNumber, price = null } = parameters;
2171
+ const rowsByKey = /* @__PURE__ */ new Map();
2172
+ for (const offer of offers) for (const collateral of offer.collaterals) {
2173
+ const key = `${offer.chainId}-${collateral.oracle}`.toLowerCase();
2174
+ if (rowsByKey.has(key)) continue;
2175
+ rowsByKey.set(key, fromCollateral({
2176
+ chainId: offer.chainId,
2177
+ collateral,
2178
+ blockNumber,
2179
+ price
2180
+ }));
2181
+ }
2182
+ return Array.from(rowsByKey.values());
2183
+ }
2332
2184
  let Conversion;
2333
2185
  (function(_Conversion) {
2334
2186
  function collateralToLoan(amount, params) {
@@ -2344,14 +2196,14 @@ let Conversion;
2344
2196
 
2345
2197
  //#endregion
2346
2198
  //#region src/core/Position.ts
2347
- var Position_exports = /* @__PURE__ */ __export({
2199
+ var Position_exports = /* @__PURE__ */ __exportAll({
2348
2200
  Type: () => Type,
2349
- from: () => from$5
2201
+ from: () => from$7
2350
2202
  });
2351
- let Type = /* @__PURE__ */ function(Type$1) {
2352
- Type$1["ERC20"] = "erc20";
2353
- Type$1["VAULT_V1"] = "vault_v1";
2354
- return Type$1;
2203
+ let Type = /* @__PURE__ */ function(Type) {
2204
+ Type["ERC20"] = "erc20";
2205
+ Type["VAULT_V1"] = "vault_v1";
2206
+ return Type;
2355
2207
  }({});
2356
2208
  /**
2357
2209
  * @constructor
@@ -2359,7 +2211,7 @@ let Type = /* @__PURE__ */ function(Type$1) {
2359
2211
  * @param parameters - {@link from.Parameters}
2360
2212
  * @returns The created Position. {@link from.ReturnType}
2361
2213
  */
2362
- function from$5(parameters) {
2214
+ function from$7(parameters) {
2363
2215
  return {
2364
2216
  chainId: parameters.chainId,
2365
2217
  contract: parameters.contract.toLowerCase(),
@@ -2373,10 +2225,10 @@ function from$5(parameters) {
2373
2225
 
2374
2226
  //#endregion
2375
2227
  //#region src/core/Quote.ts
2376
- var Quote_exports = /* @__PURE__ */ __export({
2228
+ var Quote_exports = /* @__PURE__ */ __exportAll({
2377
2229
  InvalidQuoteError: () => InvalidQuoteError,
2378
2230
  QuoteSchema: () => QuoteSchema,
2379
- from: () => from$4,
2231
+ from: () => from$6,
2380
2232
  fromSnakeCase: () => fromSnakeCase,
2381
2233
  random: () => random
2382
2234
  });
@@ -2397,7 +2249,7 @@ const QuoteSchema = zod.object({
2397
2249
  * const quote = Quote.from({ obligationId: "0x123", ask: { price: 100n }, bid: { price: 100n } });
2398
2250
  * ```
2399
2251
  */
2400
- function from$4(parameters) {
2252
+ function from$6(parameters) {
2401
2253
  try {
2402
2254
  const parsedQuote = QuoteSchema.parse(parameters);
2403
2255
  return {
@@ -2416,7 +2268,7 @@ function from$4(parameters) {
2416
2268
  * @returns The created quote. {@link fromSnakeCase.ReturnType}
2417
2269
  */
2418
2270
  function fromSnakeCase(snake) {
2419
- return from$4(fromSnakeCase$3(snake));
2271
+ return from$6(fromSnakeCase$3(snake));
2420
2272
  }
2421
2273
  /**
2422
2274
  * Generates a random quote.
@@ -2427,46 +2279,526 @@ function fromSnakeCase(snake) {
2427
2279
  * const quote = Quote.random();
2428
2280
  * ```
2429
2281
  */
2430
- function random() {
2431
- return from$4({
2432
- obligationId: id(random$2()),
2433
- ask: { price: BigInt(int(1e6)) },
2434
- bid: { price: BigInt(int(1e6)) }
2435
- });
2436
- }
2437
- var InvalidQuoteError = class extends BaseError {
2438
- constructor(error) {
2439
- super("Invalid quote.", { cause: error });
2440
- _defineProperty(this, "name", "Quote.InvalidQuoteError");
2282
+ function random() {
2283
+ return from$6({
2284
+ obligationId: id(random$2()),
2285
+ ask: { price: BigInt(int(1e6)) },
2286
+ bid: { price: BigInt(int(1e6)) }
2287
+ });
2288
+ }
2289
+ var InvalidQuoteError = class extends BaseError {
2290
+ constructor(error) {
2291
+ super("Invalid quote.", { cause: error });
2292
+ _defineProperty(this, "name", "Quote.InvalidQuoteError");
2293
+ }
2294
+ };
2295
+
2296
+ //#endregion
2297
+ //#region src/core/TradingFee.ts
2298
+ var TradingFee_exports = /* @__PURE__ */ __exportAll({
2299
+ BREAKPOINTS: () => BREAKPOINTS,
2300
+ InvalidFeeError: () => InvalidFeeError,
2301
+ InvalidFeesLengthError: () => InvalidFeesLengthError,
2302
+ WAD: () => WAD,
2303
+ activate: () => activate,
2304
+ compute: () => compute,
2305
+ deactivate: () => deactivate,
2306
+ from: () => from$5,
2307
+ getFees: () => getFees,
2308
+ isActivated: () => isActivated
2309
+ });
2310
+ /**
2311
+ * Time breakpoints in seconds for piecewise linear fee interpolation.
2312
+ * Matches on-chain constants: 0d, 1d, 7d, 30d, 90d, 180d.
2313
+ */
2314
+ const BREAKPOINTS = [
2315
+ 0n,
2316
+ 86400n,
2317
+ 604800n,
2318
+ 2592000n,
2319
+ 7776000n,
2320
+ 15552000n
2321
+ ];
2322
+ /** WAD constant (1e18) for fee scaling. */
2323
+ const WAD = 10n ** 18n;
2324
+ /**
2325
+ * Create a TradingFee from an activation flag and 6 fee values.
2326
+ * @param activated - Whether the fee is active.
2327
+ * @param fees - Tuple of 6 fee values in WAD (one per breakpoint: 0d, 1d, 7d, 30d, 90d, 180d).
2328
+ * @returns A new TradingFee instance.
2329
+ * @throws {@link InvalidFeeError} if any fee exceeds WAD (100%).
2330
+ * @throws {@link InvalidFeesLengthError} if fees array doesn't have exactly 6 elements.
2331
+ */
2332
+ function from$5(activated, fees) {
2333
+ if (fees.length !== 6) throw new InvalidFeesLengthError(fees.length);
2334
+ for (let i = 0; i < 6; i++) {
2335
+ const fee = fees[i];
2336
+ if (fee < 0n || fee > WAD) throw new InvalidFeeError(fee, i);
2337
+ }
2338
+ const frozenFees = Object.freeze([...fees]);
2339
+ return Object.freeze({
2340
+ _activated: activated,
2341
+ _fees: frozenFees
2342
+ });
2343
+ }
2344
+ /**
2345
+ * Compute the trading fee for a given time to maturity using piecewise linear interpolation.
2346
+ * @param tradingFee - The TradingFee instance.
2347
+ * @param timeToMaturity - Time to maturity in seconds.
2348
+ * @returns The interpolated fee in WAD. Returns 0n if not activated.
2349
+ */
2350
+ function compute(tradingFee, timeToMaturity) {
2351
+ if (!tradingFee._activated) return 0n;
2352
+ const time = BigInt(Math.max(0, Math.floor(timeToMaturity)));
2353
+ if (time >= BREAKPOINTS[5]) return tradingFee._fees[5];
2354
+ const { index, start, end } = getSegment(time);
2355
+ const feeLower = tradingFee._fees[index];
2356
+ const feeUpper = tradingFee._fees[index + 1];
2357
+ const segmentLength = end - start;
2358
+ return (feeLower * (end - time) + feeUpper * (time - start)) / segmentLength;
2359
+ }
2360
+ /**
2361
+ * Check if the trading fee is activated.
2362
+ * @param tradingFee - The TradingFee instance.
2363
+ * @returns True if activated, false otherwise.
2364
+ */
2365
+ function isActivated(tradingFee) {
2366
+ return tradingFee._activated;
2367
+ }
2368
+ /**
2369
+ * Create a new TradingFee with activation enabled.
2370
+ * @param tradingFee - The TradingFee instance.
2371
+ * @returns A new TradingFee with activated set to true.
2372
+ */
2373
+ function activate(tradingFee) {
2374
+ return Object.freeze({
2375
+ _activated: true,
2376
+ _fees: tradingFee._fees
2377
+ });
2378
+ }
2379
+ /**
2380
+ * Create a new TradingFee with activation disabled.
2381
+ * @param tradingFee - The TradingFee instance.
2382
+ * @returns A new TradingFee with activated set to false.
2383
+ */
2384
+ function deactivate(tradingFee) {
2385
+ return Object.freeze({
2386
+ _activated: false,
2387
+ _fees: tradingFee._fees
2388
+ });
2389
+ }
2390
+ /**
2391
+ * Get the fee values at each breakpoint.
2392
+ * @param tradingFee - The TradingFee instance.
2393
+ * @returns The tuple of 6 fee values.
2394
+ */
2395
+ function getFees(tradingFee) {
2396
+ return tradingFee._fees;
2397
+ }
2398
+ /**
2399
+ * Determine which segment a timeToMaturity falls into for interpolation.
2400
+ * @param timeToMaturity - Time to maturity in seconds.
2401
+ * @returns Object with index, start, and end of the segment.
2402
+ */
2403
+ function getSegment(timeToMaturity) {
2404
+ if (timeToMaturity < BREAKPOINTS[1]) return {
2405
+ index: 0,
2406
+ start: BREAKPOINTS[0],
2407
+ end: BREAKPOINTS[1]
2408
+ };
2409
+ if (timeToMaturity < BREAKPOINTS[2]) return {
2410
+ index: 1,
2411
+ start: BREAKPOINTS[1],
2412
+ end: BREAKPOINTS[2]
2413
+ };
2414
+ if (timeToMaturity < BREAKPOINTS[3]) return {
2415
+ index: 2,
2416
+ start: BREAKPOINTS[2],
2417
+ end: BREAKPOINTS[3]
2418
+ };
2419
+ if (timeToMaturity < BREAKPOINTS[4]) return {
2420
+ index: 3,
2421
+ start: BREAKPOINTS[3],
2422
+ end: BREAKPOINTS[4]
2423
+ };
2424
+ return {
2425
+ index: 4,
2426
+ start: BREAKPOINTS[4],
2427
+ end: BREAKPOINTS[5]
2428
+ };
2429
+ }
2430
+ /** Error thrown when a fee value is invalid (negative or exceeds WAD). */
2431
+ var InvalidFeeError = class extends BaseError {
2432
+ constructor(fee, index) {
2433
+ super(`Invalid fee at index ${index}: ${fee}. Fee must be between 0 and ${WAD} (WAD).`);
2434
+ _defineProperty(this, "name", "TradingFee.InvalidFeeError");
2435
+ }
2436
+ };
2437
+ /** Error thrown when fees array doesn't have exactly 6 elements. */
2438
+ var InvalidFeesLengthError = class extends BaseError {
2439
+ constructor(length) {
2440
+ super(`Invalid fees length: ${length}. Expected exactly 6 fee values.`);
2441
+ _defineProperty(this, "name", "TradingFee.InvalidFeesLengthError");
2442
+ }
2443
+ };
2444
+
2445
+ //#endregion
2446
+ //#region src/core/Transfer.ts
2447
+ var Transfer_exports = /* @__PURE__ */ __exportAll({ from: () => from$4 });
2448
+ /**
2449
+ * @constructor
2450
+ *
2451
+ * Creates a {@link Transfer}.
2452
+ * @param parameters - {@link from.Parameters}
2453
+ * @returns The created Transfer. {@link from.ReturnType}
2454
+ *
2455
+ * @example
2456
+ * ```ts
2457
+ * const transfer = Transfer.from({ id: "1", chainId: 1, contract: "0x123", from: "0x456", to: "0x789", value: 100n, blockNumber: 100n });
2458
+ * ```
2459
+ */
2460
+ function from$4(parameters) {
2461
+ return {
2462
+ id: parameters.id,
2463
+ chainId: parameters.chainId,
2464
+ contract: parameters.contract.toLowerCase(),
2465
+ from: parameters.from.toLowerCase(),
2466
+ to: parameters.to.toLowerCase(),
2467
+ value: parameters.value,
2468
+ blockNumber: parameters.blockNumber
2469
+ };
2470
+ }
2471
+
2472
+ //#endregion
2473
+ //#region src/core/Tree.ts
2474
+ var Tree_exports = /* @__PURE__ */ __exportAll({
2475
+ DecodeError: () => DecodeError,
2476
+ EncodeError: () => EncodeError,
2477
+ SignatureDomainError: () => SignatureDomainError,
2478
+ TreeError: () => TreeError,
2479
+ VERSION: () => VERSION,
2480
+ decode: () => decode,
2481
+ encode: () => encode,
2482
+ encodeUnsigned: () => encodeUnsigned,
2483
+ from: () => from$3,
2484
+ proofs: () => proofs,
2485
+ signatureDomain: () => signatureDomain,
2486
+ signatureTypes: () => signatureTypes
2487
+ });
2488
+ const VERSION = 1;
2489
+ /**
2490
+ * EIP-712 types for signing the tree root (Root(bytes32 root)).
2491
+ */
2492
+ const signatureTypes = {
2493
+ EIP712Domain: [{
2494
+ name: "chainId",
2495
+ type: "uint256"
2496
+ }, {
2497
+ name: "verifyingContract",
2498
+ type: "address"
2499
+ }],
2500
+ Root: [{
2501
+ name: "root",
2502
+ type: "bytes32"
2503
+ }]
2504
+ };
2505
+ const normalizeHash = (hash) => hash.toLowerCase();
2506
+ /**
2507
+ * Builds a Merkle tree from a list of offers.
2508
+ *
2509
+ * Leaves are the offer `hash` values as `bytes32` and are deterministically
2510
+ * ordered following the StandardMerkleTree leaf ordering so that the resulting
2511
+ * root is stable regardless of the input order.
2512
+ *
2513
+ * @param offers - Offers to include in the tree.
2514
+ * @returns A `StandardMerkleTree` of `bytes32` leaves representing the offers.
2515
+ * @throws {TreeError} If tree building fails due to offer inconsistencies.
2516
+ */
2517
+ const from$3 = (offers) => {
2518
+ const leaves = offers.map((offer) => [hash(offer)]);
2519
+ const tree = _openzeppelin_merkle_tree.StandardMerkleTree.of(leaves, ["bytes32"]);
2520
+ const orderedOffers = orderOffers(tree, offers);
2521
+ return Object.assign(tree, { offers: orderedOffers });
2522
+ };
2523
+ const orderOffers = (tree, offers) => {
2524
+ const offerByHash = /* @__PURE__ */ new Map();
2525
+ for (const offer of offers) offerByHash.set(normalizeHash(hash(offer)), offer);
2526
+ const entries = tree.dump().values.map((value) => {
2527
+ const hash = normalizeHash(value.value[0]);
2528
+ const offer = offerByHash.get(hash);
2529
+ if (!offer) throw new TreeError(`missing offer for leaf ${hash}`);
2530
+ return {
2531
+ offer,
2532
+ treeIndex: value.treeIndex
2533
+ };
2534
+ });
2535
+ entries.sort((a, b) => b.treeIndex - a.treeIndex);
2536
+ return entries.map((item) => item.offer);
2537
+ };
2538
+ /**
2539
+ * Generates merkle proofs for all offers in a tree.
2540
+ *
2541
+ * Each proof allows independent verification that an offer is included in the tree
2542
+ * without requiring the full tree. Proofs are ordered by StandardMerkleTree leaf ordering.
2543
+ *
2544
+ * @param tree - The {@link Tree} to generate proofs for.
2545
+ * @returns Array of proofs - {@link Proof}
2546
+ */
2547
+ const proofs = (tree) => {
2548
+ return tree.offers.map((offer) => {
2549
+ return {
2550
+ offer,
2551
+ path: tree.getProof([hash(offer)])
2552
+ };
2553
+ });
2554
+ };
2555
+ /**
2556
+ * Normalizes a Root signature domain (BigInt chain id, lowercase address).
2557
+ * @throws {SignatureDomainError} When the domain is invalid.
2558
+ */
2559
+ const signatureDomain = (domain) => {
2560
+ return normalizeSignatureDomain(domain, (reason) => new SignatureDomainError(reason));
2561
+ };
2562
+ const normalizeSignatureDomain = (domain, errorFactory) => {
2563
+ let chainId;
2564
+ try {
2565
+ chainId = typeof domain.chainId === "bigint" ? domain.chainId : BigInt(domain.chainId);
2566
+ } catch {
2567
+ throw errorFactory("invalid chainId");
2568
+ }
2569
+ if (chainId < 0n) throw errorFactory("invalid chainId");
2570
+ if (!(0, viem.isAddress)(domain.verifyingContract)) throw errorFactory("invalid verifyingContract");
2571
+ return {
2572
+ chainId,
2573
+ verifyingContract: domain.verifyingContract.toLowerCase()
2574
+ };
2575
+ };
2576
+ const assertHex = (value, expectedBytes, name, errorFactory = (reason) => new DecodeError(reason)) => {
2577
+ if (typeof value !== "string" || !(0, viem.isHex)(value)) throw errorFactory(`${name} is not a valid hex string`);
2578
+ if ((0, viem.hexToBytes)(value).length !== expectedBytes) throw errorFactory(`${name}: expected ${expectedBytes} bytes`);
2579
+ };
2580
+ const verifySignatureAndRecoverAddress = async (params) => {
2581
+ const { root, signature, domain, errorFactory } = params;
2582
+ assertHex(root, 32, "root", errorFactory);
2583
+ assertHex(signature, 65, "signature", errorFactory);
2584
+ const hash = (0, viem.hashTypedData)({
2585
+ domain,
2586
+ types: signatureTypes,
2587
+ primaryType: "Root",
2588
+ message: { root }
2589
+ });
2590
+ try {
2591
+ return await (0, viem.recoverAddress)({
2592
+ hash,
2593
+ signature
2594
+ });
2595
+ } catch {
2596
+ throw errorFactory("signature recovery failed");
2597
+ }
2598
+ };
2599
+ /**
2600
+ * Encodes a merkle tree with signature into hex calldata for onchain broadcast.
2601
+ *
2602
+ * Layout: `0x{vv}{gzip([...offers])}{root}{signature}` where:
2603
+ * - `{vv}`: 1-byte version (currently 0x01)
2604
+ * - `{gzip([...offers])}`: gzipped JSON array of serialized offers
2605
+ * - `{root}`: 32-byte merkle root
2606
+ * - `{signature}`: 65-byte EIP-712 signature over Root(bytes32 root)
2607
+ *
2608
+ * Validates signature authenticity and root integrity before encoding.
2609
+ *
2610
+ * @example
2611
+ * ```typescript
2612
+ * const tree = Tree.from(offers);
2613
+ * const signature = await wallet.signTypedData({
2614
+ * account: wallet.account,
2615
+ * domain: Tree.signatureDomain({ chainId, verifyingContract }),
2616
+ * types: Tree.signatureTypes,
2617
+ * primaryType: "Root",
2618
+ * message: { root: tree.root },
2619
+ * });
2620
+ * const calldata = await Tree.encode(tree, signature, { chainId, verifyingContract });
2621
+ * await broadcast(calldata);
2622
+ * ```
2623
+ *
2624
+ * @example
2625
+ * Manual construction (for advanced users):
2626
+ * ```typescript
2627
+ * const tree = Tree.from(offers);
2628
+ * const compressed = gzip(JSON.stringify(tree.offers.map(Offer.serialize)));
2629
+ * const partial = `0x01${bytesToHex(compressed)}${tree.root.slice(2)}`;
2630
+ * const signature = await wallet.signTypedData({
2631
+ * account: wallet.account,
2632
+ * domain: Tree.signatureDomain({ chainId, verifyingContract }),
2633
+ * types: Tree.signatureTypes,
2634
+ * primaryType: "Root",
2635
+ * message: { root: tree.root },
2636
+ * });
2637
+ * const calldata = `${partial}${signature.slice(2)}`;
2638
+ * ```
2639
+ *
2640
+ * @param tree - Merkle tree of offers
2641
+ * @param signature - EIP-712 signature over Root(bytes32 root)
2642
+ * @param domain - EIP-712 domain with chain id and verifying contract
2643
+ * @returns Hex-encoded calldata ready for onchain broadcast
2644
+ * @throws {EncodeError} If signature verification fails or root mismatch
2645
+ */
2646
+ const encode = async (tree, signature, domain) => {
2647
+ const errorFactory = (reason) => new EncodeError(reason);
2648
+ const normalizedDomain = normalizeSignatureDomain(domain, errorFactory);
2649
+ validateTreeForEncoding(tree, normalizedDomain);
2650
+ await verifySignatureAndRecoverAddress({
2651
+ root: tree.root,
2652
+ signature,
2653
+ domain: normalizedDomain,
2654
+ errorFactory
2655
+ });
2656
+ const unsigned = encodeUnsignedBytes(tree);
2657
+ const sigBytes = (0, viem.hexToBytes)(signature);
2658
+ const encoded = new Uint8Array(unsigned.length + sigBytes.length);
2659
+ encoded.set(unsigned, 0);
2660
+ encoded.set(sigBytes, unsigned.length);
2661
+ return (0, viem.bytesToHex)(encoded);
2662
+ };
2663
+ /**
2664
+ * Encodes a merkle tree without a signature into hex payload for client-side signing.
2665
+ *
2666
+ * Layout: `0x{vv}{gzip([...offers])}{root}` where:
2667
+ * - `{vv}`: 1-byte version (currently 0x01)
2668
+ * - `{gzip([...offers])}`: gzipped JSON array of serialized offers
2669
+ * - `{root}`: 32-byte merkle root
2670
+ *
2671
+ * Validates root integrity before encoding.
2672
+ *
2673
+ * @param tree - Merkle tree of offers
2674
+ * @returns Hex-encoded unsigned payload
2675
+ * @throws {EncodeError} If root mismatch
2676
+ */
2677
+ const encodeUnsigned = (tree) => {
2678
+ validateTreeForEncoding(tree);
2679
+ return (0, viem.bytesToHex)(encodeUnsignedBytes(tree));
2680
+ };
2681
+ const validateTreeForEncoding = (tree, domain) => {
2682
+ if (VERSION > 255) throw new EncodeError(`version overflow: ${VERSION} exceeds 255`);
2683
+ const computed = from$3(tree.offers);
2684
+ if (tree.root !== computed.root) throw new EncodeError(`root mismatch: expected ${computed.root}, got ${tree.root}`);
2685
+ if (domain) {
2686
+ const mismatched = tree.offers.find((offer) => BigInt(offer.chainId) !== domain.chainId);
2687
+ if (mismatched) throw new EncodeError(`chainId mismatch: expected ${domain.chainId}, got ${mismatched.chainId}`);
2688
+ }
2689
+ };
2690
+ const encodeUnsignedBytes = (tree) => {
2691
+ const offersPayload = tree.offers.map(serialize);
2692
+ const compressed = (0, pako.gzip)(JSON.stringify(offersPayload));
2693
+ const rootBytes = (0, viem.hexToBytes)(tree.root);
2694
+ const encoded = new Uint8Array(1 + compressed.length + 32);
2695
+ encoded[0] = VERSION;
2696
+ encoded.set(compressed, 1);
2697
+ encoded.set(rootBytes, 1 + compressed.length);
2698
+ return encoded;
2699
+ };
2700
+ /**
2701
+ * Decodes hex calldata into a validated merkle tree.
2702
+ *
2703
+ * Validates signature before decompression for fail-fast rejection of invalid payloads.
2704
+ * Returns the tree with separately validated signature and recovered signer address.
2705
+ *
2706
+ * Validation order:
2707
+ * 1. Version check
2708
+ * 2. Signature verification (fail-fast, before decompression)
2709
+ * 3. Decompression (only if signature valid)
2710
+ * 4. Root verification (computed from offers vs embedded root)
2711
+ *
2712
+ * @example
2713
+ * ```typescript
2714
+ * const { tree, signature, signer } = await Tree.decode(calldata, { chainId, verifyingContract });
2715
+ * console.log(`Tree signed by ${signer} with ${tree.offers.length} offers`);
2716
+ * ```
2717
+ *
2718
+ * @param encoded - Hex calldata in format `0x{vv}{gzip}{root}{signature}`
2719
+ * @param domain - EIP-712 domain with chain id and verifying contract
2720
+ * @returns Validated tree, signature, and recovered signer address
2721
+ * @throws {DecodeError} If version invalid, signature invalid, or root mismatch
2722
+ */
2723
+ const decode = async (encoded, domain) => {
2724
+ const errorFactory = (reason) => new DecodeError(reason);
2725
+ const normalizedDomain = normalizeSignatureDomain(domain, errorFactory);
2726
+ const bytes = (0, viem.hexToBytes)(encoded);
2727
+ if (bytes.length < 98) throw new DecodeError("payload too short");
2728
+ const version = bytes[0];
2729
+ if (version !== (VERSION & 255)) throw new DecodeError(`invalid version: expected ${VERSION}, got ${version ?? 0}`);
2730
+ const signature = (0, viem.bytesToHex)(bytes.slice(-65));
2731
+ const root = (0, viem.bytesToHex)(bytes.slice(-97, -65));
2732
+ assertHex(root, 32, "root");
2733
+ assertHex(signature, 65, "signature");
2734
+ const signer = await verifySignatureAndRecoverAddress({
2735
+ root,
2736
+ signature,
2737
+ domain: normalizedDomain,
2738
+ errorFactory
2739
+ });
2740
+ const compressed = bytes.slice(1, -97);
2741
+ let decoded;
2742
+ try {
2743
+ decoded = (0, pako.ungzip)(compressed, { to: "string" });
2744
+ } catch {
2745
+ throw new DecodeError("decompression failed");
2746
+ }
2747
+ let rawOffers;
2748
+ try {
2749
+ rawOffers = JSON.parse(decoded);
2750
+ } catch {
2751
+ throw new DecodeError("JSON parse failed");
2752
+ }
2753
+ const tree = from$3(rawOffers.map((o) => OfferSchema().parse(o)));
2754
+ if (root !== tree.root) throw new DecodeError(`root mismatch: expected ${tree.root}, got ${root}`);
2755
+ const chainIdMismatch = tree.offers.find((offer) => BigInt(offer.chainId) !== normalizedDomain.chainId);
2756
+ if (chainIdMismatch) throw new DecodeError(`chainId mismatch: expected ${normalizedDomain.chainId}, got ${chainIdMismatch.chainId}`);
2757
+ return {
2758
+ tree,
2759
+ signature,
2760
+ signer
2761
+ };
2762
+ };
2763
+ /**
2764
+ * Error thrown during tree building operations.
2765
+ * Indicates structural issues with the tree (missing offers, inconsistent state).
2766
+ */
2767
+ var TreeError = class extends BaseError {
2768
+ constructor(reason) {
2769
+ super(`Tree error: ${reason}`);
2770
+ _defineProperty(this, "name", "Tree.TreeError");
2771
+ }
2772
+ };
2773
+ /**
2774
+ * Error thrown during tree encoding.
2775
+ * Indicates validation failures (signature, root mismatch, mixed makers).
2776
+ */
2777
+ var EncodeError = class extends BaseError {
2778
+ constructor(reason) {
2779
+ super(`Failed to encode tree: ${reason}`);
2780
+ _defineProperty(this, "name", "Tree.EncodeError");
2781
+ }
2782
+ };
2783
+ /**
2784
+ * Error thrown during tree decoding.
2785
+ * Indicates payload corruption, version mismatch, or validation failures.
2786
+ */
2787
+ var DecodeError = class extends BaseError {
2788
+ constructor(reason) {
2789
+ super(`Failed to decode tree: ${reason}`);
2790
+ _defineProperty(this, "name", "Tree.DecodeError");
2441
2791
  }
2442
2792
  };
2443
-
2444
- //#endregion
2445
- //#region src/core/Transfer.ts
2446
- var Transfer_exports = /* @__PURE__ */ __export({ from: () => from$3 });
2447
2793
  /**
2448
- * @constructor
2449
- *
2450
- * Creates a {@link Transfer}.
2451
- * @param parameters - {@link from.Parameters}
2452
- * @returns The created Transfer. {@link from.ReturnType}
2453
- *
2454
- * @example
2455
- * ```ts
2456
- * const transfer = Transfer.from({ id: "1", chainId: 1, contract: "0x123", from: "0x456", to: "0x789", value: 100n, blockNumber: 100n });
2457
- * ```
2794
+ * Error thrown when an invalid signature domain is supplied.
2458
2795
  */
2459
- function from$3(parameters) {
2460
- return {
2461
- id: parameters.id,
2462
- chainId: parameters.chainId,
2463
- contract: parameters.contract.toLowerCase(),
2464
- from: parameters.from.toLowerCase(),
2465
- to: parameters.to.toLowerCase(),
2466
- value: parameters.value,
2467
- blockNumber: parameters.blockNumber
2468
- };
2469
- }
2796
+ var SignatureDomainError = class extends BaseError {
2797
+ constructor(reason) {
2798
+ super(`Invalid signature domain: ${reason}`);
2799
+ _defineProperty(this, "name", "Tree.SignatureDomainError");
2800
+ }
2801
+ };
2470
2802
 
2471
2803
  //#endregion
2472
2804
  //#region src/core/types.ts
@@ -2474,7 +2806,7 @@ const BrandTypeId = Symbol.for("mempool/Brand");
2474
2806
 
2475
2807
  //#endregion
2476
2808
  //#region src/api/Schema/OfferResponse.ts
2477
- var OfferResponse_exports = /* @__PURE__ */ __export({ from: () => from$2 });
2809
+ var OfferResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$2 });
2478
2810
  /**
2479
2811
  * Creates an `OfferResponse` matching the Solidity Offer struct layout.
2480
2812
  * @constructor
@@ -2542,7 +2874,7 @@ const API_ERROR_CODES = [
2542
2874
  ];
2543
2875
 
2544
2876
  //#endregion
2545
- //#region \0@oxc-project+runtime@0.97.0/helpers/decorate.js
2877
+ //#region \0@oxc-project+runtime@0.110.0/helpers/decorate.js
2546
2878
  function __decorate(decorators, target, key, desc) {
2547
2879
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2548
2880
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -2633,6 +2965,21 @@ const validateOfferExample = {
2633
2965
  data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
2634
2966
  }
2635
2967
  };
2968
+ const callbackTypesRequestExample = { callbacks: [{
2969
+ chain_id: 1,
2970
+ addresses: [
2971
+ "0x1111111111111111111111111111111111111111",
2972
+ "0x3333333333333333333333333333333333333333",
2973
+ "0x9999999999999999999999999999999999999999"
2974
+ ]
2975
+ }] };
2976
+ const callbackTypesResponseExample = [{
2977
+ chain_id: 1,
2978
+ sell_erc20_callback: ["0x1111111111111111111111111111111111111111"],
2979
+ buy_erc20: ["0x5555555555555555555555555555555555555555"],
2980
+ buy_vault_v1_callback: ["0x3333333333333333333333333333333333333333"],
2981
+ not_supported: ["0x9999999999999999999999999999999999999999"]
2982
+ }];
2636
2983
  const routerStatusExample = {
2637
2984
  status: "live",
2638
2985
  initialized: true,
@@ -2701,6 +3048,55 @@ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
2701
3048
  type: "string",
2702
3049
  example: validateOfferExample.callback.data
2703
3050
  })], ValidateCallbackRequest.prototype, "data", void 0);
3051
+ var CallbackTypesChainRequest = class {};
3052
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3053
+ type: "number",
3054
+ example: callbackTypesRequestExample.callbacks[0].chain_id
3055
+ })], CallbackTypesChainRequest.prototype, "chain_id", void 0);
3056
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3057
+ type: () => [String],
3058
+ example: callbackTypesRequestExample.callbacks[0].addresses
3059
+ })], CallbackTypesChainRequest.prototype, "addresses", void 0);
3060
+ var CallbackTypesRequest = class {};
3061
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3062
+ type: () => [CallbackTypesChainRequest],
3063
+ example: callbackTypesRequestExample.callbacks
3064
+ })], CallbackTypesRequest.prototype, "callbacks", void 0);
3065
+ var CallbackTypesChainResponse = class {};
3066
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3067
+ type: "number",
3068
+ example: callbackTypesResponseExample[0].chain_id
3069
+ })], CallbackTypesChainResponse.prototype, "chain_id", void 0);
3070
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3071
+ type: () => [String],
3072
+ required: false,
3073
+ example: callbackTypesResponseExample[0].buy_vault_v1_callback
3074
+ })], CallbackTypesChainResponse.prototype, "buy_vault_v1_callback", void 0);
3075
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3076
+ type: () => [String],
3077
+ required: false,
3078
+ example: callbackTypesResponseExample[0].sell_erc20_callback
3079
+ })], CallbackTypesChainResponse.prototype, "sell_erc20_callback", void 0);
3080
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3081
+ type: () => [String],
3082
+ required: false,
3083
+ example: callbackTypesResponseExample[0].buy_erc20
3084
+ })], CallbackTypesChainResponse.prototype, "buy_erc20", void 0);
3085
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3086
+ type: () => [String],
3087
+ example: callbackTypesResponseExample[0].not_supported
3088
+ })], CallbackTypesChainResponse.prototype, "not_supported", void 0);
3089
+ var CallbackTypesSuccessResponse = class extends SuccessResponse {};
3090
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3091
+ type: "string",
3092
+ nullable: true,
3093
+ example: "maturity:1:1730415600:end_of_next_month"
3094
+ })], CallbackTypesSuccessResponse.prototype, "cursor", void 0);
3095
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3096
+ type: () => [CallbackTypesChainResponse],
3097
+ description: "Callback types grouped by chain.",
3098
+ example: callbackTypesResponseExample
3099
+ })], CallbackTypesSuccessResponse.prototype, "data", void 0);
2704
3100
  var AskResponse = class {};
2705
3101
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
2706
3102
  type: "string",
@@ -3163,7 +3559,7 @@ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3163
3559
  type: () => [BookLevelResponse],
3164
3560
  description: "Aggregated book levels grouped by computed price."
3165
3561
  })], BookListResponse.prototype, "data", void 0);
3166
- let BooksController = class BooksController$1 {
3562
+ let BooksController = class BooksController {
3167
3563
  async getBook() {}
3168
3564
  };
3169
3565
  __decorate([
@@ -3209,7 +3605,7 @@ BooksController = __decorate([(0, openapi_metadata_decorators.ApiTags)("Markets"
3209
3605
  description: "Bad Request",
3210
3606
  type: BadRequestResponse
3211
3607
  })], BooksController);
3212
- let ValidateController = class ValidateController$1 {
3608
+ let ValidateController = class ValidateController {
3213
3609
  async validateOffers() {}
3214
3610
  };
3215
3611
  __decorate([
@@ -3236,7 +3632,29 @@ ValidateController = __decorate([(0, openapi_metadata_decorators.ApiTags)("Make"
3236
3632
  description: "Bad Request",
3237
3633
  type: BadRequestResponse
3238
3634
  })], ValidateController);
3239
- let OffersController = class OffersController$1 {
3635
+ let CallbacksController = class CallbacksController {
3636
+ async resolveCallbackTypes() {}
3637
+ };
3638
+ __decorate([
3639
+ (0, openapi_metadata_decorators.ApiOperation)({
3640
+ methods: ["post"],
3641
+ path: "/v1/callbacks",
3642
+ summary: "Resolve callback types",
3643
+ description: "Returns callback types for callback addresses grouped by chain."
3644
+ }),
3645
+ (0, openapi_metadata_decorators.ApiBody)({ type: CallbackTypesRequest }),
3646
+ (0, openapi_metadata_decorators.ApiResponse)({
3647
+ status: 200,
3648
+ description: "Success",
3649
+ type: CallbackTypesSuccessResponse
3650
+ })
3651
+ ], CallbacksController.prototype, "resolveCallbackTypes", null);
3652
+ CallbacksController = __decorate([(0, openapi_metadata_decorators.ApiTags)("Make"), (0, openapi_metadata_decorators.ApiResponse)({
3653
+ status: 400,
3654
+ description: "Bad Request",
3655
+ type: BadRequestResponse
3656
+ })], CallbacksController);
3657
+ let OffersController = class OffersController {
3240
3658
  async getOffers() {}
3241
3659
  };
3242
3660
  __decorate([
@@ -3291,7 +3709,7 @@ OffersController = __decorate([(0, openapi_metadata_decorators.ApiTags)("Markets
3291
3709
  description: "Bad Request",
3292
3710
  type: BadRequestResponse
3293
3711
  })], OffersController);
3294
- let HealthController = class HealthController$1 {
3712
+ let HealthController = class HealthController {
3295
3713
  async getRouterStatus() {}
3296
3714
  async getCollectorsHealth() {}
3297
3715
  async getChainsHealth() {}
@@ -3357,68 +3775,222 @@ __decorate([
3357
3775
  })
3358
3776
  ], HealthController.prototype, "getChainsHealth", null);
3359
3777
  HealthController = __decorate([(0, openapi_metadata_decorators.ApiTags)("System")], HealthController);
3360
- const maturitiesExample = {
3361
- end_of_month: 1738335600,
3362
- end_of_next_month: 1740754800
3363
- };
3364
- const chainConfigExample = {
3778
+ const configContractsExample = {
3365
3779
  chain_id: 505050505,
3366
- contracts: { mempool: "0xD946246695A9259F3B33a78629026F61B3Ab40aF" },
3367
- maturities: maturitiesExample
3780
+ address: "0xD946246695A9259F3B33a78629026F61B3Ab40aF",
3781
+ name: "mempool"
3782
+ };
3783
+ const configContractsPayloadExample = [
3784
+ {
3785
+ chain_id: 505050505,
3786
+ address: "0xD946246695A9259F3B33a78629026F61B3Ab40aF",
3787
+ name: "mempool"
3788
+ },
3789
+ {
3790
+ chain_id: 505050505,
3791
+ address: "0x8A409D5D6394fC197c596d4E6E2c35e5d13f8a4d",
3792
+ name: "multicall"
3793
+ },
3794
+ {
3795
+ chain_id: 505050505,
3796
+ address: "0x23DFBc4B8B80C14CC5e25011B8491f268395BAd6",
3797
+ name: "v2"
3798
+ }
3799
+ ];
3800
+ const configRulesMaturityExample = {
3801
+ type: "maturity",
3802
+ chain_id: 1,
3803
+ name: "end_of_next_month",
3804
+ timestamp: 1730415600
3805
+ };
3806
+ const configRulesCallbackExample = {
3807
+ type: "callback",
3808
+ chain_id: 1,
3809
+ address: "0x1111111111111111111111111111111111111111",
3810
+ callback_type: "sell_erc20_callback"
3811
+ };
3812
+ const configRulesLoanTokenExample = {
3813
+ type: "loan_token",
3814
+ chain_id: 1,
3815
+ address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
3368
3816
  };
3369
- var ConfigContractsResponse = class {};
3817
+ const configRulesChecksumExample = "f1d2d2f924e986ac86fdf7b36c94bcdf";
3818
+ const configRulesPayloadExample = [
3819
+ configRulesMaturityExample,
3820
+ configRulesCallbackExample,
3821
+ configRulesLoanTokenExample
3822
+ ];
3823
+ const configContractNames = [
3824
+ "mempool",
3825
+ "multicall",
3826
+ "v2"
3827
+ ];
3828
+ const configContractsCursorExample = "505050505:0xd946246695a9259f3b33a78629026f61b3ab40af";
3829
+ var ConfigContractResponse = class {};
3830
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3831
+ type: "number",
3832
+ example: configContractsExample.chain_id
3833
+ })], ConfigContractResponse.prototype, "chain_id", void 0);
3370
3834
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3371
3835
  type: "string",
3372
- example: chainConfigExample.contracts.mempool
3373
- })], ConfigContractsResponse.prototype, "mempool", void 0);
3374
- var MaturitiesResponse = class {};
3836
+ example: configContractsExample.address
3837
+ })], ConfigContractResponse.prototype, "address", void 0);
3375
3838
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3376
- type: "number",
3377
- description: "Unix timestamp for end of current month maturity (last Friday 15:00 UTC).",
3378
- example: maturitiesExample.end_of_month
3379
- })], MaturitiesResponse.prototype, "end_of_month", void 0);
3839
+ type: "string",
3840
+ enum: configContractNames,
3841
+ example: configContractsExample.name
3842
+ })], ConfigContractResponse.prototype, "name", void 0);
3843
+ var ConfigContractsSuccessResponse = class extends SuccessResponse {};
3844
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3845
+ type: "string",
3846
+ nullable: true,
3847
+ example: null
3848
+ })], ConfigContractsSuccessResponse.prototype, "cursor", void 0);
3849
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3850
+ type: () => [ConfigContractResponse],
3851
+ description: "Indexer contract configuration for all indexed chains.",
3852
+ example: configContractsPayloadExample
3853
+ })], ConfigContractsSuccessResponse.prototype, "data", void 0);
3854
+ var ConfigRulesMeta = class {};
3855
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3856
+ type: "string",
3857
+ example: timestampExample
3858
+ })], ConfigRulesMeta.prototype, "timestamp", void 0);
3859
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3860
+ type: "string",
3861
+ example: configRulesChecksumExample
3862
+ })], ConfigRulesMeta.prototype, "checksum", void 0);
3863
+ var ConfigRulesRuleResponse = class {};
3864
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3865
+ type: "string",
3866
+ example: configRulesMaturityExample.type
3867
+ })], ConfigRulesRuleResponse.prototype, "type", void 0);
3380
3868
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3381
3869
  type: "number",
3382
- description: "Unix timestamp for end of next month maturity (last Friday 15:00 UTC).",
3383
- example: maturitiesExample.end_of_next_month
3384
- })], MaturitiesResponse.prototype, "end_of_next_month", void 0);
3385
- var ConfigDataResponse = class {};
3870
+ example: configRulesMaturityExample.chain_id
3871
+ })], ConfigRulesRuleResponse.prototype, "chain_id", void 0);
3872
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3873
+ type: "string",
3874
+ example: configRulesMaturityExample.name,
3875
+ required: false
3876
+ })], ConfigRulesRuleResponse.prototype, "name", void 0);
3386
3877
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3387
3878
  type: "number",
3388
- example: chainConfigExample.chain_id
3389
- })], ConfigDataResponse.prototype, "chain_id", void 0);
3390
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({ type: () => ConfigContractsResponse })], ConfigDataResponse.prototype, "contracts", void 0);
3879
+ example: configRulesMaturityExample.timestamp,
3880
+ required: false
3881
+ })], ConfigRulesRuleResponse.prototype, "timestamp", void 0);
3882
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3883
+ type: "string",
3884
+ example: configRulesCallbackExample.address,
3885
+ required: false
3886
+ })], ConfigRulesRuleResponse.prototype, "address", void 0);
3391
3887
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3392
- type: () => MaturitiesResponse,
3393
- description: "Supported maturity timestamps. Offers must use one of these values.",
3394
- example: chainConfigExample.maturities
3395
- })], ConfigDataResponse.prototype, "maturities", void 0);
3396
- var ConfigSuccessResponse = class extends SuccessResponse {};
3888
+ type: "string",
3889
+ example: configRulesCallbackExample.callback_type,
3890
+ required: false
3891
+ })], ConfigRulesRuleResponse.prototype, "callback_type", void 0);
3892
+ var ConfigRulesSuccessResponse = class {};
3893
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({ type: () => ConfigRulesMeta })], ConfigRulesSuccessResponse.prototype, "meta", void 0);
3397
3894
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3398
3895
  type: "string",
3399
3896
  nullable: true,
3400
3897
  example: null
3401
- })], ConfigSuccessResponse.prototype, "cursor", void 0);
3402
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3403
- type: () => [ConfigDataResponse],
3404
- description: "Array of chain configurations for all indexed chains.",
3405
- example: [chainConfigExample]
3406
- })], ConfigSuccessResponse.prototype, "data", void 0);
3407
- let ConfigController = class ConfigController$1 {
3408
- async getConfig() {}
3898
+ })], ConfigRulesSuccessResponse.prototype, "cursor", void 0);
3899
+ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3900
+ type: () => [ConfigRulesRuleResponse],
3901
+ description: "Configured rules returned by the router API.",
3902
+ example: configRulesPayloadExample
3903
+ })], ConfigRulesSuccessResponse.prototype, "data", void 0);
3904
+ let ConfigContractsController = class ConfigContractsController {
3905
+ async getConfigContracts() {}
3906
+ };
3907
+ __decorate([
3908
+ (0, openapi_metadata_decorators.ApiOperation)({
3909
+ methods: ["get"],
3910
+ path: "/v1/config/contracts",
3911
+ summary: "Get indexer contract configuration",
3912
+ description: "Returns contract addresses used by indexers (mempool, v2) and multicall for indexed chains."
3913
+ }),
3914
+ (0, openapi_metadata_decorators.ApiQuery)({
3915
+ name: "cursor",
3916
+ type: "string",
3917
+ required: false,
3918
+ example: configContractsCursorExample,
3919
+ description: "Pagination cursor in chain_id:address format (lowercase address)."
3920
+ }),
3921
+ (0, openapi_metadata_decorators.ApiQuery)({
3922
+ name: "limit",
3923
+ type: "number",
3924
+ required: false,
3925
+ example: 1e3,
3926
+ description: "Maximum number of contracts to return (max 1000)."
3927
+ }),
3928
+ (0, openapi_metadata_decorators.ApiQuery)({
3929
+ name: "chains",
3930
+ type: ["number"],
3931
+ required: false,
3932
+ example: "1,8453",
3933
+ description: "Filter by chain IDs (comma-separated).",
3934
+ style: "form",
3935
+ explode: false
3936
+ }),
3937
+ (0, openapi_metadata_decorators.ApiResponse)({
3938
+ status: 200,
3939
+ description: "Success",
3940
+ type: ConfigContractsSuccessResponse
3941
+ })
3942
+ ], ConfigContractsController.prototype, "getConfigContracts", null);
3943
+ ConfigContractsController = __decorate([(0, openapi_metadata_decorators.ApiTags)("System")], ConfigContractsController);
3944
+ let ConfigRulesController = class ConfigRulesController {
3945
+ async getConfigRules() {}
3409
3946
  };
3410
- __decorate([(0, openapi_metadata_decorators.ApiOperation)({
3411
- methods: ["get"],
3412
- path: "/v1/config",
3413
- summary: "Get router configuration",
3414
- description: "Returns chain configurations including contract addresses and supported maturity timestamps."
3415
- }), (0, openapi_metadata_decorators.ApiResponse)({
3416
- status: 200,
3417
- description: "Success",
3418
- type: ConfigSuccessResponse
3419
- })], ConfigController.prototype, "getConfig", null);
3420
- ConfigController = __decorate([(0, openapi_metadata_decorators.ApiTags)("System")], ConfigController);
3421
- let ObligationsController = class ObligationsController$1 {
3947
+ __decorate([
3948
+ (0, openapi_metadata_decorators.ApiOperation)({
3949
+ methods: ["get"],
3950
+ path: "/v1/config/rules",
3951
+ summary: "Get config rules",
3952
+ description: "Returns configured rules for supported chains."
3953
+ }),
3954
+ (0, openapi_metadata_decorators.ApiQuery)({
3955
+ name: "cursor",
3956
+ type: "string",
3957
+ required: false,
3958
+ example: "maturity:1:1730415600:end_of_next_month",
3959
+ description: "Pagination cursor in type:chain_id:<value> format."
3960
+ }),
3961
+ (0, openapi_metadata_decorators.ApiQuery)({
3962
+ name: "limit",
3963
+ type: "number",
3964
+ required: false,
3965
+ example: 100,
3966
+ description: "Maximum number of rules to return (max 1000)."
3967
+ }),
3968
+ (0, openapi_metadata_decorators.ApiQuery)({
3969
+ name: "types",
3970
+ type: ["string"],
3971
+ required: false,
3972
+ example: "maturity,loan_token",
3973
+ description: "Filter by rule types (comma-separated).",
3974
+ style: "form",
3975
+ explode: false
3976
+ }),
3977
+ (0, openapi_metadata_decorators.ApiQuery)({
3978
+ name: "chains",
3979
+ type: ["number"],
3980
+ required: false,
3981
+ example: "1,8453",
3982
+ description: "Filter by chain IDs (comma-separated).",
3983
+ style: "form",
3984
+ explode: false
3985
+ }),
3986
+ (0, openapi_metadata_decorators.ApiResponse)({
3987
+ status: 200,
3988
+ description: "Success",
3989
+ type: ConfigRulesSuccessResponse
3990
+ })
3991
+ ], ConfigRulesController.prototype, "getConfigRules", null);
3992
+ ConfigRulesController = __decorate([(0, openapi_metadata_decorators.ApiTags)("System")], ConfigRulesController);
3993
+ let ObligationsController = class ObligationsController {
3422
3994
  async getObligations() {}
3423
3995
  async getObligation() {}
3424
3996
  };
@@ -3442,32 +4014,40 @@ __decorate([
3442
4014
  description: "Maximum number of obligations to return."
3443
4015
  }),
3444
4016
  (0, openapi_metadata_decorators.ApiQuery)({
3445
- name: "chain",
3446
- type: "number",
4017
+ name: "chains",
4018
+ type: ["number"],
3447
4019
  required: false,
3448
- example: 1,
3449
- description: "Filter by chain ID."
4020
+ example: "1,8453",
4021
+ description: "Filter by chain IDs (comma-separated).",
4022
+ style: "form",
4023
+ explode: false
3450
4024
  }),
3451
4025
  (0, openapi_metadata_decorators.ApiQuery)({
3452
- name: "loan_token",
3453
- type: "string",
4026
+ name: "loan_tokens",
4027
+ type: ["string"],
3454
4028
  required: false,
3455
- example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
3456
- description: "Filter by loan token address."
4029
+ example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078,0x34Cf890dB685FC536E05652FB41f02090c3fb751",
4030
+ description: "Filter by loan token addresses (comma-separated).",
4031
+ style: "form",
4032
+ explode: false
3457
4033
  }),
3458
4034
  (0, openapi_metadata_decorators.ApiQuery)({
3459
- name: "collateral_token",
3460
- type: "string",
4035
+ name: "collateral_tokens",
4036
+ type: ["string"],
3461
4037
  required: false,
3462
- example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
3463
- description: "Filter by collateral token (matches any collateral in the obligation)."
4038
+ example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751,0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
4039
+ description: "Filter by collateral tokens (comma-separated, matches any collateral).",
4040
+ style: "form",
4041
+ explode: false
3464
4042
  }),
3465
4043
  (0, openapi_metadata_decorators.ApiQuery)({
3466
- name: "maturity",
3467
- type: "number",
4044
+ name: "maturities",
4045
+ type: ["number"],
3468
4046
  required: false,
3469
- example: 1761922800,
3470
- description: "Filter by exact maturity timestamp (unix seconds)."
4047
+ example: "1761922800,1764524800",
4048
+ description: "Filter by exact maturity timestamps (comma-separated, unix seconds).",
4049
+ style: "form",
4050
+ explode: false
3471
4051
  }),
3472
4052
  (0, openapi_metadata_decorators.ApiResponse)({
3473
4053
  status: 200,
@@ -3499,7 +4079,7 @@ ObligationsController = __decorate([(0, openapi_metadata_decorators.ApiTags)("Ma
3499
4079
  description: "Bad Request",
3500
4080
  type: BadRequestResponse
3501
4081
  })], ObligationsController);
3502
- let UsersController = class UsersController$1 {
4082
+ let UsersController = class UsersController {
3503
4083
  async getUserPositions() {}
3504
4084
  };
3505
4085
  __decorate([
@@ -3538,16 +4118,18 @@ UsersController = __decorate([(0, openapi_metadata_decorators.ApiTags)("Make"),
3538
4118
  description: "Bad Request",
3539
4119
  type: BadRequestResponse
3540
4120
  })], UsersController);
3541
- const OpenApi = async (options = {}) => {
3542
- const document = await (0, openapi_metadata.generateDocument)({
4121
+ const OpenApi = async () => {
4122
+ return await (0, openapi_metadata.generateDocument)({
3543
4123
  controllers: [
3544
4124
  BooksController,
3545
- ConfigController,
4125
+ ConfigContractsController,
4126
+ ConfigRulesController,
3546
4127
  OffersController,
3547
4128
  ObligationsController,
3548
4129
  HealthController,
3549
4130
  UsersController,
3550
- ValidateController
4131
+ ValidateController,
4132
+ CallbacksController
3551
4133
  ],
3552
4134
  document: {
3553
4135
  openapi: "3.1.0",
@@ -3579,17 +4161,11 @@ const OpenApi = async (options = {}) => {
3579
4161
  ]
3580
4162
  }
3581
4163
  });
3582
- if (options.rules && options.rules.length > 0) {
3583
- const rulesDescription = options.rules.map((rule) => `- **${rule.name}**: ${rule.description}`).join("\n");
3584
- const validatePath = document.paths?.["/v1/validate"];
3585
- if (validatePath && "post" in validatePath && validatePath.post) validatePath.post.description = `Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure.\n\n**Available validation rules:**\n${rulesDescription}`;
3586
- }
3587
- return document;
3588
4164
  };
3589
4165
 
3590
4166
  //#endregion
3591
4167
  //#region src/api/Schema/PositionResponse.ts
3592
- var PositionResponse_exports = /* @__PURE__ */ __export({ from: () => from$1 });
4168
+ var PositionResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$1 });
3593
4169
  /**
3594
4170
  * Creates a `PositionResponse` from a `PositionWithReserved`.
3595
4171
  * @param position - {@link PositionWithReserved}
@@ -3609,6 +4185,10 @@ function from$1(position) {
3609
4185
  //#region src/api/Schema/requests.ts
3610
4186
  const MAX_LIMIT = 100;
3611
4187
  const DEFAULT_LIMIT = 20;
4188
+ const CONFIG_RULES_MAX_LIMIT = 1e3;
4189
+ const CONFIG_RULES_DEFAULT_LIMIT = 100;
4190
+ const CONFIG_CONTRACTS_MAX_LIMIT = 1e3;
4191
+ const CONFIG_CONTRACTS_DEFAULT_LIMIT = 1e3;
3612
4192
  /** Validate cursor is a valid base64url-encoded JSON object.
3613
4193
  * Domain layer handles semantic validation of cursor fields. */
3614
4194
  function isValidBase64urlJson(val) {
@@ -3620,6 +4200,15 @@ function isValidBase64urlJson(val) {
3620
4200
  return false;
3621
4201
  }
3622
4202
  }
4203
+ const csvArray = (schema) => zod.preprocess((value) => {
4204
+ if (value === void 0) return void 0;
4205
+ if (Array.isArray(value)) {
4206
+ if (value.some((item) => typeof item !== "string")) return value;
4207
+ return value.flatMap((item) => item.split(",")).map((item) => item.trim()).filter((item) => item.length > 0);
4208
+ }
4209
+ if (typeof value === "string") return value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
4210
+ return value;
4211
+ }, zod.array(schema)).optional();
3623
4212
  const PaginationQueryParams = zod.object({
3624
4213
  cursor: zod.string().optional().refine((val) => {
3625
4214
  if (!val) return true;
@@ -3633,6 +4222,43 @@ const PaginationQueryParams = zod.object({
3633
4222
  example: 10
3634
4223
  })
3635
4224
  });
4225
+ const ConfigRuleTypes = zod.enum([
4226
+ "maturity",
4227
+ "callback",
4228
+ "loan_token"
4229
+ ]);
4230
+ const GetConfigRulesQueryParams = zod.object({
4231
+ cursor: zod.string().regex(/^(maturity|callback|loan_token):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
4232
+ description: "Pagination cursor in type:chain_id:<value> format",
4233
+ example: "maturity:1:1730415600:end_of_next_month"
4234
+ }),
4235
+ limit: zod.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(zod.number().max(CONFIG_RULES_MAX_LIMIT, { message: `Limit cannot exceed ${CONFIG_RULES_MAX_LIMIT}` })).optional().default(CONFIG_RULES_DEFAULT_LIMIT).meta({
4236
+ description: `Limit maximum: ${CONFIG_RULES_MAX_LIMIT}. Default: ${CONFIG_RULES_DEFAULT_LIMIT}`,
4237
+ example: 100
4238
+ }),
4239
+ types: csvArray(ConfigRuleTypes).meta({
4240
+ description: "Filter by rule types (comma-separated).",
4241
+ example: "maturity,loan_token"
4242
+ }),
4243
+ chains: csvArray(zod.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
4244
+ description: "Filter by chain IDs (comma-separated).",
4245
+ example: "1,8453"
4246
+ })
4247
+ });
4248
+ const GetConfigContractsQueryParams = zod.object({
4249
+ cursor: zod.string().regex(/^[1-9]\d*:0x[a-fA-F0-9]{40}$/, { message: "Cursor must be in the format chain_id:0x..." }).optional().meta({
4250
+ description: "Pagination cursor in chain_id:address format (lowercase address).",
4251
+ example: "1:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
4252
+ }),
4253
+ limit: zod.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(zod.number().max(CONFIG_CONTRACTS_MAX_LIMIT, { message: `Limit cannot exceed ${CONFIG_CONTRACTS_MAX_LIMIT}` })).optional().default(CONFIG_CONTRACTS_DEFAULT_LIMIT).meta({
4254
+ description: `Limit maximum: ${CONFIG_CONTRACTS_MAX_LIMIT}. Default: ${CONFIG_CONTRACTS_DEFAULT_LIMIT}`,
4255
+ example: 1e3
4256
+ }),
4257
+ chains: csvArray(zod.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
4258
+ description: "Filter by chain IDs (comma-separated).",
4259
+ example: "1,8453"
4260
+ })
4261
+ });
3636
4262
  const GetOffersQueryParams = zod.object({
3637
4263
  ...PaginationQueryParams.shape,
3638
4264
  side: zod.enum(["buy", "sell"]).optional().meta({
@@ -3670,21 +4296,21 @@ const GetObligationsQueryParams = zod.object({
3670
4296
  description: "Obligation id cursor",
3671
4297
  example: "0x1234567890123456789012345678901234567890123456789012345678901234"
3672
4298
  }),
3673
- chain: zod.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).optional().meta({
3674
- description: "Filter by chain ID",
3675
- example: "1"
4299
+ chains: csvArray(zod.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
4300
+ description: "Filter by chain IDs (comma-separated).",
4301
+ example: "1,8453"
3676
4302
  }),
3677
- loan_token: zod.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Loan token must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
3678
- description: "Filter by loan token address",
3679
- example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
4303
+ loan_tokens: csvArray(zod.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Loan token must be a valid 20-byte address" }).transform((val) => val.toLowerCase())).meta({
4304
+ description: "Filter by loan token addresses (comma-separated).",
4305
+ example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078,0x34Cf890dB685FC536E05652FB41f02090c3fb751"
3680
4306
  }),
3681
- collateral_token: zod.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Collateral token must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
3682
- description: "Filter by collateral token (matches any collateral in the obligation)",
3683
- example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751"
4307
+ collateral_tokens: csvArray(zod.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Collateral token must be a valid 20-byte address" }).transform((val) => val.toLowerCase())).meta({
4308
+ description: "Filter by collateral tokens (comma-separated, matches any collateral).",
4309
+ example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751,0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
3684
4310
  }),
3685
- maturity: zod.string().regex(/^[1-9]\d*$/, { message: "Maturity must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).optional().meta({
3686
- description: "Filter by exact maturity timestamp (unix seconds)",
3687
- example: "1761922800"
4311
+ maturities: csvArray(zod.string().regex(/^[1-9]\d*$/, { message: "Maturity must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
4312
+ description: "Filter by exact maturity timestamps (comma-separated, unix seconds).",
4313
+ example: "1761922800,1764524800"
3688
4314
  })
3689
4315
  });
3690
4316
  const GetObligationParams = zod.object({ obligation_id: zod.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({
@@ -3735,6 +4361,16 @@ const GetBookParams = zod.object({
3735
4361
  })
3736
4362
  });
3737
4363
  const ValidateOffersBody = zod.object({ offers: zod.array(zod.unknown()).min(1, { message: "'offers' must contain at least 1 offer" }) }).strict();
4364
+ const CallbackTypesBody = zod.object({ callbacks: zod.array(zod.object({
4365
+ chain_id: zod.number().int().positive().meta({
4366
+ description: "Chain id.",
4367
+ example: 1
4368
+ }),
4369
+ addresses: zod.array(zod.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Callback address must be a valid 20-byte address" }).transform((val) => val.toLowerCase())).meta({
4370
+ description: "Callback contract addresses.",
4371
+ example: ["0x1111111111111111111111111111111111111111", "0x3333333333333333333333333333333333333333"]
4372
+ })
4373
+ }).strict()) }).strict();
3738
4374
  const GetUserPositionsParams = zod.object({
3739
4375
  ...PaginationQueryParams.shape,
3740
4376
  user_address: zod.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "User address must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).meta({
@@ -3746,11 +4382,14 @@ const schemas = {
3746
4382
  get_health: HealthQueryParams,
3747
4383
  get_health_collectors: HealthQueryParams,
3748
4384
  get_health_chains: HealthQueryParams,
4385
+ get_config_contracts: GetConfigContractsQueryParams,
4386
+ get_config_rules: GetConfigRulesQueryParams,
3749
4387
  get_offers: GetOffersQueryParams,
3750
4388
  get_obligations: GetObligationsQueryParams,
3751
4389
  get_obligation: GetObligationParams,
3752
4390
  get_book: GetBookParams,
3753
4391
  validate_offers: ValidateOffersBody,
4392
+ callback_types: CallbackTypesBody,
3754
4393
  get_user_positions: GetUserPositionsParams
3755
4394
  };
3756
4395
  function parse(action, query) {
@@ -3762,14 +4401,16 @@ function safeParse(action, query, error) {
3762
4401
 
3763
4402
  //#endregion
3764
4403
  //#region src/api/Schema/index.ts
3765
- var Schema_exports = /* @__PURE__ */ __export({
4404
+ var Schema_exports = /* @__PURE__ */ __exportAll({
3766
4405
  BookResponse: () => BookResponse_exports,
3767
4406
  BooksController: () => BooksController,
4407
+ CallbacksController: () => CallbacksController,
3768
4408
  ChainHealth: () => ChainHealth,
3769
4409
  ChainsHealthResponse: () => ChainsHealthResponse,
3770
4410
  CollectorHealth: () => CollectorHealth,
3771
4411
  CollectorsHealthResponse: () => CollectorsHealthResponse,
3772
- ConfigController: () => ConfigController,
4412
+ ConfigContractsController: () => ConfigContractsController,
4413
+ ConfigRulesController: () => ConfigRulesController,
3773
4414
  HealthController: () => HealthController,
3774
4415
  ObligationResponse: () => ObligationResponse_exports,
3775
4416
  ObligationsController: () => ObligationsController,
@@ -3786,7 +4427,7 @@ var Schema_exports = /* @__PURE__ */ __export({
3786
4427
 
3787
4428
  //#endregion
3788
4429
  //#region src/client/Client.ts
3789
- var Client_exports = /* @__PURE__ */ __export({
4430
+ var Client_exports$1 = /* @__PURE__ */ __exportAll({
3790
4431
  HttpForbiddenError: () => HttpForbiddenError,
3791
4432
  HttpGetApiFailedError: () => HttpGetApiFailedError,
3792
4433
  HttpRateLimitError: () => HttpRateLimitError,
@@ -3819,12 +4460,16 @@ function connect$1(parameters) {
3819
4460
  };
3820
4461
  const apiClient = (0, openapi_fetch.default)({
3821
4462
  baseUrl: config.url.toString(),
3822
- headers: config.headers
4463
+ headers: config.headers,
4464
+ querySerializer: { array: {
4465
+ style: "form",
4466
+ explode: false
4467
+ } }
3823
4468
  });
3824
4469
  return {
3825
4470
  ...config,
3826
- getOffers: (parameters$1) => getOffers(apiClient, parameters$1),
3827
- getObligations: (parameters$1) => getObligations(apiClient, parameters$1)
4471
+ getOffers: (parameters) => getOffers(apiClient, parameters),
4472
+ getObligations: (parameters) => getObligations(apiClient, parameters)
3828
4473
  };
3829
4474
  }
3830
4475
  async function getOffers(apiClient, parameters) {
@@ -3851,7 +4496,7 @@ async function getOffers(apiClient, parameters) {
3851
4496
  obligation_units: offerData.obligation_units,
3852
4497
  obligation_shares: offerData.obligation_shares,
3853
4498
  price: offerData.price,
3854
- maturity: from$10(offerData.obligation.maturity),
4499
+ maturity: from$11(offerData.obligation.maturity),
3855
4500
  expiry: offerData.expiry,
3856
4501
  start: offerData.start,
3857
4502
  group: offerData.group,
@@ -3887,10 +4532,10 @@ async function getObligations(apiClient, parameters) {
3887
4532
  const { data, error, response } = await apiClient.GET("/v1/obligations", { params: { query: {
3888
4533
  cursor: parameters?.cursor,
3889
4534
  limit: parameters?.limit,
3890
- chain: parameters?.chainId,
3891
- loan_token: parameters?.loanToken,
3892
- collateral_token: parameters?.collateralToken,
3893
- maturity: parameters?.maturity
4535
+ chains: parameters?.chainIds,
4536
+ loan_tokens: parameters?.loanTokens,
4537
+ collateral_tokens: parameters?.collateralTokens,
4538
+ maturities: parameters?.maturities
3894
4539
  } } });
3895
4540
  if (error !== void 0) {
3896
4541
  switch (response.status) {
@@ -3909,7 +4554,7 @@ async function getObligations(apiClient, parameters) {
3909
4554
  oracle: collateral.oracle,
3910
4555
  lltv: collateral.lltv
3911
4556
  })),
3912
- maturity: from$10(item.maturity)
4557
+ maturity: from$11(item.maturity)
3913
4558
  });
3914
4559
  const { obligationId: _, ...returned } = {
3915
4560
  id: () => id(obligation),
@@ -3958,10 +4603,125 @@ var HttpGetApiFailedError = class extends BaseError {
3958
4603
  }
3959
4604
  };
3960
4605
 
4606
+ //#endregion
4607
+ //#region src/gatekeeper/Client.ts
4608
+ var Client_exports = /* @__PURE__ */ __exportAll({ createHttpClient: () => createHttpClient });
4609
+ const DEFAULT_TIMEOUT_MS = 1e4;
4610
+ /**
4611
+ * Create an HTTP client for a gatekeeper service.
4612
+ * @param config - Gatekeeper client configuration. {@link ClientConfig}
4613
+ * @returns An HTTP-backed gatekeeper client. {@link GatekeeperClient}
4614
+ */
4615
+ function createHttpClient(config) {
4616
+ const fetchFn = config.fetchFn ?? fetch;
4617
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
4618
+ const baseUrl = normalizeBaseUrl(config.baseUrl);
4619
+ const baseHeaders = config.originSecret ? { "x-origin-verify": config.originSecret } : void 0;
4620
+ const request = async (path, init) => {
4621
+ const controller = new AbortController();
4622
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
4623
+ try {
4624
+ return await fetchFn(`${baseUrl}${path}`, {
4625
+ ...init,
4626
+ headers: mergeHeaders(baseHeaders, init.headers),
4627
+ signal: controller.signal
4628
+ });
4629
+ } finally {
4630
+ clearTimeout(timeout);
4631
+ }
4632
+ };
4633
+ const validate = async (body) => {
4634
+ const response = await request("/v1/validate", {
4635
+ method: "POST",
4636
+ headers: { "content-type": "application/json" },
4637
+ body: JSON.stringify(body)
4638
+ });
4639
+ const json = await response.json();
4640
+ return {
4641
+ statusCode: response.status,
4642
+ body: json
4643
+ };
4644
+ };
4645
+ const getConfigRules = async (query) => {
4646
+ const params = new URLSearchParams();
4647
+ if (query?.cursor) params.set("cursor", query.cursor);
4648
+ if (query?.limit !== void 0) params.set("limit", query.limit.toString());
4649
+ if (query?.types !== void 0) {
4650
+ const typesValue = Array.isArray(query.types) ? query.types.join(",") : query.types;
4651
+ if (typesValue.length > 0) params.set("types", typesValue);
4652
+ }
4653
+ const response = await request(params.size > 0 ? `/v1/config/rules?${params.toString()}` : "/v1/config/rules", { method: "GET" });
4654
+ const json = await response.json();
4655
+ return {
4656
+ statusCode: response.status,
4657
+ body: json
4658
+ };
4659
+ };
4660
+ const isAllowed = async (offers) => {
4661
+ const { statusCode, body } = await validate({ offers: offers.map((offer) => toSnakeCase(offer)) });
4662
+ if (statusCode !== 200) {
4663
+ const errorMessage = extractErrorMessage(body);
4664
+ throw new Error(`Gatekeeper validation failed: ${errorMessage ?? `status ${statusCode}`}`);
4665
+ }
4666
+ const data = body.data;
4667
+ if (!data || typeof data !== "object") throw new Error("Gatekeeper validation response is invalid.");
4668
+ if ("issues" in data) {
4669
+ const issues = data.issues.map((issue) => ({
4670
+ ruleName: issue.rule,
4671
+ message: issue.message,
4672
+ item: offers[issue.index]
4673
+ }));
4674
+ const invalidIndices = new Set(data.issues.map((issue) => issue.index));
4675
+ return {
4676
+ valid: offers.filter((_, index) => !invalidIndices.has(index)),
4677
+ issues
4678
+ };
4679
+ }
4680
+ if (!("payload" in data) || !("root" in data)) throw new Error("Gatekeeper validation response is missing payload data.");
4681
+ return {
4682
+ valid: offers.slice(),
4683
+ issues: []
4684
+ };
4685
+ };
4686
+ const getCallbackTypes = async (requestPayload) => {
4687
+ const response = await request("/v1/callbacks", {
4688
+ method: "POST",
4689
+ headers: { "content-type": "application/json" },
4690
+ body: JSON.stringify(requestPayload)
4691
+ });
4692
+ const json = await response.json();
4693
+ if (!response.ok) throw new Error(`Gatekeeper callbacks request failed: ${extractErrorMessage(json) ?? response.statusText}`);
4694
+ if (!("data" in json) || !Array.isArray(json.data)) throw new Error("Gatekeeper callbacks response is invalid.");
4695
+ return json.data;
4696
+ };
4697
+ return {
4698
+ baseUrl,
4699
+ validate,
4700
+ getConfigRules,
4701
+ isAllowed,
4702
+ getCallbackTypes
4703
+ };
4704
+ }
4705
+ function mergeHeaders(base, extra) {
4706
+ if (!base && !extra) return void 0;
4707
+ const merged = new Headers(base ?? void 0);
4708
+ if (extra) for (const [key, value] of new Headers(extra).entries()) merged.set(key, value);
4709
+ return merged;
4710
+ }
4711
+ function normalizeBaseUrl(url) {
4712
+ return url.trim().replace(/\/+$/, "");
4713
+ }
4714
+ function extractErrorMessage(payload) {
4715
+ if (!payload || typeof payload !== "object") return void 0;
4716
+ const error = payload.error;
4717
+ if (!error || typeof error !== "object") return void 0;
4718
+ return typeof error.message === "string" ? error.message : void 0;
4719
+ }
4720
+
3961
4721
  //#endregion
3962
4722
  //#region src/gatekeeper/Gate.ts
3963
- var Gate_exports = /* @__PURE__ */ __export({
3964
- batch: () => batch$1,
4723
+ var Gate_exports = /* @__PURE__ */ __exportAll({
4724
+ batch: () => batch,
3965
4725
  run: () => run,
3966
4726
  single: () => single
3967
4727
  });
@@ -3972,12 +4732,12 @@ var Gate_exports = /* @__PURE__ */ __export({
3972
4732
  * @param run - The function that validates the rule.
3973
4733
  * @returns The created rule.
3974
4734
  */
3975
- function single(name, description, run$1) {
4735
+ function single(name, description, run) {
3976
4736
  return {
3977
4737
  kind: "single",
3978
4738
  name,
3979
4739
  description,
3980
- run: run$1
4740
+ run
3981
4741
  };
3982
4742
  }
3983
4743
  /**
@@ -3987,12 +4747,12 @@ function single(name, description, run$1) {
3987
4747
  * @param run - The function that validates the rule.
3988
4748
  * @returns The created rule.
3989
4749
  */
3990
- function batch$1(name, description, run$1) {
4750
+ function batch(name, description, run) {
3991
4751
  return {
3992
4752
  kind: "batch",
3993
4753
  name,
3994
4754
  description,
3995
- run: run$1
4755
+ run
3996
4756
  };
3997
4757
  }
3998
4758
  async function run(parameters) {
@@ -4043,16 +4803,26 @@ async function run(parameters) {
4043
4803
  };
4044
4804
  }
4045
4805
 
4806
+ //#endregion
4807
+ //#region src/gatekeeper/Gatekeeper.ts
4808
+ var Gatekeeper_exports = /* @__PURE__ */ __exportAll({ create: () => create });
4809
+ /**
4810
+ * Create a gatekeeper instance with the provided rules.
4811
+ * @param parameters - Gatekeeper parameters. {@link GatekeeperParameters}
4812
+ * @returns Gatekeeper instance. {@link Gatekeeper}
4813
+ */
4814
+ function create(parameters) {
4815
+ const { rules } = parameters;
4816
+ return { isAllowed: async (offers) => {
4817
+ return await run({
4818
+ items: offers,
4819
+ rules
4820
+ });
4821
+ } };
4822
+ }
4823
+
4046
4824
  //#endregion
4047
4825
  //#region src/gatekeeper/GateConfig.ts
4048
- var GateConfig_exports = /* @__PURE__ */ __export({
4049
- assets: () => assets,
4050
- configs: () => configs,
4051
- getCallback: () => getCallback,
4052
- getCallbackAddresses: () => getCallbackAddresses,
4053
- getCallbackType: () => getCallbackType,
4054
- getCallbackTypeAddresses: () => getCallbackTypeAddresses
4055
- });
4056
4826
  /**
4057
4827
  * Returns the callback configuration for a given chain and callback type, if it exists.
4058
4828
  *
@@ -4071,19 +4841,8 @@ function getCallback(chain, type) {
4071
4841
  * @param address - Callback contract address
4072
4842
  * @returns The callback type when found, otherwise undefined
4073
4843
  */
4074
- function getCallbackType(chain, address$1) {
4075
- return configs[chain].callbacks?.find((c) => c.type !== CallbackType.BuyWithEmptyCallback && c.addresses.includes(address$1?.toLowerCase()))?.type;
4076
- }
4077
- /**
4078
- * Returns the callback addresses for a given chain and callback type, if it exists.
4079
- * @param chain - Chain name for which to read the validation configuration
4080
- * @param type - Callback type to retrieve
4081
- * @returns The matching callback addresses or an empty array if not configured
4082
- */
4083
- function getCallbackTypeAddresses(chain, type) {
4084
- if (type === CallbackType.BuyWithEmptyCallback) return [];
4085
- const match = configs[chain].callbacks?.find((c) => c.type === type);
4086
- return match && "addresses" in match ? match.addresses : [];
4844
+ function getCallbackType(chain, address) {
4845
+ return configs[chain].callbacks?.find((c) => c.type !== Type$1.BuyWithEmptyCallback && c.addresses.includes(address?.toLowerCase()))?.type;
4087
4846
  }
4088
4847
  /**
4089
4848
  * Returns the list of allowed non-empty callback addresses for a chain.
@@ -4092,7 +4851,7 @@ function getCallbackTypeAddresses(chain, type) {
4092
4851
  * @returns Array of allowed callback addresses (lowercased). Empty when none configured
4093
4852
  */
4094
4853
  const getCallbackAddresses = (chain) => {
4095
- return configs[chain].callbacks?.filter((c) => c.type !== CallbackType.BuyWithEmptyCallback).flatMap((c) => c.addresses) ?? [];
4854
+ return configs[chain].callbacks?.filter((c) => c.type !== Type$1.BuyWithEmptyCallback).flatMap((c) => c.addresses) ?? [];
4096
4855
  };
4097
4856
  const assets = {
4098
4857
  [ChainId.ETHEREUM.toString()]: [
@@ -4125,83 +4884,68 @@ const configs = {
4125
4884
  ethereum: {
4126
4885
  callbacks: [
4127
4886
  {
4128
- type: CallbackType.BuyVaultV1Callback,
4887
+ type: Type$1.BuyVaultV1Callback,
4129
4888
  addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4130
4889
  vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
4131
4890
  },
4132
4891
  {
4133
- type: CallbackType.SellERC20Callback,
4892
+ type: Type$1.SellERC20Callback,
4134
4893
  addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4135
4894
  },
4136
- { type: CallbackType.BuyWithEmptyCallback }
4895
+ { type: Type$1.BuyWithEmptyCallback }
4137
4896
  ],
4138
4897
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4139
4898
  },
4140
4899
  base: {
4141
4900
  callbacks: [
4142
4901
  {
4143
- type: CallbackType.BuyVaultV1Callback,
4902
+ type: Type$1.BuyVaultV1Callback,
4144
4903
  addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4145
4904
  vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0xFf62A7c278C62eD665133147129245053Bbf5918"]
4146
4905
  },
4147
4906
  {
4148
- type: CallbackType.SellERC20Callback,
4907
+ type: Type$1.SellERC20Callback,
4149
4908
  addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4150
4909
  },
4151
- { type: CallbackType.BuyWithEmptyCallback }
4910
+ { type: Type$1.BuyWithEmptyCallback }
4152
4911
  ],
4153
4912
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4154
4913
  },
4155
4914
  "ethereum-virtual-testnet": {
4156
4915
  callbacks: [
4157
4916
  {
4158
- type: CallbackType.BuyVaultV1Callback,
4917
+ type: Type$1.BuyVaultV1Callback,
4159
4918
  addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4160
4919
  vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
4161
4920
  },
4162
4921
  {
4163
- type: CallbackType.SellERC20Callback,
4922
+ type: Type$1.SellERC20Callback,
4164
4923
  addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4165
4924
  },
4166
- { type: CallbackType.BuyWithEmptyCallback }
4925
+ { type: Type$1.BuyWithEmptyCallback }
4167
4926
  ],
4168
4927
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4169
4928
  },
4170
4929
  anvil: {
4171
4930
  callbacks: [
4172
4931
  {
4173
- type: CallbackType.BuyVaultV1Callback,
4932
+ type: Type$1.BuyVaultV1Callback,
4174
4933
  addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4175
4934
  vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
4176
4935
  },
4177
4936
  {
4178
- type: CallbackType.SellERC20Callback,
4937
+ type: Type$1.SellERC20Callback,
4179
4938
  addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4180
4939
  },
4181
- { type: CallbackType.BuyWithEmptyCallback }
4940
+ { type: Type$1.BuyWithEmptyCallback }
4182
4941
  ],
4183
4942
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4184
4943
  }
4185
4944
  };
4186
4945
 
4187
- //#endregion
4188
- //#region src/gatekeeper/Gatekeeper.ts
4189
- var Gatekeeper_exports = /* @__PURE__ */ __export({ create: () => create });
4190
- function create(parameters) {
4191
- return {
4192
- rules: parameters.rules,
4193
- isAllowed: async (offers) => {
4194
- return await run({
4195
- items: offers,
4196
- rules: parameters.rules
4197
- });
4198
- }
4199
- };
4200
- }
4201
-
4202
4946
  //#endregion
4203
4947
  //#region src/gatekeeper/Rules.ts
4204
- var Rules_exports = /* @__PURE__ */ __export({
4948
+ var Rules_exports = /* @__PURE__ */ __exportAll({
4205
4949
  amountMutualExclusivity: () => amountMutualExclusivity,
4206
4950
  callback: () => callback,
4207
4951
  chains: () => chains,
@@ -4220,21 +4964,21 @@ function validity(parameters) {
4220
4964
  const { client } = parameters;
4221
4965
  const sellErc20CallbackInvalid = single("sell_erc20_callback_invalid", "Validates that sell offers have valid ERC20 callback data matching offer collaterals", (offer) => {
4222
4966
  const callbackType = getCallbackType(client.chain.name, offer.callback.address);
4223
- if (callbackType !== CallbackType.SellERC20Callback) return;
4967
+ if (callbackType !== Type$1.SellERC20Callback) return;
4224
4968
  const decoded = decode$2(callbackType, offer.callback.data);
4225
4969
  if (decoded.length === 0) return { message: "Callback data cannot be decoded or is empty." };
4226
- if (callbackType === CallbackType.SellERC20Callback) {
4970
+ if (callbackType === Type$1.SellERC20Callback) {
4227
4971
  const offerCollaterals = new Set(offer.collaterals.map((c) => c.asset.toLowerCase()));
4228
4972
  if (decoded.length !== offer.collaterals.length) return { message: `Sell callback collateral length mismatch. Expected ${offer.collaterals.length}, got ${decoded.length}.` };
4229
4973
  for (const { contract } of decoded) if (!offerCollaterals.has(contract.toLowerCase())) return { message: "Sell callback collateral is not part of offer collaterals." };
4230
4974
  }
4231
4975
  });
4232
- const buyCallbackVaultInvalid = batch$1("buy_offers_callback_vault_invalid", "Validates that buy offers have valid vault callbacks registered in allowed factories with matching assets", async (offers) => {
4976
+ 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) => {
4233
4977
  const validationIssues = /* @__PURE__ */ new Map();
4234
4978
  const offersByVaultAddress = /* @__PURE__ */ new Map();
4235
4979
  for (let i = 0; i < offers.length; i++) {
4236
4980
  const offer = offers[i];
4237
- if (getCallbackType(client.chain.name, offer.callback.address) !== CallbackType.BuyVaultV1Callback) continue;
4981
+ if (getCallbackType(client.chain.name, offer.callback.address) !== Type$1.BuyVaultV1Callback) continue;
4238
4982
  try {
4239
4983
  const callbackVaults = decodeBuyVaultV1Callback(offer.callback.data);
4240
4984
  for (const { contract } of callbackVaults) {
@@ -4249,7 +4993,7 @@ function validity(parameters) {
4249
4993
  }
4250
4994
  const uniqueVaultAddresses = Array.from(offersByVaultAddress.keys());
4251
4995
  if (uniqueVaultAddresses.length === 0) return validationIssues;
4252
- const allowedFactories = getCallback(client.chain.name, CallbackType.BuyVaultV1Callback)?.vaultFactories.map((f) => f.toLowerCase());
4996
+ const allowedFactories = getCallback(client.chain.name, Type$1.BuyVaultV1Callback)?.vaultFactories.map((f) => f.toLowerCase());
4253
4997
  if (!allowedFactories) return validationIssues;
4254
4998
  const multicallContracts = [];
4255
4999
  for (const vaultAddress of uniqueVaultAddresses) {
@@ -4317,16 +5061,16 @@ function validity(parameters) {
4317
5061
  buyCallbackVaultInvalid
4318
5062
  ];
4319
5063
  }
4320
- const chains = ({ chains: chains$2 }) => single("chain_ids", `Validates that offer chain is one of: [${chains$2.map((c) => c.id).join(", ")}]`, (offer) => {
4321
- const allowedChainIds = chains$2.map((c) => c.id);
4322
- if (!allowedChainIds.some((id$1) => id$1 === offer.chainId)) return { message: `Chain ID ${offer.chainId} is not in the allowed chains (${allowedChainIds.join(", ")})` };
5064
+ const chains = ({ chains }) => single("chain_ids", `Validates that offer chain is one of: [${chains.map((c) => c.id).join(", ")}]`, (offer) => {
5065
+ const allowedChainIds = chains.map((c) => c.id);
5066
+ if (!allowedChainIds.some((id) => id === offer.chainId)) return { message: `Chain ID ${offer.chainId} is not in the allowed chains (${allowedChainIds.join(", ")})` };
4323
5067
  });
4324
5068
  const maturity = ({ maturities }) => single("maturity", `Validates that offer maturity is one of: [${maturities.join(", ")}]`, (offer) => {
4325
- const allowedMaturities = maturities.map((m) => from$10(m));
5069
+ const allowedMaturities = maturities.map((m) => from$11(m));
4326
5070
  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}` };
4327
5071
  });
4328
- const callback = ({ callbacks, allowedAddresses }) => single("callback", `Validates callbacks: buy empty callback is ${callbacks.includes(CallbackType.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) => {
4329
- if (isEmptyCallback(offer) && offer.buy && !callbacks?.find((c) => c === CallbackType.BuyWithEmptyCallback)) return { message: "Buy offers with empty callback not allowed." };
5072
+ 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) => {
5073
+ if (isEmptyCallback(offer) && offer.buy && !callbacks?.find((c) => c === Type$1.BuyWithEmptyCallback)) return { message: "Buy offers with empty callback not allowed." };
4330
5074
  if (isEmptyCallback(offer) && !offer.buy) return { message: "Sell offers require a non-empty callback." };
4331
5075
  if (!isEmptyCallback(offer)) {
4332
5076
  if (!allowedAddresses.includes(offer.callback.address?.toLowerCase())) return { message: `Callback address ${offer.callback.address} is not allowed.` };
@@ -4348,7 +5092,7 @@ const token = ({ assetsByChainId }) => single("token", "Validates that offer loa
4348
5092
  * Returns an issue only for the first non-conforming offer.
4349
5093
  * This rule is signing-agnostic; signer verification is handled at the collector level.
4350
5094
  */
4351
- const sameMaker = () => batch$1("mixed_maker", "Validates that all offers in a batch have the same maker address", (offers) => {
5095
+ const sameMaker = () => batch("mixed_maker", "Validates that all offers in a batch have the same maker address", (offers) => {
4352
5096
  const issues = /* @__PURE__ */ new Map();
4353
5097
  if (offers.length === 0) return issues;
4354
5098
  const firstMaker = offers[0].maker.toLowerCase();
@@ -4382,9 +5126,9 @@ const morphoRules = (chains$2) => {
4382
5126
  maturity({ maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth] }),
4383
5127
  callback({
4384
5128
  callbacks: [
4385
- CallbackType.BuyWithEmptyCallback,
4386
- CallbackType.BuyVaultV1Callback,
4387
- CallbackType.SellERC20Callback
5129
+ Type$1.BuyWithEmptyCallback,
5130
+ Type$1.BuyVaultV1Callback,
5131
+ Type$1.SellERC20Callback
4388
5132
  ],
4389
5133
  allowedAddresses: chains$2.flatMap((c) => getCallbackAddresses(c.name))
4390
5134
  }),
@@ -4399,12 +5143,13 @@ function from(parameters) {
4399
5143
  const config = {
4400
5144
  client: parameters.client,
4401
5145
  mempoolAddress: parameters.mempoolAddress,
5146
+ morphoAddress: parameters.morphoAddress,
4402
5147
  blockWindow: parameters.blockWindow
4403
5148
  };
4404
5149
  return {
4405
- add: (parameters$1) => add(config, parameters$1),
4406
- get: (parameters$1) => get(config, parameters$1),
4407
- stream: (parameters$1) => streamOffers(config, parameters$1)
5150
+ add: (parameters) => add(config, parameters),
5151
+ get: (parameters) => get(config, parameters),
5152
+ stream: (parameters) => streamOffers(config, parameters)
4408
5153
  };
4409
5154
  }
4410
5155
  /**
@@ -4416,11 +5161,18 @@ function from(parameters) {
4416
5161
  */
4417
5162
  async function add(config, offers) {
4418
5163
  if (!config.client.account) throw new WalletAccountNotSetError();
4419
- const tree = from$8(offers.map((o) => from$7(o)));
5164
+ const tree = from$3(offers.map((o) => from$9(o)));
4420
5165
  const chainId = await getChainId(config.client);
4421
5166
  for (const offer of tree.offers) if (chainId !== offer.chainId) throw new ChainIdMismatchError(offer.chainId, chainId);
4422
- const signature = await sign(tree.offers, config.client);
4423
- const encoded = await encode$1(tree, signature);
5167
+ const signatureDomain$1 = resolveSignatureDomain(config, chainId);
5168
+ const signature = await config.client.signTypedData({
5169
+ account: config.client.account,
5170
+ domain: signatureDomain(signatureDomain$1),
5171
+ types: signatureTypes,
5172
+ primaryType: "Root",
5173
+ message: { root: tree.root }
5174
+ });
5175
+ const encoded = await encode(tree, signature, signatureDomain$1);
4424
5176
  try {
4425
5177
  return await config.client.sendTransaction({
4426
5178
  chain: config.client.chain,
@@ -4459,6 +5211,7 @@ const getChainId = async (client) => {
4459
5211
  };
4460
5212
  async function* streamOffers(config, parameters) {
4461
5213
  const { loanToken, blockNumberGte, blockNumberLte, order = "desc", options: { maxBatchSize = DEFAULT_BATCH_SIZE, blockWindow = config.blockWindow } = {} } = parameters;
5214
+ const signatureDomain = resolveSignatureDomain(config, await getChainId(config.client));
4462
5215
  const stream = streamLogs({
4463
5216
  client: config.client.extend(viem.publicActions),
4464
5217
  contractAddress: config.mempoolAddress,
@@ -4490,7 +5243,7 @@ async function* streamOffers(config, parameters) {
4490
5243
  if (!log) continue;
4491
5244
  const [payload] = (0, viem.decodeAbiParameters)([{ type: "bytes" }], log.data);
4492
5245
  try {
4493
- const { tree } = await decode$1(payload);
5246
+ const { tree } = await decode(payload, signatureDomain);
4494
5247
  for (const offer of tree.offers) {
4495
5248
  if (loanToken && offer.loanToken.toLowerCase() !== loanToken.toLowerCase()) continue;
4496
5249
  offers.push(offer);
@@ -4525,10 +5278,25 @@ var ChainIdMismatchError = class extends BaseError {
4525
5278
  _defineProperty(this, "name", "Mempool.ChainIdMismatchError");
4526
5279
  }
4527
5280
  };
5281
+ const resolveSignatureDomain = (config, chainId) => {
5282
+ const chain = config.client.chain;
5283
+ const verifyingContract = config.morphoAddress ?? chain?.custom?.morpho?.address ?? getChain(chainId)?.custom.morpho.address;
5284
+ if (!verifyingContract || verifyingContract.toLowerCase() === viem.zeroAddress) throw new MissingMorphoAddressError();
5285
+ return {
5286
+ chainId,
5287
+ verifyingContract
5288
+ };
5289
+ };
5290
+ var MissingMorphoAddressError = class extends BaseError {
5291
+ constructor() {
5292
+ super("Morpho address is required to verify root signatures (zero address is invalid).");
5293
+ _defineProperty(this, "name", "Mempool.MissingMorphoAddressError");
5294
+ }
5295
+ };
4528
5296
 
4529
5297
  //#endregion
4530
5298
  //#region src/mempool/MempoolClient.ts
4531
- var MempoolClient_exports = /* @__PURE__ */ __export({ connect: () => connect });
5299
+ var MempoolClient_exports = /* @__PURE__ */ __exportAll({ connect: () => connect });
4532
5300
  /**
4533
5301
  * Client to interact with the Mempool contract on a specific chain.
4534
5302
  */
@@ -4561,7 +5329,7 @@ const retry = async (fn, attempts = 3, delayMs = 50) => {
4561
5329
  async function batchMulticall(parameters) {
4562
5330
  const { client, calls, batchSize, retryAttempts, retryDelayMs, blockNumber } = parameters;
4563
5331
  const results = [];
4564
- for (const callsBatch of batch(calls, batchSize)) {
5332
+ for (const callsBatch of batch$1(calls, batchSize)) {
4565
5333
  const batchResults = await retry(() => (0, viem_actions.multicall)(client, {
4566
5334
  allowFailure: false,
4567
5335
  contracts: callsBatch,
@@ -4574,7 +5342,7 @@ async function batchMulticall(parameters) {
4574
5342
 
4575
5343
  //#endregion
4576
5344
  //#region src/utils/Group.ts
4577
- var Group_exports = /* @__PURE__ */ __export({ fromNumber: () => fromNumber });
5345
+ var Group_exports = /* @__PURE__ */ __exportAll({ fromNumber: () => fromNumber });
4578
5346
  /**
4579
5347
  * Creates a bytes32 group identifier from a number.
4580
5348
  * @param n - A non-negative integer.
@@ -4598,7 +5366,7 @@ function lazy(pollFn) {
4598
5366
  let active = true;
4599
5367
  let resolveNext = null;
4600
5368
  const queue = [];
4601
- const wait$1 = () => new Promise((resolve) => {
5369
+ const wait = () => new Promise((resolve) => {
4602
5370
  resolveNext = resolve;
4603
5371
  });
4604
5372
  const emit = (item) => {
@@ -4616,7 +5384,7 @@ function lazy(pollFn) {
4616
5384
  unpoll = pollFn(emit, { stop });
4617
5385
  try {
4618
5386
  while (active) {
4619
- if (queue.length === 0) await wait$1();
5387
+ if (queue.length === 0) await wait();
4620
5388
  while (queue.length > 0 && active) yield queue.shift();
4621
5389
  }
4622
5390
  } finally {
@@ -4655,7 +5423,7 @@ function poll(fn, { interval }) {
4655
5423
 
4656
5424
  //#endregion
4657
5425
  //#region src/utils/time.ts
4658
- var time_exports = /* @__PURE__ */ __export({
5426
+ var time_exports = /* @__PURE__ */ __exportAll({
4659
5427
  max: () => max,
4660
5428
  now: () => now
4661
5429
  });
@@ -4668,14 +5436,14 @@ function max() {
4668
5436
 
4669
5437
  //#endregion
4670
5438
  //#region src/utils/index.ts
4671
- var utils_exports = /* @__PURE__ */ __export({
5439
+ var utils_exports = /* @__PURE__ */ __exportAll({
4672
5440
  BaseError: () => BaseError,
4673
5441
  Group: () => Group_exports,
4674
5442
  Random: () => Random_exports,
4675
5443
  ReorgError: () => ReorgError,
4676
5444
  Time: () => time_exports,
4677
5445
  atMostOneNonZero: () => atMostOneNonZero,
4678
- batch: () => batch,
5446
+ batch: () => batch$1,
4679
5447
  batchMulticall: () => batchMulticall,
4680
5448
  fromSnakeCase: () => fromSnakeCase$3,
4681
5449
  lazy: () => lazy,
@@ -4738,16 +5506,16 @@ Object.defineProperty(exports, 'Format', {
4738
5506
  return Format_exports;
4739
5507
  }
4740
5508
  });
4741
- Object.defineProperty(exports, 'GateConfig', {
5509
+ Object.defineProperty(exports, 'Gatekeeper', {
4742
5510
  enumerable: true,
4743
5511
  get: function () {
4744
- return GateConfig_exports;
5512
+ return Gatekeeper_exports;
4745
5513
  }
4746
5514
  });
4747
- Object.defineProperty(exports, 'Gatekeeper', {
5515
+ Object.defineProperty(exports, 'GatekeeperClient', {
4748
5516
  enumerable: true,
4749
5517
  get: function () {
4750
- return Gatekeeper_exports;
5518
+ return Client_exports;
4751
5519
  }
4752
5520
  });
4753
5521
  Object.defineProperty(exports, 'LLTV', {
@@ -4813,7 +5581,7 @@ Object.defineProperty(exports, 'RouterApi', {
4813
5581
  Object.defineProperty(exports, 'RouterClient', {
4814
5582
  enumerable: true,
4815
5583
  get: function () {
4816
- return Client_exports;
5584
+ return Client_exports$1;
4817
5585
  }
4818
5586
  });
4819
5587
  Object.defineProperty(exports, 'Rules', {
@@ -4828,6 +5596,12 @@ Object.defineProperty(exports, 'Time', {
4828
5596
  return time_exports;
4829
5597
  }
4830
5598
  });
5599
+ Object.defineProperty(exports, 'TradingFee', {
5600
+ enumerable: true,
5601
+ get: function () {
5602
+ return TradingFee_exports;
5603
+ }
5604
+ });
4831
5605
  Object.defineProperty(exports, 'Transfer', {
4832
5606
  enumerable: true,
4833
5607
  get: function () {