@morpho-dev/router 0.7.2 → 0.8.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.
Files changed (65) hide show
  1. package/dist/cli.js +292 -122
  2. package/dist/drizzle/migrations/0000_setup_single_migration_folder.sql +64 -64
  3. package/dist/drizzle/migrations/0001_add-trigger-for-consumed-events.sql +5 -5
  4. package/dist/drizzle/migrations/0002_insert-status-code.sql +1 -1
  5. package/dist/drizzle/migrations/0003_update-triggers-for-consumed-events.sql +1 -1
  6. package/dist/drizzle/migrations/0004_drop-status-offers-foreign-key-constraint.sql +1 -1
  7. package/dist/drizzle/migrations/0005_add-index-to-boost-group-query-and-offer-hash.sql +1 -1
  8. package/dist/drizzle/migrations/0006_add-callbacks-and-positions-relations.sql +11 -11
  9. package/dist/drizzle/migrations/0008_validation.sql +10 -10
  10. package/dist/drizzle/migrations/0009_add-transfers-table.sql +4 -4
  11. package/dist/drizzle/migrations/0010_add-price.sql +1 -1
  12. package/dist/drizzle/migrations/0011_nullable-callback-amount.sql +1 -1
  13. package/dist/drizzle/migrations/0012_add-position-asset.sql +1 -1
  14. package/dist/drizzle/migrations/0013_remove-depecrated-domains.sql +13 -13
  15. package/dist/drizzle/migrations/0014_rename-offers-v2-into-offers.sql +19 -19
  16. package/dist/drizzle/migrations/0015_add-lots-table.sql +3 -3
  17. package/dist/drizzle/migrations/0016_merkle-metadata.sql +7 -7
  18. package/dist/drizzle/migrations/0017_dusty_the_hunter.sql +1 -1
  19. package/dist/drizzle/migrations/0018_add_chain_collector_constraints.sql +3 -3
  20. package/dist/drizzle/migrations/0019_add-obligation-units-shares.sql +2 -2
  21. package/dist/drizzle/migrations/0020_add-session.sql +1 -1
  22. package/dist/drizzle/migrations/0021_drop_chain_collector_epoch_indexes.sql +2 -2
  23. package/dist/drizzle/migrations/0021_migrate-rate-to-price.sql +6 -6
  24. package/dist/drizzle/migrations/0022_consolidate-price.sql +5 -5
  25. package/dist/drizzle/migrations/0023_remove-block-number-for-collaterals.sql +1 -1
  26. package/dist/drizzle/migrations/0024_add-obligation-id-to-lots.sql +8 -0
  27. package/dist/drizzle/migrations/0025_rename-price-to-tick.sql +202 -0
  28. package/dist/drizzle/migrations/meta/0000_snapshot.json +48 -48
  29. package/dist/drizzle/migrations/meta/0001_snapshot.json +48 -48
  30. package/dist/drizzle/migrations/meta/0002_snapshot.json +48 -48
  31. package/dist/drizzle/migrations/meta/0003_snapshot.json +48 -48
  32. package/dist/drizzle/migrations/meta/0004_snapshot.json +47 -47
  33. package/dist/drizzle/migrations/meta/0005_snapshot.json +47 -47
  34. package/dist/drizzle/migrations/meta/0006_snapshot.json +61 -61
  35. package/dist/drizzle/migrations/meta/0008_snapshot.json +62 -62
  36. package/dist/drizzle/migrations/meta/0009_snapshot.json +66 -66
  37. package/dist/drizzle/migrations/meta/0010_snapshot.json +66 -66
  38. package/dist/drizzle/migrations/meta/0013_snapshot.json +48 -48
  39. package/dist/drizzle/migrations/meta/0014_snapshot.json +48 -48
  40. package/dist/drizzle/migrations/meta/0015_snapshot.json +52 -52
  41. package/dist/drizzle/migrations/meta/0016_snapshot.json +61 -61
  42. package/dist/drizzle/migrations/meta/0017_snapshot.json +61 -61
  43. package/dist/drizzle/migrations/meta/0018_snapshot.json +62 -62
  44. package/dist/drizzle/migrations/meta/0019_snapshot.json +62 -62
  45. package/dist/drizzle/migrations/meta/0023_snapshot.json +62 -62
  46. package/dist/drizzle/migrations/meta/0024_snapshot.json +1448 -0
  47. package/dist/drizzle/migrations/meta/0025_snapshot.json +1448 -0
  48. package/dist/drizzle/migrations/meta/_journal.json +14 -0
  49. package/dist/index.browser.d.mts +103 -33
  50. package/dist/index.browser.d.mts.map +1 -1
  51. package/dist/index.browser.d.ts +103 -33
  52. package/dist/index.browser.d.ts.map +1 -1
  53. package/dist/index.browser.js +298 -146
  54. package/dist/index.browser.js.map +1 -1
  55. package/dist/index.browser.mjs +293 -147
  56. package/dist/index.browser.mjs.map +1 -1
  57. package/dist/index.node.d.mts +182 -63
  58. package/dist/index.node.d.mts.map +1 -1
  59. package/dist/index.node.d.ts +182 -63
  60. package/dist/index.node.d.ts.map +1 -1
  61. package/dist/index.node.js +342 -127
  62. package/dist/index.node.js.map +1 -1
  63. package/dist/index.node.mjs +337 -128
  64. package/dist/index.node.mjs.map +1 -1
  65. package/package.json +1 -1
@@ -11,11 +11,191 @@ import { generateDocument } from "openapi-metadata";
11
11
  import { ApiBody, ApiOperation, ApiParam, ApiProperty, ApiQuery, ApiResponse, ApiTags } from "openapi-metadata/decorators";
12
12
  import createOpenApiFetchClient from "openapi-fetch";
13
13
 
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
+ //#region src/utils/Errors.ts
57
+ var Errors_exports = /* @__PURE__ */ __exportAll({
58
+ BaseError: () => BaseError,
59
+ ReorgError: () => ReorgError
60
+ });
61
+ /**
62
+ * Base error class inherited by all errors thrown by mempool.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { Errors } from 'mempool'
67
+ * throw new Errors.BaseError('An error occurred')
68
+ * ```
69
+ */
70
+ var BaseError = class BaseError extends Error {
71
+ constructor(shortMessage, options = {}) {
72
+ const details = (() => {
73
+ if (options.cause instanceof BaseError) {
74
+ if (options.cause.details) return options.cause.details;
75
+ if (options.cause.shortMessage) return options.cause.shortMessage;
76
+ }
77
+ if (options.cause && "details" in options.cause && typeof options.cause.details === "string") return options.cause.details;
78
+ if (options.cause?.message) return options.cause.message;
79
+ return options.details;
80
+ })();
81
+ const message = [
82
+ shortMessage || "An error occurred.",
83
+ ...options.metaMessages ? ["", ...options.metaMessages] : [],
84
+ ...details ? ["", details ? `Details: ${details}` : void 0] : []
85
+ ].filter((x) => typeof x === "string").join("\n");
86
+ 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
+ this.cause = options.cause;
92
+ this.details = details;
93
+ this.shortMessage = shortMessage;
94
+ }
95
+ walk(fn) {
96
+ return walk(this, fn);
97
+ }
98
+ };
99
+ /** @internal */
100
+ function walk(err, fn) {
101
+ if (fn?.(err)) return err;
102
+ if (err && typeof err === "object" && "cause" in err && err.cause) return walk(err.cause, fn);
103
+ return fn ? null : err;
104
+ }
105
+ var ReorgError = class extends BaseError {
106
+ constructor(blockNumber) {
107
+ super(`Reorg detected at block number ${blockNumber}`);
108
+ _defineProperty(this, "name", "ReorgError");
109
+ }
110
+ };
111
+
112
+ //#endregion
113
+ //#region src/core/Tick.ts
114
+ var Tick_exports = /* @__PURE__ */ __exportAll({
115
+ InvalidPriceError: () => InvalidPriceError,
116
+ InvalidTickError: () => InvalidTickError,
117
+ MAX_PRICE: () => MAX_PRICE,
118
+ TICK_RANGE: () => TICK_RANGE,
119
+ priceToTick: () => priceToTick,
120
+ tickToPrice: () => tickToPrice
121
+ });
122
+ /** ln(1 + 0.025), scaled by 1e18. Matches TickLib onchain constant. */
123
+ const LN_ONE_PLUS_DELTA = 24692612590371501n;
124
+ /** ln(2), scaled by 1e18. Matches TickLib onchain constant. */
125
+ const LN2 = 693147180559945309n;
126
+ const WAD$1 = 10n ** 18n;
127
+ const WAD_SQUARED = 10n ** 36n;
128
+ const PRICE_STEP = 10n ** 13n;
129
+ const HALF_TICK_RANGE = 495n;
130
+ /** Tick domain supported by Morpho V2. */
131
+ const TICK_RANGE = 990;
132
+ /** Max allowed price (1e18 in wad). */
133
+ const MAX_PRICE = WAD$1;
134
+ /**
135
+ * Converts a tick to a wad price using the same approximation and rounding as TickLib.
136
+ * @param tick - Tick value in the inclusive range [0, 990].
137
+ * @returns The price in wad units.
138
+ * @throws {@link InvalidTickError} If tick is not an integer in range [0, 990].
139
+ */
140
+ function tickToPrice(tick) {
141
+ assertTick(tick);
142
+ return divHalfDownUnchecked(divHalfDownUnchecked(WAD_SQUARED, WAD$1 + wExp(LN_ONE_PLUS_DELTA * (HALF_TICK_RANGE - BigInt(tick)))), PRICE_STEP) * PRICE_STEP;
143
+ }
144
+ /**
145
+ * Returns the lowest tick with a higher-or-equal price.
146
+ * @param price - Price in wad units.
147
+ * @returns The first tick whose {@link tickToPrice} is greater than or equal to `price`.
148
+ * @throws {@link InvalidPriceError} If price is outside [0, 1e18].
149
+ */
150
+ function priceToTick(price) {
151
+ assertPrice(price);
152
+ let low = 0;
153
+ let high = TICK_RANGE;
154
+ while (low !== high) {
155
+ const mid = Math.floor((low + high) / 2);
156
+ if (tickToPrice(mid) < price) low = mid + 1;
157
+ else high = mid;
158
+ }
159
+ return low;
160
+ }
161
+ function divHalfDownUnchecked(x, d) {
162
+ return (x + (d - 1n) / 2n) / d;
163
+ }
164
+ function wExp(x) {
165
+ if (x < 0n) return WAD_SQUARED / wExp(-x);
166
+ const q = (x + LN2 / 2n) / LN2;
167
+ const r = x - q * LN2;
168
+ const secondTerm = r * r / (2n * WAD$1);
169
+ const thirdTerm = secondTerm * r / (3n * WAD$1);
170
+ return WAD$1 + r + secondTerm + thirdTerm << q;
171
+ }
172
+ function assertTick(tick) {
173
+ if (!Number.isInteger(tick) || tick < 0 || tick > TICK_RANGE) throw new InvalidTickError(tick);
174
+ }
175
+ function assertPrice(price) {
176
+ if (price < 0n || price > MAX_PRICE) throw new InvalidPriceError(price);
177
+ }
178
+ var InvalidTickError = class extends BaseError {
179
+ constructor(tick) {
180
+ super(`Invalid tick: ${tick}. Tick must be an integer between 0 and ${TICK_RANGE}.`);
181
+ _defineProperty(this, "name", "Tick.InvalidTickError");
182
+ }
183
+ };
184
+ var InvalidPriceError = class extends BaseError {
185
+ constructor(price) {
186
+ super(`Invalid price: ${price}. Price must be between 0 and ${MAX_PRICE}.`);
187
+ _defineProperty(this, "name", "Tick.InvalidPriceError");
188
+ }
189
+ };
190
+
191
+ //#endregion
14
192
  //#region src/api/Schema/BookResponse.ts
15
193
  var BookResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$15 });
16
194
  function from$15(level) {
195
+ const price = tickToPrice(level.tick);
17
196
  return {
18
- price: level.price.toString(),
197
+ tick: level.tick,
198
+ price: price.toString(),
19
199
  assets: level.assets.toString(),
20
200
  count: level.count
21
201
  };
@@ -363,105 +543,6 @@ function* batch$1(array, batchSize) {
363
543
  for (let i = 0; i < array.length; i += batchSize) yield array.slice(i, i + batchSize);
364
544
  }
365
545
 
366
- //#endregion
367
- //#region \0@oxc-project+runtime@0.110.0/helpers/typeof.js
368
- function _typeof(o) {
369
- "@babel/helpers - typeof";
370
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
371
- return typeof o;
372
- } : function(o) {
373
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
374
- }, _typeof(o);
375
- }
376
-
377
- //#endregion
378
- //#region \0@oxc-project+runtime@0.110.0/helpers/toPrimitive.js
379
- function toPrimitive(t, r) {
380
- if ("object" != _typeof(t) || !t) return t;
381
- var e = t[Symbol.toPrimitive];
382
- if (void 0 !== e) {
383
- var i = e.call(t, r || "default");
384
- if ("object" != _typeof(i)) return i;
385
- throw new TypeError("@@toPrimitive must return a primitive value.");
386
- }
387
- return ("string" === r ? String : Number)(t);
388
- }
389
-
390
- //#endregion
391
- //#region \0@oxc-project+runtime@0.110.0/helpers/toPropertyKey.js
392
- function toPropertyKey(t) {
393
- var i = toPrimitive(t, "string");
394
- return "symbol" == _typeof(i) ? i : i + "";
395
- }
396
-
397
- //#endregion
398
- //#region \0@oxc-project+runtime@0.110.0/helpers/defineProperty.js
399
- function _defineProperty(e, r, t) {
400
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
401
- value: t,
402
- enumerable: !0,
403
- configurable: !0,
404
- writable: !0
405
- }) : e[r] = t, e;
406
- }
407
-
408
- //#endregion
409
- //#region src/utils/Errors.ts
410
- var Errors_exports = /* @__PURE__ */ __exportAll({
411
- BaseError: () => BaseError,
412
- ReorgError: () => ReorgError
413
- });
414
- /**
415
- * Base error class inherited by all errors thrown by mempool.
416
- *
417
- * @example
418
- * ```ts
419
- * import { Errors } from 'mempool'
420
- * throw new Errors.BaseError('An error occurred')
421
- * ```
422
- */
423
- var BaseError = class BaseError extends Error {
424
- constructor(shortMessage, options = {}) {
425
- const details = (() => {
426
- if (options.cause instanceof BaseError) {
427
- if (options.cause.details) return options.cause.details;
428
- if (options.cause.shortMessage) return options.cause.shortMessage;
429
- }
430
- if (options.cause && "details" in options.cause && typeof options.cause.details === "string") return options.cause.details;
431
- if (options.cause?.message) return options.cause.message;
432
- return options.details;
433
- })();
434
- const message = [
435
- shortMessage || "An error occurred.",
436
- ...options.metaMessages ? ["", ...options.metaMessages] : [],
437
- ...details ? ["", details ? `Details: ${details}` : void 0] : []
438
- ].filter((x) => typeof x === "string").join("\n");
439
- super(message, options.cause ? { cause: options.cause } : void 0);
440
- _defineProperty(this, "details", void 0);
441
- _defineProperty(this, "shortMessage", void 0);
442
- _defineProperty(this, "cause", void 0);
443
- _defineProperty(this, "name", "BaseError");
444
- this.cause = options.cause;
445
- this.details = details;
446
- this.shortMessage = shortMessage;
447
- }
448
- walk(fn) {
449
- return walk(this, fn);
450
- }
451
- };
452
- /** @internal */
453
- function walk(err, fn) {
454
- if (fn?.(err)) return err;
455
- if (err && typeof err === "object" && "cause" in err && err.cause) return walk(err.cause, fn);
456
- return fn ? null : err;
457
- }
458
- var ReorgError = class extends BaseError {
459
- constructor(blockNumber) {
460
- super(`Reorg detected at block number ${blockNumber}`);
461
- _defineProperty(this, "name", "ReorgError");
462
- }
463
- };
464
-
465
546
  //#endregion
466
547
  //#region src/core/Chain.ts
467
548
  var Chain_exports = /* @__PURE__ */ __exportAll({
@@ -1508,7 +1589,7 @@ const OfferSchema = () => {
1508
1589
  assets: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
1509
1590
  obligationUnits: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
1510
1591
  obligationShares: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
1511
- price: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
1592
+ tick: z$1.coerce.number().int().min(0).max(990),
1512
1593
  maturity: MaturitySchema,
1513
1594
  expiry: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
1514
1595
  start: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
@@ -1580,7 +1661,7 @@ const serialize = (offer) => ({
1580
1661
  assets: offer.assets.toString(),
1581
1662
  obligationUnits: offer.obligationUnits.toString(),
1582
1663
  obligationShares: offer.obligationShares.toString(),
1583
- price: offer.price.toString(),
1664
+ tick: offer.tick,
1584
1665
  maturity: Number(offer.maturity),
1585
1666
  expiry: Number(offer.expiry),
1586
1667
  start: Number(offer.start),
@@ -1625,14 +1706,13 @@ function random$1(config) {
1625
1706
  [.98, 2]
1626
1707
  ]));
1627
1708
  const buy = config?.buy !== void 0 ? config.buy : bool();
1628
- const ONE = 1000000000000000000n;
1629
- const qMin = buy ? 16 : 4;
1630
- const len = (buy ? 32 : 16) - qMin + 1;
1631
- const pricePairs = Array.from({ length: len }, (_, idx) => {
1632
- const q = qMin + idx;
1633
- return [BigInt(q) * (ONE / 4n), buy ? 1 + idx : 1 + (len - 1 - idx)];
1709
+ const tickMin = buy ? 0 : 495;
1710
+ const len = (buy ? 495 : 990) - tickMin + 1;
1711
+ const tickPairs = Array.from({ length: len }, (_, idx) => {
1712
+ const weight = buy ? 1 + idx : 1 + (len - 1 - idx);
1713
+ return [tickMin + idx, weight];
1634
1714
  });
1635
- const price = config?.price ?? weightedChoice(pricePairs);
1715
+ const tick = config?.tick ?? weightedChoice(tickPairs);
1636
1716
  const loanTokenDecimals = config?.assetsDecimals?.[loanToken] ?? 18;
1637
1717
  const unit = BigInt(10) ** BigInt(loanTokenDecimals);
1638
1718
  const amountBase = BigInt(100 + int(999901));
@@ -1646,7 +1726,7 @@ function random$1(config) {
1646
1726
  assets: assetsScaled,
1647
1727
  obligationUnits: config?.obligationUnits ?? 0n,
1648
1728
  obligationShares: config?.obligationShares ?? 0n,
1649
- price,
1729
+ tick,
1650
1730
  maturity,
1651
1731
  expiry: config?.expiry ?? maturity - 1,
1652
1732
  start: config?.start ?? maturity - 10,
@@ -1711,7 +1791,7 @@ const types = {
1711
1791
  type: "uint256"
1712
1792
  },
1713
1793
  {
1714
- name: "price",
1794
+ name: "tick",
1715
1795
  type: "uint256"
1716
1796
  },
1717
1797
  {
@@ -1779,7 +1859,7 @@ function hash(offer) {
1779
1859
  assets: offer.assets,
1780
1860
  obligationUnits: offer.obligationUnits,
1781
1861
  obligationShares: offer.obligationShares,
1782
- price: offer.price,
1862
+ tick: BigInt(offer.tick),
1783
1863
  maturity: BigInt(offer.maturity),
1784
1864
  expiry: BigInt(offer.expiry),
1785
1865
  group: offer.group,
@@ -1830,7 +1910,7 @@ const OfferAbi = [
1830
1910
  type: "uint256"
1831
1911
  },
1832
1912
  {
1833
- name: "price",
1913
+ name: "tick",
1834
1914
  type: "uint256"
1835
1915
  },
1836
1916
  {
@@ -1901,7 +1981,7 @@ function encode$1(offer) {
1901
1981
  offer.assets,
1902
1982
  offer.obligationUnits,
1903
1983
  offer.obligationShares,
1904
- offer.price,
1984
+ BigInt(offer.tick),
1905
1985
  BigInt(offer.maturity),
1906
1986
  BigInt(offer.expiry),
1907
1987
  offer.group,
@@ -1926,7 +2006,7 @@ function decode$1(data) {
1926
2006
  assets: decoded[1],
1927
2007
  obligationUnits: decoded[2],
1928
2008
  obligationShares: decoded[3],
1929
- price: decoded[4],
2009
+ tick: Number(decoded[4]),
1930
2010
  maturity: from$11(Number(decoded[5])),
1931
2011
  expiry: Number(decoded[6]),
1932
2012
  group: decoded[7],
@@ -2827,7 +2907,7 @@ function from$2(input) {
2827
2907
  obligation_shares: input.obligationShares.toString(),
2828
2908
  start: input.start,
2829
2909
  expiry: input.expiry,
2830
- price: input.price.toString(),
2910
+ tick: input.tick,
2831
2911
  group: input.group,
2832
2912
  session: input.session,
2833
2913
  callback: input.callback.address,
@@ -2900,7 +2980,7 @@ const offerExample = {
2900
2980
  obligation_shares: "0",
2901
2981
  start: 1761922790,
2902
2982
  expiry: 1761922799,
2903
- price: "2750000000000000000",
2983
+ tick: 495,
2904
2984
  group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
2905
2985
  session: "0x0000000000000000000000000000000000000000000000000000000000000000",
2906
2986
  callback: "0x0000000000000000000000000000000000000000",
@@ -2941,7 +3021,7 @@ const validateOfferExample = {
2941
3021
  assets: "369216000000000000000000",
2942
3022
  obligation_units: "0",
2943
3023
  obligation_shares: "0",
2944
- price: "2750000000000000000",
3024
+ tick: 495,
2945
3025
  maturity: 1761922799,
2946
3026
  expiry: 1761922799,
2947
3027
  start: 1761922790,
@@ -3085,9 +3165,11 @@ __decorate([ApiProperty({
3085
3165
  example: offerExample.offer.expiry
3086
3166
  })], OfferDataResponse.prototype, "expiry", void 0);
3087
3167
  __decorate([ApiProperty({
3088
- type: "string",
3089
- example: offerExample.offer.price
3090
- })], OfferDataResponse.prototype, "price", void 0);
3168
+ type: "number",
3169
+ example: offerExample.offer.tick,
3170
+ minimum: 0,
3171
+ maximum: 990
3172
+ })], OfferDataResponse.prototype, "tick", void 0);
3091
3173
  __decorate([ApiProperty({
3092
3174
  type: "string",
3093
3175
  example: offerExample.offer.group
@@ -3328,9 +3410,11 @@ __decorate([ApiProperty({
3328
3410
  required: false
3329
3411
  })], ValidateOfferRequest.prototype, "obligation_shares", void 0);
3330
3412
  __decorate([ApiProperty({
3331
- type: "string",
3332
- example: validateOfferExample.price
3333
- })], ValidateOfferRequest.prototype, "price", void 0);
3413
+ type: "number",
3414
+ example: validateOfferExample.tick,
3415
+ minimum: 0,
3416
+ maximum: 990
3417
+ })], ValidateOfferRequest.prototype, "tick", void 0);
3334
3418
  __decorate([ApiProperty({
3335
3419
  type: "number",
3336
3420
  example: validateOfferExample.maturity
@@ -3430,9 +3514,16 @@ __decorate([ApiProperty({
3430
3514
  description: "List of validation issues. Returned when any offer fails validation."
3431
3515
  })], ValidationFailureResponse.prototype, "data", void 0);
3432
3516
  var BookLevelResponse = class {};
3517
+ __decorate([ApiProperty({
3518
+ type: "number",
3519
+ example: 495,
3520
+ minimum: 0,
3521
+ maximum: 990
3522
+ })], BookLevelResponse.prototype, "tick", void 0);
3433
3523
  __decorate([ApiProperty({
3434
3524
  type: "string",
3435
- example: "2750000000000000000"
3525
+ example: "500000000000000000",
3526
+ description: "Price derived from tick, scaled by 1e18."
3436
3527
  })], BookLevelResponse.prototype, "price", void 0);
3437
3528
  __decorate([ApiProperty({
3438
3529
  type: "string",
@@ -3446,6 +3537,7 @@ const positionExample = {
3446
3537
  chain_id: 1,
3447
3538
  contract: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
3448
3539
  user: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
3540
+ obligation_id: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67",
3449
3541
  reserved: "200000000000000000000",
3450
3542
  block_number: 21345678
3451
3543
  };
@@ -3462,6 +3554,12 @@ __decorate([ApiProperty({
3462
3554
  type: "string",
3463
3555
  example: positionExample.user
3464
3556
  })], PositionListItemResponse.prototype, "user", void 0);
3557
+ __decorate([ApiProperty({
3558
+ type: "string",
3559
+ nullable: true,
3560
+ example: positionExample.obligation_id,
3561
+ description: "Obligation id this reserved amount belongs to, or null if no lots exist."
3562
+ })], PositionListItemResponse.prototype, "obligation_id", void 0);
3465
3563
  __decorate([ApiProperty({
3466
3564
  type: "string",
3467
3565
  example: positionExample.reserved
@@ -3489,7 +3587,7 @@ __decorate([ApiProperty({
3489
3587
  })], BookListResponse.prototype, "cursor", void 0);
3490
3588
  __decorate([ApiProperty({
3491
3589
  type: () => [BookLevelResponse],
3492
- description: "Aggregated book levels grouped by computed price."
3590
+ description: "Aggregated book levels grouped by offer tick."
3493
3591
  })], BookListResponse.prototype, "data", void 0);
3494
3592
  let BooksController = class BooksController {
3495
3593
  async getBook() {}
@@ -3499,7 +3597,7 @@ __decorate([
3499
3597
  methods: ["get"],
3500
3598
  path: "/v1/books/{obligationId}/{side}",
3501
3599
  summary: "Get aggregated book",
3502
- description: "Returns aggregated book data for a given obligation and side. Offers are grouped by computed price with summed takeable amounts. Book levels are sorted by price (ascending for buy side, descending for sell side)."
3600
+ description: "Returns aggregated book data for a given obligation and side. Offers are grouped by tick with summed takeable amounts, and each level includes the corresponding wad-scaled price. Book levels are sorted by tick (ascending for sell side, descending for buy side)."
3503
3601
  }),
3504
3602
  ApiParam({
3505
3603
  name: "obligationId",
@@ -3524,7 +3622,7 @@ __decorate([
3524
3622
  name: "limit",
3525
3623
  type: "number",
3526
3624
  example: 10,
3527
- description: "Maximum number of price levels to return."
3625
+ description: "Maximum number of tick levels to return."
3528
3626
  }),
3529
3627
  ApiResponse({
3530
3628
  status: 200,
@@ -3718,6 +3816,11 @@ const configRulesLoanTokenExample = {
3718
3816
  chain_id: 1,
3719
3817
  address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
3720
3818
  };
3819
+ const configRulesCollateralTokenExample = {
3820
+ type: "collateral_token",
3821
+ chain_id: 1,
3822
+ address: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
3823
+ };
3721
3824
  const configRulesOracleExample = {
3722
3825
  type: "oracle",
3723
3826
  chain_id: 1,
@@ -3727,6 +3830,7 @@ const configRulesChecksumExample = "f1d2d2f924e986ac86fdf7b36c94bcdf";
3727
3830
  const configRulesPayloadExample = [
3728
3831
  configRulesMaturityExample,
3729
3832
  configRulesLoanTokenExample,
3833
+ configRulesCollateralTokenExample,
3730
3834
  configRulesOracleExample
3731
3835
  ];
3732
3836
  const configContractNames = [
@@ -3853,7 +3957,7 @@ __decorate([
3853
3957
  methods: ["get"],
3854
3958
  path: "/v1/config/rules",
3855
3959
  summary: "Get config rules",
3856
- description: "Returns configured rules (maturities, loan tokens, oracles) for supported chains."
3960
+ description: "Returns configured rules (maturities, loan tokens, collateral tokens, oracles) for supported chains."
3857
3961
  }),
3858
3962
  ApiQuery({
3859
3963
  name: "cursor",
@@ -3873,7 +3977,7 @@ __decorate([
3873
3977
  name: "types",
3874
3978
  type: ["string"],
3875
3979
  required: false,
3876
- example: "maturity,loan_token,oracle",
3980
+ example: "maturity,loan_token,collateral_token,oracle",
3877
3981
  description: "Filter by rule types (comma-separated).",
3878
3982
  style: "form",
3879
3983
  explode: false
@@ -3991,7 +4095,7 @@ __decorate([
3991
4095
  methods: ["get"],
3992
4096
  path: "/v1/users/{userAddress}/positions",
3993
4097
  summary: "Get user positions",
3994
- description: "Returns positions for a user with reserved balance. The reserved balance is the amount locked by active offers (max lot upper - offset - consumed)."
4098
+ description: "Returns positions for a user with reserved balance per obligation. Each (position, obligation) pair is returned as a separate row. Positions with no lots return a single row with obligation_id = null and reserved = 0."
3995
4099
  }),
3996
4100
  ApiParam({
3997
4101
  name: "userAddress",
@@ -4079,6 +4183,7 @@ function from$1(position) {
4079
4183
  chain_id: position.chainId,
4080
4184
  contract: position.contract,
4081
4185
  user: position.user,
4186
+ obligation_id: position.obligationId,
4082
4187
  reserved: position.reserved.toString(),
4083
4188
  block_number: position.blockNumber
4084
4189
  };
@@ -4132,10 +4237,11 @@ const ConfigRuleTypes = z$1.enum([
4132
4237
  "maturity",
4133
4238
  "callback",
4134
4239
  "loan_token",
4240
+ "collateral_token",
4135
4241
  "oracle"
4136
4242
  ]);
4137
4243
  const GetConfigRulesQueryParams = z$1.object({
4138
- cursor: z$1.string().regex(/^(maturity|callback|loan_token|oracle):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
4244
+ 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({
4139
4245
  description: "Pagination cursor in type:chain_id:<value> format",
4140
4246
  example: "maturity:1:1730415600:end_of_next_month"
4141
4247
  }),
@@ -4145,7 +4251,7 @@ const GetConfigRulesQueryParams = z$1.object({
4145
4251
  }),
4146
4252
  types: csvArray(ConfigRuleTypes).meta({
4147
4253
  description: "Filter by rule types (comma-separated).",
4148
- example: "maturity,loan_token,oracle"
4254
+ example: "maturity,loan_token,collateral_token,oracle"
4149
4255
  }),
4150
4256
  chains: csvArray(z$1.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
4151
4257
  description: "Filter by chain IDs (comma-separated).",
@@ -4245,12 +4351,11 @@ const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obl
4245
4351
  description: "Obligation id",
4246
4352
  example: "0x1234567890123456789012345678901234567890123456789012345678901234"
4247
4353
  }) });
4248
- /** Validate a book cursor format: {side, lastPrice, offersCursor} */
4354
+ /** Validate a book cursor format: {side, lastTick, offersCursor} */
4249
4355
  function isValidBookCursor(cursorString) {
4250
- const isNumericString = (value) => typeof value === "string" && /^-?\d+$/.test(value);
4251
4356
  try {
4252
4357
  const v = JSON.parse(Buffer.from(cursorString, "base64url").toString("utf8"));
4253
- return (v?.side === "buy" || v?.side === "sell") && isNumericString(v?.lastPrice) && (v?.offersCursor === null || typeof v?.offersCursor === "string");
4358
+ return (v?.side === "buy" || v?.side === "sell") && typeof v?.lastTick === "number" && Number.isInteger(v.lastTick) && (v?.offersCursor === null || typeof v?.offersCursor === "string");
4254
4359
  } catch {
4255
4360
  return false;
4256
4361
  }
@@ -4411,7 +4516,7 @@ async function getOffers(apiClient, parameters) {
4411
4516
  assets: offerData.assets,
4412
4517
  obligation_units: offerData.obligation_units,
4413
4518
  obligation_shares: offerData.obligation_shares,
4414
- price: offerData.price,
4519
+ tick: offerData.tick,
4415
4520
  maturity: from$11(offerData.obligation.maturity),
4416
4521
  expiry: offerData.expiry,
4417
4522
  start: offerData.start,
@@ -4759,6 +4864,33 @@ const assets = {
4759
4864
  "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
4760
4865
  ]
4761
4866
  };
4867
+ const collateralAssets = {
4868
+ [ChainId.ETHEREUM.toString()]: [
4869
+ "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
4870
+ "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
4871
+ "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
4872
+ "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
4873
+ ],
4874
+ [ChainId.BASE.toString()]: [
4875
+ "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
4876
+ "0x4200000000000000000000000000000000000006",
4877
+ "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
4878
+ "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
4879
+ "0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42"
4880
+ ],
4881
+ [ChainId["ETHEREUM-VIRTUAL-TESTNET"].toString()]: [
4882
+ "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
4883
+ "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
4884
+ "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
4885
+ "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
4886
+ ],
4887
+ [ChainId.ANVIL.toString()]: [
4888
+ "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
4889
+ "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
4890
+ "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
4891
+ "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
4892
+ ]
4893
+ };
4762
4894
  const oracles = {
4763
4895
  [ChainId.ETHEREUM.toString()]: [
4764
4896
  "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
@@ -4821,10 +4953,11 @@ var Rules_exports = /* @__PURE__ */ __exportAll({
4821
4953
  amountMutualExclusivity: () => amountMutualExclusivity,
4822
4954
  callback: () => callback,
4823
4955
  chains: () => chains,
4956
+ collateralToken: () => collateralToken,
4957
+ loanToken: () => loanToken,
4824
4958
  maturity: () => maturity,
4825
4959
  oracle: () => oracle,
4826
4960
  sameMaker: () => sameMaker,
4827
- token: () => token,
4828
4961
  validity: () => validity
4829
4962
  });
4830
4963
  /**
@@ -4852,15 +4985,25 @@ const callback = ({ callbacks }) => single("callback", `Validates callbacks: buy
4852
4985
  if (isEmptyCallback(offer) && !offer.buy && !callbacks.includes(Type$1.SellWithEmptyCallback)) return { message: "Sell offers with empty callback not allowed." };
4853
4986
  });
4854
4987
  /**
4855
- * A validation rule that checks if the offer's tokens are allowed for its chain.
4856
- * @param assetsByChainId - Allowed assets indexed by chain id.
4988
+ * A validation rule that checks if the offer's loan token is allowed for its chain.
4989
+ * @param assetsByChainId - Allowed loan tokens indexed by chain id.
4990
+ * @returns The issue that was found. If the offer is valid, this will be undefined.
4991
+ */
4992
+ const loanToken = ({ assetsByChainId }) => single("loan_token", "Validates that offer loan token is in the allowed token list for the offer chain", (offer) => {
4993
+ const allowedLoanTokens = assetsByChainId[offer.chainId]?.map((asset) => asset.toLowerCase());
4994
+ if (!allowedLoanTokens || allowedLoanTokens.length === 0) return { message: `No allowed loan tokens for chain ${offer.chainId}` };
4995
+ if (!allowedLoanTokens.includes(offer.loanToken.toLowerCase())) return { message: "Loan token is not allowed" };
4996
+ });
4997
+ /**
4998
+ * A validation rule that checks if the offer's collateral tokens are allowed for its chain.
4999
+ * @param collateralAssetsByChainId - Allowed collateral tokens indexed by chain id.
4857
5000
  * @returns The issue that was found. If the offer is valid, this will be undefined.
4858
5001
  */
4859
- const token = ({ assetsByChainId }) => single("token", "Validates that offer loan token and collateral tokens are in the allowed assets list for the offer chain", (offer) => {
4860
- const allowedAssets = assetsByChainId[offer.chainId]?.map((asset) => asset.toLowerCase());
4861
- if (!allowedAssets || allowedAssets.length === 0) return { message: `No allowed assets for chain ${offer.chainId}` };
4862
- if (!allowedAssets.includes(offer.loanToken.toLowerCase())) return { message: "Loan token is not allowed" };
4863
- if (offer.collaterals.some((collateral) => !allowedAssets.includes(collateral.asset.toLowerCase()))) return { message: "Collateral is not allowed" };
5002
+ const collateralToken = ({ collateralAssetsByChainId }) => single("collateral_token", "Validates that offer collateral tokens are in the allowed token list for the offer chain", (offer) => {
5003
+ const allowedCollateralTokens = collateralAssetsByChainId[offer.chainId]?.map((asset) => asset.toLowerCase()) ?? [];
5004
+ if (allowedCollateralTokens.length === 0) return { message: `No allowed collateral tokens for chain ${offer.chainId}` };
5005
+ if (offer.collaterals.length === 0) return { message: "At least one collateral token is required" };
5006
+ if (offer.collaterals.some((collateral) => !allowedCollateralTokens.includes(collateral.asset.toLowerCase()))) return { message: "Collateral token is not allowed" };
4864
5007
  });
4865
5008
  /**
4866
5009
  * A validation rule that checks if the offer's oracle addresses are allowed for its chain.
@@ -4903,9 +5046,11 @@ const amountMutualExclusivity = () => single("amount_mutual_exclusivity", "Valid
4903
5046
  //#region src/gatekeeper/morphoRules.ts
4904
5047
  const morphoRules = (chains$2) => {
4905
5048
  const assetsByChainId = {};
5049
+ const collateralAssetsByChainId = {};
4906
5050
  const oraclesByChainId = {};
4907
5051
  for (const chain of chains$2) {
4908
5052
  assetsByChainId[chain.id] = assets[chain.id.toString()] ?? [];
5053
+ collateralAssetsByChainId[chain.id] = collateralAssets[chain.id.toString()] ?? [];
4909
5054
  oraclesByChainId[chain.id] = oracles[chain.id.toString()] ?? [];
4910
5055
  }
4911
5056
  return [
@@ -4917,7 +5062,8 @@ const morphoRules = (chains$2) => {
4917
5062
  callbacks: [Type$1.BuyWithEmptyCallback, Type$1.SellWithEmptyCallback],
4918
5063
  allowedAddresses: []
4919
5064
  }),
4920
- token({ assetsByChainId }),
5065
+ loanToken({ assetsByChainId }),
5066
+ collateralToken({ collateralAssetsByChainId }),
4921
5067
  oracle({ oraclesByChainId })
4922
5068
  ];
4923
5069
  };
@@ -5243,5 +5389,5 @@ var utils_exports = /* @__PURE__ */ __exportAll({
5243
5389
  });
5244
5390
 
5245
5391
  //#endregion
5246
- 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, 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, 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 };
5392
+ 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, 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 };
5247
5393
  //# sourceMappingURL=index.browser.mjs.map