@morpho-dev/router 0.1.15 → 0.1.17

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.
@@ -2,12 +2,12 @@
2
2
 
3
3
  var v4 = require('zod/v4');
4
4
  var viem = require('viem');
5
+ var zodOpenapi = require('zod-openapi');
5
6
  var actions = require('viem/actions');
6
7
  var chains$1 = require('viem/chains');
7
8
  var z7 = require('zod');
8
- var jsBase64 = require('js-base64');
9
9
  var accounts = require('viem/accounts');
10
- var zodOpenapi = require('zod-openapi');
10
+ var jsBase64 = require('js-base64');
11
11
 
12
12
  function _interopNamespace(e) {
13
13
  if (e && e.__esModule) return e;
@@ -37,7 +37,7 @@ var __export = (target, all) => {
37
37
  };
38
38
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
39
39
 
40
- // src/api/Api/Schema/index.ts
40
+ // src/api/Schema/index.ts
41
41
  var Schema_exports = {};
42
42
  __export(Schema_exports, {
43
43
  ChainHealth: () => ChainHealth,
@@ -59,27 +59,89 @@ var CollectorHealth = v4.z.object({
59
59
  lag: v4.z.number().nullable(),
60
60
  status: v4.z.enum(["live", "lagging", "unknown"])
61
61
  });
62
- var CollectorsHealthResponse = v4.z.object({
63
- collectors: v4.z.array(CollectorHealth)
64
- });
62
+ var CollectorsHealthResponse = v4.z.array(CollectorHealth);
65
63
  var ChainHealth = v4.z.object({
66
64
  chain_id: v4.z.number(),
67
65
  block_number: v4.z.number(),
68
66
  updated_at: v4.z.string()
69
67
  });
70
- var ChainsHealthResponse = v4.z.object({
71
- chains: v4.z.array(ChainHealth)
72
- });
68
+ var ChainsHealthResponse = v4.z.array(ChainHealth);
73
69
  var RouterStatusResponse = v4.z.object({
74
70
  status: v4.z.enum(["live", "syncing"])
75
71
  });
76
72
 
77
- // src/api/Api/Schema/ObligationResponse.ts
73
+ // src/api/Schema/ObligationResponse.ts
78
74
  var ObligationResponse_exports = {};
79
75
  __export(ObligationResponse_exports, {
80
- from: () => from6
76
+ from: () => from
81
77
  });
82
78
 
79
+ // src/utils/Format.ts
80
+ var Format_exports = {};
81
+ __export(Format_exports, {
82
+ fromSnakeCase: () => fromSnakeCase,
83
+ toSnakeCase: () => toSnakeCase
84
+ });
85
+ function toSnakeCase(obj) {
86
+ return stringifyBigint(
87
+ processObject(
88
+ obj,
89
+ (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`),
90
+ (value) => typeof value === "string" && viem.isAddress(value.toLowerCase()) ? viem.getAddress(value.toLowerCase()) : value
91
+ )
92
+ );
93
+ }
94
+ function fromSnakeCase(obj) {
95
+ return processObject(
96
+ obj,
97
+ (s) => viem.isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()),
98
+ (value) => typeof value === "string" && viem.isAddress(value.toLowerCase()) ? value.toLowerCase() : value
99
+ );
100
+ }
101
+ function processObject(obj, fnKey, fnValue) {
102
+ if (typeof obj !== "object" || obj === null) return obj;
103
+ if (Array.isArray(obj)) return obj.map((item) => processObject(item, fnKey, fnValue));
104
+ return Object.entries(obj).reduce(
105
+ (acc, [key, value]) => {
106
+ const newKey = fnKey(key);
107
+ acc[newKey] = typeof value === "object" && value !== null ? processObject(value, fnKey, fnValue) : fnValue(value);
108
+ return acc;
109
+ },
110
+ {}
111
+ );
112
+ }
113
+ function stringifyBigint(value) {
114
+ if (typeof value === "bigint") return value.toString();
115
+ if (Array.isArray(value)) return value.map(stringifyBigint);
116
+ if (value && typeof value === "object") {
117
+ const out = {};
118
+ for (const [k, v] of Object.entries(value)) {
119
+ out[k] = stringifyBigint(v);
120
+ }
121
+ return out;
122
+ }
123
+ return value;
124
+ }
125
+
126
+ // src/api/Schema/ObligationResponse.ts
127
+ function from(obligation, quote) {
128
+ return toSnakeCase({
129
+ id: quote.obligationId,
130
+ ...obligation,
131
+ ask: quote.ask,
132
+ bid: quote.bid
133
+ });
134
+ }
135
+
136
+ // src/api/Schema/OfferResponse.ts
137
+ var OfferResponse_exports = {};
138
+ __export(OfferResponse_exports, {
139
+ from: () => from2
140
+ });
141
+ function from2(offer) {
142
+ return toSnakeCase(offer);
143
+ }
144
+
83
145
  // src/core/Abi.ts
84
146
  var Abi_exports = {};
85
147
  __export(Abi_exports, {
@@ -649,7 +711,7 @@ var Collateral_exports = {};
649
711
  __export(Collateral_exports, {
650
712
  CollateralSchema: () => CollateralSchema,
651
713
  CollateralsSchema: () => CollateralsSchema,
652
- from: () => from2
714
+ from: () => from4
653
715
  });
654
716
  var transformHex = (val, ctx) => {
655
717
  if (viem.isHex(val)) return val;
@@ -679,11 +741,11 @@ __export(LLTV_exports, {
679
741
  InvalidOptionError: () => InvalidOptionError,
680
742
  LLTVSchema: () => LLTVSchema,
681
743
  Options: () => Options,
682
- from: () => from
744
+ from: () => from3
683
745
  });
684
746
  var Options = [0.385, 0.5, 0.625, 0.77, 0.86, 0.915, 0.945, 0.965, 0.98];
685
747
  var LLTV_SCALED = Options.map((lltv) => BigInt(lltv * 10 ** 18));
686
- function from(lltv) {
748
+ function from3(lltv) {
687
749
  if (typeof lltv === "bigint" && !LLTV_SCALED.includes(lltv)) throw new InvalidLLTVError(lltv);
688
750
  if (typeof lltv === "bigint") return lltv;
689
751
  if (typeof lltv === "number" && !Options.includes(lltv)) throw new InvalidOptionError(lltv);
@@ -712,7 +774,7 @@ var InvalidLLTVError = class extends BaseError {
712
774
  var LLTVSchema = z7__namespace.bigint({ coerce: true }).refine(
713
775
  (lltv) => {
714
776
  try {
715
- from(lltv);
777
+ from3(lltv);
716
778
  return true;
717
779
  } catch (_) {
718
780
  return false;
@@ -723,7 +785,7 @@ var LLTVSchema = z7__namespace.bigint({ coerce: true }).refine(
723
785
  return "Invalid LLTV: must be one of 0.385, 0.625, 0.77, 0.86, 0.915, 0.945, 0.965 or 0.98 (scaled by 1e18)";
724
786
  }
725
787
  }
726
- ).transform((lltv) => from(lltv));
788
+ ).transform((lltv) => from3(lltv));
727
789
 
728
790
  // src/core/Collateral.ts
729
791
  var CollateralSchema = z7__namespace.object({
@@ -759,105 +821,14 @@ var CollateralsSchema = z7__namespace.array(CollateralSchema).min(1, { message:
759
821
  message: "Collaterals must not contain duplicate assets"
760
822
  }
761
823
  );
762
- var from2 = (parameters) => {
824
+ var from4 = (parameters) => {
763
825
  return {
764
826
  asset: parameters.asset.toLowerCase(),
765
- lltv: from(parameters.lltv),
827
+ lltv: from3(parameters.lltv),
766
828
  oracle: parameters.oracle.toLowerCase()
767
829
  };
768
830
  };
769
831
 
770
- // src/core/Cursor.ts
771
- var Cursor_exports = {};
772
- __export(Cursor_exports, {
773
- decode: () => decode,
774
- encode: () => encode,
775
- validate: () => validate
776
- });
777
- function validate(cursor) {
778
- if (!cursor || typeof cursor !== "object") {
779
- throw new Error("Cursor must be an object");
780
- }
781
- const c = cursor;
782
- if (!["rate", "maturity", "expiry", "amount"].includes(c.sort)) {
783
- throw new Error(
784
- `Invalid sort field: ${c.sort}. Must be one of: rate, maturity, expiry, amount`
785
- );
786
- }
787
- if (!["asc", "desc"].includes(c.dir)) {
788
- throw new Error(`Invalid direction: ${c.dir}. Must be one of: asc, desc`);
789
- }
790
- if (!/^0x[a-fA-F0-9]{64}$/.test(c.hash)) {
791
- throw new Error(
792
- `Invalid hash format: ${c.hash}. Must be a 64-character hex string starting with 0x`
793
- );
794
- }
795
- const validations = {
796
- rate: {
797
- field: "rate",
798
- type: "string",
799
- pattern: /^\d+$/,
800
- error: "numeric string"
801
- },
802
- amount: {
803
- field: "assets",
804
- type: "string",
805
- pattern: /^\d+$/,
806
- error: "numeric string"
807
- },
808
- maturity: {
809
- field: "maturity",
810
- type: "number",
811
- validator: (val) => val > 0,
812
- error: "positive number"
813
- },
814
- expiry: {
815
- field: "expiry",
816
- type: "number",
817
- validator: (val) => val > 0,
818
- error: "positive number"
819
- }
820
- };
821
- const validation = validations[c.sort];
822
- if (!validation) {
823
- throw new Error(`Invalid sort field: ${c.sort}`);
824
- }
825
- const fieldValue = c[validation.field];
826
- if (!fieldValue) {
827
- throw new Error(`${c.sort} sort requires '${validation.field}' field to be present`);
828
- }
829
- if (typeof fieldValue !== validation.type) {
830
- throw new Error(
831
- `${c.sort} sort requires '${validation.field}' field of type ${validation.type}`
832
- );
833
- }
834
- if (validation.pattern && !validation.pattern.test(fieldValue)) {
835
- throw new Error(
836
- `Invalid ${validation.field} format: ${fieldValue}. Must be a ${validation.error}`
837
- );
838
- }
839
- if (validation.validator && !validation.validator(fieldValue)) {
840
- throw new Error(
841
- `Invalid ${validation.field} value: ${fieldValue}. Must be a ${validation.error}`
842
- );
843
- }
844
- if (c.page !== void 0) {
845
- if (typeof c.page !== "number" || !Number.isInteger(c.page) || c.page < 1) {
846
- throw new Error("Invalid page: must be a positive integer");
847
- }
848
- }
849
- return true;
850
- }
851
- function encode(c) {
852
- return jsBase64.Base64.encodeURL(JSON.stringify(c));
853
- }
854
- function decode(token) {
855
- if (!token) return null;
856
- const decoded = JSON.parse(jsBase64.Base64.decode(token));
857
- validate(decoded);
858
- return decoded;
859
- }
860
-
861
832
  // src/core/Liquidity.ts
862
833
  var Liquidity_exports = {};
863
834
  __export(Liquidity_exports, {
@@ -923,12 +894,12 @@ __export(Maturity_exports, {
923
894
  InvalidFormatError: () => InvalidFormatError,
924
895
  InvalidOptionError: () => InvalidOptionError2,
925
896
  MaturitySchema: () => MaturitySchema,
926
- from: () => from3
897
+ from: () => from5
927
898
  });
928
899
  var MaturitySchema = z7__namespace.number().int().refine(
929
900
  (maturity) => {
930
901
  try {
931
- from3(maturity);
902
+ from5(maturity);
932
903
  return true;
933
904
  } catch (_e) {
934
905
  return false;
@@ -953,7 +924,7 @@ var MaturityOptions = {
953
924
  end_of_quarter: () => endOfQuarter(),
954
925
  end_of_next_quarter: () => endOfNextQuarter()
955
926
  };
956
- function from3(ts) {
927
+ function from5(ts) {
957
928
  if (typeof ts === "string") {
958
929
  if (ts in MaturityOptions) return MaturityOptions[ts]();
959
930
  throw new InvalidOptionError2(ts);
@@ -1031,71 +1002,22 @@ __export(Obligation_exports, {
1031
1002
  CollateralsAreNotSortedError: () => CollateralsAreNotSortedError,
1032
1003
  InvalidObligationError: () => InvalidObligationError,
1033
1004
  ObligationSchema: () => ObligationSchema,
1034
- from: () => from4,
1005
+ from: () => from6,
1035
1006
  fromSnakeCase: () => fromSnakeCase2,
1036
1007
  id: () => id,
1037
1008
  random: () => random
1038
1009
  });
1039
-
1040
- // src/utils/Format.ts
1041
- var Format_exports = {};
1042
- __export(Format_exports, {
1043
- fromSnakeCase: () => fromSnakeCase,
1044
- toSnakeCase: () => toSnakeCase
1045
- });
1046
- function toSnakeCase(obj) {
1047
- return stringifyBigint(
1048
- processObject(
1049
- obj,
1050
- (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`),
1051
- (value) => typeof value === "string" && viem.isAddress(value.toLowerCase()) ? viem.getAddress(value.toLowerCase()) : value
1052
- )
1053
- );
1054
- }
1055
- function fromSnakeCase(obj) {
1056
- return processObject(
1057
- obj,
1058
- (s) => viem.isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()),
1059
- (value) => typeof value === "string" && viem.isAddress(value.toLowerCase()) ? value.toLowerCase() : value
1060
- );
1061
- }
1062
- function processObject(obj, fnKey, fnValue) {
1063
- if (typeof obj !== "object" || obj === null) return obj;
1064
- if (Array.isArray(obj)) return obj.map((item) => processObject(item, fnKey, fnValue));
1065
- return Object.entries(obj).reduce(
1066
- (acc, [key, value]) => {
1067
- const newKey = fnKey(key);
1068
- acc[newKey] = typeof value === "object" && value !== null ? processObject(value, fnKey, fnValue) : fnValue(value);
1069
- return acc;
1070
- },
1071
- {}
1072
- );
1073
- }
1074
- function stringifyBigint(value) {
1075
- if (typeof value === "bigint") return value.toString();
1076
- if (Array.isArray(value)) return value.map(stringifyBigint);
1077
- if (value && typeof value === "object") {
1078
- const out = {};
1079
- for (const [k, v] of Object.entries(value)) {
1080
- out[k] = stringifyBigint(v);
1081
- }
1082
- return out;
1083
- }
1084
- return value;
1085
- }
1086
-
1087
- // src/core/Obligation.ts
1088
1010
  var ObligationSchema = z7__namespace.object({
1089
1011
  chainId: z7__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256),
1090
1012
  loanToken: z7__namespace.string().transform(transformAddress),
1091
1013
  collaterals: CollateralsSchema,
1092
1014
  maturity: MaturitySchema
1093
1015
  });
1094
- function from4(parameters) {
1016
+ function from6(parameters) {
1095
1017
  try {
1096
1018
  const parsedObligation = ObligationSchema.parse({
1097
1019
  ...parameters,
1098
- maturity: from3(parameters.maturity)
1020
+ maturity: from5(parameters.maturity)
1099
1021
  });
1100
1022
  return {
1101
1023
  chainId: parsedObligation.chainId,
@@ -1108,7 +1030,7 @@ function from4(parameters) {
1108
1030
  }
1109
1031
  }
1110
1032
  function fromSnakeCase2(input) {
1111
- return from4(fromSnakeCase(input));
1033
+ return from6(fromSnakeCase(input));
1112
1034
  }
1113
1035
  function id(obligation) {
1114
1036
  let lastAsset = "";
@@ -1146,17 +1068,17 @@ function id(obligation) {
1146
1068
  );
1147
1069
  }
1148
1070
  function random() {
1149
- return from4({
1071
+ return from6({
1150
1072
  chainId: 1n,
1151
1073
  loanToken: accounts.privateKeyToAccount(accounts.generatePrivateKey()).address,
1152
1074
  collaterals: [
1153
- from2({
1075
+ from4({
1154
1076
  asset: accounts.privateKeyToAccount(accounts.generatePrivateKey()).address,
1155
1077
  oracle: accounts.privateKeyToAccount(accounts.generatePrivateKey()).address,
1156
1078
  lltv: 0.965
1157
1079
  })
1158
1080
  ],
1159
- maturity: from3("end_of_next_quarter")
1081
+ maturity: from5("end_of_next_quarter")
1160
1082
  });
1161
1083
  }
1162
1084
  var InvalidObligationError = class extends BaseError {
@@ -1180,10 +1102,10 @@ __export(Offer_exports, {
1180
1102
  OfferHashSchema: () => OfferHashSchema,
1181
1103
  OfferSchema: () => OfferSchema,
1182
1104
  consumedEvent: () => consumedEvent,
1183
- decode: () => decode2,
1105
+ decode: () => decode,
1184
1106
  domain: () => domain,
1185
- encode: () => encode2,
1186
- from: () => from5,
1107
+ encode: () => encode,
1108
+ from: () => from7,
1187
1109
  fromConsumedLog: () => fromConsumedLog,
1188
1110
  fromSnakeCase: () => fromSnakeCase3,
1189
1111
  hash: () => hash,
@@ -1352,7 +1274,7 @@ var OfferSchema = (parameters) => {
1352
1274
  path: ["expiry"]
1353
1275
  });
1354
1276
  };
1355
- function from5(input) {
1277
+ function from7(input) {
1356
1278
  try {
1357
1279
  const parsedOffer = OfferSchema({ omitHash: true }).parse(input);
1358
1280
  const parsedHash = OfferHashSchema.parse(hash(parsedOffer));
@@ -1365,17 +1287,17 @@ function from5(input) {
1365
1287
  }
1366
1288
  }
1367
1289
  function fromSnakeCase3(input) {
1368
- return from5(fromSnakeCase(input));
1290
+ return from7(fromSnakeCase(input));
1369
1291
  }
1370
1292
  function toSnakeCase2(offer) {
1371
1293
  return toSnakeCase(offer);
1372
1294
  }
1373
1295
  function random2() {
1374
1296
  const loanToken = accounts.privateKeyToAccount(accounts.generatePrivateKey()).address;
1375
- const maturity = from3("end_of_month");
1376
- const expiry = from3("end_of_week") - 1;
1377
- const lltv = from(0.965);
1378
- const offer = from5({
1297
+ const maturity = from5("end_of_month");
1298
+ const expiry = from5("end_of_week") - 1;
1299
+ const lltv = from3(0.965);
1300
+ const offer = from7({
1379
1301
  offering: accounts.privateKeyToAccount(accounts.generatePrivateKey()).address,
1380
1302
  assets: BigInt(Math.floor(Math.random() * 1e6)),
1381
1303
  rate: BigInt(Math.floor(Math.random() * 1e6)),
@@ -1387,7 +1309,7 @@ function random2() {
1387
1309
  chainId: 1n,
1388
1310
  loanToken,
1389
1311
  collaterals: [
1390
- from2({
1312
+ from4({
1391
1313
  asset: viem.zeroAddress,
1392
1314
  oracle: viem.zeroAddress,
1393
1315
  lltv
@@ -1485,7 +1407,7 @@ function hash(offer) {
1485
1407
  }
1486
1408
  function obligationId(offer) {
1487
1409
  return id(
1488
- from4({
1410
+ from6({
1489
1411
  chainId: offer.chainId,
1490
1412
  loanToken: offer.loanToken,
1491
1413
  collaterals: offer.collaterals,
@@ -1524,7 +1446,7 @@ var OfferAbi = [
1524
1446
  },
1525
1447
  { name: "signature", type: "bytes" }
1526
1448
  ];
1527
- function encode2(offer) {
1449
+ function encode(offer) {
1528
1450
  return viem.encodeAbiParameters(OfferAbi, [
1529
1451
  offer.offering,
1530
1452
  offer.assets,
@@ -1541,18 +1463,18 @@ function encode2(offer) {
1541
1463
  offer.signature ?? "0x"
1542
1464
  ]);
1543
1465
  }
1544
- function decode2(data, blockNumber) {
1466
+ function decode(data, blockNumber) {
1545
1467
  let decoded;
1546
1468
  try {
1547
1469
  decoded = viem.decodeAbiParameters(OfferAbi, data);
1548
1470
  } catch (error) {
1549
1471
  throw new InvalidOfferError(error);
1550
1472
  }
1551
- const offer = from5({
1473
+ const offer = from7({
1552
1474
  offering: decoded[0],
1553
1475
  assets: decoded[1],
1554
1476
  rate: decoded[2],
1555
- maturity: from3(Number(decoded[3])),
1477
+ maturity: from5(Number(decoded[3])),
1556
1478
  expiry: Number(decoded[4]),
1557
1479
  nonce: decoded[5],
1558
1480
  buy: decoded[6],
@@ -1560,7 +1482,7 @@ function decode2(data, blockNumber) {
1560
1482
  loanToken: decoded[8],
1561
1483
  start: Number(decoded[9]),
1562
1484
  collaterals: decoded[10].map((c) => {
1563
- return from2({
1485
+ return from4({
1564
1486
  asset: c.asset,
1565
1487
  oracle: c.oracle,
1566
1488
  lltv: c.lltv
@@ -1611,22 +1533,152 @@ var AccountNotSetError = class extends BaseError {
1611
1533
  }
1612
1534
  };
1613
1535
 
1536
+ // src/core/Quote.ts
1537
+ var Quote_exports = {};
1538
+ __export(Quote_exports, {
1539
+ InvalidQuoteError: () => InvalidQuoteError,
1540
+ QuoteSchema: () => QuoteSchema,
1541
+ from: () => from8,
1542
+ fromSnakeCase: () => fromSnakeCase4,
1543
+ random: () => random3
1544
+ });
1545
+ var QuoteSchema = z7__namespace.object({
1546
+ obligationId: z7__namespace.string().transform(transformHex),
1547
+ ask: z7__namespace.object({
1548
+ rate: z7__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256)
1549
+ }),
1550
+ bid: z7__namespace.object({
1551
+ rate: z7__namespace.bigint({ coerce: true }).min(0n).max(viem.maxUint256)
1552
+ })
1553
+ });
1554
+ function from8(parameters) {
1555
+ try {
1556
+ const parsedQuote = QuoteSchema.parse(parameters);
1557
+ return {
1558
+ obligationId: parsedQuote.obligationId,
1559
+ ask: parsedQuote.ask,
1560
+ bid: parsedQuote.bid
1561
+ };
1562
+ } catch (error) {
1563
+ throw new InvalidQuoteError(error);
1564
+ }
1565
+ }
1566
+ function fromSnakeCase4(snake) {
1567
+ return from8(fromSnakeCase(snake));
1568
+ }
1569
+ function random3() {
1570
+ return from8({
1571
+ obligationId: Obligation_exports.id(Obligation_exports.random()),
1572
+ ask: {
1573
+ rate: BigInt(Math.floor(Math.random() * 1e6))
1574
+ },
1575
+ bid: {
1576
+ rate: BigInt(Math.floor(Math.random() * 1e6))
1577
+ }
1578
+ });
1579
+ }
1580
+ var InvalidQuoteError = class extends BaseError {
1581
+ constructor(error) {
1582
+ super("Invalid quote.", { cause: error });
1583
+ __publicField(this, "name", "Quote.InvalidQuoteError");
1584
+ }
1585
+ };
1586
+
1614
1587
  // src/core/types.ts
1615
1588
  var BrandTypeId = Symbol.for("mempool/Brand");
1616
1589
 
1617
- // src/api/Api/Schema/ObligationResponse.ts
1618
- function from6(obligation) {
1619
- return toSnakeCase({ id: Obligation_exports.id(obligation), ...obligation });
1620
- }
1621
-
1622
- // src/api/Api/Schema/OfferResponse.ts
1623
- var OfferResponse_exports = {};
1624
- __export(OfferResponse_exports, {
1625
- from: () => from7
1590
+ // src/stores/utils/Cursor.ts
1591
+ var Cursor_exports = {};
1592
+ __export(Cursor_exports, {
1593
+ decode: () => decode2,
1594
+ encode: () => encode2,
1595
+ validate: () => validate
1626
1596
  });
1627
- function from7(offer) {
1628
- return toSnakeCase(offer);
1597
+ function validate(cursor) {
1598
+ if (!cursor || typeof cursor !== "object") {
1599
+ throw new Error("Cursor must be an object");
1600
+ }
1601
+ const c = cursor;
1602
+ if (!["rate", "maturity", "expiry", "amount"].includes(c.sort)) {
1603
+ throw new Error(
1604
+ `Invalid sort field: ${c.sort}. Must be one of: rate, maturity, expiry, amount`
1605
+ );
1606
+ }
1607
+ if (!["asc", "desc"].includes(c.dir)) {
1608
+ throw new Error(`Invalid direction: ${c.dir}. Must be one of: asc, desc`);
1609
+ }
1610
+ if (!/^0x[a-fA-F0-9]{64}$/.test(c.hash)) {
1611
+ throw new Error(
1612
+ `Invalid hash format: ${c.hash}. Must be a 64-character hex string starting with 0x`
1613
+ );
1614
+ }
1615
+ const validations = {
1616
+ rate: {
1617
+ field: "rate",
1618
+ type: "string",
1619
+ pattern: /^\d+$/,
1620
+ error: "numeric string"
1621
+ },
1622
+ amount: {
1623
+ field: "assets",
1624
+ type: "string",
1625
+ pattern: /^\d+$/,
1626
+ error: "numeric string"
1627
+ },
1628
+ maturity: {
1629
+ field: "maturity",
1630
+ type: "number",
1631
+ validator: (val) => val > 0,
1632
+ error: "positive number"
1633
+ },
1634
+ expiry: {
1635
+ field: "expiry",
1636
+ type: "number",
1637
+ validator: (val) => val > 0,
1638
+ error: "positive number"
1639
+ }
1640
+ };
1641
+ const validation = validations[c.sort];
1642
+ if (!validation) {
1643
+ throw new Error(`Invalid sort field: ${c.sort}`);
1644
+ }
1645
+ const fieldValue = c[validation.field];
1646
+ if (!fieldValue) {
1647
+ throw new Error(`${c.sort} sort requires '${validation.field}' field to be present`);
1648
+ }
1649
+ if (typeof fieldValue !== validation.type) {
1650
+ throw new Error(
1651
+ `${c.sort} sort requires '${validation.field}' field of type ${validation.type}`
1652
+ );
1653
+ }
1654
+ if (validation.pattern && !validation.pattern.test(fieldValue)) {
1655
+ throw new Error(
1656
+ `Invalid ${validation.field} format: ${fieldValue}. Must be a ${validation.error}`
1657
+ );
1658
+ }
1659
+ if (validation.validator && !validation.validator(fieldValue)) {
1660
+ throw new Error(
1661
+ `Invalid ${validation.field} value: ${fieldValue}. Must be a ${validation.error}`
1662
+ );
1663
+ }
1664
+ if (c.page !== void 0) {
1665
+ if (typeof c.page !== "number" || !Number.isInteger(c.page) || c.page < 1) {
1666
+ throw new Error("Invalid page: must be a positive integer");
1667
+ }
1668
+ }
1669
+ return true;
1670
+ }
1671
+ function encode2(c) {
1672
+ return jsBase64.Base64.encodeURL(JSON.stringify(c));
1629
1673
  }
1674
+ function decode2(token) {
1675
+ if (!token) return null;
1676
+ const decoded = JSON.parse(jsBase64.Base64.decode(token));
1677
+ validate(decoded);
1678
+ return decoded;
1679
+ }
1680
+
1681
+ // src/api/Schema/requests.ts
1630
1682
  var MAX_LIMIT = 100;
1631
1683
  var DEFAULT_LIMIT = 20;
1632
1684
  var PaginationQueryParams = z7__namespace.object({
@@ -1689,14 +1741,74 @@ function safeParse(action, query, error) {
1689
1741
  });
1690
1742
  }
1691
1743
 
1692
- // src/api/Api/Schema/openapi.ts
1693
- var successResponseSchema = v4.z.object({
1694
- status: v4.z.literal("success"),
1695
- cursor: v4.z.string().nullable(),
1696
- data: v4.z.array(v4.z.any()),
1697
- meta: v4.z.object({
1698
- timestamp: v4.z.string()
1699
- })
1744
+ // src/api/Schema/openapi.ts
1745
+ var timestampExample = "2024-01-01T12:00:00.000Z";
1746
+ var cursorExample = "eyJvZmZzZXQiOjEwMH0";
1747
+ function makeSuccessResponse(parameters) {
1748
+ const { dataSchema, dataDescription, dataExample, cursor } = parameters;
1749
+ const withDataMeta = dataDescription ? dataSchema.meta({ description: dataDescription }) : dataSchema;
1750
+ return v4.z.object({
1751
+ status: v4.z.literal("success"),
1752
+ cursor: v4.z.string().nullable(),
1753
+ data: v4.z.any(),
1754
+ meta: v4.z.object({
1755
+ timestamp: v4.z.string()
1756
+ })
1757
+ }).extend({
1758
+ data: withDataMeta
1759
+ }).meta({
1760
+ example: {
1761
+ status: "success",
1762
+ cursor,
1763
+ data: dataExample,
1764
+ meta: { timestamp: timestampExample }
1765
+ }
1766
+ });
1767
+ }
1768
+ var OffersSuccessResponseSchema = makeSuccessResponse({
1769
+ dataSchema: v4.z.array(v4.z.any()),
1770
+ dataDescription: "Offers matching the provided filters.",
1771
+ dataExample: [toSnakeCase(Offer_exports.random())],
1772
+ cursor: cursorExample
1773
+ });
1774
+ var ObligationsSuccessResponseSchema = makeSuccessResponse({
1775
+ dataSchema: v4.z.array(v4.z.any()),
1776
+ dataDescription: "Obligations known to the router.",
1777
+ dataExample: [toSnakeCase(Obligation_exports.random())],
1778
+ cursor: cursorExample
1779
+ });
1780
+ var RouterStatusSuccessResponseSchema = makeSuccessResponse({
1781
+ dataSchema: RouterStatusResponse,
1782
+ dataDescription: "Aggregated router status.",
1783
+ dataExample: { status: "live" },
1784
+ cursor: null
1785
+ });
1786
+ var CollectorsHealthSuccessResponseSchema = makeSuccessResponse({
1787
+ dataSchema: CollectorsHealthResponse,
1788
+ dataDescription: "Collectors health details and sync status.",
1789
+ dataExample: [
1790
+ {
1791
+ name: "mempool_offers",
1792
+ chain_id: "1",
1793
+ block_number: 21345678,
1794
+ updated_at: "2024-01-01T12:00:00.000Z",
1795
+ lag: 0,
1796
+ status: "live"
1797
+ }
1798
+ ],
1799
+ cursor: null
1800
+ });
1801
+ var ChainsHealthSuccessResponseSchema = makeSuccessResponse({
1802
+ dataSchema: ChainsHealthResponse,
1803
+ dataDescription: "Latest processed block per chain.",
1804
+ dataExample: [
1805
+ {
1806
+ chain_id: "1",
1807
+ block_number: 21345678,
1808
+ updated_at: "2024-01-01T12:00:00.000Z"
1809
+ }
1810
+ ],
1811
+ cursor: null
1700
1812
  });
1701
1813
  var errorResponseSchema = v4.z.object({
1702
1814
  status: v4.z.literal("error"),
@@ -1708,6 +1820,24 @@ var errorResponseSchema = v4.z.object({
1708
1820
  meta: v4.z.object({
1709
1821
  timestamp: v4.z.string()
1710
1822
  })
1823
+ }).meta({
1824
+ description: "Error response wrapper.",
1825
+ example: {
1826
+ status: "error",
1827
+ error: {
1828
+ code: "VALIDATION_ERROR",
1829
+ message: "Invalid cursor format. Must be a valid base64url-encoded cursor object",
1830
+ details: [
1831
+ {
1832
+ field: "cursor",
1833
+ issue: "Invalid cursor format. Must be a valid base64url-encoded cursor object"
1834
+ }
1835
+ ]
1836
+ },
1837
+ meta: {
1838
+ timestamp: timestampExample
1839
+ }
1840
+ }
1711
1841
  });
1712
1842
  var paths = {
1713
1843
  "/v1/offers": {
@@ -1723,7 +1853,7 @@ var paths = {
1723
1853
  description: "Success",
1724
1854
  content: {
1725
1855
  "application/json": {
1726
- schema: successResponseSchema
1856
+ schema: OffersSuccessResponseSchema
1727
1857
  }
1728
1858
  }
1729
1859
  },
@@ -1751,7 +1881,7 @@ var paths = {
1751
1881
  description: "Success",
1752
1882
  content: {
1753
1883
  "application/json": {
1754
- schema: successResponseSchema
1884
+ schema: ObligationsSuccessResponseSchema
1755
1885
  }
1756
1886
  }
1757
1887
  },
@@ -1776,7 +1906,7 @@ var paths = {
1776
1906
  description: "Success",
1777
1907
  content: {
1778
1908
  "application/json": {
1779
- schema: RouterStatusResponse
1909
+ schema: RouterStatusSuccessResponseSchema
1780
1910
  }
1781
1911
  }
1782
1912
  }
@@ -1793,7 +1923,7 @@ var paths = {
1793
1923
  description: "Success",
1794
1924
  content: {
1795
1925
  "application/json": {
1796
- schema: CollectorsHealthResponse
1926
+ schema: CollectorsHealthSuccessResponseSchema
1797
1927
  }
1798
1928
  }
1799
1929
  }
@@ -1810,7 +1940,7 @@ var paths = {
1810
1940
  description: "Success",
1811
1941
  content: {
1812
1942
  "application/json": {
1813
- schema: ChainsHealthResponse
1943
+ schema: ChainsHealthSuccessResponseSchema
1814
1944
  }
1815
1945
  }
1816
1946
  }
@@ -1842,14 +1972,14 @@ var OpenApi = zodOpenapi.createDocument({
1842
1972
  description: "Production server"
1843
1973
  },
1844
1974
  {
1845
- url: "http://localhost:8081",
1975
+ url: "http://localhost:7891",
1846
1976
  description: "Local development server"
1847
1977
  }
1848
1978
  ],
1849
1979
  paths
1850
1980
  });
1851
1981
 
1852
- // src/api/Client.ts
1982
+ // src/client/Client.ts
1853
1983
  var Client_exports = {};
1854
1984
  __export(Client_exports, {
1855
1985
  HttpForbiddenError: () => HttpForbiddenError,
@@ -1904,8 +2034,16 @@ async function getObligations(config, parameters) {
1904
2034
  if (parameters?.limit !== void 0) {
1905
2035
  url.searchParams.set("limit", parameters.limit.toString());
1906
2036
  }
1907
- const { cursor: returnedCursor, data: obligationsSnake } = await getApi(config, url);
1908
- const obligations = obligationsSnake.map(Obligation_exports.fromSnakeCase);
2037
+ const { cursor: returnedCursor, data: items } = await getApi(config, url);
2038
+ const obligations = items.map((item) => {
2039
+ const obligation = Obligation_exports.fromSnakeCase(item);
2040
+ const { obligationId: _, ...returned } = {
2041
+ id: () => Obligation_exports.id(obligation),
2042
+ ...obligation,
2043
+ ...Quote_exports.fromSnakeCase({ obligation_id: item.id, ask: item.ask, bid: item.bid })
2044
+ };
2045
+ return returned;
2046
+ });
1909
2047
  return {
1910
2048
  cursor: returnedCursor,
1911
2049
  obligations
@@ -2303,7 +2441,7 @@ __export(MempoolClient_exports, {
2303
2441
  });
2304
2442
  var DEFAULT_BATCH_SIZE2 = 100;
2305
2443
  var DEFAULT_BLOCK_WINDOW2 = 100;
2306
- function from8(parameters) {
2444
+ function from9(parameters) {
2307
2445
  const config = {
2308
2446
  client: parameters.client,
2309
2447
  mempoolAddress: parameters.mempoolAddress,
@@ -2448,7 +2586,7 @@ var ChainIdMismatchError = class extends BaseError {
2448
2586
 
2449
2587
  // src/mempool/MempoolClient.ts
2450
2588
  function connect2(parameters) {
2451
- return from8(parameters);
2589
+ return from9(parameters);
2452
2590
  }
2453
2591
 
2454
2592
  exports.Abi = Abi_exports;
@@ -2465,6 +2603,7 @@ exports.Maturity = Maturity_exports;
2465
2603
  exports.Mempool = MempoolClient_exports;
2466
2604
  exports.Obligation = Obligation_exports;
2467
2605
  exports.Offer = Offer_exports;
2606
+ exports.Quote = Quote_exports;
2468
2607
  exports.RouterApi = Schema_exports;
2469
2608
  exports.RouterClient = Client_exports;
2470
2609
  exports.Time = time_exports;