@morpho-dev/router 0.1.9 → 0.1.10
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.
- package/dist/index.browser.d.cts +116 -3
- package/dist/index.browser.d.ts +116 -3
- package/dist/index.browser.js +128 -13
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.mjs +128 -13
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.cts +116 -3
- package/dist/index.node.d.ts +116 -3
- package/dist/index.node.js +125 -8
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +126 -9
- package/dist/index.node.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.browser.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Errors, LLTV, Utils, Offer, Format } from '@morpho-dev/mempool';
|
|
2
2
|
export * from '@morpho-dev/mempool';
|
|
3
|
+
import { parseUnits, encodeAbiParameters, maxUint256, formatUnits, decodeAbiParameters, erc20Abi } from 'viem';
|
|
3
4
|
import { Base64 } from 'js-base64';
|
|
4
|
-
import { parseUnits, maxUint256, formatUnits, erc20Abi } from 'viem';
|
|
5
5
|
import { z } from 'zod/v4';
|
|
6
6
|
import { createDocument } from 'zod-openapi';
|
|
7
7
|
|
|
@@ -17,13 +17,25 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
|
|
|
17
17
|
var Callback_exports = {};
|
|
18
18
|
__export(Callback_exports, {
|
|
19
19
|
CallbackType: () => CallbackType,
|
|
20
|
+
WhitelistedCallbackAddresses: () => WhitelistedCallbackAddresses,
|
|
20
21
|
buildLiquidity: () => buildLiquidity,
|
|
22
|
+
decode: () => decode,
|
|
23
|
+
encode: () => encode,
|
|
21
24
|
getCallbackIdForOffer: () => getCallbackIdForOffer
|
|
22
25
|
});
|
|
23
26
|
var CallbackType = /* @__PURE__ */ ((CallbackType2) => {
|
|
24
27
|
CallbackType2["BuyWithEmptyCallback"] = "buy_with_empty_callback";
|
|
28
|
+
CallbackType2["SellWithdrawFromWallet"] = "sell_withdraw_from_wallet";
|
|
25
29
|
return CallbackType2;
|
|
26
30
|
})(CallbackType || {});
|
|
31
|
+
var WhitelistedCallbackAddresses = {
|
|
32
|
+
["buy_with_empty_callback" /* BuyWithEmptyCallback */]: [],
|
|
33
|
+
["sell_withdraw_from_wallet" /* SellWithdrawFromWallet */]: [
|
|
34
|
+
"0x1111111111111111111111111111111111111111",
|
|
35
|
+
"0x2222222222222222222222222222222222222222"
|
|
36
|
+
// @TODO: update once deployed and add mapping per chain if needed
|
|
37
|
+
]
|
|
38
|
+
};
|
|
27
39
|
function buildLiquidity(parameters) {
|
|
28
40
|
const { type, user, contract, chainId, amount, index = 0, updatedAt = /* @__PURE__ */ new Date() } = parameters;
|
|
29
41
|
if (type !== "buy_with_empty_callback" /* BuyWithEmptyCallback */)
|
|
@@ -65,12 +77,44 @@ function getCallbackIdForOffer(offer) {
|
|
|
65
77
|
}
|
|
66
78
|
return null;
|
|
67
79
|
}
|
|
80
|
+
function decodeSellWithdrawFromWalletData(data) {
|
|
81
|
+
if (!data || data === "0x") throw new Error("Empty callback data");
|
|
82
|
+
try {
|
|
83
|
+
const [collaterals, amounts] = decodeAbiParameters(
|
|
84
|
+
[{ type: "address[]" }, { type: "uint256[]" }],
|
|
85
|
+
data
|
|
86
|
+
);
|
|
87
|
+
if (collaterals.length !== amounts.length) {
|
|
88
|
+
throw new Error("Mismatched array lengths");
|
|
89
|
+
}
|
|
90
|
+
return collaterals.map((c, i) => ({ collateral: c, amount: amounts[i] }));
|
|
91
|
+
} catch (_) {
|
|
92
|
+
throw new Error("Invalid SellWithdrawFromWallet callback data");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function decode(parameters) {
|
|
96
|
+
const { type, data } = parameters;
|
|
97
|
+
if (type === "sell_withdraw_from_wallet" /* SellWithdrawFromWallet */) {
|
|
98
|
+
return decodeSellWithdrawFromWalletData(data);
|
|
99
|
+
}
|
|
100
|
+
throw new Error(`CallbackType not implemented: ${type}`);
|
|
101
|
+
}
|
|
102
|
+
function encode(parameters) {
|
|
103
|
+
const { type, data } = parameters;
|
|
104
|
+
if (type === "sell_withdraw_from_wallet" /* SellWithdrawFromWallet */) {
|
|
105
|
+
return encodeAbiParameters(
|
|
106
|
+
[{ type: "address[]" }, { type: "uint256[]" }],
|
|
107
|
+
[data.collaterals, data.amounts]
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
throw new Error(`CallbackType not implemented: ${type}`);
|
|
111
|
+
}
|
|
68
112
|
|
|
69
113
|
// src/core/Cursor.ts
|
|
70
114
|
var Cursor_exports = {};
|
|
71
115
|
__export(Cursor_exports, {
|
|
72
|
-
decode: () =>
|
|
73
|
-
encode: () =>
|
|
116
|
+
decode: () => decode2,
|
|
117
|
+
encode: () => encode2,
|
|
74
118
|
validate: () => validate
|
|
75
119
|
});
|
|
76
120
|
function validate(cursor) {
|
|
@@ -142,10 +186,10 @@ function validate(cursor) {
|
|
|
142
186
|
}
|
|
143
187
|
return true;
|
|
144
188
|
}
|
|
145
|
-
function
|
|
189
|
+
function encode2(c) {
|
|
146
190
|
return Base64.encodeURL(JSON.stringify(c));
|
|
147
191
|
}
|
|
148
|
-
function
|
|
192
|
+
function decode2(token) {
|
|
149
193
|
if (!token) return null;
|
|
150
194
|
const decoded = JSON.parse(Base64.decode(token));
|
|
151
195
|
validate(decoded);
|
|
@@ -554,7 +598,7 @@ var GetOffersQueryParams = z.object({
|
|
|
554
598
|
(val) => {
|
|
555
599
|
if (!val) return true;
|
|
556
600
|
try {
|
|
557
|
-
const decoded =
|
|
601
|
+
const decoded = decode2(val);
|
|
558
602
|
return decoded !== null;
|
|
559
603
|
} catch (_error) {
|
|
560
604
|
return false;
|
|
@@ -726,7 +770,7 @@ var MatchOffersQueryParams = z.object({
|
|
|
726
770
|
(val) => {
|
|
727
771
|
if (!val) return true;
|
|
728
772
|
try {
|
|
729
|
-
const decoded =
|
|
773
|
+
const decoded = decode2(val);
|
|
730
774
|
return decoded !== null;
|
|
731
775
|
} catch (_error) {
|
|
732
776
|
return false;
|
|
@@ -1202,18 +1246,89 @@ function morpho() {
|
|
|
1202
1246
|
return { message: "Expiry mismatch" };
|
|
1203
1247
|
}
|
|
1204
1248
|
});
|
|
1205
|
-
const
|
|
1206
|
-
|
|
1207
|
-
|
|
1249
|
+
const sellEmptyCallback = single(
|
|
1250
|
+
"sell_offers_empty_callback",
|
|
1251
|
+
(offer, _) => {
|
|
1252
|
+
if (!offer.buy && offer.callback.data === "0x") {
|
|
1253
|
+
return { message: "Sell offers require a non-empty callback." };
|
|
1254
|
+
}
|
|
1208
1255
|
}
|
|
1209
|
-
|
|
1256
|
+
);
|
|
1257
|
+
const buyNonEmptyCallback = single(
|
|
1258
|
+
"buy_offers_non_empty_callback",
|
|
1259
|
+
(offer, _) => {
|
|
1260
|
+
if (offer.buy && offer.callback.data !== "0x") {
|
|
1261
|
+
return { message: "Buy offers must use an empty callback." };
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
);
|
|
1265
|
+
const sellNonWhitelistedCallback = single(
|
|
1266
|
+
"sell_offers_non_whitelisted_callback",
|
|
1267
|
+
(offer, _) => {
|
|
1268
|
+
if (!offer.buy && offer.callback.data !== "0x") {
|
|
1269
|
+
const allowed = new Set(
|
|
1270
|
+
WhitelistedCallbackAddresses["sell_withdraw_from_wallet" /* SellWithdrawFromWallet */].map(
|
|
1271
|
+
(a) => a.toLowerCase()
|
|
1272
|
+
)
|
|
1273
|
+
);
|
|
1274
|
+
const callbackAddress = offer.callback.address?.toLowerCase();
|
|
1275
|
+
if (!callbackAddress || !allowed.has(callbackAddress)) {
|
|
1276
|
+
return { message: "Sell offer callback address is not whitelisted." };
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
);
|
|
1281
|
+
const sellCallbackDataInvalid = single(
|
|
1282
|
+
"sell_offers_callback_data_invalid",
|
|
1283
|
+
(offer, _) => {
|
|
1284
|
+
if (!offer.buy && offer.callback.data !== "0x") {
|
|
1285
|
+
try {
|
|
1286
|
+
const decoded = decode({
|
|
1287
|
+
type: "sell_withdraw_from_wallet" /* SellWithdrawFromWallet */,
|
|
1288
|
+
data: offer.callback.data
|
|
1289
|
+
});
|
|
1290
|
+
if (decoded.length === 0) {
|
|
1291
|
+
return { message: "Sell offer callback data must include at least one collateral." };
|
|
1292
|
+
}
|
|
1293
|
+
} catch (_2) {
|
|
1294
|
+
return { message: "Sell offer callback data cannot be decoded." };
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
);
|
|
1299
|
+
const sellCallbackCollateralInvalid = single(
|
|
1300
|
+
"sell_offers_callback_collateral_invalid",
|
|
1301
|
+
(offer, _) => {
|
|
1302
|
+
if (!offer.buy && offer.callback.data !== "0x") {
|
|
1303
|
+
try {
|
|
1304
|
+
const decoded = decode({
|
|
1305
|
+
type: "sell_withdraw_from_wallet" /* SellWithdrawFromWallet */,
|
|
1306
|
+
data: offer.callback.data
|
|
1307
|
+
});
|
|
1308
|
+
const offerCollaterals = new Set(
|
|
1309
|
+
offer.collaterals.map((c) => c.asset.toLowerCase())
|
|
1310
|
+
);
|
|
1311
|
+
for (const { collateral } of decoded) {
|
|
1312
|
+
if (!offerCollaterals.has(collateral.toLowerCase())) {
|
|
1313
|
+
return { message: "Sell callback collateral is not part of offer collaterals." };
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
} catch (_2) {
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
);
|
|
1210
1321
|
return [
|
|
1211
1322
|
chainId,
|
|
1212
1323
|
loanToken,
|
|
1213
1324
|
expiry,
|
|
1214
|
-
// note: callback
|
|
1325
|
+
// note: callback rules should be the last ones, since they do not mean that the offer is forever invalid
|
|
1215
1326
|
// integrators should be able to choose if they want to keep the offer or not
|
|
1216
|
-
|
|
1327
|
+
sellEmptyCallback,
|
|
1328
|
+
buyNonEmptyCallback,
|
|
1329
|
+
sellNonWhitelistedCallback,
|
|
1330
|
+
sellCallbackDataInvalid,
|
|
1331
|
+
sellCallbackCollateralInvalid
|
|
1217
1332
|
];
|
|
1218
1333
|
}
|
|
1219
1334
|
|