@morpho-dev/router 0.1.16 → 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.
@@ -1,11 +1,11 @@
1
1
  import { z } from 'zod/v4';
2
- import { maxUint256, isAddress, isHex, decodeAbiParameters, encodeAbiParameters, keccak256, zeroAddress, hashTypedData, getAddress, publicActions } from 'viem';
2
+ import { maxUint256, isAddress, isHex, getAddress, decodeAbiParameters, encodeAbiParameters, keccak256, zeroAddress, hashTypedData, publicActions } from 'viem';
3
+ import { createDocument } from 'zod-openapi';
3
4
  import { getBlock, getLogs } from 'viem/actions';
4
5
  import { base, mainnet, anvil } from 'viem/chains';
5
6
  import * as z7 from 'zod';
6
- import { Base64 } from 'js-base64';
7
7
  import { privateKeyToAccount, generatePrivateKey } from 'viem/accounts';
8
- import { createDocument } from 'zod-openapi';
8
+ import { Base64 } from 'js-base64';
9
9
 
10
10
  var __defProp = Object.defineProperty;
11
11
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -15,7 +15,7 @@ var __export = (target, all) => {
15
15
  };
16
16
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
17
17
 
18
- // src/api/Api/Schema/index.ts
18
+ // src/api/Schema/index.ts
19
19
  var Schema_exports = {};
20
20
  __export(Schema_exports, {
21
21
  ChainHealth: () => ChainHealth,
@@ -37,27 +37,89 @@ var CollectorHealth = z.object({
37
37
  lag: z.number().nullable(),
38
38
  status: z.enum(["live", "lagging", "unknown"])
39
39
  });
40
- var CollectorsHealthResponse = z.object({
41
- collectors: z.array(CollectorHealth)
42
- });
40
+ var CollectorsHealthResponse = z.array(CollectorHealth);
43
41
  var ChainHealth = z.object({
44
42
  chain_id: z.number(),
45
43
  block_number: z.number(),
46
44
  updated_at: z.string()
47
45
  });
48
- var ChainsHealthResponse = z.object({
49
- chains: z.array(ChainHealth)
50
- });
46
+ var ChainsHealthResponse = z.array(ChainHealth);
51
47
  var RouterStatusResponse = z.object({
52
48
  status: z.enum(["live", "syncing"])
53
49
  });
54
50
 
55
- // src/api/Api/Schema/ObligationResponse.ts
51
+ // src/api/Schema/ObligationResponse.ts
56
52
  var ObligationResponse_exports = {};
57
53
  __export(ObligationResponse_exports, {
58
- from: () => from6
54
+ from: () => from
59
55
  });
60
56
 
57
+ // src/utils/Format.ts
58
+ var Format_exports = {};
59
+ __export(Format_exports, {
60
+ fromSnakeCase: () => fromSnakeCase,
61
+ toSnakeCase: () => toSnakeCase
62
+ });
63
+ function toSnakeCase(obj) {
64
+ return stringifyBigint(
65
+ processObject(
66
+ obj,
67
+ (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`),
68
+ (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? getAddress(value.toLowerCase()) : value
69
+ )
70
+ );
71
+ }
72
+ function fromSnakeCase(obj) {
73
+ return processObject(
74
+ obj,
75
+ (s) => isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()),
76
+ (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? value.toLowerCase() : value
77
+ );
78
+ }
79
+ function processObject(obj, fnKey, fnValue) {
80
+ if (typeof obj !== "object" || obj === null) return obj;
81
+ if (Array.isArray(obj)) return obj.map((item) => processObject(item, fnKey, fnValue));
82
+ return Object.entries(obj).reduce(
83
+ (acc, [key, value]) => {
84
+ const newKey = fnKey(key);
85
+ acc[newKey] = typeof value === "object" && value !== null ? processObject(value, fnKey, fnValue) : fnValue(value);
86
+ return acc;
87
+ },
88
+ {}
89
+ );
90
+ }
91
+ function stringifyBigint(value) {
92
+ if (typeof value === "bigint") return value.toString();
93
+ if (Array.isArray(value)) return value.map(stringifyBigint);
94
+ if (value && typeof value === "object") {
95
+ const out = {};
96
+ for (const [k, v] of Object.entries(value)) {
97
+ out[k] = stringifyBigint(v);
98
+ }
99
+ return out;
100
+ }
101
+ return value;
102
+ }
103
+
104
+ // src/api/Schema/ObligationResponse.ts
105
+ function from(obligation, quote) {
106
+ return toSnakeCase({
107
+ id: quote.obligationId,
108
+ ...obligation,
109
+ ask: quote.ask,
110
+ bid: quote.bid
111
+ });
112
+ }
113
+
114
+ // src/api/Schema/OfferResponse.ts
115
+ var OfferResponse_exports = {};
116
+ __export(OfferResponse_exports, {
117
+ from: () => from2
118
+ });
119
+ function from2(offer) {
120
+ return toSnakeCase(offer);
121
+ }
122
+
61
123
  // src/core/Abi.ts
62
124
  var Abi_exports = {};
63
125
  __export(Abi_exports, {
@@ -627,7 +689,7 @@ var Collateral_exports = {};
627
689
  __export(Collateral_exports, {
628
690
  CollateralSchema: () => CollateralSchema,
629
691
  CollateralsSchema: () => CollateralsSchema,
630
- from: () => from2
692
+ from: () => from4
631
693
  });
632
694
  var transformHex = (val, ctx) => {
633
695
  if (isHex(val)) return val;
@@ -657,11 +719,11 @@ __export(LLTV_exports, {
657
719
  InvalidOptionError: () => InvalidOptionError,
658
720
  LLTVSchema: () => LLTVSchema,
659
721
  Options: () => Options,
660
- from: () => from
722
+ from: () => from3
661
723
  });
662
724
  var Options = [0.385, 0.5, 0.625, 0.77, 0.86, 0.915, 0.945, 0.965, 0.98];
663
725
  var LLTV_SCALED = Options.map((lltv) => BigInt(lltv * 10 ** 18));
664
- function from(lltv) {
726
+ function from3(lltv) {
665
727
  if (typeof lltv === "bigint" && !LLTV_SCALED.includes(lltv)) throw new InvalidLLTVError(lltv);
666
728
  if (typeof lltv === "bigint") return lltv;
667
729
  if (typeof lltv === "number" && !Options.includes(lltv)) throw new InvalidOptionError(lltv);
@@ -690,7 +752,7 @@ var InvalidLLTVError = class extends BaseError {
690
752
  var LLTVSchema = z7.bigint({ coerce: true }).refine(
691
753
  (lltv) => {
692
754
  try {
693
- from(lltv);
755
+ from3(lltv);
694
756
  return true;
695
757
  } catch (_) {
696
758
  return false;
@@ -701,7 +763,7 @@ var LLTVSchema = z7.bigint({ coerce: true }).refine(
701
763
  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)";
702
764
  }
703
765
  }
704
- ).transform((lltv) => from(lltv));
766
+ ).transform((lltv) => from3(lltv));
705
767
 
706
768
  // src/core/Collateral.ts
707
769
  var CollateralSchema = z7.object({
@@ -737,105 +799,14 @@ var CollateralsSchema = z7.array(CollateralSchema).min(1, { message: "At least o
737
799
  message: "Collaterals must not contain duplicate assets"
738
800
  }
739
801
  );
740
- var from2 = (parameters) => {
802
+ var from4 = (parameters) => {
741
803
  return {
742
804
  asset: parameters.asset.toLowerCase(),
743
- lltv: from(parameters.lltv),
805
+ lltv: from3(parameters.lltv),
744
806
  oracle: parameters.oracle.toLowerCase()
745
807
  };
746
808
  };
747
809
 
748
- // src/core/Cursor.ts
749
- var Cursor_exports = {};
750
- __export(Cursor_exports, {
751
- decode: () => decode,
752
- encode: () => encode,
753
- validate: () => validate
754
- });
755
- function validate(cursor) {
756
- if (!cursor || typeof cursor !== "object") {
757
- throw new Error("Cursor must be an object");
758
- }
759
- const c = cursor;
760
- if (!["rate", "maturity", "expiry", "amount"].includes(c.sort)) {
761
- throw new Error(
762
- `Invalid sort field: ${c.sort}. Must be one of: rate, maturity, expiry, amount`
763
- );
764
- }
765
- if (!["asc", "desc"].includes(c.dir)) {
766
- throw new Error(`Invalid direction: ${c.dir}. Must be one of: asc, desc`);
767
- }
768
- if (!/^0x[a-fA-F0-9]{64}$/.test(c.hash)) {
769
- throw new Error(
770
- `Invalid hash format: ${c.hash}. Must be a 64-character hex string starting with 0x`
771
- );
772
- }
773
- const validations = {
774
- rate: {
775
- field: "rate",
776
- type: "string",
777
- pattern: /^\d+$/,
778
- error: "numeric string"
779
- },
780
- amount: {
781
- field: "assets",
782
- type: "string",
783
- pattern: /^\d+$/,
784
- error: "numeric string"
785
- },
786
- maturity: {
787
- field: "maturity",
788
- type: "number",
789
- validator: (val) => val > 0,
790
- error: "positive number"
791
- },
792
- expiry: {
793
- field: "expiry",
794
- type: "number",
795
- validator: (val) => val > 0,
796
- error: "positive number"
797
- }
798
- };
799
- const validation = validations[c.sort];
800
- if (!validation) {
801
- throw new Error(`Invalid sort field: ${c.sort}`);
802
- }
803
- const fieldValue = c[validation.field];
804
- if (!fieldValue) {
805
- throw new Error(`${c.sort} sort requires '${validation.field}' field to be present`);
806
- }
807
- if (typeof fieldValue !== validation.type) {
808
- throw new Error(
809
- `${c.sort} sort requires '${validation.field}' field of type ${validation.type}`
810
- );
811
- }
812
- if (validation.pattern && !validation.pattern.test(fieldValue)) {
813
- throw new Error(
814
- `Invalid ${validation.field} format: ${fieldValue}. Must be a ${validation.error}`
815
- );
816
- }
817
- if (validation.validator && !validation.validator(fieldValue)) {
818
- throw new Error(
819
- `Invalid ${validation.field} value: ${fieldValue}. Must be a ${validation.error}`
820
- );
821
- }
822
- if (c.page !== void 0) {
823
- if (typeof c.page !== "number" || !Number.isInteger(c.page) || c.page < 1) {
824
- throw new Error("Invalid page: must be a positive integer");
825
- }
826
- }
827
- return true;
828
- }
829
- function encode(c) {
830
- return Base64.encodeURL(JSON.stringify(c));
831
- }
832
- function decode(token) {
833
- if (!token) return null;
834
- const decoded = JSON.parse(Base64.decode(token));
835
- validate(decoded);
836
- return decoded;
837
- }
838
-
839
810
  // src/core/Liquidity.ts
840
811
  var Liquidity_exports = {};
841
812
  __export(Liquidity_exports, {
@@ -901,12 +872,12 @@ __export(Maturity_exports, {
901
872
  InvalidFormatError: () => InvalidFormatError,
902
873
  InvalidOptionError: () => InvalidOptionError2,
903
874
  MaturitySchema: () => MaturitySchema,
904
- from: () => from3
875
+ from: () => from5
905
876
  });
906
877
  var MaturitySchema = z7.number().int().refine(
907
878
  (maturity) => {
908
879
  try {
909
- from3(maturity);
880
+ from5(maturity);
910
881
  return true;
911
882
  } catch (_e) {
912
883
  return false;
@@ -931,7 +902,7 @@ var MaturityOptions = {
931
902
  end_of_quarter: () => endOfQuarter(),
932
903
  end_of_next_quarter: () => endOfNextQuarter()
933
904
  };
934
- function from3(ts) {
905
+ function from5(ts) {
935
906
  if (typeof ts === "string") {
936
907
  if (ts in MaturityOptions) return MaturityOptions[ts]();
937
908
  throw new InvalidOptionError2(ts);
@@ -1009,71 +980,22 @@ __export(Obligation_exports, {
1009
980
  CollateralsAreNotSortedError: () => CollateralsAreNotSortedError,
1010
981
  InvalidObligationError: () => InvalidObligationError,
1011
982
  ObligationSchema: () => ObligationSchema,
1012
- from: () => from4,
983
+ from: () => from6,
1013
984
  fromSnakeCase: () => fromSnakeCase2,
1014
985
  id: () => id,
1015
986
  random: () => random
1016
987
  });
1017
-
1018
- // src/utils/Format.ts
1019
- var Format_exports = {};
1020
- __export(Format_exports, {
1021
- fromSnakeCase: () => fromSnakeCase,
1022
- toSnakeCase: () => toSnakeCase
1023
- });
1024
- function toSnakeCase(obj) {
1025
- return stringifyBigint(
1026
- processObject(
1027
- obj,
1028
- (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`),
1029
- (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? getAddress(value.toLowerCase()) : value
1030
- )
1031
- );
1032
- }
1033
- function fromSnakeCase(obj) {
1034
- return processObject(
1035
- obj,
1036
- (s) => isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()),
1037
- (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? value.toLowerCase() : value
1038
- );
1039
- }
1040
- function processObject(obj, fnKey, fnValue) {
1041
- if (typeof obj !== "object" || obj === null) return obj;
1042
- if (Array.isArray(obj)) return obj.map((item) => processObject(item, fnKey, fnValue));
1043
- return Object.entries(obj).reduce(
1044
- (acc, [key, value]) => {
1045
- const newKey = fnKey(key);
1046
- acc[newKey] = typeof value === "object" && value !== null ? processObject(value, fnKey, fnValue) : fnValue(value);
1047
- return acc;
1048
- },
1049
- {}
1050
- );
1051
- }
1052
- function stringifyBigint(value) {
1053
- if (typeof value === "bigint") return value.toString();
1054
- if (Array.isArray(value)) return value.map(stringifyBigint);
1055
- if (value && typeof value === "object") {
1056
- const out = {};
1057
- for (const [k, v] of Object.entries(value)) {
1058
- out[k] = stringifyBigint(v);
1059
- }
1060
- return out;
1061
- }
1062
- return value;
1063
- }
1064
-
1065
- // src/core/Obligation.ts
1066
988
  var ObligationSchema = z7.object({
1067
989
  chainId: z7.bigint({ coerce: true }).min(0n).max(maxUint256),
1068
990
  loanToken: z7.string().transform(transformAddress),
1069
991
  collaterals: CollateralsSchema,
1070
992
  maturity: MaturitySchema
1071
993
  });
1072
- function from4(parameters) {
994
+ function from6(parameters) {
1073
995
  try {
1074
996
  const parsedObligation = ObligationSchema.parse({
1075
997
  ...parameters,
1076
- maturity: from3(parameters.maturity)
998
+ maturity: from5(parameters.maturity)
1077
999
  });
1078
1000
  return {
1079
1001
  chainId: parsedObligation.chainId,
@@ -1086,7 +1008,7 @@ function from4(parameters) {
1086
1008
  }
1087
1009
  }
1088
1010
  function fromSnakeCase2(input) {
1089
- return from4(fromSnakeCase(input));
1011
+ return from6(fromSnakeCase(input));
1090
1012
  }
1091
1013
  function id(obligation) {
1092
1014
  let lastAsset = "";
@@ -1124,17 +1046,17 @@ function id(obligation) {
1124
1046
  );
1125
1047
  }
1126
1048
  function random() {
1127
- return from4({
1049
+ return from6({
1128
1050
  chainId: 1n,
1129
1051
  loanToken: privateKeyToAccount(generatePrivateKey()).address,
1130
1052
  collaterals: [
1131
- from2({
1053
+ from4({
1132
1054
  asset: privateKeyToAccount(generatePrivateKey()).address,
1133
1055
  oracle: privateKeyToAccount(generatePrivateKey()).address,
1134
1056
  lltv: 0.965
1135
1057
  })
1136
1058
  ],
1137
- maturity: from3("end_of_next_quarter")
1059
+ maturity: from5("end_of_next_quarter")
1138
1060
  });
1139
1061
  }
1140
1062
  var InvalidObligationError = class extends BaseError {
@@ -1158,10 +1080,10 @@ __export(Offer_exports, {
1158
1080
  OfferHashSchema: () => OfferHashSchema,
1159
1081
  OfferSchema: () => OfferSchema,
1160
1082
  consumedEvent: () => consumedEvent,
1161
- decode: () => decode2,
1083
+ decode: () => decode,
1162
1084
  domain: () => domain,
1163
- encode: () => encode2,
1164
- from: () => from5,
1085
+ encode: () => encode,
1086
+ from: () => from7,
1165
1087
  fromConsumedLog: () => fromConsumedLog,
1166
1088
  fromSnakeCase: () => fromSnakeCase3,
1167
1089
  hash: () => hash,
@@ -1330,7 +1252,7 @@ var OfferSchema = (parameters) => {
1330
1252
  path: ["expiry"]
1331
1253
  });
1332
1254
  };
1333
- function from5(input) {
1255
+ function from7(input) {
1334
1256
  try {
1335
1257
  const parsedOffer = OfferSchema({ omitHash: true }).parse(input);
1336
1258
  const parsedHash = OfferHashSchema.parse(hash(parsedOffer));
@@ -1343,17 +1265,17 @@ function from5(input) {
1343
1265
  }
1344
1266
  }
1345
1267
  function fromSnakeCase3(input) {
1346
- return from5(fromSnakeCase(input));
1268
+ return from7(fromSnakeCase(input));
1347
1269
  }
1348
1270
  function toSnakeCase2(offer) {
1349
1271
  return toSnakeCase(offer);
1350
1272
  }
1351
1273
  function random2() {
1352
1274
  const loanToken = privateKeyToAccount(generatePrivateKey()).address;
1353
- const maturity = from3("end_of_month");
1354
- const expiry = from3("end_of_week") - 1;
1355
- const lltv = from(0.965);
1356
- const offer = from5({
1275
+ const maturity = from5("end_of_month");
1276
+ const expiry = from5("end_of_week") - 1;
1277
+ const lltv = from3(0.965);
1278
+ const offer = from7({
1357
1279
  offering: privateKeyToAccount(generatePrivateKey()).address,
1358
1280
  assets: BigInt(Math.floor(Math.random() * 1e6)),
1359
1281
  rate: BigInt(Math.floor(Math.random() * 1e6)),
@@ -1365,7 +1287,7 @@ function random2() {
1365
1287
  chainId: 1n,
1366
1288
  loanToken,
1367
1289
  collaterals: [
1368
- from2({
1290
+ from4({
1369
1291
  asset: zeroAddress,
1370
1292
  oracle: zeroAddress,
1371
1293
  lltv
@@ -1463,7 +1385,7 @@ function hash(offer) {
1463
1385
  }
1464
1386
  function obligationId(offer) {
1465
1387
  return id(
1466
- from4({
1388
+ from6({
1467
1389
  chainId: offer.chainId,
1468
1390
  loanToken: offer.loanToken,
1469
1391
  collaterals: offer.collaterals,
@@ -1502,7 +1424,7 @@ var OfferAbi = [
1502
1424
  },
1503
1425
  { name: "signature", type: "bytes" }
1504
1426
  ];
1505
- function encode2(offer) {
1427
+ function encode(offer) {
1506
1428
  return encodeAbiParameters(OfferAbi, [
1507
1429
  offer.offering,
1508
1430
  offer.assets,
@@ -1519,18 +1441,18 @@ function encode2(offer) {
1519
1441
  offer.signature ?? "0x"
1520
1442
  ]);
1521
1443
  }
1522
- function decode2(data, blockNumber) {
1444
+ function decode(data, blockNumber) {
1523
1445
  let decoded;
1524
1446
  try {
1525
1447
  decoded = decodeAbiParameters(OfferAbi, data);
1526
1448
  } catch (error) {
1527
1449
  throw new InvalidOfferError(error);
1528
1450
  }
1529
- const offer = from5({
1451
+ const offer = from7({
1530
1452
  offering: decoded[0],
1531
1453
  assets: decoded[1],
1532
1454
  rate: decoded[2],
1533
- maturity: from3(Number(decoded[3])),
1455
+ maturity: from5(Number(decoded[3])),
1534
1456
  expiry: Number(decoded[4]),
1535
1457
  nonce: decoded[5],
1536
1458
  buy: decoded[6],
@@ -1538,7 +1460,7 @@ function decode2(data, blockNumber) {
1538
1460
  loanToken: decoded[8],
1539
1461
  start: Number(decoded[9]),
1540
1462
  collaterals: decoded[10].map((c) => {
1541
- return from2({
1463
+ return from4({
1542
1464
  asset: c.asset,
1543
1465
  oracle: c.oracle,
1544
1466
  lltv: c.lltv
@@ -1589,22 +1511,152 @@ var AccountNotSetError = class extends BaseError {
1589
1511
  }
1590
1512
  };
1591
1513
 
1514
+ // src/core/Quote.ts
1515
+ var Quote_exports = {};
1516
+ __export(Quote_exports, {
1517
+ InvalidQuoteError: () => InvalidQuoteError,
1518
+ QuoteSchema: () => QuoteSchema,
1519
+ from: () => from8,
1520
+ fromSnakeCase: () => fromSnakeCase4,
1521
+ random: () => random3
1522
+ });
1523
+ var QuoteSchema = z7.object({
1524
+ obligationId: z7.string().transform(transformHex),
1525
+ ask: z7.object({
1526
+ rate: z7.bigint({ coerce: true }).min(0n).max(maxUint256)
1527
+ }),
1528
+ bid: z7.object({
1529
+ rate: z7.bigint({ coerce: true }).min(0n).max(maxUint256)
1530
+ })
1531
+ });
1532
+ function from8(parameters) {
1533
+ try {
1534
+ const parsedQuote = QuoteSchema.parse(parameters);
1535
+ return {
1536
+ obligationId: parsedQuote.obligationId,
1537
+ ask: parsedQuote.ask,
1538
+ bid: parsedQuote.bid
1539
+ };
1540
+ } catch (error) {
1541
+ throw new InvalidQuoteError(error);
1542
+ }
1543
+ }
1544
+ function fromSnakeCase4(snake) {
1545
+ return from8(fromSnakeCase(snake));
1546
+ }
1547
+ function random3() {
1548
+ return from8({
1549
+ obligationId: Obligation_exports.id(Obligation_exports.random()),
1550
+ ask: {
1551
+ rate: BigInt(Math.floor(Math.random() * 1e6))
1552
+ },
1553
+ bid: {
1554
+ rate: BigInt(Math.floor(Math.random() * 1e6))
1555
+ }
1556
+ });
1557
+ }
1558
+ var InvalidQuoteError = class extends BaseError {
1559
+ constructor(error) {
1560
+ super("Invalid quote.", { cause: error });
1561
+ __publicField(this, "name", "Quote.InvalidQuoteError");
1562
+ }
1563
+ };
1564
+
1592
1565
  // src/core/types.ts
1593
1566
  var BrandTypeId = Symbol.for("mempool/Brand");
1594
1567
 
1595
- // src/api/Api/Schema/ObligationResponse.ts
1596
- function from6(obligation) {
1597
- return toSnakeCase({ id: Obligation_exports.id(obligation), ...obligation });
1598
- }
1599
-
1600
- // src/api/Api/Schema/OfferResponse.ts
1601
- var OfferResponse_exports = {};
1602
- __export(OfferResponse_exports, {
1603
- from: () => from7
1568
+ // src/stores/utils/Cursor.ts
1569
+ var Cursor_exports = {};
1570
+ __export(Cursor_exports, {
1571
+ decode: () => decode2,
1572
+ encode: () => encode2,
1573
+ validate: () => validate
1604
1574
  });
1605
- function from7(offer) {
1606
- return toSnakeCase(offer);
1575
+ function validate(cursor) {
1576
+ if (!cursor || typeof cursor !== "object") {
1577
+ throw new Error("Cursor must be an object");
1578
+ }
1579
+ const c = cursor;
1580
+ if (!["rate", "maturity", "expiry", "amount"].includes(c.sort)) {
1581
+ throw new Error(
1582
+ `Invalid sort field: ${c.sort}. Must be one of: rate, maturity, expiry, amount`
1583
+ );
1584
+ }
1585
+ if (!["asc", "desc"].includes(c.dir)) {
1586
+ throw new Error(`Invalid direction: ${c.dir}. Must be one of: asc, desc`);
1587
+ }
1588
+ if (!/^0x[a-fA-F0-9]{64}$/.test(c.hash)) {
1589
+ throw new Error(
1590
+ `Invalid hash format: ${c.hash}. Must be a 64-character hex string starting with 0x`
1591
+ );
1592
+ }
1593
+ const validations = {
1594
+ rate: {
1595
+ field: "rate",
1596
+ type: "string",
1597
+ pattern: /^\d+$/,
1598
+ error: "numeric string"
1599
+ },
1600
+ amount: {
1601
+ field: "assets",
1602
+ type: "string",
1603
+ pattern: /^\d+$/,
1604
+ error: "numeric string"
1605
+ },
1606
+ maturity: {
1607
+ field: "maturity",
1608
+ type: "number",
1609
+ validator: (val) => val > 0,
1610
+ error: "positive number"
1611
+ },
1612
+ expiry: {
1613
+ field: "expiry",
1614
+ type: "number",
1615
+ validator: (val) => val > 0,
1616
+ error: "positive number"
1617
+ }
1618
+ };
1619
+ const validation = validations[c.sort];
1620
+ if (!validation) {
1621
+ throw new Error(`Invalid sort field: ${c.sort}`);
1622
+ }
1623
+ const fieldValue = c[validation.field];
1624
+ if (!fieldValue) {
1625
+ throw new Error(`${c.sort} sort requires '${validation.field}' field to be present`);
1626
+ }
1627
+ if (typeof fieldValue !== validation.type) {
1628
+ throw new Error(
1629
+ `${c.sort} sort requires '${validation.field}' field of type ${validation.type}`
1630
+ );
1631
+ }
1632
+ if (validation.pattern && !validation.pattern.test(fieldValue)) {
1633
+ throw new Error(
1634
+ `Invalid ${validation.field} format: ${fieldValue}. Must be a ${validation.error}`
1635
+ );
1636
+ }
1637
+ if (validation.validator && !validation.validator(fieldValue)) {
1638
+ throw new Error(
1639
+ `Invalid ${validation.field} value: ${fieldValue}. Must be a ${validation.error}`
1640
+ );
1641
+ }
1642
+ if (c.page !== void 0) {
1643
+ if (typeof c.page !== "number" || !Number.isInteger(c.page) || c.page < 1) {
1644
+ throw new Error("Invalid page: must be a positive integer");
1645
+ }
1646
+ }
1647
+ return true;
1648
+ }
1649
+ function encode2(c) {
1650
+ return Base64.encodeURL(JSON.stringify(c));
1607
1651
  }
1652
+ function decode2(token) {
1653
+ if (!token) return null;
1654
+ const decoded = JSON.parse(Base64.decode(token));
1655
+ validate(decoded);
1656
+ return decoded;
1657
+ }
1658
+
1659
+ // src/api/Schema/requests.ts
1608
1660
  var MAX_LIMIT = 100;
1609
1661
  var DEFAULT_LIMIT = 20;
1610
1662
  var PaginationQueryParams = z7.object({
@@ -1667,14 +1719,74 @@ function safeParse(action, query, error) {
1667
1719
  });
1668
1720
  }
1669
1721
 
1670
- // src/api/Api/Schema/openapi.ts
1671
- var successResponseSchema = z.object({
1672
- status: z.literal("success"),
1673
- cursor: z.string().nullable(),
1674
- data: z.array(z.any()),
1675
- meta: z.object({
1676
- timestamp: z.string()
1677
- })
1722
+ // src/api/Schema/openapi.ts
1723
+ var timestampExample = "2024-01-01T12:00:00.000Z";
1724
+ var cursorExample = "eyJvZmZzZXQiOjEwMH0";
1725
+ function makeSuccessResponse(parameters) {
1726
+ const { dataSchema, dataDescription, dataExample, cursor } = parameters;
1727
+ const withDataMeta = dataDescription ? dataSchema.meta({ description: dataDescription }) : dataSchema;
1728
+ return z.object({
1729
+ status: z.literal("success"),
1730
+ cursor: z.string().nullable(),
1731
+ data: z.any(),
1732
+ meta: z.object({
1733
+ timestamp: z.string()
1734
+ })
1735
+ }).extend({
1736
+ data: withDataMeta
1737
+ }).meta({
1738
+ example: {
1739
+ status: "success",
1740
+ cursor,
1741
+ data: dataExample,
1742
+ meta: { timestamp: timestampExample }
1743
+ }
1744
+ });
1745
+ }
1746
+ var OffersSuccessResponseSchema = makeSuccessResponse({
1747
+ dataSchema: z.array(z.any()),
1748
+ dataDescription: "Offers matching the provided filters.",
1749
+ dataExample: [toSnakeCase(Offer_exports.random())],
1750
+ cursor: cursorExample
1751
+ });
1752
+ var ObligationsSuccessResponseSchema = makeSuccessResponse({
1753
+ dataSchema: z.array(z.any()),
1754
+ dataDescription: "Obligations known to the router.",
1755
+ dataExample: [toSnakeCase(Obligation_exports.random())],
1756
+ cursor: cursorExample
1757
+ });
1758
+ var RouterStatusSuccessResponseSchema = makeSuccessResponse({
1759
+ dataSchema: RouterStatusResponse,
1760
+ dataDescription: "Aggregated router status.",
1761
+ dataExample: { status: "live" },
1762
+ cursor: null
1763
+ });
1764
+ var CollectorsHealthSuccessResponseSchema = makeSuccessResponse({
1765
+ dataSchema: CollectorsHealthResponse,
1766
+ dataDescription: "Collectors health details and sync status.",
1767
+ dataExample: [
1768
+ {
1769
+ name: "mempool_offers",
1770
+ chain_id: "1",
1771
+ block_number: 21345678,
1772
+ updated_at: "2024-01-01T12:00:00.000Z",
1773
+ lag: 0,
1774
+ status: "live"
1775
+ }
1776
+ ],
1777
+ cursor: null
1778
+ });
1779
+ var ChainsHealthSuccessResponseSchema = makeSuccessResponse({
1780
+ dataSchema: ChainsHealthResponse,
1781
+ dataDescription: "Latest processed block per chain.",
1782
+ dataExample: [
1783
+ {
1784
+ chain_id: "1",
1785
+ block_number: 21345678,
1786
+ updated_at: "2024-01-01T12:00:00.000Z"
1787
+ }
1788
+ ],
1789
+ cursor: null
1678
1790
  });
1679
1791
  var errorResponseSchema = z.object({
1680
1792
  status: z.literal("error"),
@@ -1686,6 +1798,24 @@ var errorResponseSchema = z.object({
1686
1798
  meta: z.object({
1687
1799
  timestamp: z.string()
1688
1800
  })
1801
+ }).meta({
1802
+ description: "Error response wrapper.",
1803
+ example: {
1804
+ status: "error",
1805
+ error: {
1806
+ code: "VALIDATION_ERROR",
1807
+ message: "Invalid cursor format. Must be a valid base64url-encoded cursor object",
1808
+ details: [
1809
+ {
1810
+ field: "cursor",
1811
+ issue: "Invalid cursor format. Must be a valid base64url-encoded cursor object"
1812
+ }
1813
+ ]
1814
+ },
1815
+ meta: {
1816
+ timestamp: timestampExample
1817
+ }
1818
+ }
1689
1819
  });
1690
1820
  var paths = {
1691
1821
  "/v1/offers": {
@@ -1701,7 +1831,7 @@ var paths = {
1701
1831
  description: "Success",
1702
1832
  content: {
1703
1833
  "application/json": {
1704
- schema: successResponseSchema
1834
+ schema: OffersSuccessResponseSchema
1705
1835
  }
1706
1836
  }
1707
1837
  },
@@ -1729,7 +1859,7 @@ var paths = {
1729
1859
  description: "Success",
1730
1860
  content: {
1731
1861
  "application/json": {
1732
- schema: successResponseSchema
1862
+ schema: ObligationsSuccessResponseSchema
1733
1863
  }
1734
1864
  }
1735
1865
  },
@@ -1754,7 +1884,7 @@ var paths = {
1754
1884
  description: "Success",
1755
1885
  content: {
1756
1886
  "application/json": {
1757
- schema: RouterStatusResponse
1887
+ schema: RouterStatusSuccessResponseSchema
1758
1888
  }
1759
1889
  }
1760
1890
  }
@@ -1771,7 +1901,7 @@ var paths = {
1771
1901
  description: "Success",
1772
1902
  content: {
1773
1903
  "application/json": {
1774
- schema: CollectorsHealthResponse
1904
+ schema: CollectorsHealthSuccessResponseSchema
1775
1905
  }
1776
1906
  }
1777
1907
  }
@@ -1788,7 +1918,7 @@ var paths = {
1788
1918
  description: "Success",
1789
1919
  content: {
1790
1920
  "application/json": {
1791
- schema: ChainsHealthResponse
1921
+ schema: ChainsHealthSuccessResponseSchema
1792
1922
  }
1793
1923
  }
1794
1924
  }
@@ -1820,14 +1950,14 @@ var OpenApi = createDocument({
1820
1950
  description: "Production server"
1821
1951
  },
1822
1952
  {
1823
- url: "http://localhost:8081",
1953
+ url: "http://localhost:7891",
1824
1954
  description: "Local development server"
1825
1955
  }
1826
1956
  ],
1827
1957
  paths
1828
1958
  });
1829
1959
 
1830
- // src/api/Client.ts
1960
+ // src/client/Client.ts
1831
1961
  var Client_exports = {};
1832
1962
  __export(Client_exports, {
1833
1963
  HttpForbiddenError: () => HttpForbiddenError,
@@ -1882,8 +2012,16 @@ async function getObligations(config, parameters) {
1882
2012
  if (parameters?.limit !== void 0) {
1883
2013
  url.searchParams.set("limit", parameters.limit.toString());
1884
2014
  }
1885
- const { cursor: returnedCursor, data: obligationsSnake } = await getApi(config, url);
1886
- const obligations = obligationsSnake.map(Obligation_exports.fromSnakeCase);
2015
+ const { cursor: returnedCursor, data: items } = await getApi(config, url);
2016
+ const obligations = items.map((item) => {
2017
+ const obligation = Obligation_exports.fromSnakeCase(item);
2018
+ const { obligationId: _, ...returned } = {
2019
+ id: () => Obligation_exports.id(obligation),
2020
+ ...obligation,
2021
+ ...Quote_exports.fromSnakeCase({ obligation_id: item.id, ask: item.ask, bid: item.bid })
2022
+ };
2023
+ return returned;
2024
+ });
1887
2025
  return {
1888
2026
  cursor: returnedCursor,
1889
2027
  obligations
@@ -2281,7 +2419,7 @@ __export(MempoolClient_exports, {
2281
2419
  });
2282
2420
  var DEFAULT_BATCH_SIZE2 = 100;
2283
2421
  var DEFAULT_BLOCK_WINDOW2 = 100;
2284
- function from8(parameters) {
2422
+ function from9(parameters) {
2285
2423
  const config = {
2286
2424
  client: parameters.client,
2287
2425
  mempoolAddress: parameters.mempoolAddress,
@@ -2426,9 +2564,9 @@ var ChainIdMismatchError = class extends BaseError {
2426
2564
 
2427
2565
  // src/mempool/MempoolClient.ts
2428
2566
  function connect2(parameters) {
2429
- return from8(parameters);
2567
+ return from9(parameters);
2430
2568
  }
2431
2569
 
2432
- export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, Collateral_exports as Collateral, Cursor_exports as Cursor, Errors_exports as Errors, Format_exports as Format, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Maturity_exports as Maturity, MempoolClient_exports as Mempool, Obligation_exports as Obligation, Offer_exports as Offer, Schema_exports as RouterApi, Client_exports as RouterClient, time_exports as Time, utils_exports as Utils, Validation_exports as Validation, ValidationRule_exports as ValidationRule };
2570
+ export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, Collateral_exports as Collateral, Cursor_exports as Cursor, Errors_exports as Errors, Format_exports as Format, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Maturity_exports as Maturity, MempoolClient_exports as Mempool, Obligation_exports as Obligation, Offer_exports as Offer, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports as RouterClient, time_exports as Time, utils_exports as Utils, Validation_exports as Validation, ValidationRule_exports as ValidationRule };
2433
2571
  //# sourceMappingURL=index.browser.mjs.map
2434
2572
  //# sourceMappingURL=index.browser.mjs.map