@morpho-dev/router 0.10.0 → 0.11.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.
@@ -6,53 +6,14 @@ import { ApiBody, ApiOperation, ApiParam, ApiProperty, ApiQuery, ApiResponse, Ap
6
6
  import * as z$1 from "zod";
7
7
  import createOpenApiFetchClient from "openapi-fetch";
8
8
  import { bytesToHex, concatHex, decodeAbiParameters, encodeAbiParameters, getAddress, hashTypedData, hexToBytes, isAddress, isHex, keccak256, maxUint256, numberToHex, pad, parseAbi, publicActions, recoverAddress, zeroAddress } from "viem";
9
- import { getBlock, getLogs, multicall } from "viem/actions";
9
+ import { getBlockNumber, getLogs, multicall } from "viem/actions";
10
10
  import { anvil, base, mainnet } from "viem/chains";
11
11
  import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
12
12
  import { gzip, ungzip } from "pako";
13
+ import { context, propagation } from "@opentelemetry/api";
14
+ import "drizzle-orm";
15
+ import { bigint, boolean, foreignKey, index, integer, numeric, pgSchema, primaryKey, serial, text, timestamp, uniqueIndex, varchar } from "drizzle-orm/pg-core";
13
16
 
14
- //#region \0@oxc-project+runtime@0.110.0/helpers/typeof.js
15
- function _typeof(o) {
16
- "@babel/helpers - typeof";
17
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
18
- return typeof o;
19
- } : function(o) {
20
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
21
- }, _typeof(o);
22
- }
23
-
24
- //#endregion
25
- //#region \0@oxc-project+runtime@0.110.0/helpers/toPrimitive.js
26
- function toPrimitive(t, r) {
27
- if ("object" != _typeof(t) || !t) return t;
28
- var e = t[Symbol.toPrimitive];
29
- if (void 0 !== e) {
30
- var i = e.call(t, r || "default");
31
- if ("object" != _typeof(i)) return i;
32
- throw new TypeError("@@toPrimitive must return a primitive value.");
33
- }
34
- return ("string" === r ? String : Number)(t);
35
- }
36
-
37
- //#endregion
38
- //#region \0@oxc-project+runtime@0.110.0/helpers/toPropertyKey.js
39
- function toPropertyKey(t) {
40
- var i = toPrimitive(t, "string");
41
- return "symbol" == _typeof(i) ? i : i + "";
42
- }
43
-
44
- //#endregion
45
- //#region \0@oxc-project+runtime@0.110.0/helpers/defineProperty.js
46
- function _defineProperty(e, r, t) {
47
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
48
- value: t,
49
- enumerable: !0,
50
- configurable: !0,
51
- writable: !0
52
- }) : e[r] = t, e;
53
- }
54
-
55
- //#endregion
56
17
  //#region src/utils/Errors.ts
57
18
  var Errors_exports = /* @__PURE__ */ __exportAll({
58
19
  BaseError: () => BaseError,
@@ -68,6 +29,10 @@ var Errors_exports = /* @__PURE__ */ __exportAll({
68
29
  * ```
69
30
  */
70
31
  var BaseError = class BaseError extends Error {
32
+ details;
33
+ shortMessage;
34
+ cause;
35
+ name = "BaseError";
71
36
  constructor(shortMessage, options = {}) {
72
37
  const details = (() => {
73
38
  if (options.cause instanceof BaseError) {
@@ -84,10 +49,6 @@ var BaseError = class BaseError extends Error {
84
49
  ...details ? ["", details ? `Details: ${details}` : void 0] : []
85
50
  ].filter((x) => typeof x === "string").join("\n");
86
51
  super(message, options.cause ? { cause: options.cause } : void 0);
87
- _defineProperty(this, "details", void 0);
88
- _defineProperty(this, "shortMessage", void 0);
89
- _defineProperty(this, "cause", void 0);
90
- _defineProperty(this, "name", "BaseError");
91
52
  this.cause = options.cause;
92
53
  this.details = details;
93
54
  this.shortMessage = shortMessage;
@@ -103,9 +64,9 @@ function walk(err, fn) {
103
64
  return fn ? null : err;
104
65
  }
105
66
  var ReorgError = class extends BaseError {
67
+ name = "ReorgError";
106
68
  constructor(blockNumber) {
107
69
  super(`Reorg detected at block number ${blockNumber}`);
108
- _defineProperty(this, "name", "ReorgError");
109
70
  }
110
71
  };
111
72
 
@@ -176,15 +137,15 @@ function assertPrice(price) {
176
137
  if (price < 0n || price > MAX_PRICE) throw new InvalidPriceError(price);
177
138
  }
178
139
  var InvalidTickError = class extends BaseError {
140
+ name = "Tick.InvalidTickError";
179
141
  constructor(tick) {
180
142
  super(`Invalid tick: ${tick}. Tick must be an integer between 0 and ${TICK_RANGE}.`);
181
- _defineProperty(this, "name", "Tick.InvalidTickError");
182
143
  }
183
144
  };
184
145
  var InvalidPriceError = class extends BaseError {
146
+ name = "Tick.InvalidPriceError";
185
147
  constructor(price) {
186
148
  super(`Invalid price: ${price}. Price must be between 0 and ${MAX_PRICE}.`);
187
- _defineProperty(this, "name", "Tick.InvalidPriceError");
188
149
  }
189
150
  };
190
151
 
@@ -385,7 +346,7 @@ const offerExample = {
385
346
  receiver_if_maker_is_seller: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
386
347
  },
387
348
  offer_hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
388
- obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc",
349
+ obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf79",
389
350
  chain_id: 1,
390
351
  consumed: "0",
391
352
  takeable: "369216000000000000000000",
@@ -957,7 +918,7 @@ const positionExample = {
957
918
  chain_id: 1,
958
919
  contract: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
959
920
  user: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
960
- obligation_id: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67",
921
+ obligation_id: "0x12590ae1aee324a005be565f3bcdd16dbf8daf79",
961
922
  reserved: "200000000000000000000",
962
923
  block_number: 21345678
963
924
  };
@@ -1642,11 +1603,14 @@ function isValidBase64urlJson(val) {
1642
1603
  function isValidOfferHashCursor(val) {
1643
1604
  return /^0x[a-f0-9]{64}$/i.test(val);
1644
1605
  }
1606
+ function isValidObligationIdCursor(val) {
1607
+ return /^0x[a-f0-9]{40}$/i.test(val);
1608
+ }
1645
1609
  function isValidOfferCursor(val) {
1646
1610
  const [hash, obligationId, ...rest] = val.split(":");
1647
1611
  if (rest.length !== 0) return false;
1648
1612
  if (!hash || !obligationId) return false;
1649
- return isValidOfferHashCursor(hash) && isValidOfferHashCursor(obligationId);
1613
+ return isValidOfferHashCursor(hash) && isValidObligationIdCursor(obligationId);
1650
1614
  }
1651
1615
  const csvArray = (schema) => z$1.preprocess((value) => {
1652
1616
  if (value === void 0) return void 0;
@@ -1675,10 +1639,14 @@ const ConfigRuleTypes = z$1.enum([
1675
1639
  "callback",
1676
1640
  "loan_token",
1677
1641
  "collateral_token",
1678
- "oracle"
1642
+ "oracle",
1643
+ "group_consistency",
1644
+ "group_immutability",
1645
+ "max_collaterals",
1646
+ "min_duration"
1679
1647
  ]);
1680
1648
  const GetConfigRulesQueryParams = z$1.object({
1681
- cursor: z$1.string().regex(/^(maturity|callback|loan_token|collateral_token|oracle):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
1649
+ cursor: z$1.string().regex(/^(maturity|callback|loan_token|collateral_token|oracle|group_consistency|group_immutability|max_collaterals|min_duration):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
1682
1650
  description: "Pagination cursor in type:chain_id:<value> format",
1683
1651
  example: "maturity:1:1730415600:end_of_next_month"
1684
1652
  }),
@@ -1718,9 +1686,9 @@ const GetOffersQueryParams = PaginationQueryParams.omit({ cursor: true }).extend
1718
1686
  description: "Side of the offer. Required when using obligation_id.",
1719
1687
  example: "buy"
1720
1688
  }),
1721
- obligation_id: z$1.string().regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).optional().meta({
1689
+ obligation_id: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Obligation id must be a valid 20-byte hex string" }).transform((val) => val.toLowerCase()).optional().meta({
1722
1690
  description: "Offers obligation id. Required when not using maker.",
1723
- example: "0x1234567890123456789012345678901234567890123456789012345678901234"
1691
+ example: "0x1234567890123456789012345678901234567890"
1724
1692
  }),
1725
1693
  maker: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Maker must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
1726
1694
  description: "Maker address to filter offers by. Alternative to obligation_id + side.",
@@ -1805,9 +1773,9 @@ const GetObligationsQueryParams = z$1.object({
1805
1773
  example: "-ask,bid,maturity"
1806
1774
  })
1807
1775
  });
1808
- const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
1776
+ const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 20-byte hex string" }).regex(/^0x[a-fA-F0-9]{40}$/, { error: "Obligation id must be a valid 20-byte hex string" }).transform((val) => val.toLowerCase()).meta({
1809
1777
  description: "Obligation id",
1810
- example: "0x1234567890123456789012345678901234567890123456789012345678901234"
1778
+ example: "0x1234567890123456789012345678901234567890"
1811
1779
  }) });
1812
1780
  /** Validate a book cursor format: {side, lastTick, offersCursor} */
1813
1781
  function isValidBookCursor(cursorString) {
@@ -1842,9 +1810,9 @@ const HealthQueryParams = z$1.object({ strict: z$1.enum([
1842
1810
  }) });
1843
1811
  const GetBookParams = z$1.object({
1844
1812
  ...BookPaginationQueryParams.shape,
1845
- obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
1813
+ obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 20-byte hex string" }).regex(/^0x[a-fA-F0-9]{40}$/, { error: "Obligation id must be a valid 20-byte hex string" }).transform((val) => val.toLowerCase()).meta({
1846
1814
  description: "Obligation id",
1847
- example: "0x1234567890123456789012345678901234567890123456789012345678901234"
1815
+ example: "0x1234567890123456789012345678901234567890"
1848
1816
  }),
1849
1817
  side: z$1.enum(["buy", "sell"]).meta({
1850
1818
  description: "Side of the book (buy or sell).",
@@ -1932,55 +1900,57 @@ const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed meta
1932
1900
  //#region src/core/Abi/MorphoV2.ts
1933
1901
  const MorphoV2 = parseAbi([
1934
1902
  "constructor()",
1935
- "function collateralOf(bytes32 id, address user, address collateralToken) view returns (uint256)",
1903
+ "function collateralOf(bytes20 id, address user, uint256 collateralIndex) view returns (uint128)",
1936
1904
  "function consume(bytes32 group, uint256 amount)",
1937
1905
  "function consumed(address user, bytes32 group) view returns (uint256)",
1938
- "function debtOf(bytes32 id, address user) view returns (uint256)",
1906
+ "function debtOf(bytes20 id, address user) view returns (uint256)",
1939
1907
  "function defaultFees(address loanToken, uint256 index) view returns (uint16)",
1940
1908
  "function feeSetter() view returns (address)",
1941
- "function fees(bytes32 id) view returns (uint16[6])",
1909
+ "function fees(bytes20 id) view returns (uint16[6])",
1942
1910
  "function flashLoan(address token, uint256 assets, address callback, bytes data)",
1943
- "function isHealthy((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bytes32 id, address borrower) view returns (bool)",
1944
- "function liquidate((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, (uint256 collateralIndex, uint256 repaid, uint256 seized)[] seizures, address borrower, bytes data) returns ((uint256 collateralIndex, uint256 repaid, uint256 seized)[])",
1911
+ "function isHealthy((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, bytes20 id, address borrower) view returns (bool)",
1912
+ "function liquidate((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 collateralIndex, uint256 seizedAssets, uint256 repaidUnits, address borrower, bytes data) returns (uint256, uint256)",
1945
1913
  "function multicall(bytes[] calls)",
1946
- "function obligationCreated(bytes32 id) view returns (bool)",
1947
- "function obligationState(bytes32 id) view returns (uint128 totalUnits, uint128 totalShares, uint256 withdrawable, bool created)",
1914
+ "function obligationCreated(bytes20 id) view returns (bool)",
1915
+ "function obligationState(bytes20 id) view returns (uint128 totalUnits, uint128 totalShares, uint256 withdrawable, bool created, uint16[6] fees)",
1948
1916
  "function owner() view returns (address)",
1949
- "function repay((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, address onBehalf)",
1917
+ "function repay((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 obligationUnits, address onBehalf)",
1950
1918
  "function session(address user) view returns (bytes32)",
1951
1919
  "function setDefaultTradingFee(address loanToken, uint256 index, uint256 newTradingFee)",
1952
1920
  "function setFeeSetter(address newFeeSetter)",
1953
- "function setObligationTradingFee(bytes32 id, uint256 index, uint256 newTradingFee)",
1921
+ "function setObligationTradingFee(bytes20 id, uint256 index, uint256 newTradingFee)",
1954
1922
  "function setOwner(address newOwner)",
1955
1923
  "function setTradingFeeRecipient(address feeRecipient)",
1956
- "function sharesOf(bytes32 id, address user) view returns (uint256)",
1924
+ "function sharesOf(bytes20 id, address user) view returns (uint256)",
1957
1925
  "function shuffleSession()",
1958
- "function supplyCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, address collateral, uint256 assets, address onBehalf)",
1959
- "function take(uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, address taker, address takerCallback, bytes takerCallbackData, address receiverIfTakerIsSeller, ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bool buy, address maker, uint256 assets, uint256 obligationUnits, uint256 obligationShares, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData, address receiverIfMakerIsSeller) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof) returns (uint256, uint256, uint256, uint256)",
1960
- "function totalShares(bytes32 id) view returns (uint256)",
1961
- "function totalUnits(bytes32 id) view returns (uint256)",
1962
- "function touchObligation((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation) returns (bytes32)",
1963
- "function tradingFee(bytes32 id, uint256 timeToMaturity) view returns (uint256)",
1926
+ "function supplyCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 collateralIndex, uint256 assets, address onBehalf)",
1927
+ "function take(uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, address taker, address takerCallback, bytes takerCallbackData, address receiverIfTakerIsSeller, ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, bool buy, address maker, uint256 assets, uint256 obligationUnits, uint256 obligationShares, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData, address receiverIfMakerIsSeller) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof) returns (uint256, uint256, uint256, uint256)",
1928
+ "function toId((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation) view returns (bytes20)",
1929
+ "function toObligation(bytes20 id) view returns ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue))",
1930
+ "function totalShares(bytes20 id) view returns (uint256)",
1931
+ "function totalUnits(bytes20 id) view returns (uint256)",
1932
+ "function touchObligation((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation) returns (bytes20)",
1933
+ "function tradingFee(bytes20 id, uint256 timeToMaturity) view returns (uint256)",
1964
1934
  "function tradingFeeRecipient() view returns (address)",
1965
- "function withdraw((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, uint256 shares, address onBehalf, address receiver) returns (uint256, uint256)",
1966
- "function withdrawCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, address collateral, uint256 assets, address onBehalf, address receiver)",
1967
- "function withdrawable(bytes32 id) view returns (uint256)",
1935
+ "function withdraw((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 obligationUnits, uint256 shares, address onBehalf, address receiver) returns (uint256, uint256)",
1936
+ "function withdrawCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 collateralIndex, uint256 assets, address onBehalf, address receiver)",
1937
+ "function withdrawable(bytes20 id) view returns (uint256)",
1968
1938
  "event Constructor(address indexed owner)",
1969
1939
  "event Consume(address indexed user, bytes32 indexed group, uint256 amount)",
1970
1940
  "event FlashLoan(address indexed caller, address indexed token, uint256 assets)",
1971
- "event Liquidate(address indexed caller, bytes32 indexed id, (uint256 collateralIndex, uint256 repaid, uint256 seized)[] seizures, address indexed borrower, uint256 totalRepaid, uint256 badDebt)",
1972
- "event ObligationCreated(bytes32 indexed id, (address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation)",
1973
- "event Repay(address indexed caller, bytes32 indexed id, uint256 obligationUnits, address indexed onBehalf)",
1941
+ "event Liquidate(address indexed caller, bytes20 indexed id_, uint256 collateralIndex, uint256 seizedAssets, uint256 repaidUnits, address indexed borrower, uint256 badDebt)",
1942
+ "event ObligationCreated(bytes20 indexed id_, (address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation)",
1943
+ "event Repay(address indexed caller, bytes20 indexed id_, uint256 obligationUnits, address indexed onBehalf)",
1974
1944
  "event SetDefaultTradingFee(address indexed loanToken, uint256 indexed index, uint256 newTradingFee)",
1975
1945
  "event SetFeeSetter(address indexed feeSetter)",
1976
- "event SetObligationTradingFee(bytes32 indexed id, uint256 indexed index, uint256 newTradingFee)",
1946
+ "event SetObligationTradingFee(bytes20 indexed id_, uint256 indexed index, uint256 newTradingFee)",
1977
1947
  "event SetOwner(address indexed owner)",
1978
1948
  "event SetTradingFeeRecipient(address indexed feeRecipient)",
1979
1949
  "event ShuffleSession(address indexed user, bytes32 session)",
1980
- "event SupplyCollateral(address caller, bytes32 indexed id, address indexed collateral, uint256 assets, address indexed onBehalf)",
1981
- "event Take(address caller, bytes32 indexed id, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, bool buyerIsLender, bool sellerIsBorrower, address sellerReceiver, bytes32 group, uint256 consumed)",
1982
- "event Withdraw(address caller, bytes32 indexed id, uint256 obligationUnits, uint256 shares, address indexed onBehalf, address indexed receiver)",
1983
- "event WithdrawCollateral(address caller, bytes32 indexed id, address indexed collateral, uint256 assets, address indexed onBehalf, address receiver)"
1950
+ "event SupplyCollateral(address caller, bytes20 indexed id_, address indexed collateral, uint256 assets, address indexed onBehalf)",
1951
+ "event Take(address caller, bytes20 indexed id_, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, bool buyerIsLender, bool sellerIsBorrower, address sellerReceiver, bytes32 group, uint256 consumed)",
1952
+ "event Withdraw(address caller, bytes20 indexed id_, uint256 obligationUnits, uint256 shares, address indexed onBehalf, address indexed receiver)",
1953
+ "event WithdrawCollateral(address caller, bytes20 indexed id_, address indexed collateral, uint256 assets, address indexed onBehalf, address receiver)"
1984
1954
  ]);
1985
1955
 
1986
1956
  //#endregion
@@ -2138,6 +2108,7 @@ const Morpho = [
2138
2108
  //#endregion
2139
2109
  //#region src/core/Callback.ts
2140
2110
  var Callback_exports = /* @__PURE__ */ __exportAll({
2111
+ CallbackType: () => CallbackType,
2141
2112
  Type: () => Type$1,
2142
2113
  isEmptyCallback: () => isEmptyCallback
2143
2114
  });
@@ -2146,30 +2117,12 @@ let Type$1 = /* @__PURE__ */ function(Type) {
2146
2117
  Type["SellWithEmptyCallback"] = "sell_with_empty_callback";
2147
2118
  return Type;
2148
2119
  }({});
2120
+ let CallbackType = /* @__PURE__ */ function(CallbackType) {
2121
+ CallbackType["Empty"] = "empty";
2122
+ return CallbackType;
2123
+ }({});
2149
2124
  const isEmptyCallback = (offer) => offer.callback.data === "0x";
2150
2125
 
2151
- //#endregion
2152
- //#region src/utils/BigMath.ts
2153
- function max$1(a, b) {
2154
- return a > b ? a : b;
2155
- }
2156
- function min(a, b) {
2157
- return a < b ? a : b;
2158
- }
2159
- /**
2160
- * Checks if at most one of the given values is non-zero.
2161
- * @param values - The bigint values to check.
2162
- * @returns True if zero or one value is non-zero, false if two or more are non-zero.
2163
- */
2164
- function atMostOneNonZero(...values) {
2165
- let nonZeroCount = 0;
2166
- for (const value of values) if (value !== 0n) {
2167
- nonZeroCount++;
2168
- if (nonZeroCount > 1) return false;
2169
- }
2170
- return true;
2171
- }
2172
-
2173
2126
  //#endregion
2174
2127
  //#region src/utils/batch.ts
2175
2128
  /**
@@ -2193,6 +2146,28 @@ function* batch$1(array, batchSize) {
2193
2146
  for (let i = 0; i < array.length; i += batchSize) yield array.slice(i, i + batchSize);
2194
2147
  }
2195
2148
 
2149
+ //#endregion
2150
+ //#region src/utils/BigMath.ts
2151
+ function max$1(a, b) {
2152
+ return a > b ? a : b;
2153
+ }
2154
+ function min(a, b) {
2155
+ return a < b ? a : b;
2156
+ }
2157
+ /**
2158
+ * Checks if at most one of the given values is non-zero.
2159
+ * @param values - The bigint values to check.
2160
+ * @returns True if zero or one value is non-zero, false if two or more are non-zero.
2161
+ */
2162
+ function atMostOneNonZero(...values) {
2163
+ let nonZeroCount = 0;
2164
+ for (const value of values) if (value !== 0n) {
2165
+ nonZeroCount++;
2166
+ if (nonZeroCount > 1) return false;
2167
+ }
2168
+ return true;
2169
+ }
2170
+
2196
2171
  //#endregion
2197
2172
  //#region src/core/Chain.ts
2198
2173
  var Chain_exports = /* @__PURE__ */ __exportAll({
@@ -2201,9 +2176,10 @@ var Chain_exports = /* @__PURE__ */ __exportAll({
2201
2176
  InvalidBlockRangeError: () => InvalidBlockRangeError,
2202
2177
  InvalidBlockWindowError: () => InvalidBlockWindowError,
2203
2178
  MissingBlockNumberError: () => MissingBlockNumberError,
2179
+ UnrecoverableLogsResponseSizeError: () => UnrecoverableLogsResponseSizeError,
2204
2180
  chainIds: () => chainIds,
2205
2181
  chainNames: () => chainNames,
2206
- chains: () => chains,
2182
+ chains: () => chains$1,
2207
2183
  getChain: () => getChain,
2208
2184
  getWhitelistedChains: () => getWhitelistedChains,
2209
2185
  streamLogs: () => streamLogs
@@ -2220,17 +2196,17 @@ const chainNameLookup = new Map(Object.entries(ChainId).map(([key, value]) => [v
2220
2196
  function getChain(chainId) {
2221
2197
  const chainName = chainNameLookup.get(chainId);
2222
2198
  if (!chainName) return void 0;
2223
- return chains[chainName];
2199
+ return chains$1[chainName];
2224
2200
  }
2225
2201
  const getWhitelistedChains = () => {
2226
2202
  return [
2227
- chains.ethereum,
2228
- chains.base,
2229
- chains["ethereum-virtual-testnet"],
2230
- chains.anvil
2203
+ chains$1.ethereum,
2204
+ chains$1.base,
2205
+ chains$1["ethereum-virtual-testnet"],
2206
+ chains$1.anvil
2231
2207
  ];
2232
2208
  };
2233
- const chains = {
2209
+ const chains$1 = {
2234
2210
  ethereum: {
2235
2211
  ...mainnet,
2236
2212
  id: ChainId.ETHEREUM,
@@ -2267,8 +2243,8 @@ const chains = {
2267
2243
  name: "base",
2268
2244
  custom: {
2269
2245
  morpho: {
2270
- address: "0x3F067BC9D8898F6ec02D6480c3fF1026E512BcBF",
2271
- blockCreated: 41799989
2246
+ address: "0x4C752Cdc4b13c9A6a933CbecfE050eC0BA0B45f9",
2247
+ blockCreated: 42365274
2272
2248
  },
2273
2249
  morphoBlue: {
2274
2250
  address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
@@ -2297,8 +2273,8 @@ const chains = {
2297
2273
  name: "ethereum-virtual-testnet",
2298
2274
  custom: {
2299
2275
  morpho: {
2300
- address: "0xc9f3c65996fc46b9500608b2c9a9152c01c540f7",
2301
- blockCreated: 23226871
2276
+ address: "0x9ac49a344376964291f7289663beb78e2952de44",
2277
+ blockCreated: 23229385
2302
2278
  },
2303
2279
  morphoBlue: {
2304
2280
  address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
@@ -2356,33 +2332,72 @@ const MAX_BATCH_SIZE = 1e4;
2356
2332
  const DEFAULT_BATCH_SIZE$1 = 2500;
2357
2333
  const MAX_BLOCK_WINDOW = 1e4;
2358
2334
  const DEFAULT_BLOCK_WINDOW = 8e3;
2335
+ const MIN_BLOCK_WINDOW = 0n;
2336
+ const oversizedLogsErrorPatterns = [
2337
+ "cannot create a string longer than",
2338
+ "response is too big",
2339
+ "response size exceeded",
2340
+ "log response size exceeded",
2341
+ "query returned more than",
2342
+ "too many results"
2343
+ ];
2344
+ const getLatestBlockNumber = async (client) => {
2345
+ return await getBlockNumber(client, { cacheTime: 0 });
2346
+ };
2359
2347
  async function* streamLogs(parameters) {
2360
2348
  const { client, contractAddress, event, blockNumberGte, blockNumberLte, order = "desc", options: { maxBatchSize = DEFAULT_BATCH_SIZE$1, blockWindow = DEFAULT_BLOCK_WINDOW } = {} } = parameters;
2361
2349
  if (maxBatchSize > MAX_BATCH_SIZE) throw new InvalidBatchSizeError(maxBatchSize);
2362
2350
  if (blockWindow > MAX_BLOCK_WINDOW) throw new InvalidBlockWindowError(blockWindow);
2363
2351
  if (order === "asc" && blockNumberGte === void 0) throw new MissingBlockNumberError();
2364
- const latestBlock = (await getBlock(client, {
2365
- blockTag: "latest",
2366
- includeTransactions: false
2367
- })).number;
2352
+ const ascendingLowerBound = order === "asc" ? BigInt(blockNumberGte) : void 0;
2353
+ const latestBlock = await getLatestBlockNumber(client);
2354
+ let upperBound = blockNumberLte === void 0 ? latestBlock : min(BigInt(blockNumberLte), latestBlock);
2355
+ const lowerBound = BigInt(blockNumberGte || 0);
2356
+ const configuredBlockWindow = BigInt(blockWindow);
2357
+ let adaptiveBlockWindow = configuredBlockWindow;
2368
2358
  let toBlock = 0n;
2369
- if (order === "asc") toBlock = min(BigInt(blockNumberGte) + BigInt(blockWindow), blockNumberLte ? BigInt(blockNumberLte) : latestBlock);
2370
- if (order === "desc") toBlock = blockNumberLte === void 0 ? latestBlock : min(BigInt(blockNumberLte), latestBlock);
2359
+ if (order === "asc") toBlock = min(ascendingLowerBound + adaptiveBlockWindow, upperBound);
2360
+ if (order === "desc") toBlock = upperBound;
2371
2361
  let fromBlock = 0n;
2372
- if (order === "asc") fromBlock = min(BigInt(blockNumberGte), latestBlock);
2373
- if (order === "desc") fromBlock = max$1(BigInt(blockNumberGte || toBlock - BigInt(blockWindow)), 0n);
2374
- if (order === "asc") toBlock = min(toBlock, fromBlock + BigInt(blockWindow));
2375
- if (order === "desc") fromBlock = max$1(fromBlock, toBlock - BigInt(blockWindow));
2362
+ if (order === "asc") fromBlock = ascendingLowerBound;
2363
+ if (order === "desc") fromBlock = max$1(BigInt(blockNumberGte || toBlock - adaptiveBlockWindow), 0n);
2364
+ if (order === "asc") toBlock = min(toBlock, fromBlock + adaptiveBlockWindow);
2365
+ if (order === "desc") fromBlock = max$1(fromBlock, toBlock - adaptiveBlockWindow);
2376
2366
  if (fromBlock > toBlock) throw new InvalidBlockRangeError(fromBlock, toBlock);
2377
2367
  let streaming = true;
2378
2368
  while (streaming) {
2379
- const logs = await getLogs(client, {
2380
- address: contractAddress,
2381
- event,
2382
- fromBlock,
2383
- toBlock
2384
- });
2385
- streaming = order === "asc" ? toBlock < (blockNumberLte || latestBlock) : fromBlock > (blockNumberGte || 0n);
2369
+ let logs;
2370
+ try {
2371
+ logs = await getLogs(client, {
2372
+ address: contractAddress,
2373
+ event,
2374
+ fromBlock,
2375
+ toBlock
2376
+ });
2377
+ } catch (err) {
2378
+ if (order === "asc" && isBlockOutOfRangeError(err)) {
2379
+ const previousUpperBound = upperBound;
2380
+ const previousFromBlock = fromBlock;
2381
+ const previousToBlock = toBlock;
2382
+ const latestBlockOnRetry = await getLatestBlockNumber(client);
2383
+ upperBound = min(upperBound, latestBlockOnRetry);
2384
+ if (upperBound < ascendingLowerBound) throw new InvalidBlockRangeError(ascendingLowerBound, upperBound);
2385
+ toBlock = min(toBlock, upperBound);
2386
+ fromBlock = max$1(min(fromBlock, upperBound), ascendingLowerBound);
2387
+ if (fromBlock > toBlock) throw new InvalidBlockRangeError(fromBlock, toBlock);
2388
+ if (!(upperBound < previousUpperBound || fromBlock < previousFromBlock || toBlock < previousToBlock)) throw err;
2389
+ continue;
2390
+ }
2391
+ if (isOversizedLogsError(err)) {
2392
+ if (fromBlock === toBlock) throw new UnrecoverableLogsResponseSizeError(fromBlock, err);
2393
+ adaptiveBlockWindow = max$1((toBlock - fromBlock) / 2n, MIN_BLOCK_WINDOW);
2394
+ if (order === "asc") toBlock = min(fromBlock + adaptiveBlockWindow, upperBound);
2395
+ else fromBlock = max$1(toBlock - adaptiveBlockWindow, lowerBound);
2396
+ continue;
2397
+ }
2398
+ throw err;
2399
+ }
2400
+ streaming = order === "asc" ? toBlock < upperBound : fromBlock > lowerBound;
2386
2401
  if (logs.length === 0 && !streaming) break;
2387
2402
  if (logs.length === 0 && streaming) yield {
2388
2403
  logs: [],
@@ -2397,17 +2412,19 @@ async function* streamLogs(parameters) {
2397
2412
  logs: logBatch,
2398
2413
  blockNumber: logBatch.length === maxBatchSize ? Number(logBatch[logBatch.length - 1]?.blockNumber) : order === "asc" ? Number(toBlock) : Number(fromBlock)
2399
2414
  };
2415
+ if (adaptiveBlockWindow < configuredBlockWindow) {
2416
+ const expandedBlockWindow = adaptiveBlockWindow === 0n ? 1n : adaptiveBlockWindow * 2n;
2417
+ adaptiveBlockWindow = min(expandedBlockWindow, configuredBlockWindow);
2418
+ }
2400
2419
  if (order === "asc") {
2401
- const upperBound = BigInt(blockNumberLte || latestBlock);
2402
2420
  const nextFromBlock = min(BigInt(toBlock) + 1n, upperBound);
2403
- const nextToBlock = min(toBlock + BigInt(blockWindow) + 1n, upperBound);
2421
+ const nextToBlock = min(toBlock + adaptiveBlockWindow + 1n, upperBound);
2404
2422
  fromBlock = nextFromBlock;
2405
2423
  toBlock = nextToBlock;
2406
2424
  }
2407
2425
  if (order === "desc") {
2408
- const lowerBound = BigInt(blockNumberGte || 0);
2409
2426
  const nextToBlock = max$1(fromBlock - 1n, lowerBound);
2410
- const nextFromBlock = max$1(fromBlock - BigInt(blockWindow) - 1n, lowerBound);
2427
+ const nextFromBlock = max$1(fromBlock - adaptiveBlockWindow - 1n, lowerBound);
2411
2428
  toBlock = nextToBlock;
2412
2429
  fromBlock = nextFromBlock;
2413
2430
  }
@@ -2417,30 +2434,62 @@ async function* streamLogs(parameters) {
2417
2434
  blockNumber: order === "asc" ? Number(toBlock) : Number(fromBlock)
2418
2435
  };
2419
2436
  }
2437
+ const isBlockOutOfRangeError = (error) => {
2438
+ let cause = error;
2439
+ while (cause && typeof cause === "object") {
2440
+ const candidate = cause;
2441
+ if (typeof candidate.message === "string" && candidate.message.includes("BlockOutOfRangeError") || typeof candidate.details === "string" && candidate.details.includes("BlockOutOfRangeError")) return true;
2442
+ cause = candidate.cause;
2443
+ }
2444
+ return false;
2445
+ };
2420
2446
  var InvalidBlockRangeError = class extends BaseError {
2447
+ name = "Chain.InvalidBlockRangeError";
2448
+ fromBlock;
2449
+ toBlock;
2421
2450
  constructor(fromBlock, toBlock) {
2422
2451
  super(`Invalid block range while streaming data from chain. From block ${fromBlock} to block ${toBlock}.`);
2423
- _defineProperty(this, "name", "Chain.InvalidBlockRangeError");
2452
+ this.fromBlock = fromBlock;
2453
+ this.toBlock = toBlock;
2424
2454
  }
2425
2455
  };
2426
2456
  var InvalidBlockWindowError = class extends BaseError {
2457
+ name = "Chain.InvalidBlockWindowError";
2427
2458
  constructor(blockWindow) {
2428
2459
  super(`Invalid block window while streaming data from chain. Maximum is ${MAX_BLOCK_WINDOW}. Got ${blockWindow}.`);
2429
- _defineProperty(this, "name", "Chain.InvalidBlockWindowError");
2430
2460
  }
2431
2461
  };
2432
2462
  var InvalidBatchSizeError = class extends BaseError {
2463
+ name = "Chain.InvalidBatchSizeError";
2433
2464
  constructor(maxBatchSize) {
2434
2465
  super(`Invalid batch size while streaming data from chain. Maximum is ${MAX_BATCH_SIZE}. Got ${maxBatchSize}.`);
2435
- _defineProperty(this, "name", "Chain.InvalidBatchSizeError");
2436
2466
  }
2437
2467
  };
2438
2468
  var MissingBlockNumberError = class extends BaseError {
2469
+ name = "Chain.MissingBlockNumberError";
2439
2470
  constructor() {
2440
2471
  super("Missing block number when streaming data from chain in ascending order.");
2441
- _defineProperty(this, "name", "Chain.MissingBlockNumberError");
2442
2472
  }
2443
2473
  };
2474
+ var UnrecoverableLogsResponseSizeError = class extends BaseError {
2475
+ name = "Chain.UnrecoverableLogsResponseSizeError";
2476
+ constructor(blockNumber, cause) {
2477
+ const rootCause = cause instanceof Error ? cause : cause === void 0 ? void 0 : new Error(String(cause));
2478
+ super(`Failed to stream logs because even a single-block query exceeded the RPC response size limit at block ${blockNumber}.`, { cause: rootCause });
2479
+ }
2480
+ };
2481
+ function isOversizedLogsError(err) {
2482
+ return oversizedLogsErrorPatterns.some((pattern) => collectErrorMessages(err).includes(pattern));
2483
+ }
2484
+ function collectErrorMessages(err) {
2485
+ if (!(err instanceof Error)) return "";
2486
+ const fragments = [err.message];
2487
+ const candidate = err;
2488
+ if (typeof candidate.details === "string") fragments.push(candidate.details);
2489
+ if (typeof candidate.shortMessage === "string") fragments.push(candidate.shortMessage);
2490
+ if (candidate.cause instanceof Error) fragments.push(collectErrorMessages(candidate.cause));
2491
+ return fragments.join(" ").toLowerCase();
2492
+ }
2444
2493
 
2445
2494
  //#endregion
2446
2495
  //#region src/core/ChainRegistry.ts
@@ -2663,15 +2712,15 @@ function from$11(lltv) {
2663
2712
  return BigInt(lltv * 10 ** 18);
2664
2713
  }
2665
2714
  var InvalidOptionError$1 = class extends BaseError {
2715
+ name = "LLTV.InvalidOptionError";
2666
2716
  constructor(input) {
2667
2717
  super(`Invalid LLTV option. Input: "${input}". Accepted values are: ${Options.map((option) => `"${option}"`).join(", ")}.`);
2668
- _defineProperty(this, "name", "LLTV.InvalidOptionError");
2669
2718
  }
2670
2719
  };
2671
2720
  var InvalidLLTVError = class extends BaseError {
2721
+ name = "LLTV.InvalidLLTVError";
2672
2722
  constructor(input) {
2673
2723
  super(`Invalid LLTV. Input: "${input}". Accepted values are: ${LLTV_SCALED.map((option) => `"${option}"`).join(", ")}.`);
2674
- _defineProperty(this, "name", "LLTV.InvalidLLTVError");
2675
2724
  }
2676
2725
  };
2677
2726
  const LLTVSchema = z$1.bigint({ coerce: true }).refine((lltv) => {
@@ -2806,9 +2855,9 @@ function convertToShares(parameters) {
2806
2855
  return parameters.assets * (parameters.totalSupply + 10n ** BigInt(parameters.decimalsOffset)) / denominator;
2807
2856
  }
2808
2857
  var DenominatorIsZeroError = class extends BaseError {
2858
+ name = "ERC4626.DenominatorIsZeroError";
2809
2859
  constructor() {
2810
2860
  super("Denominator is 0.");
2811
- _defineProperty(this, "name", "ERC4626.DenominatorIsZeroError");
2812
2861
  }
2813
2862
  };
2814
2863
 
@@ -2876,9 +2925,9 @@ const MaturitySchema = z$1.number().int().refine((maturity) => {
2876
2925
  }
2877
2926
  }, { error: (issue) => {
2878
2927
  try {
2879
- return `The maturity is set to ${/* @__PURE__ */ new Date(issue.input * 1e3)}. It must fall on the allowed settlement cycles (Friday 15:00 UTC at the end of week/month/quarter).`;
2928
+ return `The maturity is set to ${/* @__PURE__ */ new Date(issue.input * 1e3)}. It must be at 15:00:00 UTC.`;
2880
2929
  } catch (_) {
2881
- 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).`;
2930
+ return `The maturity is set to ${issue.input}. It must be at 15:00:00 UTC.`;
2882
2931
  }
2883
2932
  } }).transform((maturity) => maturity);
2884
2933
  let MaturityType = /* @__PURE__ */ function(MaturityType) {
@@ -2910,9 +2959,14 @@ function from$9(ts) {
2910
2959
  throw new InvalidOptionError(ts);
2911
2960
  }
2912
2961
  if (typeof ts === "number" && ts > 0xe8d4a51000) throw new InvalidFormatError();
2913
- if (!Object.values(MaturityOptions).some((option) => option() === ts)) throw new InvalidDateError(ts);
2962
+ if (!isAt15UTC(ts)) throw new InvalidDateError(ts);
2914
2963
  return ts;
2915
2964
  }
2965
+ /** Checks whether a timestamp (in seconds) falls at exactly 15:00:00 UTC. */
2966
+ function isAt15UTC(ts) {
2967
+ const date = /* @__PURE__ */ new Date(ts * 1e3);
2968
+ return date.getUTCHours() === 15 && date.getUTCMinutes() === 0 && date.getUTCSeconds() === 0 && date.getUTCMilliseconds() === 0;
2969
+ }
2916
2970
  /** Returns the end of the current week (friday at 15:00:00 UTC) */
2917
2971
  const endOfWeek = () => fridayOfWeek(0);
2918
2972
  /** Returns the end of the next week (friday at 15:00:00 UTC) */
@@ -2965,21 +3019,21 @@ const lastFridayOfQuarter = (quartersAhead = 0) => {
2965
3019
  return lastFridayOfMonth(now.getUTCFullYear() + Math.floor(quarterIndex / 4), quarterIndex % 4 * 3 + 2);
2966
3020
  };
2967
3021
  var InvalidFormatError = class extends BaseError {
3022
+ name = "Maturity.InvalidFormatError";
2968
3023
  constructor() {
2969
3024
  super("Invalid maturity format. Maturity should be expressed in seconds.");
2970
- _defineProperty(this, "name", "Maturity.InvalidFormatError");
2971
3025
  }
2972
3026
  };
2973
3027
  var InvalidDateError = class extends BaseError {
3028
+ name = "Maturity.InvalidDateError";
2974
3029
  constructor(input) {
2975
- super(`Invalid maturity date. Input: "${input}". Accepted values are: ${Object.values(MaturityOptions).map((option) => `"${option()}"`).join(", ")}.`);
2976
- _defineProperty(this, "name", "Maturity.InvalidDateError");
3030
+ super(`Invalid maturity date. Input: "${input}". Maturity must be at 15:00:00 UTC.`);
2977
3031
  }
2978
3032
  };
2979
3033
  var InvalidOptionError = class extends BaseError {
3034
+ name = "Maturity.InvalidOptionError";
2980
3035
  constructor(input) {
2981
3036
  super(`Invalid maturity option. Input: "${input}". Accepted values are: ${Object.keys(MaturityOptions).map((option) => `"${option}"`).join(", ")}.`);
2982
- _defineProperty(this, "name", "Maturity.InvalidOptionError");
2983
3037
  }
2984
3038
  };
2985
3039
 
@@ -3000,7 +3054,8 @@ var Obligation_exports = /* @__PURE__ */ __exportAll({
3000
3054
  const ObligationSchema = z$1.object({
3001
3055
  loanToken: z$1.string().transform(transformAddress),
3002
3056
  collaterals: CollateralsSchema,
3003
- maturity: MaturitySchema
3057
+ maturity: MaturitySchema,
3058
+ minCollatValue: z$1.bigint({ coerce: true }).min(0n).optional().default(0n)
3004
3059
  });
3005
3060
  const abi = [
3006
3061
  {
@@ -3015,6 +3070,10 @@ const abi = [
3015
3070
  {
3016
3071
  type: "uint256",
3017
3072
  name: "maturity"
3073
+ },
3074
+ {
3075
+ type: "uint256",
3076
+ name: "minCollatValue"
3018
3077
  }
3019
3078
  ];
3020
3079
  const tupleAbi = [{
@@ -3052,7 +3111,8 @@ function from$8(parameters) {
3052
3111
  return {
3053
3112
  loanToken: parsedObligation.loanToken.toLowerCase(),
3054
3113
  collaterals: parsedObligation.collaterals.sort((a, b) => a.asset.localeCompare(b.asset)),
3055
- maturity: parsedObligation.maturity
3114
+ maturity: parsedObligation.maturity,
3115
+ minCollatValue: parsedObligation.minCollatValue
3056
3116
  };
3057
3117
  } catch (error) {
3058
3118
  throw new InvalidObligationError(error);
@@ -3069,7 +3129,8 @@ function fromSnakeCase$2(input) {
3069
3129
  }
3070
3130
  /**
3071
3131
  * Calculates a canonical key for an obligation payload.
3072
- * The key is computed as keccak256(abi.encode(loanToken, collaterals, maturity)).
3132
+ * The key is computed as keccak256(abi.encode(loanToken, collaterals, maturity, minCollatValue)).
3133
+ * If omitted, `minCollatValue` defaults to `0`.
3073
3134
  * @throws If the collaterals are not sorted alphabetically by address. {@link CollateralsAreNotSortedError}
3074
3135
  * @param parameters - {@link key.Parameters}
3075
3136
  * @returns The obligation key as a 32-byte hex string. {@link key.ReturnType}
@@ -3095,7 +3156,8 @@ function key(parameters) {
3095
3156
  lltv: c.lltv,
3096
3157
  oracle: c.oracle.toLowerCase()
3097
3158
  })),
3098
- BigInt(parameters.maturity)
3159
+ BigInt(parameters.maturity),
3160
+ parameters.minCollatValue ?? 0n
3099
3161
  ]));
3100
3162
  }
3101
3163
  /**
@@ -3129,15 +3191,15 @@ function fromOffer$1(offer) {
3129
3191
  });
3130
3192
  }
3131
3193
  var InvalidObligationError = class extends BaseError {
3194
+ name = "Obligation.InvalidObligationError";
3132
3195
  constructor(error) {
3133
3196
  super("Invalid obligation.", { cause: error });
3134
- _defineProperty(this, "name", "Obligation.InvalidObligationError");
3135
3197
  }
3136
3198
  };
3137
3199
  var CollateralsAreNotSortedError = class extends BaseError {
3200
+ name = "Obligation.CollateralsAreNotSortedError";
3138
3201
  constructor() {
3139
3202
  super("Collaterals are not sorted alphabetically by address.");
3140
- _defineProperty(this, "name", "Obligation.CollateralsAreNotSortedError");
3141
3203
  }
3142
3204
  };
3143
3205
 
@@ -3147,39 +3209,42 @@ var Id_exports = /* @__PURE__ */ __exportAll({
3147
3209
  creationCode: () => creationCode,
3148
3210
  toId: () => toId
3149
3211
  });
3150
- const CREATION_CODE_PREFIX = "0x603f380380603f5f395ff3";
3212
+ const CREATION_CODE_PREFIX = "0x600b380380600b5f395ff3";
3151
3213
  /**
3152
3214
  * Builds the same creation code as `IdLib.creationCode` in Solidity.
3153
3215
  *
3154
- * Layout: `prefix (11 bytes) + chainId (32 bytes) + morphoV2 (20 bytes) + abi.encode(obligation)`.
3216
+ * Layout: `prefix (11 bytes) + abi.encode(obligation)`.
3155
3217
  *
3156
3218
  * @param parameters - {@link creationCode.Parameters}
3157
3219
  * @returns The CREATE2 init code bytes. {@link creationCode.ReturnType}
3158
3220
  */
3159
3221
  function creationCode(parameters) {
3160
- const encodedObligation = encodeAbiParameters(tupleAbi, [{
3222
+ return concatHex([CREATION_CODE_PREFIX, encodeAbiParameters(tupleAbi, [{
3161
3223
  loanToken: parameters.obligation.loanToken.toLowerCase(),
3162
3224
  collaterals: parameters.obligation.collaterals.map((collateral) => ({
3163
3225
  token: collateral.asset.toLowerCase(),
3164
3226
  lltv: collateral.lltv,
3165
3227
  oracle: collateral.oracle.toLowerCase()
3166
3228
  })),
3167
- maturity: BigInt(parameters.obligation.maturity)
3168
- }]);
3169
- return concatHex([
3170
- CREATION_CODE_PREFIX,
3171
- numberToHex(BigInt(parameters.chainId), { size: 32 }),
3172
- parameters.morphoV2.toLowerCase(),
3173
- encodedObligation
3174
- ]);
3229
+ maturity: BigInt(parameters.obligation.maturity),
3230
+ minCollatValue: 0n
3231
+ }])]);
3175
3232
  }
3176
3233
  /**
3177
- * Computes the same id as `IdLib.toId` in Solidity.
3234
+ * Computes the same id as `IdLib.toId` in Solidity using the CREATE2 preimage:
3235
+ * `keccak256(0xff ++ morphoV2 ++ chainId ++ keccak256(creationCode))`,
3236
+ * then truncates to the lower 20 bytes.
3237
+ *
3178
3238
  * @param parameters - {@link toId.Parameters}
3179
3239
  * @returns The obligation id. {@link toId.ReturnType}
3180
3240
  */
3181
3241
  function toId(parameters) {
3182
- return keccak256(creationCode(parameters));
3242
+ return `0x${keccak256(concatHex([
3243
+ "0xff",
3244
+ parameters.morphoV2.toLowerCase(),
3245
+ numberToHex(BigInt(parameters.chainId), { size: 32 }),
3246
+ keccak256(creationCode(parameters))
3247
+ ])).slice(-40)}`;
3183
3248
  }
3184
3249
 
3185
3250
  //#endregion
@@ -3476,7 +3541,7 @@ function hash(offer) {
3476
3541
  * The id is computed with {@link Id.toId}.
3477
3542
  * @param offer - The offer to calculate the obligation id for.
3478
3543
  * @param parameters - The chain context used by the onchain id function.
3479
- * @returns The obligation id as a 32-byte hex string.
3544
+ * @returns The obligation id as a 20-byte hex string.
3480
3545
  */
3481
3546
  function obligationId(offer, parameters) {
3482
3547
  return toId({
@@ -3639,10 +3704,10 @@ const takeEvent = {
3639
3704
  internalType: "address"
3640
3705
  },
3641
3706
  {
3642
- name: "id",
3643
- type: "bytes32",
3707
+ name: "id_",
3708
+ type: "bytes20",
3644
3709
  indexed: true,
3645
- internalType: "bytes32"
3710
+ internalType: "bytes20"
3646
3711
  },
3647
3712
  {
3648
3713
  name: "maker",
@@ -3761,10 +3826,10 @@ const repayEvent = {
3761
3826
  internalType: "address"
3762
3827
  },
3763
3828
  {
3764
- name: "id",
3765
- type: "bytes32",
3829
+ name: "id_",
3830
+ type: "bytes20",
3766
3831
  indexed: true,
3767
- internalType: "bytes32"
3832
+ internalType: "bytes20"
3768
3833
  },
3769
3834
  {
3770
3835
  name: "obligationUnits",
@@ -3795,46 +3860,35 @@ const liquidateEvent = {
3795
3860
  internalType: "address"
3796
3861
  },
3797
3862
  {
3798
- name: "id",
3799
- type: "bytes32",
3863
+ name: "id_",
3864
+ type: "bytes20",
3800
3865
  indexed: true,
3801
- internalType: "bytes32"
3866
+ internalType: "bytes20"
3802
3867
  },
3803
3868
  {
3804
- name: "seizures",
3805
- type: "tuple[]",
3869
+ name: "collateralIndex",
3870
+ type: "uint256",
3806
3871
  indexed: false,
3807
- internalType: "struct IMorphoV2.Seizure[]",
3808
- components: [
3809
- {
3810
- name: "collateralIndex",
3811
- type: "uint256",
3812
- internalType: "uint256"
3813
- },
3814
- {
3815
- name: "repaid",
3816
- type: "uint256",
3817
- internalType: "uint256"
3818
- },
3819
- {
3820
- name: "seized",
3821
- type: "uint256",
3822
- internalType: "uint256"
3823
- }
3824
- ]
3872
+ internalType: "uint256"
3825
3873
  },
3826
3874
  {
3827
- name: "borrower",
3828
- type: "address",
3829
- indexed: true,
3830
- internalType: "address"
3875
+ name: "seizedAssets",
3876
+ type: "uint256",
3877
+ indexed: false,
3878
+ internalType: "uint256"
3831
3879
  },
3832
3880
  {
3833
- name: "totalRepaid",
3881
+ name: "repaidUnits",
3834
3882
  type: "uint256",
3835
3883
  indexed: false,
3836
3884
  internalType: "uint256"
3837
3885
  },
3886
+ {
3887
+ name: "borrower",
3888
+ type: "address",
3889
+ indexed: true,
3890
+ internalType: "address"
3891
+ },
3838
3892
  {
3839
3893
  name: "badDebt",
3840
3894
  type: "uint256",
@@ -3858,10 +3912,10 @@ const supplyCollateralEvent = {
3858
3912
  internalType: "address"
3859
3913
  },
3860
3914
  {
3861
- name: "id",
3862
- type: "bytes32",
3915
+ name: "id_",
3916
+ type: "bytes20",
3863
3917
  indexed: true,
3864
- internalType: "bytes32"
3918
+ internalType: "bytes20"
3865
3919
  },
3866
3920
  {
3867
3921
  name: "collateral",
@@ -3898,10 +3952,10 @@ const withdrawCollateralEvent = {
3898
3952
  internalType: "address"
3899
3953
  },
3900
3954
  {
3901
- name: "id",
3902
- type: "bytes32",
3955
+ name: "id_",
3956
+ type: "bytes20",
3903
3957
  indexed: true,
3904
- internalType: "bytes32"
3958
+ internalType: "bytes20"
3905
3959
  },
3906
3960
  {
3907
3961
  name: "collateral",
@@ -3931,9 +3985,9 @@ const withdrawCollateralEvent = {
3931
3985
  anonymous: false
3932
3986
  };
3933
3987
  var InvalidOfferError = class InvalidOfferError extends BaseError {
3988
+ name = "Offer.InvalidOfferError";
3934
3989
  constructor(error) {
3935
3990
  super("Invalid offer.", { cause: error });
3936
- _defineProperty(this, "name", "Offer.InvalidOfferError");
3937
3991
  }
3938
3992
  /**
3939
3993
  * Formats ZodError issues into a human-readable string with line breaks.
@@ -4146,9 +4200,9 @@ function random() {
4146
4200
  });
4147
4201
  }
4148
4202
  var InvalidQuoteError = class extends BaseError {
4203
+ name = "Quote.InvalidQuoteError";
4149
4204
  constructor(error) {
4150
4205
  super("Invalid quote.", { cause: error });
4151
- _defineProperty(this, "name", "Quote.InvalidQuoteError");
4152
4206
  }
4153
4207
  };
4154
4208
  function sideFromTick(side) {
@@ -4294,16 +4348,16 @@ function getSegment(timeToMaturity) {
4294
4348
  }
4295
4349
  /** Error thrown when a fee value is invalid (negative or exceeds WAD). */
4296
4350
  var InvalidFeeError = class extends BaseError {
4351
+ name = "TradingFee.InvalidFeeError";
4297
4352
  constructor(fee, index) {
4298
4353
  super(`Invalid fee at index ${index}: ${fee}. Fee must be between 0 and ${WAD} (WAD).`);
4299
- _defineProperty(this, "name", "TradingFee.InvalidFeeError");
4300
4354
  }
4301
4355
  };
4302
4356
  /** Error thrown when fees array doesn't have exactly 6 elements. */
4303
4357
  var InvalidFeesLengthError = class extends BaseError {
4358
+ name = "TradingFee.InvalidFeesLengthError";
4304
4359
  constructor(length) {
4305
4360
  super(`Invalid fees length: ${length}. Expected exactly 6 fee values.`);
4306
- _defineProperty(this, "name", "TradingFee.InvalidFeesLengthError");
4307
4361
  }
4308
4362
  };
4309
4363
 
@@ -4343,7 +4397,7 @@ var Tree_exports = /* @__PURE__ */ __exportAll({
4343
4397
  EncodeError: () => EncodeError,
4344
4398
  SignatureDomainError: () => SignatureDomainError,
4345
4399
  TreeError: () => TreeError,
4346
- VERSION: () => VERSION,
4400
+ VERSION: () => VERSION$1,
4347
4401
  decode: () => decode,
4348
4402
  encode: () => encode,
4349
4403
  encodeUnsigned: () => encodeUnsigned,
@@ -4352,7 +4406,7 @@ var Tree_exports = /* @__PURE__ */ __exportAll({
4352
4406
  signatureDomain: () => signatureDomain,
4353
4407
  signatureTypes: () => signatureTypes
4354
4408
  });
4355
- const VERSION = 1;
4409
+ const VERSION$1 = 1;
4356
4410
  /**
4357
4411
  * EIP-712 types for signing the tree root (Root(bytes32 root)).
4358
4412
  */
@@ -4546,7 +4600,7 @@ const encodeUnsigned = (tree) => {
4546
4600
  return bytesToHex(encodeUnsignedBytes(tree));
4547
4601
  };
4548
4602
  const validateTreeForEncoding = (tree) => {
4549
- if (VERSION > 255) throw new EncodeError(`version overflow: ${VERSION} exceeds 255`);
4603
+ if (VERSION$1 > 255) throw new EncodeError(`version overflow: ${VERSION$1} exceeds 255`);
4550
4604
  const computed = from$1(tree.offers);
4551
4605
  if (tree.root !== computed.root) throw new EncodeError(`root mismatch: expected ${computed.root}, got ${tree.root}`);
4552
4606
  };
@@ -4555,7 +4609,7 @@ const encodeUnsignedBytes = (tree) => {
4555
4609
  const compressed = gzip(JSON.stringify(offersPayload));
4556
4610
  const rootBytes = hexToBytes(tree.root);
4557
4611
  const encoded = new Uint8Array(1 + compressed.length + 32);
4558
- encoded[0] = VERSION;
4612
+ encoded[0] = VERSION$1;
4559
4613
  encoded.set(compressed, 1);
4560
4614
  encoded.set(rootBytes, 1 + compressed.length);
4561
4615
  return encoded;
@@ -4589,7 +4643,7 @@ const decode = async (encoded, domain) => {
4589
4643
  const bytes = hexToBytes(encoded);
4590
4644
  if (bytes.length < 98) throw new DecodeError("payload too short");
4591
4645
  const version = bytes[0];
4592
- if (version !== (VERSION & 255)) throw new DecodeError(`invalid version: expected ${VERSION}, got ${version ?? 0}`);
4646
+ if (version !== (VERSION$1 & 255)) throw new DecodeError(`invalid version: expected ${VERSION$1}, got ${version ?? 0}`);
4593
4647
  const signature = bytesToHex(bytes.slice(-65));
4594
4648
  const root = bytesToHex(bytes.slice(-97, -65));
4595
4649
  assertHex(root, 32, "root");
@@ -4626,9 +4680,9 @@ const decode = async (encoded, domain) => {
4626
4680
  * Indicates structural issues with the tree (missing offers, inconsistent state).
4627
4681
  */
4628
4682
  var TreeError = class extends BaseError {
4683
+ name = "Tree.TreeError";
4629
4684
  constructor(reason) {
4630
4685
  super(`Tree error: ${reason}`);
4631
- _defineProperty(this, "name", "Tree.TreeError");
4632
4686
  }
4633
4687
  };
4634
4688
  /**
@@ -4636,9 +4690,9 @@ var TreeError = class extends BaseError {
4636
4690
  * Indicates validation failures (signature, root mismatch, mixed makers).
4637
4691
  */
4638
4692
  var EncodeError = class extends BaseError {
4693
+ name = "Tree.EncodeError";
4639
4694
  constructor(reason) {
4640
4695
  super(`Failed to encode tree: ${reason}`);
4641
- _defineProperty(this, "name", "Tree.EncodeError");
4642
4696
  }
4643
4697
  };
4644
4698
  /**
@@ -4646,18 +4700,18 @@ var EncodeError = class extends BaseError {
4646
4700
  * Indicates payload corruption, version mismatch, or validation failures.
4647
4701
  */
4648
4702
  var DecodeError = class extends BaseError {
4703
+ name = "Tree.DecodeError";
4649
4704
  constructor(reason) {
4650
4705
  super(`Failed to decode tree: ${reason}`);
4651
- _defineProperty(this, "name", "Tree.DecodeError");
4652
4706
  }
4653
4707
  };
4654
4708
  /**
4655
4709
  * Error thrown when an invalid signature domain is supplied.
4656
4710
  */
4657
4711
  var SignatureDomainError = class extends BaseError {
4712
+ name = "Tree.SignatureDomainError";
4658
4713
  constructor(reason) {
4659
4714
  super(`Invalid signature domain: ${reason}`);
4660
- _defineProperty(this, "name", "Tree.SignatureDomainError");
4661
4715
  }
4662
4716
  };
4663
4717
 
@@ -4815,36 +4869,51 @@ async function getObligations(apiClient, parameters) {
4815
4869
  };
4816
4870
  }
4817
4871
  var InvalidUrlError = class extends BaseError {
4872
+ name = "Router.InvalidUrlError";
4818
4873
  constructor(url) {
4819
4874
  super(`URL "${url}" is not http/https.`);
4820
- _defineProperty(this, "name", "Router.InvalidUrlError");
4821
4875
  }
4822
4876
  };
4823
4877
  var HttpUnauthorizedError = class extends BaseError {
4878
+ name = "Router.HttpUnauthorizedError";
4824
4879
  constructor() {
4825
4880
  super("Unauthorized.", { metaMessages: ["Ensure that an API key is provided."] });
4826
- _defineProperty(this, "name", "Router.HttpUnauthorizedError");
4827
4881
  }
4828
4882
  };
4829
4883
  var HttpForbiddenError = class extends BaseError {
4884
+ name = "Router.HttpForbiddenError";
4830
4885
  constructor() {
4831
4886
  super("Forbidden.", { metaMessages: ["Ensure that the API key is valid."] });
4832
- _defineProperty(this, "name", "Router.HttpForbiddenError");
4833
4887
  }
4834
4888
  };
4835
4889
  var HttpRateLimitError = class extends BaseError {
4890
+ name = "Router.HttpRateLimitError";
4836
4891
  constructor() {
4837
4892
  super("Rate limit exceeded.", { metaMessages: ["The number of allowed requests has been exceeded. You must wait for the rate limit to reset."] });
4838
- _defineProperty(this, "name", "Router.HttpRateLimitError");
4839
4893
  }
4840
4894
  };
4841
4895
  var HttpGetApiFailedError = class extends BaseError {
4896
+ name = "Router.HttpGetApiFailedError";
4842
4897
  constructor(message, { details } = {}) {
4843
4898
  super(message, { metaMessages: [details] });
4844
- _defineProperty(this, "name", "Router.HttpGetApiFailedError");
4845
4899
  }
4846
4900
  };
4847
4901
 
4902
+ //#endregion
4903
+ //#region src/observability/TraceHeaders.ts
4904
+ /**
4905
+ * Inject active trace context headers into outgoing HTTP headers.
4906
+ * @param headers - Existing headers for the outgoing request.
4907
+ * @returns Headers enriched with active trace context.
4908
+ */
4909
+ function withActiveTraceHeaders(headers) {
4910
+ const enrichedHeaders = new Headers(headers);
4911
+ const carrier = {};
4912
+ propagation.inject(context.active(), carrier);
4913
+ for (const [key, value] of Object.entries(carrier)) enrichedHeaders.set(key, value);
4914
+ return enrichedHeaders;
4915
+ }
4916
+
4848
4917
  //#endregion
4849
4918
  //#region src/gatekeeper/Client.ts
4850
4919
  var Client_exports = /* @__PURE__ */ __exportAll({ createHttpClient: () => createHttpClient });
@@ -4865,7 +4934,7 @@ function createHttpClient(config) {
4865
4934
  try {
4866
4935
  return await fetchFn(`${baseUrl}${path}`, {
4867
4936
  ...init,
4868
- headers: mergeHeaders(baseHeaders, init.headers),
4937
+ headers: withActiveTraceHeaders(mergeHeaders(baseHeaders, init.headers)),
4869
4938
  signal: controller.signal
4870
4939
  });
4871
4940
  } finally {
@@ -5117,7 +5186,7 @@ const collateralAssets = {
5117
5186
  "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
5118
5187
  ]
5119
5188
  };
5120
- const oracles = {
5189
+ const oracles$1 = {
5121
5190
  [ChainId.ETHEREUM.toString()]: [
5122
5191
  "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
5123
5192
  "0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
@@ -5139,6 +5208,7 @@ const oracles = {
5139
5208
  ],
5140
5209
  [ChainId["ETHEREUM-VIRTUAL-TESTNET"].toString()]: [
5141
5210
  "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
5211
+ "0xEeee770BADd886dF3864029e4B377B5F6a2B6b83",
5142
5212
  "0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
5143
5213
  "0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
5144
5214
  "0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
@@ -5147,6 +5217,7 @@ const oracles = {
5147
5217
  ],
5148
5218
  [ChainId.ANVIL.toString()]: [
5149
5219
  "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
5220
+ "0xEeee770BADd886dF3864029e4B377B5F6a2B6b83",
5150
5221
  "0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
5151
5222
  "0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
5152
5223
  "0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
@@ -5157,30 +5228,626 @@ const oracles = {
5157
5228
  const configs = {
5158
5229
  ethereum: {
5159
5230
  callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5160
- maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
5231
+ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
5232
+ minDuration: 10
5161
5233
  },
5162
5234
  base: {
5163
5235
  callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5164
- maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
5236
+ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
5237
+ minDuration: 10
5165
5238
  },
5166
5239
  "ethereum-virtual-testnet": {
5167
5240
  callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5168
- maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
5241
+ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
5242
+ minDuration: 10
5169
5243
  },
5170
5244
  anvil: {
5171
5245
  callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5172
- maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
5246
+ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
5247
+ minDuration: 10
5248
+ }
5249
+ };
5250
+
5251
+ //#endregion
5252
+ //#region src/utils/retry.ts
5253
+ const retry = async (fn, attempts = 3, delayMs = 50) => {
5254
+ let lastErr;
5255
+ for (let i = 0; i < attempts; i++) try {
5256
+ return await fn();
5257
+ } catch (err) {
5258
+ lastErr = err;
5259
+ if (i < attempts - 1) await new Promise((r) => setTimeout(r, delayMs));
5260
+ }
5261
+ throw lastErr;
5262
+ };
5263
+
5264
+ //#endregion
5265
+ //#region src/utils/batchMulticall.ts
5266
+ /**
5267
+ * Helper function to execute multicall in batches with retry logic.
5268
+ * Abstracts the common pattern of batching calls, retrying, and collecting results.
5269
+ *
5270
+ * @param parameters - Configuration for batched multicall
5271
+ * @returns Promise resolving to flattened array of results
5272
+ */
5273
+ async function batchMulticall(parameters) {
5274
+ const { client, calls, batchSize, retryAttempts, retryDelayMs, blockNumber } = parameters;
5275
+ const results = [];
5276
+ for (const callsBatch of batch$1(calls, batchSize)) {
5277
+ const batchResults = await retry(() => multicall(client, {
5278
+ allowFailure: false,
5279
+ contracts: callsBatch,
5280
+ ...blockNumber ? { blockNumber } : {}
5281
+ }), retryAttempts, retryDelayMs);
5282
+ results.push(...batchResults);
5173
5283
  }
5284
+ return results;
5285
+ }
5286
+
5287
+ //#endregion
5288
+ //#region src/utils/Group.ts
5289
+ var Group_exports = /* @__PURE__ */ __exportAll({ fromNumber: () => fromNumber });
5290
+ /**
5291
+ * Creates a bytes32 group identifier from a number.
5292
+ * @param n - A non-negative integer.
5293
+ * @throws {Error} If n is negative or not an integer.
5294
+ */
5295
+ const fromNumber = (n) => {
5296
+ if (!Number.isInteger(n)) throw new Error(`Group.fromNumber: expected integer, got ${n}`);
5297
+ if (n < 0) throw new Error(`Group.fromNumber: expected non-negative, got ${n}`);
5298
+ return pad(`0x${n.toString(16)}`, { size: 32 });
5174
5299
  };
5175
5300
 
5301
+ //#endregion
5302
+ //#region src/utils/lazy.ts
5303
+ /**
5304
+ * Transform a polling function into an async generator.
5305
+ * @param fn - The polling function to transform.
5306
+ * @returns An async generator.
5307
+ */
5308
+ function lazy(pollFn) {
5309
+ return () => (async function* () {
5310
+ let active = true;
5311
+ let resolveNext = null;
5312
+ const queue = [];
5313
+ const wait = () => new Promise((resolve) => {
5314
+ resolveNext = resolve;
5315
+ });
5316
+ const emit = (item) => {
5317
+ queue.push(item);
5318
+ resolveNext?.();
5319
+ resolveNext = null;
5320
+ };
5321
+ let unpoll = null;
5322
+ const stop = () => {
5323
+ active = false;
5324
+ unpoll?.();
5325
+ resolveNext?.();
5326
+ resolveNext = null;
5327
+ };
5328
+ unpoll = pollFn(emit, { stop });
5329
+ try {
5330
+ while (active) {
5331
+ if (queue.length === 0) await wait();
5332
+ while (queue.length > 0 && active) yield queue.shift();
5333
+ }
5334
+ } finally {
5335
+ stop();
5336
+ }
5337
+ })();
5338
+ }
5339
+
5340
+ //#endregion
5341
+ //#region src/utils/wait.ts
5342
+ async function wait(time) {
5343
+ return new Promise((res) => setTimeout(res, time));
5344
+ }
5345
+
5346
+ //#endregion
5347
+ //#region src/utils/poll.ts
5348
+ /**
5349
+ * Polls a function at a specified interval.
5350
+ * Inspired by https://github.com/wevm/viem/blob/845994d20275d08ff892018e237a4b599eeefb6a/src/utils/poll.ts
5351
+ */
5352
+ function poll(fn, { interval }) {
5353
+ let active = true;
5354
+ const unwatch = () => active = false;
5355
+ const watch = async () => {
5356
+ while (active) {
5357
+ const delay = await interval();
5358
+ if (!active) break;
5359
+ await wait(delay);
5360
+ if (!active) break;
5361
+ await fn({ unpoll: unwatch });
5362
+ }
5363
+ };
5364
+ watch();
5365
+ return unwatch;
5366
+ }
5367
+
5368
+ //#endregion
5369
+ //#region src/utils/time.ts
5370
+ var time_exports = /* @__PURE__ */ __exportAll({
5371
+ max: () => max,
5372
+ now: () => now
5373
+ });
5374
+ function now() {
5375
+ return Math.floor(Date.now() / 1e3);
5376
+ }
5377
+ function max() {
5378
+ return 0x77e772392b600000;
5379
+ }
5380
+
5381
+ //#endregion
5382
+ //#region src/utils/index.ts
5383
+ var utils_exports = /* @__PURE__ */ __exportAll({
5384
+ BaseError: () => BaseError,
5385
+ Group: () => Group_exports,
5386
+ Random: () => Random_exports,
5387
+ ReorgError: () => ReorgError,
5388
+ Time: () => time_exports,
5389
+ atMostOneNonZero: () => atMostOneNonZero,
5390
+ batch: () => batch$1,
5391
+ batchMulticall: () => batchMulticall,
5392
+ fromSnakeCase: () => fromSnakeCase$3,
5393
+ lazy: () => lazy,
5394
+ max: () => max$1,
5395
+ min: () => min,
5396
+ poll: () => poll,
5397
+ retry: () => retry,
5398
+ stringifyBigint: () => stringifyBigint,
5399
+ toSnakeCase: () => toSnakeCase$1,
5400
+ wait: () => wait
5401
+ });
5402
+
5403
+ //#endregion
5404
+ //#region src/database/drizzle/VERSION.ts
5405
+ const VERSION = "router_v1.13";
5406
+
5407
+ //#endregion
5408
+ //#region src/database/drizzle/schema.ts
5409
+ const s = pgSchema(VERSION);
5410
+ var EnumTableName = /* @__PURE__ */ function(EnumTableName) {
5411
+ EnumTableName["OBLIGATIONS"] = "obligations";
5412
+ EnumTableName["OBLIGATION_ID_KEYS"] = "obligation_id_keys";
5413
+ EnumTableName["GROUPS"] = "groups";
5414
+ EnumTableName["CONSUMED_EVENTS"] = "consumed_events";
5415
+ EnumTableName["OBLIGATION_COLLATERALS_V2"] = "obligation_collaterals_v2";
5416
+ EnumTableName["ORACLES"] = "oracles";
5417
+ EnumTableName["OFFERS"] = "offers";
5418
+ EnumTableName["OFFERS_CALLBACKS"] = "offers_callbacks";
5419
+ EnumTableName["CALLBACKS"] = "callbacks";
5420
+ EnumTableName["POSITIONS"] = "positions";
5421
+ EnumTableName["TRANSFERS"] = "transfers";
5422
+ EnumTableName["VALIDATIONS"] = "validations";
5423
+ EnumTableName["COLLECTORS"] = "collectors";
5424
+ EnumTableName["CHAINS"] = "chains";
5425
+ EnumTableName["LOTS"] = "lots";
5426
+ EnumTableName["LOTS_POSITIONS"] = "lots_positions";
5427
+ EnumTableName["OFFSETS"] = "offsets";
5428
+ EnumTableName["TREES"] = "trees";
5429
+ EnumTableName["MERKLE_PATHS"] = "merkle_paths";
5430
+ return EnumTableName;
5431
+ }(EnumTableName || {});
5432
+ const TABLE_NAMES = Object.values(EnumTableName);
5433
+ const VERSIONED_TABLE_NAMES = TABLE_NAMES.map((table) => `"${VERSION}"."${table}"`);
5434
+ const obligations = s.table(EnumTableName.OBLIGATIONS, {
5435
+ obligationKey: varchar("obligation_key", { length: 66 }).primaryKey(),
5436
+ loanToken: varchar("loan_token", { length: 42 }).notNull(),
5437
+ maturity: integer("maturity").notNull()
5438
+ });
5439
+ const obligationIdKeys = s.table(EnumTableName.OBLIGATION_ID_KEYS, {
5440
+ obligationId: varchar("obligation_id", { length: 42 }).primaryKey(),
5441
+ obligationKey: varchar("obligation_key", { length: 66 }).notNull().references(() => obligations.obligationKey, { onDelete: "cascade" }),
5442
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5443
+ morphoV2: varchar("morpho_v2", { length: 42 }).notNull()
5444
+ }, (table) => [index("obligation_id_keys_obligation_key_idx").on(table.obligationKey), index("obligation_id_keys_chain_id_idx").on(table.chainId)]);
5445
+ const groups = s.table(EnumTableName.GROUPS, {
5446
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5447
+ maker: varchar("maker", { length: 42 }).notNull(),
5448
+ group: varchar("group", { length: 66 }).notNull(),
5449
+ consumed: numeric("consumed", {
5450
+ precision: 78,
5451
+ scale: 0
5452
+ }).notNull(),
5453
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5454
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5455
+ }, (table) => [primaryKey({
5456
+ columns: [
5457
+ table.chainId,
5458
+ table.maker,
5459
+ table.group
5460
+ ],
5461
+ name: "groups_pk"
5462
+ }), index("groups_chain_id_maker_group_consumed_idx").on(table.chainId, table.maker, table.group, table.consumed)]);
5463
+ const consumedEvents = s.table(EnumTableName.CONSUMED_EVENTS, {
5464
+ eventId: varchar("event_id", { length: 128 }).primaryKey(),
5465
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5466
+ maker: varchar("maker", { length: 42 }).notNull(),
5467
+ group: varchar("group", { length: 66 }).notNull(),
5468
+ amount: numeric("amount", {
5469
+ precision: 78,
5470
+ scale: 0
5471
+ }).notNull(),
5472
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5473
+ createdAt: timestamp("created_at").defaultNow().notNull()
5474
+ }, (t) => [
5475
+ foreignKey({
5476
+ columns: [
5477
+ t.chainId,
5478
+ t.maker,
5479
+ t.group
5480
+ ],
5481
+ foreignColumns: [
5482
+ groups.chainId,
5483
+ groups.maker,
5484
+ groups.group
5485
+ ],
5486
+ name: "consumed_events_groups_fk"
5487
+ }).onDelete("cascade"),
5488
+ index("consumed_events_group_idx").on(t.chainId, t.maker, t.group),
5489
+ index("consumed_events_block_number_idx").on(t.blockNumber)
5490
+ ]);
5491
+ const obligationCollateralsV2 = s.table(EnumTableName.OBLIGATION_COLLATERALS_V2, {
5492
+ obligationKey: varchar("obligation_key", { length: 66 }).notNull().references(() => obligations.obligationKey, { onDelete: "cascade" }),
5493
+ asset: varchar("asset", { length: 42 }).notNull(),
5494
+ oracleAddress: varchar("oracle_address", { length: 42 }).notNull(),
5495
+ lltv: bigint("lltv", { mode: "bigint" }).notNull(),
5496
+ collateralIndex: integer("collateral_index").notNull(),
5497
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5498
+ }, (table) => [
5499
+ primaryKey({
5500
+ columns: [table.obligationKey, table.asset],
5501
+ name: "obligation_collaterals_v2_pk"
5502
+ }),
5503
+ index("obligation_collaterals_v2_obligation_key_idx").on(table.obligationKey),
5504
+ index("obligation_collaterals_v2_oracle_address_idx").on(table.oracleAddress)
5505
+ ]);
5506
+ const oracles = s.table(EnumTableName.ORACLES, {
5507
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5508
+ address: varchar("address", { length: 42 }).notNull(),
5509
+ price: numeric("price", {
5510
+ precision: 78,
5511
+ scale: 0
5512
+ }),
5513
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5514
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5515
+ }, (table) => [primaryKey({
5516
+ columns: [table.chainId, table.address],
5517
+ name: "oracles_pk"
5518
+ })]);
5519
+ const offers = s.table(EnumTableName.OFFERS, {
5520
+ hash: varchar("hash", { length: 66 }).notNull(),
5521
+ obligationId: varchar("obligation_id", { length: 42 }).notNull().references(() => obligationIdKeys.obligationId, { onDelete: "cascade" }),
5522
+ assets: numeric("assets", {
5523
+ precision: 78,
5524
+ scale: 0
5525
+ }).notNull(),
5526
+ obligationUnits: numeric("obligation_units", {
5527
+ precision: 78,
5528
+ scale: 0
5529
+ }).notNull().default("0"),
5530
+ obligationShares: numeric("obligation_shares", {
5531
+ precision: 78,
5532
+ scale: 0
5533
+ }).notNull().default("0"),
5534
+ tick: integer("tick").notNull(),
5535
+ maturity: integer("maturity").notNull(),
5536
+ expiry: integer("expiry").notNull(),
5537
+ start: integer("start").notNull(),
5538
+ groupChainId: bigint("group_chain_id", { mode: "number" }).$type().notNull(),
5539
+ groupMaker: varchar("group_maker", { length: 42 }).notNull(),
5540
+ group: varchar("group_group", { length: 66 }).notNull(),
5541
+ session: varchar("session", { length: 66 }).notNull(),
5542
+ buy: boolean("buy").notNull(),
5543
+ callbackAddress: varchar("callback_address", { length: 42 }).notNull(),
5544
+ callbackData: text("callback_data").notNull(),
5545
+ receiverIfMakerIsSeller: varchar("receiver_if_maker_is_seller", { length: 42 }),
5546
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5547
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5548
+ }, (table) => [
5549
+ primaryKey({
5550
+ columns: [table.hash, table.obligationId],
5551
+ name: "offers_pk"
5552
+ }),
5553
+ foreignKey({
5554
+ columns: [
5555
+ table.groupChainId,
5556
+ table.groupMaker,
5557
+ table.group
5558
+ ],
5559
+ foreignColumns: [
5560
+ groups.chainId,
5561
+ groups.maker,
5562
+ groups.group
5563
+ ],
5564
+ name: "offers_groups_fk"
5565
+ }).onDelete("cascade"),
5566
+ index("offers_group_fk_idx").on(table.groupChainId, table.groupMaker, table.group),
5567
+ index("offers_group_and_hash_idx").on(table.groupChainId, table.groupMaker, table.group, table.hash),
5568
+ index("offers_obligation_id_side_idx").on(table.obligationId, table.buy)
5569
+ ]);
5570
+ const offersCallbacks = s.table(EnumTableName.OFFERS_CALLBACKS, {
5571
+ offerHash: varchar("offer_hash", { length: 66 }).notNull(),
5572
+ obligationId: varchar("obligation_id", { length: 42 }).notNull(),
5573
+ callbackId: varchar("callback_id", { length: 66 })
5574
+ }, (table) => [foreignKey({
5575
+ columns: [table.offerHash, table.obligationId],
5576
+ foreignColumns: [offers.hash, offers.obligationId],
5577
+ name: "offers_callbacks_offer_fk"
5578
+ }).onDelete("cascade"), primaryKey({
5579
+ columns: [
5580
+ table.offerHash,
5581
+ table.obligationId,
5582
+ table.callbackId
5583
+ ],
5584
+ name: "offers_callbacks_pk"
5585
+ })]);
5586
+ const CallbackTypes = s.enum("callback_type", Object.values(CallbackType));
5587
+ const callbacks = s.table(EnumTableName.CALLBACKS, {
5588
+ id: varchar("id", { length: 66 }).primaryKey(),
5589
+ positionChainId: bigint("position_chain_id", { mode: "number" }).$type().notNull(),
5590
+ positionContract: varchar("position_contract", { length: 66 }).notNull(),
5591
+ positionUser: varchar("position_user", { length: 42 }).notNull(),
5592
+ positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
5593
+ type: CallbackTypes("type").notNull()
5594
+ });
5595
+ const lotsPositions = s.table(EnumTableName.LOTS_POSITIONS, {
5596
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5597
+ contract: varchar("contract", { length: 66 }).notNull(),
5598
+ user: varchar("user", { length: 42 }).notNull(),
5599
+ positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" })
5600
+ }, (table) => [primaryKey({
5601
+ columns: [
5602
+ table.chainId,
5603
+ table.contract,
5604
+ table.user
5605
+ ],
5606
+ name: "lots_positions_pk"
5607
+ })]);
5608
+ const lots = s.table(EnumTableName.LOTS, {
5609
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5610
+ user: varchar("user", { length: 42 }).notNull(),
5611
+ contract: varchar("contract", { length: 66 }).notNull(),
5612
+ group: varchar("group", { length: 66 }).notNull(),
5613
+ obligationId: varchar("obligation_id", { length: 42 }).notNull(),
5614
+ lower: numeric("lower", {
5615
+ precision: 78,
5616
+ scale: 0
5617
+ }).notNull(),
5618
+ upper: numeric("upper", {
5619
+ precision: 78,
5620
+ scale: 0
5621
+ }).notNull()
5622
+ }, (table) => [
5623
+ primaryKey({
5624
+ columns: [
5625
+ table.chainId,
5626
+ table.user,
5627
+ table.contract,
5628
+ table.group,
5629
+ table.obligationId
5630
+ ],
5631
+ name: "lots_pk"
5632
+ }),
5633
+ foreignKey({
5634
+ columns: [
5635
+ table.chainId,
5636
+ table.contract,
5637
+ table.user
5638
+ ],
5639
+ foreignColumns: [
5640
+ lotsPositions.chainId,
5641
+ lotsPositions.contract,
5642
+ lotsPositions.user
5643
+ ],
5644
+ name: "lots_lots_positions_fk"
5645
+ }).onDelete("cascade"),
5646
+ foreignKey({
5647
+ columns: [
5648
+ table.chainId,
5649
+ table.user,
5650
+ table.group
5651
+ ],
5652
+ foreignColumns: [
5653
+ groups.chainId,
5654
+ groups.maker,
5655
+ groups.group
5656
+ ],
5657
+ name: "lots_groups_fk"
5658
+ }).onDelete("cascade")
5659
+ ]);
5660
+ const offsets = s.table(EnumTableName.OFFSETS, {
5661
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5662
+ user: varchar("user", { length: 42 }).notNull(),
5663
+ contract: varchar("contract", { length: 66 }).notNull(),
5664
+ group: varchar("group", { length: 66 }).notNull(),
5665
+ obligationId: varchar("obligation_id", { length: 42 }).notNull(),
5666
+ value: numeric("value", {
5667
+ precision: 78,
5668
+ scale: 0
5669
+ }).notNull()
5670
+ }, (table) => [primaryKey({
5671
+ columns: [
5672
+ table.chainId,
5673
+ table.user,
5674
+ table.contract,
5675
+ table.group,
5676
+ table.obligationId
5677
+ ],
5678
+ name: "offsets_pk"
5679
+ }), foreignKey({
5680
+ columns: [
5681
+ table.chainId,
5682
+ table.contract,
5683
+ table.user
5684
+ ],
5685
+ foreignColumns: [
5686
+ lotsPositions.chainId,
5687
+ lotsPositions.contract,
5688
+ lotsPositions.user
5689
+ ],
5690
+ name: "offsets_lots_positions_fk"
5691
+ }).onDelete("cascade")]);
5692
+ const PositionTypes = s.enum("position_type", Object.values(Type));
5693
+ const positionTypes = s.table("position_types", {
5694
+ id: serial("id").primaryKey(),
5695
+ type: PositionTypes("type").notNull()
5696
+ });
5697
+ const positions = s.table(EnumTableName.POSITIONS, {
5698
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5699
+ contract: varchar("contract", { length: 66 }).notNull(),
5700
+ user: varchar("user", { length: 42 }).notNull(),
5701
+ positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
5702
+ balance: numeric("balance", {
5703
+ precision: 78,
5704
+ scale: 0
5705
+ }),
5706
+ asset: varchar("asset", { length: 42 }).notNull(),
5707
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5708
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5709
+ }, (table) => [primaryKey({
5710
+ columns: [
5711
+ table.chainId,
5712
+ table.contract,
5713
+ table.user,
5714
+ table.positionTypeId,
5715
+ table.asset
5716
+ ],
5717
+ name: "positions_pk"
5718
+ })]);
5719
+ const transfers = s.table(EnumTableName.TRANSFERS, {
5720
+ eventId: varchar("event_id", { length: 128 }).primaryKey(),
5721
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5722
+ contract: varchar("contract", { length: 66 }).notNull(),
5723
+ from: varchar("from", { length: 42 }).notNull(),
5724
+ to: varchar("to", { length: 42 }).notNull(),
5725
+ value: numeric("value", {
5726
+ precision: 78,
5727
+ scale: 0
5728
+ }).notNull(),
5729
+ positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
5730
+ asset: varchar("asset", { length: 42 }).notNull(),
5731
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5732
+ createdAt: timestamp("created_at").defaultNow().notNull()
5733
+ }, (table) => [
5734
+ foreignKey({
5735
+ columns: [
5736
+ table.chainId,
5737
+ table.contract,
5738
+ table.from,
5739
+ table.positionTypeId,
5740
+ table.asset
5741
+ ],
5742
+ foreignColumns: [
5743
+ positions.chainId,
5744
+ positions.contract,
5745
+ positions.user,
5746
+ positions.positionTypeId,
5747
+ positions.asset
5748
+ ],
5749
+ name: "transfers_positions_from_fk"
5750
+ }).onDelete("cascade"),
5751
+ foreignKey({
5752
+ columns: [
5753
+ table.chainId,
5754
+ table.contract,
5755
+ table.to,
5756
+ table.positionTypeId,
5757
+ table.asset
5758
+ ],
5759
+ foreignColumns: [
5760
+ positions.chainId,
5761
+ positions.contract,
5762
+ positions.user,
5763
+ positions.positionTypeId,
5764
+ positions.asset
5765
+ ],
5766
+ name: "transfers_positions_to_fk"
5767
+ }).onDelete("cascade"),
5768
+ index("transfers_chain_contract_user_idx").on(table.chainId, table.contract, table.from, table.to, table.blockNumber),
5769
+ index("transfers_chain_type_block_idx").on(table.chainId, table.positionTypeId, table.blockNumber)
5770
+ ]);
5771
+ const StatusCode = s.enum("status_code", Object.values(Status));
5772
+ const status = s.table("status", {
5773
+ id: serial("id").primaryKey(),
5774
+ code: StatusCode("code").unique()
5775
+ });
5776
+ const validations = s.table("validations", {
5777
+ offerHash: varchar("offer_hash", { length: 66 }).notNull(),
5778
+ obligationId: varchar("obligation_id", { length: 42 }).notNull(),
5779
+ statusId: integer("status_id").notNull().references(() => status.id, { onDelete: "no action" }),
5780
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5781
+ }, (table) => [primaryKey({
5782
+ columns: [table.offerHash, table.obligationId],
5783
+ name: "validations_pk"
5784
+ }), foreignKey({
5785
+ columns: [table.offerHash, table.obligationId],
5786
+ foreignColumns: [offers.hash, offers.obligationId],
5787
+ name: "validations_offer_fk"
5788
+ }).onDelete("cascade")]);
5789
+ const collectors = s.table(EnumTableName.COLLECTORS, {
5790
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull().references(() => chains.chainId, { onDelete: "no action" }),
5791
+ name: text("name").$type().notNull(),
5792
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5793
+ epoch: numeric("epoch", {
5794
+ precision: 78,
5795
+ scale: 0
5796
+ }).default("0").notNull(),
5797
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5798
+ }, (table) => [uniqueIndex("collectors_chain_name_idx").on(table.chainId, table.name)]);
5799
+ const chains = s.table(EnumTableName.CHAINS, {
5800
+ chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
5801
+ blockNumber: bigint("block_number", { mode: "number" }).notNull(),
5802
+ epoch: numeric("epoch", {
5803
+ precision: 78,
5804
+ scale: 0
5805
+ }).default("0").notNull(),
5806
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5807
+ }, (table) => [uniqueIndex("chains_chain_id_idx").on(table.chainId)]);
5808
+ const trees = s.table(EnumTableName.TREES, {
5809
+ root: varchar("root", { length: 66 }).primaryKey(),
5810
+ rootSignature: varchar("root_signature", { length: 132 }).notNull(),
5811
+ createdAt: timestamp("created_at").defaultNow().notNull()
5812
+ });
5813
+ const merklePaths = s.table(EnumTableName.MERKLE_PATHS, {
5814
+ offerHash: varchar("offer_hash", { length: 66 }).notNull(),
5815
+ obligationId: varchar("obligation_id", { length: 42 }).notNull(),
5816
+ treeRoot: varchar("tree_root", { length: 66 }).notNull().references(() => trees.root, { onDelete: "cascade" }),
5817
+ proofNodes: text("proof_nodes").notNull(),
5818
+ createdAt: timestamp("created_at").defaultNow().notNull()
5819
+ }, (table) => [
5820
+ primaryKey({
5821
+ columns: [table.offerHash, table.obligationId],
5822
+ name: "merkle_paths_pk"
5823
+ }),
5824
+ foreignKey({
5825
+ columns: [table.offerHash, table.obligationId],
5826
+ foreignColumns: [offers.hash, offers.obligationId],
5827
+ name: "merkle_paths_offer_fk"
5828
+ }).onDelete("cascade"),
5829
+ index("merkle_paths_tree_root_idx").on(table.treeRoot)
5830
+ ]);
5831
+
5832
+ //#endregion
5833
+ //#region src/database/domains/Groups.ts
5834
+ /** Build composite key for a group. */
5835
+ function compositeKey(g) {
5836
+ return `${g.chainId}-${g.maker.toLowerCase()}-${g.group.toLowerCase()}`;
5837
+ }
5838
+
5176
5839
  //#endregion
5177
5840
  //#region src/gatekeeper/Rules.ts
5178
5841
  var Rules_exports = /* @__PURE__ */ __exportAll({
5179
5842
  amountMutualExclusivity: () => amountMutualExclusivity,
5180
5843
  callback: () => callback,
5181
5844
  collateralToken: () => collateralToken,
5845
+ groupConsistency: () => groupConsistency,
5846
+ groupImmutability: () => groupImmutability,
5182
5847
  loanToken: () => loanToken,
5183
5848
  maturity: () => maturity,
5849
+ maxCollaterals: () => maxCollaterals,
5850
+ minDuration: () => minDuration,
5184
5851
  oracle: () => oracle,
5185
5852
  sameMaker: () => sameMaker
5186
5853
  });
@@ -5247,25 +5914,111 @@ const sameMaker = () => batch("mixed_maker", "Validates that all offers in a bat
5247
5914
  * At most one of (assets, obligationUnits, obligationShares) can be non-zero.
5248
5915
  * Matches contract requirement: `atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)`.
5249
5916
  */
5917
+ /**
5918
+ * A validation rule that checks if the offer duration (expiry - start) meets a minimum threshold.
5919
+ * @param minSeconds - Minimum required duration in seconds.
5920
+ * @returns The issue that was found. If the offer is valid, this will be undefined.
5921
+ */
5922
+ const minDuration = ({ minSeconds }) => single("min_duration", `Validates that offer duration (expiry - start) is at least ${minSeconds}s`, (offer) => {
5923
+ const duration = offer.expiry - offer.start;
5924
+ if (duration < minSeconds) return { message: `Duration ${duration}s is below minimum ${minSeconds}s` };
5925
+ });
5926
+ /**
5927
+ * A validation rule that checks if an offer exceeds the maximum number of collaterals.
5928
+ * The contract enforces this limit; this rule rejects early to avoid on-chain reverts.
5929
+ * @param max - Maximum allowed collaterals per offer.
5930
+ * @returns The issue that was found. If the offer is valid, this will be undefined.
5931
+ */
5932
+ const maxCollaterals = ({ max }) => single("max_collaterals", `Validates that an offer has at most ${max} collaterals`, (offer) => {
5933
+ if (offer.collaterals.length > max) return { message: `Offer has ${offer.collaterals.length} collaterals, exceeding the maximum of ${max}` };
5934
+ });
5250
5935
  const amountMutualExclusivity = () => single("amount_mutual_exclusivity", "Validates that at most one of (assets, obligationUnits, obligationShares) is non-zero", (offer) => {
5251
5936
  if (!atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)) return { message: "Inconsistent offer input: at most one of (assets, obligationUnits, obligationShares) must be non-zero" };
5252
5937
  });
5938
+ /**
5939
+ * A batch validation rule that ensures all offers within the same group are consistent.
5940
+ * All offers sharing the same group must have the same loan token, assets amount, and side (buy/sell).
5941
+ */
5942
+ const groupConsistency = () => batch("group_consistency", "Validates that all offers in a group have the same loan token, assets amount, and side", (offers) => {
5943
+ const issues = /* @__PURE__ */ new Map();
5944
+ if (offers.length === 0) return issues;
5945
+ const groupMap = /* @__PURE__ */ new Map();
5946
+ for (let i = 0; i < offers.length; i++) {
5947
+ const key = offers[i].group.toLowerCase();
5948
+ const indices = groupMap.get(key);
5949
+ if (indices) indices.push(i);
5950
+ else groupMap.set(key, [i]);
5951
+ }
5952
+ for (const indices of groupMap.values()) {
5953
+ if (indices.length <= 1) continue;
5954
+ const reference = offers[indices[0]];
5955
+ const refLoanToken = reference.loanToken.toLowerCase();
5956
+ const refAssets = reference.assets;
5957
+ const refBuy = reference.buy;
5958
+ for (let j = 1; j < indices.length; j++) {
5959
+ const idx = indices[j];
5960
+ const offer = offers[idx];
5961
+ if (offer.loanToken.toLowerCase() !== refLoanToken) issues.set(idx, { message: `All offers in a group must have the same loan token. Expected ${reference.loanToken}, got ${offer.loanToken}` });
5962
+ else if (offer.assets !== refAssets) issues.set(idx, { message: `All offers in a group must have the same assets amount. Expected ${refAssets}, got ${offer.assets}` });
5963
+ else if (offer.buy !== refBuy) issues.set(idx, { message: `All offers in a group must be on the same side. Expected ${refBuy ? "buy" : "sell"}, got ${offer.buy ? "buy" : "sell"}` });
5964
+ }
5965
+ }
5966
+ return issues;
5967
+ });
5968
+ /**
5969
+ * A batch validation rule that prevents adding offers to groups that already exist in the database.
5970
+ * Groups are immutable after creation — new offers cannot be added to an existing group.
5971
+ */
5972
+ const groupImmutability = ({ db, chainId }) => batch("group_immutability", "Validates that offers do not target groups that already exist", async (offers) => {
5973
+ const issues = /* @__PURE__ */ new Map();
5974
+ if (offers.length === 0) return issues;
5975
+ const uniqueGroups = /* @__PURE__ */ new Map();
5976
+ for (const offer of offers) {
5977
+ const key = compositeKey({
5978
+ chainId,
5979
+ maker: offer.maker,
5980
+ group: offer.group
5981
+ });
5982
+ if (!uniqueGroups.has(key)) uniqueGroups.set(key, {
5983
+ chainId,
5984
+ maker: offer.maker,
5985
+ group: offer.group
5986
+ });
5987
+ }
5988
+ const existingKeys = await db.groups.exists(Array.from(uniqueGroups.values()));
5989
+ if (existingKeys.length === 0) return issues;
5990
+ const existingSet = new Set(existingKeys.map((k) => compositeKey(k)));
5991
+ for (let i = 0; i < offers.length; i++) {
5992
+ const offer = offers[i];
5993
+ const key = compositeKey({
5994
+ chainId,
5995
+ maker: offer.maker,
5996
+ group: offer.group
5997
+ });
5998
+ if (existingSet.has(key)) issues.set(i, { message: `Cannot add offers to existing group ${offer.group}` });
5999
+ }
6000
+ return issues;
6001
+ });
5253
6002
 
5254
6003
  //#endregion
5255
6004
  //#region src/gatekeeper/morphoRules.ts
5256
6005
  const morphoRules = (parameters) => {
5257
- const { chains, chainId } = parameters;
6006
+ const { chains, chainId, db } = parameters;
6007
+ const requestChain = chains.find((c) => c.id === chainId);
6008
+ const config = requestChain ? configs[requestChain.name] : void 0;
5258
6009
  const assetsByChainId = {};
5259
6010
  const collateralAssetsByChainId = {};
5260
6011
  const oraclesByChainId = {};
5261
6012
  for (const chain of chains) {
5262
6013
  assetsByChainId[chain.id] = assets[chain.id.toString()] ?? [];
5263
6014
  collateralAssetsByChainId[chain.id] = collateralAssets[chain.id.toString()] ?? [];
5264
- oraclesByChainId[chain.id] = oracles[chain.id.toString()] ?? [];
6015
+ oraclesByChainId[chain.id] = oracles$1[chain.id.toString()] ?? [];
5265
6016
  }
5266
- return [
6017
+ const rules = [
5267
6018
  sameMaker(),
5268
6019
  amountMutualExclusivity(),
6020
+ groupConsistency(),
6021
+ ...config?.minDuration != null ? [minDuration({ minSeconds: config.minDuration })] : [],
5269
6022
  maturity({ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek] }),
5270
6023
  callback({
5271
6024
  callbacks: [Type$1.BuyWithEmptyCallback, Type$1.SellWithEmptyCallback],
@@ -5275,6 +6028,7 @@ const morphoRules = (parameters) => {
5275
6028
  assetsByChainId,
5276
6029
  chainId
5277
6030
  }),
6031
+ maxCollaterals({ max: 128 }),
5278
6032
  collateralToken({
5279
6033
  collateralAssetsByChainId,
5280
6034
  chainId
@@ -5284,6 +6038,11 @@ const morphoRules = (parameters) => {
5284
6038
  chainId
5285
6039
  })
5286
6040
  ];
6041
+ if (db) rules.push(groupImmutability({
6042
+ db,
6043
+ chainId
6044
+ }));
6045
+ return rules;
5287
6046
  };
5288
6047
 
5289
6048
  //#endregion
@@ -5409,16 +6168,13 @@ async function* streamOffers(config, parameters) {
5409
6168
  };
5410
6169
  }
5411
6170
  var WalletAccountNotSetError = class extends BaseError {
6171
+ name = "Mempool.WalletAccountNotSetError";
5412
6172
  constructor() {
5413
6173
  super("Wallet account is not set.");
5414
- _defineProperty(this, "name", "Mempool.WalletAccountNotSetError");
5415
6174
  }
5416
6175
  };
5417
6176
  var ViemClientError = class extends BaseError {
5418
- constructor(..._args) {
5419
- super(..._args);
5420
- _defineProperty(this, "name", "Mempool.ViemClientError");
5421
- }
6177
+ name = "Mempool.ViemClientError";
5422
6178
  };
5423
6179
  const resolveSignatureDomain = (config, chainId) => {
5424
6180
  const chain = config.client.chain;
@@ -5430,9 +6186,9 @@ const resolveSignatureDomain = (config, chainId) => {
5430
6186
  };
5431
6187
  };
5432
6188
  var MissingMorphoAddressError = class extends BaseError {
6189
+ name = "Mempool.MissingMorphoAddressError";
5433
6190
  constructor() {
5434
6191
  super("Morpho address is required to verify root signatures (zero address is invalid).");
5435
- _defineProperty(this, "name", "Mempool.MissingMorphoAddressError");
5436
6192
  }
5437
6193
  };
5438
6194
 
@@ -5446,158 +6202,6 @@ function connect(parameters) {
5446
6202
  return from(parameters);
5447
6203
  }
5448
6204
 
5449
- //#endregion
5450
- //#region src/utils/retry.ts
5451
- const retry = async (fn, attempts = 3, delayMs = 50) => {
5452
- let lastErr;
5453
- for (let i = 0; i < attempts; i++) try {
5454
- return await fn();
5455
- } catch (err) {
5456
- lastErr = err;
5457
- if (i < attempts - 1) await new Promise((r) => setTimeout(r, delayMs));
5458
- }
5459
- throw lastErr;
5460
- };
5461
-
5462
- //#endregion
5463
- //#region src/utils/batchMulticall.ts
5464
- /**
5465
- * Helper function to execute multicall in batches with retry logic.
5466
- * Abstracts the common pattern of batching calls, retrying, and collecting results.
5467
- *
5468
- * @param parameters - Configuration for batched multicall
5469
- * @returns Promise resolving to flattened array of results
5470
- */
5471
- async function batchMulticall(parameters) {
5472
- const { client, calls, batchSize, retryAttempts, retryDelayMs, blockNumber } = parameters;
5473
- const results = [];
5474
- for (const callsBatch of batch$1(calls, batchSize)) {
5475
- const batchResults = await retry(() => multicall(client, {
5476
- allowFailure: false,
5477
- contracts: callsBatch,
5478
- ...blockNumber ? { blockNumber } : {}
5479
- }), retryAttempts, retryDelayMs);
5480
- results.push(...batchResults);
5481
- }
5482
- return results;
5483
- }
5484
-
5485
- //#endregion
5486
- //#region src/utils/Group.ts
5487
- var Group_exports = /* @__PURE__ */ __exportAll({ fromNumber: () => fromNumber });
5488
- /**
5489
- * Creates a bytes32 group identifier from a number.
5490
- * @param n - A non-negative integer.
5491
- * @throws {Error} If n is negative or not an integer.
5492
- */
5493
- const fromNumber = (n) => {
5494
- if (!Number.isInteger(n)) throw new Error(`Group.fromNumber: expected integer, got ${n}`);
5495
- if (n < 0) throw new Error(`Group.fromNumber: expected non-negative, got ${n}`);
5496
- return pad(`0x${n.toString(16)}`, { size: 32 });
5497
- };
5498
-
5499
- //#endregion
5500
- //#region src/utils/lazy.ts
5501
- /**
5502
- * Transform a polling function into an async generator.
5503
- * @param fn - The polling function to transform.
5504
- * @returns An async generator.
5505
- */
5506
- function lazy(pollFn) {
5507
- return () => (async function* () {
5508
- let active = true;
5509
- let resolveNext = null;
5510
- const queue = [];
5511
- const wait = () => new Promise((resolve) => {
5512
- resolveNext = resolve;
5513
- });
5514
- const emit = (item) => {
5515
- queue.push(item);
5516
- resolveNext?.();
5517
- resolveNext = null;
5518
- };
5519
- let unpoll = null;
5520
- const stop = () => {
5521
- active = false;
5522
- unpoll?.();
5523
- resolveNext?.();
5524
- resolveNext = null;
5525
- };
5526
- unpoll = pollFn(emit, { stop });
5527
- try {
5528
- while (active) {
5529
- if (queue.length === 0) await wait();
5530
- while (queue.length > 0 && active) yield queue.shift();
5531
- }
5532
- } finally {
5533
- stop();
5534
- }
5535
- })();
5536
- }
5537
-
5538
- //#endregion
5539
- //#region src/utils/wait.ts
5540
- async function wait(time) {
5541
- return new Promise((res) => setTimeout(res, time));
5542
- }
5543
-
5544
- //#endregion
5545
- //#region src/utils/poll.ts
5546
- /**
5547
- * Polls a function at a specified interval.
5548
- * Inspired by https://github.com/wevm/viem/blob/845994d20275d08ff892018e237a4b599eeefb6a/src/utils/poll.ts
5549
- */
5550
- function poll(fn, { interval }) {
5551
- let active = true;
5552
- const unwatch = () => active = false;
5553
- const watch = async () => {
5554
- while (active) {
5555
- const delay = await interval();
5556
- if (!active) break;
5557
- await wait(delay);
5558
- if (!active) break;
5559
- await fn({ unpoll: unwatch });
5560
- }
5561
- };
5562
- watch();
5563
- return unwatch;
5564
- }
5565
-
5566
- //#endregion
5567
- //#region src/utils/time.ts
5568
- var time_exports = /* @__PURE__ */ __exportAll({
5569
- max: () => max,
5570
- now: () => now
5571
- });
5572
- function now() {
5573
- return Math.floor(Date.now() / 1e3);
5574
- }
5575
- function max() {
5576
- return 0x77e772392b600000;
5577
- }
5578
-
5579
- //#endregion
5580
- //#region src/utils/index.ts
5581
- var utils_exports = /* @__PURE__ */ __exportAll({
5582
- BaseError: () => BaseError,
5583
- Group: () => Group_exports,
5584
- Random: () => Random_exports,
5585
- ReorgError: () => ReorgError,
5586
- Time: () => time_exports,
5587
- atMostOneNonZero: () => atMostOneNonZero,
5588
- batch: () => batch$1,
5589
- batchMulticall: () => batchMulticall,
5590
- fromSnakeCase: () => fromSnakeCase$3,
5591
- lazy: () => lazy,
5592
- max: () => max$1,
5593
- min: () => min,
5594
- poll: () => poll,
5595
- retry: () => retry,
5596
- stringifyBigint: () => stringifyBigint,
5597
- toSnakeCase: () => toSnakeCase$1,
5598
- wait: () => wait
5599
- });
5600
-
5601
6205
  //#endregion
5602
6206
  export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainRegistry_exports as ChainRegistry, Collateral_exports as Collateral, ERC4626_exports as ERC4626, Errors_exports as Errors, Format_exports as Format, Gatekeeper_exports as Gatekeeper, Client_exports as GatekeeperClient, Id_exports as Id, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Maturity_exports as Maturity, MempoolClient_exports as Mempool, Obligation_exports as Obligation, Offer_exports as Offer, Oracle_exports as Oracle, Position_exports as Position, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports$1 as RouterClient, Rules_exports as Rules, Tick_exports as Tick, time_exports as Time, TradingFee_exports as TradingFee, Transfer_exports as Transfer, Tree_exports as Tree, utils_exports as Utils, Gate_exports as Validation, morphoRules };
5603
6207
  //# sourceMappingURL=index.browser.mjs.map