@morpho-dev/router 0.7.0 → 0.7.1

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.
@@ -253,107 +253,14 @@ const Morpho = [
253
253
  //#region src/core/Callback.ts
254
254
  var Callback_exports = /* @__PURE__ */ __exportAll({
255
255
  Type: () => Type$1,
256
- decode: () => decode$2,
257
- decodeBuyERC20: () => decodeBuyERC20,
258
- decodeBuyVaultV1Callback: () => decodeBuyVaultV1Callback,
259
- decodeSellERC20Callback: () => decodeSellERC20Callback,
260
- encode: () => encode$2,
261
- encodeBuyERC20: () => encodeBuyERC20,
262
- encodeBuyVaultV1Callback: () => encodeBuyVaultV1Callback,
263
- encodeSellERC20Callback: () => encodeSellERC20Callback,
264
256
  isEmptyCallback: () => isEmptyCallback
265
257
  });
266
258
  let Type$1 = /* @__PURE__ */ function(Type) {
267
259
  Type["BuyWithEmptyCallback"] = "buy_with_empty_callback";
268
- Type["BuyERC20"] = "buy_erc20";
269
- Type["BuyVaultV1Callback"] = "buy_vault_v1_callback";
270
- Type["SellERC20Callback"] = "sell_erc20_callback";
260
+ Type["SellWithEmptyCallback"] = "sell_with_empty_callback";
271
261
  return Type;
272
262
  }({});
273
263
  const isEmptyCallback = (offer) => offer.callback.data === "0x";
274
- function decode$2(type, data) {
275
- switch (type) {
276
- case Type$1.BuyERC20: return decodeBuyERC20(data);
277
- case Type$1.BuyVaultV1Callback: return decodeBuyVaultV1Callback(data);
278
- case Type$1.SellERC20Callback: return decodeSellERC20Callback(data);
279
- default: throw new Error("Invalid callback type");
280
- }
281
- }
282
- function encode$2(type, data) {
283
- switch (type) {
284
- case Type$1.BuyERC20:
285
- if (!("tokens" in data)) throw new Error("Invalid callback data");
286
- return encodeBuyERC20(data);
287
- case Type$1.BuyVaultV1Callback:
288
- if (!("vaults" in data)) throw new Error("Invalid callback data");
289
- return encodeBuyVaultV1Callback(data);
290
- case Type$1.SellERC20Callback:
291
- if (!("collaterals" in data)) throw new Error("Invalid callback data");
292
- return encodeSellERC20Callback(data);
293
- default: throw new Error("Invalid callback type");
294
- }
295
- }
296
- /**
297
- * Decodes BuyERC20 callback data into positions.
298
- * @param data - The ABI-encoded callback data containing token addresses and amounts.
299
- * @returns Array of positions with contract address and amount.
300
- * @throws If data is empty, malformed, or arrays have mismatched lengths.
301
- */
302
- function decodeBuyERC20(data) {
303
- if (!data || data === "0x") throw new Error("Empty callback data");
304
- let tokens;
305
- let amounts;
306
- try {
307
- [tokens, amounts] = decodeAbiParameters([{ type: "address[]" }, { type: "uint256[]" }], data);
308
- } catch (_) {
309
- throw new Error("Invalid BuyERC20 callback data");
310
- }
311
- if (tokens.length !== amounts.length) throw new Error("Mismatched array lengths");
312
- return tokens.map((token, index) => ({
313
- contract: token,
314
- amount: amounts[index]
315
- }));
316
- }
317
- /**
318
- * Encodes BuyERC20 callback parameters into ABI-encoded data.
319
- * @param parameters - The tokens and amounts to encode.
320
- * @returns ABI-encoded hex string.
321
- */
322
- function encodeBuyERC20(parameters) {
323
- return encodeAbiParameters([{ type: "address[]" }, { type: "uint256[]" }], [parameters.tokens, parameters.amounts]);
324
- }
325
- function decodeBuyVaultV1Callback(data) {
326
- if (!data || data === "0x") throw new Error("Empty callback data");
327
- try {
328
- const [vaults, amounts] = decodeAbiParameters([{ type: "address[]" }, { type: "uint256[]" }], data);
329
- if (vaults.length !== amounts.length) throw new Error("Mismatched array lengths");
330
- return vaults.map((v, i) => ({
331
- contract: v,
332
- amount: amounts[i]
333
- }));
334
- } catch (_) {
335
- throw new Error("Invalid BuyVaultV1Callback callback data");
336
- }
337
- }
338
- function decodeSellERC20Callback(data) {
339
- if (!data || data === "0x") throw new Error("Empty callback data");
340
- try {
341
- const [collaterals, amounts] = decodeAbiParameters([{ type: "address[]" }, { type: "uint256[]" }], data);
342
- if (collaterals.length !== amounts.length) throw new Error("Mismatched array lengths");
343
- return collaterals.map((c, i) => ({
344
- contract: c,
345
- amount: amounts[i]
346
- }));
347
- } catch (_) {
348
- throw new Error("Invalid SellERC20Callback callback data");
349
- }
350
- }
351
- function encodeBuyVaultV1Callback(parameters) {
352
- return encodeAbiParameters([{ type: "address[]" }, { type: "uint256[]" }], [parameters.vaults, parameters.amounts]);
353
- }
354
- function encodeSellERC20Callback(parameters) {
355
- return encodeAbiParameters([{ type: "address[]" }, { type: "uint256[]" }], [parameters.collaterals, parameters.amounts]);
356
- }
357
264
 
358
265
  //#endregion
359
266
  //#region src/utils/BigMath.ts
@@ -1109,11 +1016,9 @@ var Liquidity_exports = /* @__PURE__ */ __exportAll({
1109
1016
  calculateMaxDebt: () => calculateMaxDebt,
1110
1017
  generateAllowancePoolId: () => generateAllowancePoolId,
1111
1018
  generateBalancePoolId: () => generateBalancePoolId,
1112
- generateBuyVaultCallbackPoolId: () => generateBuyVaultCallbackPoolId,
1113
1019
  generateDebtPoolId: () => generateDebtPoolId,
1114
1020
  generateMarketLiquidityPoolId: () => generateMarketLiquidityPoolId,
1115
1021
  generateObligationCollateralPoolId: () => generateObligationCollateralPoolId,
1116
- generateSellERC20CallbackPoolId: () => generateSellERC20CallbackPoolId,
1117
1022
  generateUserVaultPositionPoolId: () => generateUserVaultPositionPoolId,
1118
1023
  generateVaultPositionPoolId: () => generateVaultPositionPoolId
1119
1024
  });
@@ -1142,14 +1047,6 @@ function generateAllowancePoolId(parameters) {
1142
1047
  return `${user}-${chainId.toString()}-${token}-allowance`.toLowerCase();
1143
1048
  }
1144
1049
  /**
1145
- * Generate pool ID for sell ERC20 callback pools.
1146
- * Each offer has its own callback pool to prevent liquidity conflicts.
1147
- */
1148
- function generateSellERC20CallbackPoolId(parameters) {
1149
- const { user, chainId, obligationId, token, offerHash } = parameters;
1150
- return `${user}-${chainId.toString()}-${obligationId}-${token}-${offerHash}-sell_erc20_callback`.toLowerCase();
1151
- }
1152
- /**
1153
1050
  * Generate pool ID for obligation collateral pools.
1154
1051
  * Obligation collateral pools represent collateral already deposited in the obligation.
1155
1052
  * These pools are shared across all offers with the same obligation.
@@ -1159,13 +1056,6 @@ function generateObligationCollateralPoolId(parameters) {
1159
1056
  return `${user}-${chainId.toString()}-${obligationId}-${token}-obligation-collateral`.toLowerCase();
1160
1057
  }
1161
1058
  /**
1162
- * Generate pool ID for buy vault callback pools.
1163
- */
1164
- function generateBuyVaultCallbackPoolId(parameters) {
1165
- const { user, chainId, vault, offerHash } = parameters;
1166
- return `${user}-${chainId.toString()}-${vault}-${offerHash}-${Type$1.BuyVaultV1Callback}`.toLowerCase();
1167
- }
1168
- /**
1169
1059
  * Generate pool ID for debt pools.
1170
1060
  */
1171
1061
  function generateDebtPoolId(parameters) {
@@ -1545,6 +1435,7 @@ var Offer_exports = /* @__PURE__ */ __exportAll({
1545
1435
  obligationId: () => obligationId,
1546
1436
  random: () => random$1,
1547
1437
  serialize: () => serialize,
1438
+ takeEvent: () => takeEvent,
1548
1439
  toSnakeCase: () => toSnakeCase,
1549
1440
  types: () => types
1550
1441
  });
@@ -1663,7 +1554,7 @@ function random$1(config) {
1663
1554
  const chain = config?.chains ? config.chains[int(config.chains.length)] : chains$1.ethereum;
1664
1555
  const loanToken = config?.loanTokens ? config.loanTokens[int(config.loanTokens.length)] : address();
1665
1556
  const collateralCandidates = config?.collateralTokens ? config.collateralTokens.filter((a) => a !== loanToken) : [address()];
1666
- const collateralAsset = collateralCandidates[int(collateralCandidates.length)];
1557
+ collateralCandidates[int(collateralCandidates.length)];
1667
1558
  const maturityOption = weightedChoice([["end_of_month", 1], ["end_of_next_month", 1]]);
1668
1559
  const maturity = config?.maturity ?? from$11(maturityOption);
1669
1560
  const lltv = from$13(weightedChoice([
@@ -1690,21 +1581,10 @@ function random$1(config) {
1690
1581
  const unit = BigInt(10) ** BigInt(loanTokenDecimals);
1691
1582
  const amountBase = BigInt(100 + int(999901));
1692
1583
  const assetsScaled = config?.assets ?? amountBase * unit;
1693
- const callbackBySide = (() => {
1694
- if (buy) return {
1695
- address: zeroAddress,
1696
- data: "0x"
1697
- };
1698
- const sellCallbackAddress = "0x3333333333333333333333333333333333333333";
1699
- const amount = assetsScaled * 1000000000000000000000n;
1700
- return {
1701
- address: sellCallbackAddress,
1702
- data: encodeSellERC20Callback({
1703
- collaterals: [collateralAsset],
1704
- amounts: [amount]
1705
- })
1706
- };
1707
- })();
1584
+ const emptyCallback = {
1585
+ address: zeroAddress,
1586
+ data: "0x"
1587
+ };
1708
1588
  return from$9({
1709
1589
  maker: config?.maker ?? address(),
1710
1590
  assets: assetsScaled,
@@ -1723,7 +1603,7 @@ function random$1(config) {
1723
1603
  ...random$3(),
1724
1604
  lltv
1725
1605
  })).sort((a, b) => a.asset.localeCompare(b.asset)),
1726
- callback: config?.callback ?? callbackBySide
1606
+ callback: config?.callback ?? emptyCallback
1727
1607
  });
1728
1608
  }
1729
1609
  const weightedChoice = (pairs) => {
@@ -2013,6 +1893,94 @@ function decode$1(data) {
2013
1893
  });
2014
1894
  }
2015
1895
  /**
1896
+ * ABI for the Take event emitted by the Morpho V2 contract.
1897
+ */
1898
+ const takeEvent = {
1899
+ type: "event",
1900
+ name: "Take",
1901
+ inputs: [
1902
+ {
1903
+ name: "caller",
1904
+ type: "address",
1905
+ indexed: false,
1906
+ internalType: "address"
1907
+ },
1908
+ {
1909
+ name: "id",
1910
+ type: "bytes32",
1911
+ indexed: true,
1912
+ internalType: "bytes32"
1913
+ },
1914
+ {
1915
+ name: "maker",
1916
+ type: "address",
1917
+ indexed: true,
1918
+ internalType: "address"
1919
+ },
1920
+ {
1921
+ name: "taker",
1922
+ type: "address",
1923
+ indexed: true,
1924
+ internalType: "address"
1925
+ },
1926
+ {
1927
+ name: "offerIsBuy",
1928
+ type: "bool",
1929
+ indexed: false,
1930
+ internalType: "bool"
1931
+ },
1932
+ {
1933
+ name: "buyerAssets",
1934
+ type: "uint256",
1935
+ indexed: false,
1936
+ internalType: "uint256"
1937
+ },
1938
+ {
1939
+ name: "sellerAssets",
1940
+ type: "uint256",
1941
+ indexed: false,
1942
+ internalType: "uint256"
1943
+ },
1944
+ {
1945
+ name: "obligationUnits",
1946
+ type: "uint256",
1947
+ indexed: false,
1948
+ internalType: "uint256"
1949
+ },
1950
+ {
1951
+ name: "obligationShares",
1952
+ type: "uint256",
1953
+ indexed: false,
1954
+ internalType: "uint256"
1955
+ },
1956
+ {
1957
+ name: "buyerIsLender",
1958
+ type: "bool",
1959
+ indexed: false,
1960
+ internalType: "bool"
1961
+ },
1962
+ {
1963
+ name: "sellerIsBorrower",
1964
+ type: "bool",
1965
+ indexed: false,
1966
+ internalType: "bool"
1967
+ },
1968
+ {
1969
+ name: "group",
1970
+ type: "bytes32",
1971
+ indexed: false,
1972
+ internalType: "bytes32"
1973
+ },
1974
+ {
1975
+ name: "consumed",
1976
+ type: "uint256",
1977
+ indexed: false,
1978
+ internalType: "uint256"
1979
+ }
1980
+ ],
1981
+ anonymous: false
1982
+ };
1983
+ /**
2016
1984
  * ABI for the Consume event emitted by the Obligation contract.
2017
1985
  */
2018
1986
  const consumedEvent = {
@@ -2867,8 +2835,8 @@ const offerExample = {
2867
2835
  price: "2750000000000000000",
2868
2836
  group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
2869
2837
  session: "0x0000000000000000000000000000000000000000000000000000000000000000",
2870
- callback: "0x1111111111111111111111111111111111111111",
2871
- callback_data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
2838
+ callback: "0x0000000000000000000000000000000000000000",
2839
+ callback_data: "0x"
2872
2840
  },
2873
2841
  offer_hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
2874
2842
  obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc",
@@ -2920,25 +2888,10 @@ const validateOfferExample = {
2920
2888
  lltv: "860000000000000000"
2921
2889
  }],
2922
2890
  callback: {
2923
- address: "0x1111111111111111111111111111111111111111",
2924
- data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
2891
+ address: "0x0000000000000000000000000000000000000000",
2892
+ data: "0x"
2925
2893
  }
2926
2894
  };
2927
- const callbackTypesRequestExample = { callbacks: [{
2928
- chain_id: 1,
2929
- addresses: [
2930
- "0x1111111111111111111111111111111111111111",
2931
- "0x3333333333333333333333333333333333333333",
2932
- "0x9999999999999999999999999999999999999999"
2933
- ]
2934
- }] };
2935
- const callbackTypesResponseExample = [{
2936
- chain_id: 1,
2937
- sell_erc20_callback: ["0x1111111111111111111111111111111111111111"],
2938
- buy_erc20: ["0x5555555555555555555555555555555555555555"],
2939
- buy_vault_v1_callback: ["0x3333333333333333333333333333333333333333"],
2940
- not_supported: ["0x9999999999999999999999999999999999999999"]
2941
- }];
2942
2895
  const routerStatusExample = {
2943
2896
  status: "live",
2944
2897
  initialized: true,
@@ -3007,55 +2960,6 @@ __decorate([ApiProperty({
3007
2960
  type: "string",
3008
2961
  example: validateOfferExample.callback.data
3009
2962
  })], ValidateCallbackRequest.prototype, "data", void 0);
3010
- var CallbackTypesChainRequest = class {};
3011
- __decorate([ApiProperty({
3012
- type: "number",
3013
- example: callbackTypesRequestExample.callbacks[0].chain_id
3014
- })], CallbackTypesChainRequest.prototype, "chain_id", void 0);
3015
- __decorate([ApiProperty({
3016
- type: () => [String],
3017
- example: callbackTypesRequestExample.callbacks[0].addresses
3018
- })], CallbackTypesChainRequest.prototype, "addresses", void 0);
3019
- var CallbackTypesRequest = class {};
3020
- __decorate([ApiProperty({
3021
- type: () => [CallbackTypesChainRequest],
3022
- example: callbackTypesRequestExample.callbacks
3023
- })], CallbackTypesRequest.prototype, "callbacks", void 0);
3024
- var CallbackTypesChainResponse = class {};
3025
- __decorate([ApiProperty({
3026
- type: "number",
3027
- example: callbackTypesResponseExample[0].chain_id
3028
- })], CallbackTypesChainResponse.prototype, "chain_id", void 0);
3029
- __decorate([ApiProperty({
3030
- type: () => [String],
3031
- required: false,
3032
- example: callbackTypesResponseExample[0].buy_vault_v1_callback
3033
- })], CallbackTypesChainResponse.prototype, "buy_vault_v1_callback", void 0);
3034
- __decorate([ApiProperty({
3035
- type: () => [String],
3036
- required: false,
3037
- example: callbackTypesResponseExample[0].sell_erc20_callback
3038
- })], CallbackTypesChainResponse.prototype, "sell_erc20_callback", void 0);
3039
- __decorate([ApiProperty({
3040
- type: () => [String],
3041
- required: false,
3042
- example: callbackTypesResponseExample[0].buy_erc20
3043
- })], CallbackTypesChainResponse.prototype, "buy_erc20", void 0);
3044
- __decorate([ApiProperty({
3045
- type: () => [String],
3046
- example: callbackTypesResponseExample[0].not_supported
3047
- })], CallbackTypesChainResponse.prototype, "not_supported", void 0);
3048
- var CallbackTypesSuccessResponse = class extends SuccessResponse {};
3049
- __decorate([ApiProperty({
3050
- type: "string",
3051
- nullable: true,
3052
- example: "maturity:1:1730415600:end_of_next_month"
3053
- })], CallbackTypesSuccessResponse.prototype, "cursor", void 0);
3054
- __decorate([ApiProperty({
3055
- type: () => [CallbackTypesChainResponse],
3056
- description: "Callback types grouped by chain.",
3057
- example: callbackTypesResponseExample
3058
- })], CallbackTypesSuccessResponse.prototype, "data", void 0);
3059
2963
  var AskResponse = class {};
3060
2964
  __decorate([ApiProperty({
3061
2965
  type: "string",
@@ -3573,7 +3477,7 @@ __decorate([
3573
3477
  methods: ["post"],
3574
3478
  path: "/v1/validate",
3575
3479
  summary: "Validate offers",
3576
- description: "Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure."
3480
+ description: "Validates offers against router validation rules. Only empty callbacks (zero address, 0x data) are accepted. Returns unsigned payload + root on success, or issues only on validation failure."
3577
3481
  }),
3578
3482
  ApiBody({ type: ValidateOffersRequest }),
3579
3483
  ApiResponse({
@@ -3592,28 +3496,6 @@ ValidateController = __decorate([ApiTags("Make"), ApiResponse({
3592
3496
  description: "Bad Request",
3593
3497
  type: BadRequestResponse
3594
3498
  })], ValidateController);
3595
- let CallbacksController = class CallbacksController {
3596
- async resolveCallbackTypes() {}
3597
- };
3598
- __decorate([
3599
- ApiOperation({
3600
- methods: ["post"],
3601
- path: "/v1/callbacks",
3602
- summary: "Resolve callback types",
3603
- description: "Returns callback types for callback addresses grouped by chain."
3604
- }),
3605
- ApiBody({ type: CallbackTypesRequest }),
3606
- ApiResponse({
3607
- status: 200,
3608
- description: "Success",
3609
- type: CallbackTypesSuccessResponse
3610
- })
3611
- ], CallbacksController.prototype, "resolveCallbackTypes", null);
3612
- CallbacksController = __decorate([ApiTags("Make"), ApiResponse({
3613
- status: 400,
3614
- description: "Bad Request",
3615
- type: BadRequestResponse
3616
- })], CallbacksController);
3617
3499
  let OffersController = class OffersController {
3618
3500
  async getOffers() {}
3619
3501
  };
@@ -3763,12 +3645,6 @@ const configRulesMaturityExample = {
3763
3645
  name: "end_of_next_month",
3764
3646
  timestamp: 1730415600
3765
3647
  };
3766
- const configRulesCallbackExample = {
3767
- type: "callback",
3768
- chain_id: 1,
3769
- address: "0x1111111111111111111111111111111111111111",
3770
- callback_type: "sell_erc20_callback"
3771
- };
3772
3648
  const configRulesLoanTokenExample = {
3773
3649
  type: "loan_token",
3774
3650
  chain_id: 1,
@@ -3782,7 +3658,6 @@ const configRulesOracleExample = {
3782
3658
  const configRulesChecksumExample = "f1d2d2f924e986ac86fdf7b36c94bcdf";
3783
3659
  const configRulesPayloadExample = [
3784
3660
  configRulesMaturityExample,
3785
- configRulesCallbackExample,
3786
3661
  configRulesLoanTokenExample,
3787
3662
  configRulesOracleExample
3788
3663
  ];
@@ -3847,14 +3722,9 @@ __decorate([ApiProperty({
3847
3722
  })], ConfigRulesRuleResponse.prototype, "timestamp", void 0);
3848
3723
  __decorate([ApiProperty({
3849
3724
  type: "string",
3850
- example: configRulesCallbackExample.address,
3725
+ example: configRulesLoanTokenExample.address,
3851
3726
  required: false
3852
3727
  })], ConfigRulesRuleResponse.prototype, "address", void 0);
3853
- __decorate([ApiProperty({
3854
- type: "string",
3855
- example: configRulesCallbackExample.callback_type,
3856
- required: false
3857
- })], ConfigRulesRuleResponse.prototype, "callback_type", void 0);
3858
3728
  var ConfigRulesSuccessResponse = class {};
3859
3729
  __decorate([ApiProperty({ type: () => ConfigRulesMeta })], ConfigRulesSuccessResponse.prototype, "meta", void 0);
3860
3730
  __decorate([ApiProperty({
@@ -3915,7 +3785,7 @@ __decorate([
3915
3785
  methods: ["get"],
3916
3786
  path: "/v1/config/rules",
3917
3787
  summary: "Get config rules",
3918
- description: "Returns configured rules for supported chains."
3788
+ description: "Returns configured rules (maturities, loan tokens, oracles) for supported chains."
3919
3789
  }),
3920
3790
  ApiQuery({
3921
3791
  name: "cursor",
@@ -4094,8 +3964,7 @@ const OpenApi = async () => {
4094
3964
  ObligationsController,
4095
3965
  HealthController,
4096
3966
  UsersController,
4097
- ValidateController,
4098
- CallbacksController
3967
+ ValidateController
4099
3968
  ],
4100
3969
  document: {
4101
3970
  openapi: "3.1.0",
@@ -4352,16 +4221,6 @@ const GetBookParams = z$1.object({
4352
4221
  })
4353
4222
  });
4354
4223
  const ValidateOffersBody = z$1.object({ offers: z$1.array(z$1.unknown()).min(1, { message: "'offers' must contain at least 1 offer" }) }).strict();
4355
- const CallbackTypesBody = z$1.object({ callbacks: z$1.array(z$1.object({
4356
- chain_id: z$1.number().int().positive().meta({
4357
- description: "Chain id.",
4358
- example: 1
4359
- }),
4360
- addresses: z$1.array(z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Callback address must be a valid 20-byte address" }).transform((val) => val.toLowerCase())).meta({
4361
- description: "Callback contract addresses.",
4362
- example: ["0x1111111111111111111111111111111111111111", "0x3333333333333333333333333333333333333333"]
4363
- })
4364
- }).strict()) }).strict();
4365
4224
  const GetUserPositionsParams = z$1.object({
4366
4225
  ...PaginationQueryParams.shape,
4367
4226
  user_address: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "User address must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).meta({
@@ -4380,7 +4239,6 @@ const schemas = {
4380
4239
  get_obligation: GetObligationParams,
4381
4240
  get_book: GetBookParams,
4382
4241
  validate_offers: ValidateOffersBody,
4383
- callback_types: CallbackTypesBody,
4384
4242
  get_user_positions: GetUserPositionsParams
4385
4243
  };
4386
4244
  function parse(action, query) {
@@ -4395,7 +4253,6 @@ function safeParse(action, query, error) {
4395
4253
  var Schema_exports = /* @__PURE__ */ __exportAll({
4396
4254
  BookResponse: () => BookResponse_exports,
4397
4255
  BooksController: () => BooksController,
4398
- CallbacksController: () => CallbacksController,
4399
4256
  ChainHealth: () => ChainHealth,
4400
4257
  ChainsHealthResponse: () => ChainsHealthResponse,
4401
4258
  CollectorHealth: () => CollectorHealth,
@@ -4674,23 +4531,11 @@ function createHttpClient(config) {
4674
4531
  issues: []
4675
4532
  };
4676
4533
  };
4677
- const getCallbackTypes = async (requestPayload) => {
4678
- const response = await request("/v1/callbacks", {
4679
- method: "POST",
4680
- headers: { "content-type": "application/json" },
4681
- body: JSON.stringify(requestPayload)
4682
- });
4683
- const json = await response.json();
4684
- if (!response.ok) throw new Error(`Gatekeeper callbacks request failed: ${extractErrorMessage(json) ?? response.statusText}`);
4685
- if (!("data" in json) || !Array.isArray(json.data)) throw new Error("Gatekeeper callbacks response is invalid.");
4686
- return json.data;
4687
- };
4688
4534
  return {
4689
4535
  baseUrl,
4690
4536
  validate,
4691
4537
  getConfigRules,
4692
- isAllowed,
4693
- getCallbackTypes
4538
+ isAllowed
4694
4539
  };
4695
4540
  }
4696
4541
  function mergeHeaders(base, extra) {
@@ -4814,36 +4659,6 @@ function create(parameters) {
4814
4659
 
4815
4660
  //#endregion
4816
4661
  //#region src/gatekeeper/GateConfig.ts
4817
- /**
4818
- * Returns the callback configuration for a given chain and callback type, if it exists.
4819
- *
4820
- * @param chain - Chain name for which to read the validation configuration
4821
- * @param type - Callback type to retrieve
4822
- * @returns The matching callback configuration or undefined if not configured
4823
- */
4824
- function getCallback(chain, type) {
4825
- return configs[chain].callbacks?.find((c) => c.type === type);
4826
- }
4827
- /**
4828
- * Attempts to infer the configured callback type from a callback address on a chain.
4829
- * Skips the empty callback type as it does not carry addresses.
4830
- *
4831
- * @param chain - Chain name for which to infer the callback type
4832
- * @param address - Callback contract address
4833
- * @returns The callback type when found, otherwise undefined
4834
- */
4835
- function getCallbackType(chain, address) {
4836
- return configs[chain].callbacks?.find((c) => c.type !== Type$1.BuyWithEmptyCallback && c.addresses.includes(address?.toLowerCase()))?.type;
4837
- }
4838
- /**
4839
- * Returns the list of allowed non-empty callback addresses for a chain.
4840
- *
4841
- * @param chain - Chain name
4842
- * @returns Array of allowed callback addresses (lowercased). Empty when none configured
4843
- */
4844
- const getCallbackAddresses = (chain) => {
4845
- return configs[chain].callbacks?.filter((c) => c.type !== Type$1.BuyWithEmptyCallback).flatMap((c) => c.addresses) ?? [];
4846
- };
4847
4662
  const assets = {
4848
4663
  [ChainId.ETHEREUM.toString()]: [
4849
4664
  "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
@@ -4915,63 +4730,19 @@ const oracles = {
4915
4730
  };
4916
4731
  const configs = {
4917
4732
  ethereum: {
4918
- callbacks: [
4919
- {
4920
- type: Type$1.BuyVaultV1Callback,
4921
- addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4922
- vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
4923
- },
4924
- {
4925
- type: Type$1.SellERC20Callback,
4926
- addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4927
- },
4928
- { type: Type$1.BuyWithEmptyCallback }
4929
- ],
4733
+ callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
4930
4734
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4931
4735
  },
4932
4736
  base: {
4933
- callbacks: [
4934
- {
4935
- type: Type$1.BuyVaultV1Callback,
4936
- addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4937
- vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0xFf62A7c278C62eD665133147129245053Bbf5918"]
4938
- },
4939
- {
4940
- type: Type$1.SellERC20Callback,
4941
- addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4942
- },
4943
- { type: Type$1.BuyWithEmptyCallback }
4944
- ],
4737
+ callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
4945
4738
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4946
4739
  },
4947
4740
  "ethereum-virtual-testnet": {
4948
- callbacks: [
4949
- {
4950
- type: Type$1.BuyVaultV1Callback,
4951
- addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4952
- vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
4953
- },
4954
- {
4955
- type: Type$1.SellERC20Callback,
4956
- addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4957
- },
4958
- { type: Type$1.BuyWithEmptyCallback }
4959
- ],
4741
+ callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
4960
4742
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4961
4743
  },
4962
4744
  anvil: {
4963
- callbacks: [
4964
- {
4965
- type: Type$1.BuyVaultV1Callback,
4966
- addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4967
- vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
4968
- },
4969
- {
4970
- type: Type$1.SellERC20Callback,
4971
- addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4972
- },
4973
- { type: Type$1.BuyWithEmptyCallback }
4974
- ],
4745
+ callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
4975
4746
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4976
4747
  }
4977
4748
  };
@@ -4991,109 +4762,13 @@ var Rules_exports = /* @__PURE__ */ __exportAll({
4991
4762
  /**
4992
4763
  * set of rules to validate offers.
4993
4764
  *
4994
- * @param parameters - Validity parameters with chain and client
4765
+ * @param _parameters - Validity parameters with chain and client
4995
4766
  * @returns Array of validation rules to evaluate against offers
4996
4767
  */
4997
- function validity(parameters) {
4998
- const { client } = parameters;
4999
- const sellErc20CallbackInvalid = single("sell_erc20_callback_invalid", "Validates that sell offers have valid ERC20 callback data matching offer collaterals", (offer) => {
5000
- const callbackType = getCallbackType(client.chain.name, offer.callback.address);
5001
- if (callbackType !== Type$1.SellERC20Callback) return;
5002
- const decoded = decode$2(callbackType, offer.callback.data);
5003
- if (decoded.length === 0) return { message: "Callback data cannot be decoded or is empty." };
5004
- if (callbackType === Type$1.SellERC20Callback) {
5005
- const offerCollaterals = new Set(offer.collaterals.map((c) => c.asset.toLowerCase()));
5006
- if (decoded.length !== offer.collaterals.length) return { message: `Sell callback collateral length mismatch. Expected ${offer.collaterals.length}, got ${decoded.length}.` };
5007
- for (const { contract } of decoded) if (!offerCollaterals.has(contract.toLowerCase())) return { message: "Sell callback collateral is not part of offer collaterals." };
5008
- }
5009
- });
5010
- const buyCallbackVaultInvalid = batch("buy_offers_callback_vault_invalid", "Validates that buy offers have valid vault callbacks registered in allowed factories with matching assets", async (offers) => {
5011
- const validationIssues = /* @__PURE__ */ new Map();
5012
- const offersByVaultAddress = /* @__PURE__ */ new Map();
5013
- for (let i = 0; i < offers.length; i++) {
5014
- const offer = offers[i];
5015
- if (getCallbackType(client.chain.name, offer.callback.address) !== Type$1.BuyVaultV1Callback) continue;
5016
- try {
5017
- const callbackVaults = decodeBuyVaultV1Callback(offer.callback.data);
5018
- for (const { contract } of callbackVaults) {
5019
- const normalizedVaultAddress = contract.toLowerCase();
5020
- if (!offersByVaultAddress.has(normalizedVaultAddress)) offersByVaultAddress.set(normalizedVaultAddress, []);
5021
- offersByVaultAddress.get(normalizedVaultAddress).push({
5022
- index: i,
5023
- offer
5024
- });
5025
- }
5026
- } catch (_) {}
5027
- }
5028
- const uniqueVaultAddresses = Array.from(offersByVaultAddress.keys());
5029
- if (uniqueVaultAddresses.length === 0) return validationIssues;
5030
- const allowedFactories = getCallback(client.chain.name, Type$1.BuyVaultV1Callback)?.vaultFactories.map((f) => f.toLowerCase());
5031
- if (!allowedFactories) return validationIssues;
5032
- const multicallContracts = [];
5033
- for (const vaultAddress of uniqueVaultAddresses) {
5034
- multicallContracts.push({
5035
- address: vaultAddress,
5036
- abi: ERC4626,
5037
- functionName: "asset"
5038
- });
5039
- for (const factoryAddress of allowedFactories) multicallContracts.push({
5040
- address: factoryAddress,
5041
- abi: MetaMorphoFactory,
5042
- functionName: "isMetaMorpho",
5043
- args: [vaultAddress]
5044
- });
5045
- }
5046
- const multicallResults = await multicall(client, {
5047
- contracts: multicallContracts,
5048
- allowFailure: true
5049
- });
5050
- const vaultAssetByAddress = /* @__PURE__ */ new Map();
5051
- const registeredVaults = /* @__PURE__ */ new Set();
5052
- const numberOfFactories = allowedFactories.length;
5053
- let resultIndex = 0;
5054
- for (const vaultAddress of uniqueVaultAddresses) {
5055
- const assetCallResult = multicallResults[resultIndex++];
5056
- const assetAddress = assetCallResult.status === "success" ? assetCallResult.result : null;
5057
- vaultAssetByAddress.set(vaultAddress, assetAddress);
5058
- let isRegisteredInFactory = false;
5059
- for (let factoryIndex = 0; factoryIndex < numberOfFactories; factoryIndex++) {
5060
- const factoryCallResult = multicallResults[resultIndex++];
5061
- if (factoryCallResult.status === "success" && factoryCallResult.result === true) isRegisteredInFactory = true;
5062
- }
5063
- if (isRegisteredInFactory) registeredVaults.add(vaultAddress);
5064
- }
5065
- const uniqueOffers = /* @__PURE__ */ new Map();
5066
- for (const offersArray of offersByVaultAddress.values()) for (const { index, offer } of offersArray) uniqueOffers.set(index, offer);
5067
- for (const [index, offer] of uniqueOffers) try {
5068
- const callbackVaults = decodeBuyVaultV1Callback(offer.callback.data);
5069
- const vaultsWithIssues = [];
5070
- for (const { contract } of callbackVaults) {
5071
- const normalizedVaultAddress = contract.toLowerCase();
5072
- const assetAddress = vaultAssetByAddress.get(normalizedVaultAddress);
5073
- const isRegistered = registeredVaults.has(normalizedVaultAddress);
5074
- const failureReasons = [];
5075
- if (assetAddress === null) failureReasons.push("asset call failed");
5076
- else if (assetAddress && assetAddress.toLowerCase() !== offer.loanToken.toLowerCase()) failureReasons.push("asset mismatch");
5077
- if (!isRegistered) failureReasons.push("not registered in factory");
5078
- if (failureReasons.length > 0) vaultsWithIssues.push({
5079
- vaultAddress: contract,
5080
- failureReasons: failureReasons.join(", ")
5081
- });
5082
- }
5083
- if (vaultsWithIssues.length > 0) {
5084
- const failureDetails = vaultsWithIssues.map((v) => `${v.vaultAddress} (${v.failureReasons})`).join("; ");
5085
- validationIssues.set(index, { message: `Buy offer callback vaults are invalid: ${failureDetails}` });
5086
- }
5087
- } catch (_) {}
5088
- return validationIssues;
5089
- });
5090
- return [
5091
- single("expiry", "Validates that offer has not expired", (offer) => {
5092
- if (offer.expiry < Math.floor(Date.now() / 1e3)) return { message: "Expiry mismatch" };
5093
- }),
5094
- sellErc20CallbackInvalid,
5095
- buyCallbackVaultInvalid
5096
- ];
4768
+ function validity(_parameters) {
4769
+ return [single("expiry", "Validates that offer has not expired", (offer) => {
4770
+ if (offer.expiry < Math.floor(Date.now() / 1e3)) return { message: "Expiry mismatch" };
4771
+ })];
5097
4772
  }
5098
4773
  const chains = ({ chains }) => single("chain_ids", `Validates that offer chain is one of: [${chains.map((c) => c.id).join(", ")}]`, (offer) => {
5099
4774
  const allowedChainIds = chains.map((c) => c.id);
@@ -5103,12 +4778,10 @@ const maturity = ({ maturities }) => single("maturity", `Validates that offer ma
5103
4778
  const allowedMaturities = maturities.map((m) => from$11(m));
5104
4779
  if (!allowedMaturities.includes(offer.maturity)) return { message: `Maturity must be end of current month (${allowedMaturities[0]}) or end of next month (${allowedMaturities[1]}). Got: ${offer.maturity}` };
5105
4780
  });
5106
- const callback = ({ callbacks, allowedAddresses }) => single("callback", `Validates callbacks: buy empty callback is ${callbacks.includes(Type$1.BuyWithEmptyCallback) ? "allowed" : "not allowed"}; sell offers must use a non-empty callback; non-empty callbacks must target one of [${allowedAddresses.map((a) => a.toLowerCase()).join(", ")}]`, (offer) => {
5107
- if (isEmptyCallback(offer) && offer.buy && !callbacks?.find((c) => c === Type$1.BuyWithEmptyCallback)) return { message: "Buy offers with empty callback not allowed." };
5108
- if (isEmptyCallback(offer) && !offer.buy) return { message: "Sell offers require a non-empty callback." };
5109
- if (!isEmptyCallback(offer)) {
5110
- if (!allowedAddresses.includes(offer.callback.address?.toLowerCase())) return { message: `Callback address ${offer.callback.address} is not allowed.` };
5111
- }
4781
+ const callback = ({ callbacks }) => single("callback", `Validates callbacks: buy empty callback is ${callbacks.includes(Type$1.BuyWithEmptyCallback) ? "allowed" : "not allowed"}; sell empty callback is ${callbacks.includes(Type$1.SellWithEmptyCallback) ? "allowed" : "not allowed"}; non-empty callbacks are rejected`, (offer) => {
4782
+ if (!isEmptyCallback(offer)) return { message: "Non-empty callbacks are not supported." };
4783
+ if (isEmptyCallback(offer) && offer.buy && !callbacks.includes(Type$1.BuyWithEmptyCallback)) return { message: "Buy offers with empty callback not allowed." };
4784
+ if (isEmptyCallback(offer) && !offer.buy && !callbacks.includes(Type$1.SellWithEmptyCallback)) return { message: "Sell offers with empty callback not allowed." };
5112
4785
  });
5113
4786
  /**
5114
4787
  * A validation rule that checks if the offer's tokens are allowed for its chain.
@@ -5173,12 +4846,8 @@ const morphoRules = (chains$2) => {
5173
4846
  chains({ chains: chains$2 }),
5174
4847
  maturity({ maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth] }),
5175
4848
  callback({
5176
- callbacks: [
5177
- Type$1.BuyWithEmptyCallback,
5178
- Type$1.BuyVaultV1Callback,
5179
- Type$1.SellERC20Callback
5180
- ],
5181
- allowedAddresses: chains$2.flatMap((c) => getCallbackAddresses(c.name))
4849
+ callbacks: [Type$1.BuyWithEmptyCallback, Type$1.SellWithEmptyCallback],
4850
+ allowedAddresses: []
5182
4851
  }),
5183
4852
  token({ assetsByChainId }),
5184
4853
  oracle({ oraclesByChainId })