@morpho-org/bundler-sdk-viem 3.1.3 → 3.2.0-next.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.
@@ -1,4 +1,5 @@
1
1
  import { ChainId, type InputMarketParams } from "@morpho-org/blue-sdk";
2
+ import type { ParaswapOffsets } from "@morpho-org/simulation-sdk";
2
3
  import { type Address, type Hex } from "viem";
3
4
  import type { Action, Authorization, InputReallocation, Permit2PermitSingle } from "./types/index.js";
4
5
  export interface BundlerCall {
@@ -231,12 +232,12 @@ export declare namespace BundlerAction {
231
232
  /**
232
233
  * Encodes a call to the GeneralAdapter1 to flash loan from Morpho Blue.
233
234
  * @param chainId The chain id for which to encode the call.
234
- * @param asset The address of the ERC20 token to flash loan.
235
- * @param amount The amount of tokens to flash loan.
235
+ * @param token The address of the ERC20 token to flash loan.
236
+ * @param assets The amount of tokens to flash loan.
236
237
  * @param callbackCalls The array of calls to execute inside Morpho Blue's `onMorphoFlashLoan` callback.
237
238
  * @param skipRevert Whether to allow the transfer to revert without making the whole bundler revert. Defaults to false.
238
239
  */
239
- function morphoFlashLoan(chainId: ChainId, asset: Address, amount: bigint, callbackCalls: BundlerCall[], skipRevert?: boolean): BundlerCall[];
240
+ function morphoFlashLoan(chainId: ChainId, token: Address, assets: bigint, callbackCalls: BundlerCall[], skipRevert?: boolean): BundlerCall[];
240
241
  /**
241
242
  * Encodes a call to trigger a public reallocation on the PublicAllocator.
242
243
  * @param chainId The chain id for which to encode the call.
@@ -247,6 +248,44 @@ export declare namespace BundlerAction {
247
248
  * @param skipRevert Whether to allow the transfer to revert without making the whole bundler revert. Defaults to false.
248
249
  */
249
250
  function publicAllocatorReallocateTo(chainId: ChainId, vault: Address, fee: bigint, withdrawals: InputReallocation[], supplyMarketParams: InputMarketParams, skipRevert?: boolean): BundlerCall[];
251
+ /**
252
+ * Encodes a call to the ParaswapAdapter to buy an exact amount of tokens via Paraswap.
253
+ * @param chainId The chain id for which to encode the call.
254
+ * @param augustus The address of the Augustus router to use.
255
+ * @param callData The encoded call data to execute.
256
+ * @param srcToken The address of the source token.
257
+ * @param dstToken The address of the destination token.
258
+ * @param offsets The offsets in callData of the exact buy amount (`exactAmount`), maximum sell amount (`limitAmount`) and quoted sell amount (`quotedAmount`).
259
+ * @param receiver The address to send the tokens to.
260
+ * @param skipRevert Whether to allow the swap to revert without making the whole bundle revert. Defaults to false.
261
+ */
262
+ function paraswapBuy(chainId: ChainId, augustus: Address, callData: Hex, srcToken: Address, dstToken: Address, offsets: ParaswapOffsets, receiver: Address, skipRevert?: boolean): BundlerCall[];
263
+ /**
264
+ * Encodes a call to the ParaswapAdapter to sell an exact amount of tokens via Paraswap.
265
+ * @param chainId The chain id for which to encode the call.
266
+ * @param augustus The address of the Augustus router to use.
267
+ * @param callData The encoded call data to execute.
268
+ * @param srcToken The address of the source token.
269
+ * @param dstToken The address of the destination token.
270
+ * @param sellEntireBalance Whether to sell the entire balance of the source token.
271
+ * @param offsets The offsets in callData of the exact sell amount (`exactAmount`), minimum buy amount (`limitAmount`) and quoted buy amount (`quotedAmount`).
272
+ * @param receiver The address to send the tokens to.
273
+ * @param skipRevert Whether to allow the swap to revert without making the whole bundle revert. Defaults to false.
274
+ */
275
+ function paraswapSell(chainId: ChainId, augustus: Address, callData: Hex, srcToken: Address, dstToken: Address, sellEntireBalance: boolean, offsets: ParaswapOffsets, receiver: Address, skipRevert?: boolean): BundlerCall[];
276
+ /**
277
+ * Encodes a call to the ParaswapAdapter to buy the exact debt of a position via Paraswap.
278
+ * @param chainId The chain id for which to encode the call.
279
+ * @param augustus The address of the Augustus router to use.
280
+ * @param callData The encoded call data to execute.
281
+ * @param srcToken The address of the source token.
282
+ * @param marketParams The market params of the market with the debt assets to buy.
283
+ * @param offsets The offsets in callData of the exact buy amount (`exactAmount`), maximum sell amount (`limitAmount`) and quoted sell amount (`quotedAmount`).
284
+ * @param onBehalf The address to buy the debt on behalf of.
285
+ * @param receiver The address to send the tokens to.
286
+ * @param skipRevert Whether to allow the swap to revert without making the whole bundle revert. Defaults to false.
287
+ */
288
+ function paraswapBuyMorphoDebt(chainId: ChainId, augustus: Address, callData: Hex, srcToken: Address, marketParams: InputMarketParams, offsets: ParaswapOffsets, onBehalf: Address, receiver: Address, skipRevert?: boolean): BundlerCall[];
250
289
  /**
251
290
  * Encodes a call to the Universal Rewards Distributor to claim rewards.
252
291
  * @param chainId The chain id for which to encode the call.
@@ -119,10 +119,24 @@ var BundlerAction;
119
119
  case "morphoWithdrawCollateral": {
120
120
  return BundlerAction.morphoWithdrawCollateral(chainId, ...args);
121
121
  }
122
+ case "morphoFlashLoan": {
123
+ const [token, assets, onMorphoFlashLoan, skipRevert] = args;
124
+ return BundlerAction.morphoFlashLoan(chainId, token, assets, onMorphoFlashLoan.flatMap(BundlerAction.encode.bind(null, chainId)), skipRevert);
125
+ }
122
126
  /* PublicAllocator */
123
127
  case "reallocateTo": {
124
128
  return BundlerAction.publicAllocatorReallocateTo(chainId, ...args);
125
129
  }
130
+ /* Paraswap */
131
+ case "paraswapBuy": {
132
+ return BundlerAction.paraswapBuy(chainId, ...args);
133
+ }
134
+ case "paraswapSell": {
135
+ return BundlerAction.paraswapSell(chainId, ...args);
136
+ }
137
+ case "paraswapBuyMorphoDebt": {
138
+ return BundlerAction.paraswapBuyMorphoDebt(chainId, ...args);
139
+ }
126
140
  /* Universal Rewards Distributor */
127
141
  case "urdClaim": {
128
142
  return BundlerAction.urdClaim(...args);
@@ -889,12 +903,12 @@ var BundlerAction;
889
903
  /**
890
904
  * Encodes a call to the GeneralAdapter1 to flash loan from Morpho Blue.
891
905
  * @param chainId The chain id for which to encode the call.
892
- * @param asset The address of the ERC20 token to flash loan.
893
- * @param amount The amount of tokens to flash loan.
906
+ * @param token The address of the ERC20 token to flash loan.
907
+ * @param assets The amount of tokens to flash loan.
894
908
  * @param callbackCalls The array of calls to execute inside Morpho Blue's `onMorphoFlashLoan` callback.
895
909
  * @param skipRevert Whether to allow the transfer to revert without making the whole bundler revert. Defaults to false.
896
910
  */
897
- function morphoFlashLoan(chainId, asset, amount, callbackCalls, skipRevert = false) {
911
+ function morphoFlashLoan(chainId, token, assets, callbackCalls, skipRevert = false) {
898
912
  const { bundler3: { generalAdapter1 }, } = (0, blue_sdk_1.getChainAddresses)(chainId);
899
913
  const reenter = callbackCalls.length > 0;
900
914
  const reenterData = reenter
@@ -906,7 +920,7 @@ var BundlerAction;
906
920
  data: (0, viem_1.encodeFunctionData)({
907
921
  abi: abis_js_1.generalAdapter1Abi,
908
922
  functionName: "morphoFlashLoan",
909
- args: [asset, amount, reenterData],
923
+ args: [token, assets, reenterData],
910
924
  }),
911
925
  value: 0n,
912
926
  skipRevert,
@@ -943,6 +957,114 @@ var BundlerAction;
943
957
  ];
944
958
  }
945
959
  BundlerAction.publicAllocatorReallocateTo = publicAllocatorReallocateTo;
960
+ /**
961
+ * Encodes a call to the ParaswapAdapter to buy an exact amount of tokens via Paraswap.
962
+ * @param chainId The chain id for which to encode the call.
963
+ * @param augustus The address of the Augustus router to use.
964
+ * @param callData The encoded call data to execute.
965
+ * @param srcToken The address of the source token.
966
+ * @param dstToken The address of the destination token.
967
+ * @param offsets The offsets in callData of the exact buy amount (`exactAmount`), maximum sell amount (`limitAmount`) and quoted sell amount (`quotedAmount`).
968
+ * @param receiver The address to send the tokens to.
969
+ * @param skipRevert Whether to allow the swap to revert without making the whole bundle revert. Defaults to false.
970
+ */
971
+ function paraswapBuy(chainId, augustus, callData, srcToken, dstToken, offsets, receiver, skipRevert = false) {
972
+ const { bundler3: { paraswapAdapter }, } = (0, blue_sdk_1.getChainAddresses)(chainId);
973
+ if (paraswapAdapter == null)
974
+ throw new errors_js_1.BundlerErrors.UnexpectedAction("paraswapBuy", chainId);
975
+ return [
976
+ {
977
+ to: paraswapAdapter,
978
+ data: (0, viem_1.encodeFunctionData)({
979
+ abi: abis_js_1.paraswapAdapterAbi,
980
+ functionName: "buy",
981
+ args: [augustus, callData, srcToken, dstToken, 0n, offsets, receiver],
982
+ }),
983
+ value: 0n,
984
+ skipRevert,
985
+ callbackHash: viem_1.zeroHash,
986
+ },
987
+ ];
988
+ }
989
+ BundlerAction.paraswapBuy = paraswapBuy;
990
+ /**
991
+ * Encodes a call to the ParaswapAdapter to sell an exact amount of tokens via Paraswap.
992
+ * @param chainId The chain id for which to encode the call.
993
+ * @param augustus The address of the Augustus router to use.
994
+ * @param callData The encoded call data to execute.
995
+ * @param srcToken The address of the source token.
996
+ * @param dstToken The address of the destination token.
997
+ * @param sellEntireBalance Whether to sell the entire balance of the source token.
998
+ * @param offsets The offsets in callData of the exact sell amount (`exactAmount`), minimum buy amount (`limitAmount`) and quoted buy amount (`quotedAmount`).
999
+ * @param receiver The address to send the tokens to.
1000
+ * @param skipRevert Whether to allow the swap to revert without making the whole bundle revert. Defaults to false.
1001
+ */
1002
+ function paraswapSell(chainId, augustus, callData, srcToken, dstToken, sellEntireBalance, offsets, receiver, skipRevert = false) {
1003
+ const { bundler3: { paraswapAdapter }, } = (0, blue_sdk_1.getChainAddresses)(chainId);
1004
+ if (paraswapAdapter == null)
1005
+ throw new errors_js_1.BundlerErrors.UnexpectedAction("paraswapSell", chainId);
1006
+ return [
1007
+ {
1008
+ to: paraswapAdapter,
1009
+ data: (0, viem_1.encodeFunctionData)({
1010
+ abi: abis_js_1.paraswapAdapterAbi,
1011
+ functionName: "sell",
1012
+ args: [
1013
+ augustus,
1014
+ callData,
1015
+ srcToken,
1016
+ dstToken,
1017
+ sellEntireBalance,
1018
+ offsets,
1019
+ receiver,
1020
+ ],
1021
+ }),
1022
+ value: 0n,
1023
+ skipRevert,
1024
+ callbackHash: viem_1.zeroHash,
1025
+ },
1026
+ ];
1027
+ }
1028
+ BundlerAction.paraswapSell = paraswapSell;
1029
+ /**
1030
+ * Encodes a call to the ParaswapAdapter to buy the exact debt of a position via Paraswap.
1031
+ * @param chainId The chain id for which to encode the call.
1032
+ * @param augustus The address of the Augustus router to use.
1033
+ * @param callData The encoded call data to execute.
1034
+ * @param srcToken The address of the source token.
1035
+ * @param marketParams The market params of the market with the debt assets to buy.
1036
+ * @param offsets The offsets in callData of the exact buy amount (`exactAmount`), maximum sell amount (`limitAmount`) and quoted sell amount (`quotedAmount`).
1037
+ * @param onBehalf The address to buy the debt on behalf of.
1038
+ * @param receiver The address to send the tokens to.
1039
+ * @param skipRevert Whether to allow the swap to revert without making the whole bundle revert. Defaults to false.
1040
+ */
1041
+ function paraswapBuyMorphoDebt(chainId, augustus, callData, srcToken, marketParams, offsets, onBehalf, receiver, skipRevert = false) {
1042
+ const { bundler3: { paraswapAdapter }, } = (0, blue_sdk_1.getChainAddresses)(chainId);
1043
+ if (paraswapAdapter == null)
1044
+ throw new errors_js_1.BundlerErrors.UnexpectedAction("paraswapBuyMorphoDebt", chainId);
1045
+ return [
1046
+ {
1047
+ to: paraswapAdapter,
1048
+ data: (0, viem_1.encodeFunctionData)({
1049
+ abi: abis_js_1.paraswapAdapterAbi,
1050
+ functionName: "buyMorphoDebt",
1051
+ args: [
1052
+ augustus,
1053
+ callData,
1054
+ srcToken,
1055
+ marketParams,
1056
+ offsets,
1057
+ onBehalf,
1058
+ receiver,
1059
+ ],
1060
+ }),
1061
+ value: 0n,
1062
+ skipRevert,
1063
+ callbackHash: viem_1.zeroHash,
1064
+ },
1065
+ ];
1066
+ }
1067
+ BundlerAction.paraswapBuyMorphoDebt = paraswapBuyMorphoDebt;
946
1068
  /* Universal Rewards Distributor */
947
1069
  /**
948
1070
  * Encodes a call to the Universal Rewards Distributor to claim rewards.
package/lib/actions.js CHANGED
@@ -70,7 +70,7 @@ const encodeErc20Approval = (token, sender, spender, amount, data) => {
70
70
  const encodeOperation = (operation, dataBefore, supportsSignature = true, index = 0) => {
71
71
  const { chainId } = dataBefore;
72
72
  const deadline = morpho_ts_1.Time.timestamp() + morpho_ts_1.Time.s.from.h(24n);
73
- const { morpho, bundler3: { bundler3, generalAdapter1 }, permit2, wNative, dai, wstEth, stEth, } = (0, blue_sdk_1.getChainAddresses)(chainId);
73
+ const { morpho, bundler3: { bundler3, generalAdapter1, paraswapAdapter }, permit2, wNative, dai, wstEth, stEth, } = (0, blue_sdk_1.getChainAddresses)(chainId);
74
74
  const actions = [];
75
75
  const requirements = new ActionBundle_js_1.ActionBundleRequirements();
76
76
  let callbackBundle;
@@ -81,7 +81,11 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
81
81
  ...operation.args,
82
82
  ...(callback && {
83
83
  callback: (dataBefore) => {
84
- callbackBundle = encodeBundle(callback, (0, simulation_sdk_1.getCurrent)(dataBefore), supportsSignature);
84
+ callbackBundle = encodeBundle(callback.map((callbackOperation) => ({
85
+ ...callbackOperation,
86
+ // Inside a callback, the sender is forced to be the generalAdapter1.
87
+ sender: generalAdapter1,
88
+ })), (0, simulation_sdk_1.getCurrent)(dataBefore), supportsSignature);
85
89
  return callback;
86
90
  },
87
91
  }),
@@ -93,7 +97,7 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
93
97
  requirements.txs.push(...callbackBundle.requirements.txs);
94
98
  requirements.signatures.push(...callbackBundle.requirements.signatures);
95
99
  }
96
- const { sender, address } = operation;
100
+ const { sender } = operation;
97
101
  switch (operation.type) {
98
102
  case "Blue_SetAuthorization": {
99
103
  const { owner, isAuthorized, authorized } = operation.args;
@@ -127,7 +131,7 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
127
131
  });
128
132
  await (0, viem_1.verifyTypedData)({
129
133
  ...typedData,
130
- address: sender, // Verify against the authorization's owner.
134
+ address: owner, // Verify against the authorization's owner.
131
135
  signature,
132
136
  });
133
137
  return (action.args[1] = signature);
@@ -152,18 +156,18 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
152
156
  }
153
157
  case "Erc20_Approve": {
154
158
  // Native token cannot be approved.
155
- if (address === blue_sdk_1.NATIVE_ADDRESS)
159
+ if (operation.address === blue_sdk_1.NATIVE_ADDRESS)
156
160
  break;
157
161
  const { amount, spender } = operation.args;
158
162
  // Signatures are not supported, skip Permit2 approval.
159
163
  if (!supportsSignature && spender === permit2)
160
164
  break;
161
- requirements.txs.push(...encodeErc20Approval(address, sender, spender, amount, dataBefore));
165
+ requirements.txs.push(...encodeErc20Approval(operation.address, sender, spender, amount, dataBefore));
162
166
  break;
163
167
  }
164
168
  case "Erc20_Permit": {
165
169
  // Native token cannot be permitted.
166
- if (address === blue_sdk_1.NATIVE_ADDRESS)
170
+ if (operation.address === blue_sdk_1.NATIVE_ADDRESS)
167
171
  break;
168
172
  const { amount, spender, nonce } = operation.args;
169
173
  // Never permit any other address than the GeneralAdapter1 otherwise
@@ -171,23 +175,17 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
171
175
  if (spender !== generalAdapter1)
172
176
  throw new errors_js_1.BundlerErrors.UnexpectedSignature(spender);
173
177
  if (supportsSignature) {
174
- const action = address === dai
178
+ const isDai = dai != null && operation.address === dai;
179
+ const action = isDai
175
180
  ? {
176
181
  type: "permitDai",
177
- args: [
178
- sender,
179
- nonce,
180
- deadline,
181
- true,
182
- null,
183
- operation.skipRevert,
184
- ],
182
+ args: [sender, nonce, deadline, true, null, operation.skipRevert],
185
183
  }
186
184
  : {
187
185
  type: "permit",
188
186
  args: [
189
187
  sender,
190
- address,
188
+ operation.address,
191
189
  amount,
192
190
  deadline,
193
191
  null,
@@ -195,14 +193,14 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
195
193
  ],
196
194
  };
197
195
  actions.push(action);
198
- const tokenData = dataBefore.getToken(address);
196
+ const tokenData = dataBefore.getToken(operation.address);
199
197
  requirements.signatures.push({
200
198
  action,
201
199
  async sign(client, account = client.account) {
202
200
  let signature = action.args[4];
203
201
  if (signature != null)
204
202
  return signature; // action is already signed
205
- if (address === dai) {
203
+ if (isDai) {
206
204
  const typedData = (0, blue_sdk_viem_1.getDaiPermitTypedData)({
207
205
  owner: sender,
208
206
  spender,
@@ -245,12 +243,12 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
245
243
  break;
246
244
  }
247
245
  // Simple permit is not supported, fallback to standard approval.
248
- requirements.txs.push(...encodeErc20Approval(address, sender, spender, amount, dataBefore));
246
+ requirements.txs.push(...encodeErc20Approval(operation.address, sender, spender, amount, dataBefore));
249
247
  break;
250
248
  }
251
249
  case "Erc20_Permit2": {
252
250
  // Native token cannot be permitted.
253
- if (address === blue_sdk_1.NATIVE_ADDRESS)
251
+ if (operation.address === blue_sdk_1.NATIVE_ADDRESS)
254
252
  break;
255
253
  const { amount, expiration, nonce } = operation.args;
256
254
  if (supportsSignature) {
@@ -260,7 +258,7 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
260
258
  sender,
261
259
  {
262
260
  details: {
263
- token: address,
261
+ token: operation.address,
264
262
  amount,
265
263
  nonce: Number(nonce),
266
264
  expiration: Number(expiration),
@@ -304,12 +302,12 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
304
302
  break;
305
303
  }
306
304
  // Signatures are not supported, fallback to standard approval.
307
- requirements.txs.push(...encodeErc20Approval(address, sender, generalAdapter1, amount, dataBefore));
305
+ requirements.txs.push(...encodeErc20Approval(operation.address, sender, generalAdapter1, amount, dataBefore));
308
306
  break;
309
307
  }
310
308
  case "Erc20_Transfer": {
311
309
  const { amount, from, to } = operation.args;
312
- if (address === blue_sdk_1.NATIVE_ADDRESS) {
310
+ if (operation.address === blue_sdk_1.NATIVE_ADDRESS) {
313
311
  actions.push({
314
312
  type: "nativeTransfer",
315
313
  args: [from, to, amount, operation.skipRevert],
@@ -320,13 +318,19 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
320
318
  if (from === generalAdapter1) {
321
319
  actions.push({
322
320
  type: "erc20Transfer",
323
- args: [address, to, amount, generalAdapter1, operation.skipRevert],
321
+ args: [
322
+ operation.address,
323
+ to,
324
+ amount,
325
+ generalAdapter1,
326
+ operation.skipRevert,
327
+ ],
324
328
  });
325
329
  break;
326
330
  }
327
331
  actions.push({
328
332
  type: "erc20TransferFrom",
329
- args: [address, amount, to, operation.skipRevert],
333
+ args: [operation.address, amount, to, operation.skipRevert],
330
334
  });
331
335
  break;
332
336
  }
@@ -335,31 +339,31 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
335
339
  if (supportsSignature) {
336
340
  actions.push({
337
341
  type: "transferFrom2",
338
- args: [address, amount, to, operation.skipRevert],
342
+ args: [operation.address, amount, to, operation.skipRevert],
339
343
  });
340
344
  break;
341
345
  }
342
346
  // Signatures are not supported, fallback to standard transfer.
343
347
  actions.push({
344
348
  type: "erc20TransferFrom",
345
- args: [address, amount, to, operation.skipRevert],
349
+ args: [operation.address, amount, to, operation.skipRevert],
346
350
  });
347
351
  break;
348
352
  }
349
353
  case "Erc20_Wrap": {
350
- const { amount } = operation.args;
351
- switch (address) {
354
+ const { amount, owner } = operation.args;
355
+ switch (operation.address) {
352
356
  case wNative: {
353
357
  actions.push({
354
358
  type: "wrapNative",
355
- args: [amount, generalAdapter1, operation.skipRevert],
359
+ args: [amount, owner, operation.skipRevert],
356
360
  });
357
361
  break;
358
362
  }
359
363
  case wstEth: {
360
364
  actions.push({
361
365
  type: "wrapStEth",
362
- args: [amount, generalAdapter1, operation.skipRevert],
366
+ args: [amount, owner, operation.skipRevert],
363
367
  });
364
368
  break;
365
369
  }
@@ -370,53 +374,58 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
370
374
  amount,
371
375
  blue_sdk_1.MathLib.MAX_UINT_256,
372
376
  viem_1.zeroAddress,
373
- generalAdapter1,
377
+ owner,
374
378
  operation.skipRevert,
375
379
  ],
376
380
  });
377
381
  break;
378
382
  }
379
383
  default: {
380
- if (blue_sdk_1.erc20WrapperTokens[chainId]?.has(address)) {
381
- const underlying = (0, blue_sdk_1.getUnwrappedToken)(address, chainId);
384
+ if (blue_sdk_1.erc20WrapperTokens[chainId]?.has(operation.address)) {
385
+ const underlying = (0, blue_sdk_1.getUnwrappedToken)(operation.address, chainId);
382
386
  if (underlying == null)
383
- throw Error(`unknown wrapped token: ${address}`);
387
+ throw Error(`unknown wrapped token: ${operation.address}`);
384
388
  actions.push({
385
389
  type: "erc20WrapperDepositFor",
386
- args: [address, underlying, amount, operation.skipRevert],
390
+ args: [
391
+ operation.address,
392
+ underlying,
393
+ amount,
394
+ operation.skipRevert,
395
+ ],
387
396
  });
388
397
  break;
389
398
  }
390
399
  // Convex token wrapping is executed onchain along with supplyCollateral, via depositFor.
391
- if (!blue_sdk_1.convexWrapperTokens[chainId]?.has(address))
392
- throw Error(`unexpected token wrap: ${address}`);
400
+ if (!blue_sdk_1.convexWrapperTokens[chainId]?.has(operation.address))
401
+ throw Error(`unexpected token wrap: ${operation.address}`);
393
402
  }
394
403
  }
395
404
  break;
396
405
  }
397
406
  case "Erc20_Unwrap": {
398
407
  const { amount, receiver } = operation.args;
399
- switch (address) {
408
+ switch (operation.address) {
400
409
  case wNative: {
401
410
  actions.push({
402
411
  type: "unwrapNative",
403
- args: [amount, generalAdapter1, operation.skipRevert],
412
+ args: [amount, receiver, operation.skipRevert],
404
413
  });
405
414
  break;
406
415
  }
407
416
  case wstEth: {
408
417
  actions.push({
409
418
  type: "unwrapStEth",
410
- args: [amount, generalAdapter1, operation.skipRevert],
419
+ args: [amount, receiver, operation.skipRevert],
411
420
  });
412
421
  break;
413
422
  }
414
423
  default: {
415
- if (!blue_sdk_1.erc20WrapperTokens[chainId]?.has(address))
416
- throw Error(`unexpected token unwrap: ${address}`);
424
+ if (!blue_sdk_1.erc20WrapperTokens[chainId]?.has(operation.address))
425
+ throw Error(`unexpected token unwrap: ${operation.address}`);
417
426
  actions.push({
418
427
  type: "erc20WrapperWithdrawTo",
419
- args: [address, receiver, amount, operation.skipRevert],
428
+ args: [operation.address, receiver, amount, operation.skipRevert],
420
429
  });
421
430
  }
422
431
  }
@@ -512,9 +521,9 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
512
521
  const { id, assets, onBehalf } = operation.args;
513
522
  const { params } = dataBefore.getMarket(id);
514
523
  if (blue_sdk_1.convexWrapperTokens[chainId]?.has(params.collateralToken)) {
515
- const underlying = (0, blue_sdk_1.getUnwrappedToken)(address, chainId);
524
+ const underlying = (0, blue_sdk_1.getUnwrappedToken)(params.collateralToken, chainId);
516
525
  if (underlying == null)
517
- throw Error(`unknown wrapped token: ${address}`);
526
+ throw Error(`unknown wrapped token: ${params.collateralToken}`);
518
527
  actions.push({
519
528
  type: "erc20WrapperDepositFor",
520
529
  args: [
@@ -551,20 +560,32 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
551
560
  const { assets = 0n, shares = 0n, owner, slippage = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, } = operation.args;
552
561
  // Accrue interest to calculate the expected share price.
553
562
  const vault = dataBefore
554
- .getAccrualVault(address)
563
+ .getAccrualVault(operation.address)
555
564
  .accrueInterest(dataBefore.block.timestamp);
556
565
  if (shares === 0n) {
557
566
  const maxSharePrice = blue_sdk_1.MathLib.mulDivUp(assets, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD + slippage), vault.toShares(assets));
558
567
  actions.push({
559
568
  type: "erc4626Deposit",
560
- args: [address, assets, maxSharePrice, owner, operation.skipRevert],
569
+ args: [
570
+ operation.address,
571
+ assets,
572
+ maxSharePrice,
573
+ owner,
574
+ operation.skipRevert,
575
+ ],
561
576
  });
562
577
  }
563
578
  else {
564
579
  const maxSharePrice = blue_sdk_1.MathLib.mulDivUp(vault.toAssets(shares), blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD + slippage), shares);
565
580
  actions.push({
566
581
  type: "erc4626Mint",
567
- args: [address, shares, maxSharePrice, owner, operation.skipRevert],
582
+ args: [
583
+ operation.address,
584
+ shares,
585
+ maxSharePrice,
586
+ owner,
587
+ operation.skipRevert,
588
+ ],
568
589
  });
569
590
  }
570
591
  break;
@@ -573,14 +594,14 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
573
594
  const { assets = 0n, shares = 0n, owner, receiver, slippage = blue_sdk_1.DEFAULT_SLIPPAGE_TOLERANCE, } = operation.args;
574
595
  // Accrue interest to calculate the expected share price.
575
596
  const vault = dataBefore
576
- .getAccrualVault(address)
597
+ .getAccrualVault(operation.address)
577
598
  .accrueInterest(dataBefore.block.timestamp);
578
599
  if (shares === 0n) {
579
600
  const minSharePrice = blue_sdk_1.MathLib.mulDivUp(assets, blue_sdk_1.MathLib.wToRay(blue_sdk_1.MathLib.WAD - slippage), vault.toShares(assets));
580
601
  actions.push({
581
602
  type: "erc4626Withdraw",
582
603
  args: [
583
- address,
604
+ operation.address,
584
605
  assets,
585
606
  minSharePrice,
586
607
  receiver,
@@ -594,7 +615,7 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
594
615
  actions.push({
595
616
  type: "erc4626Redeem",
596
617
  args: [
597
- address,
618
+ operation.address,
598
619
  shares,
599
620
  minSharePrice,
600
621
  receiver,
@@ -607,12 +628,13 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
607
628
  }
608
629
  case "MetaMorpho_PublicReallocate": {
609
630
  const { withdrawals, supplyMarketId } = operation.args;
610
- const { fee } = dataBefore.getVault(address).publicAllocatorConfig;
631
+ const { fee } = dataBefore.getVault(operation.address)
632
+ .publicAllocatorConfig;
611
633
  // Value is already accrued via another native input transfer.
612
634
  actions.push({
613
635
  type: "reallocateTo",
614
636
  args: [
615
- address,
637
+ operation.address,
616
638
  fee,
617
639
  withdrawals.map(({ id, assets }) => ({
618
640
  marketParams: dataBefore.getMarket(id).params,
@@ -624,6 +646,142 @@ const encodeOperation = (operation, dataBefore, supportsSignature = true, index
624
646
  });
625
647
  break;
626
648
  }
649
+ case "Blue_FlashLoan": {
650
+ const { token, assets } = operation.args;
651
+ actions.push({
652
+ type: "morphoFlashLoan",
653
+ args: [
654
+ token,
655
+ assets,
656
+ callbackBundle?.actions ?? [],
657
+ operation.skipRevert,
658
+ ],
659
+ });
660
+ break;
661
+ }
662
+ case "Paraswap_Buy": {
663
+ if (!("swap" in operation.args))
664
+ throw new errors_js_1.BundlerErrors.MissingSwapData();
665
+ if (paraswapAdapter == null)
666
+ throw new errors_js_1.BundlerErrors.UnexpectedAction("paraswapBuy", chainId);
667
+ const { srcToken, swap, receiver } = operation.args;
668
+ const limitAmountOffset = Number(swap.offsets.limitAmount);
669
+ const limitAmount = (0, viem_1.hexToBigInt)((0, viem_1.slice)(swap.data, limitAmountOffset, limitAmountOffset + 32));
670
+ actions.push({
671
+ type: "erc20Transfer",
672
+ args: [
673
+ srcToken,
674
+ paraswapAdapter,
675
+ limitAmount,
676
+ generalAdapter1,
677
+ operation.skipRevert,
678
+ ],
679
+ }, {
680
+ type: "paraswapBuy",
681
+ args: [
682
+ swap.to,
683
+ swap.data,
684
+ srcToken,
685
+ operation.address,
686
+ swap.offsets,
687
+ receiver === paraswapAdapter ? generalAdapter1 : receiver,
688
+ operation.skipRevert,
689
+ ],
690
+ }, {
691
+ type: "erc20Transfer",
692
+ args: [
693
+ srcToken,
694
+ generalAdapter1,
695
+ viem_1.maxUint256,
696
+ paraswapAdapter,
697
+ operation.skipRevert,
698
+ ],
699
+ });
700
+ break;
701
+ }
702
+ case "Paraswap_Sell": {
703
+ if (!("swap" in operation.args))
704
+ throw new errors_js_1.BundlerErrors.MissingSwapData();
705
+ if (paraswapAdapter == null)
706
+ throw new errors_js_1.BundlerErrors.UnexpectedAction("paraswapBuy", chainId);
707
+ const { dstToken, swap, sellEntireBalance = false, receiver, } = operation.args;
708
+ const exactAmountOffset = Number(swap.offsets.exactAmount);
709
+ const exactAmount = (0, viem_1.hexToBigInt)((0, viem_1.slice)(swap.data, exactAmountOffset, exactAmountOffset + 32));
710
+ actions.push({
711
+ type: "erc20Transfer",
712
+ args: [
713
+ operation.address,
714
+ paraswapAdapter,
715
+ sellEntireBalance ? viem_1.maxUint256 : exactAmount,
716
+ generalAdapter1,
717
+ operation.skipRevert,
718
+ ],
719
+ }, {
720
+ type: "paraswapSell",
721
+ args: [
722
+ swap.to,
723
+ swap.data,
724
+ operation.address,
725
+ dstToken,
726
+ sellEntireBalance,
727
+ swap.offsets,
728
+ receiver === paraswapAdapter ? generalAdapter1 : receiver,
729
+ operation.skipRevert,
730
+ ],
731
+ });
732
+ if (!sellEntireBalance)
733
+ actions.push({
734
+ type: "erc20Transfer",
735
+ args: [
736
+ operation.address,
737
+ generalAdapter1,
738
+ viem_1.maxUint256,
739
+ paraswapAdapter,
740
+ operation.skipRevert,
741
+ ],
742
+ });
743
+ break;
744
+ }
745
+ case "Blue_Paraswap_BuyDebt": {
746
+ if (!("swap" in operation.args))
747
+ throw new errors_js_1.BundlerErrors.MissingSwapData();
748
+ if (paraswapAdapter == null)
749
+ throw new errors_js_1.BundlerErrors.UnexpectedAction("paraswapBuy", chainId);
750
+ const { srcToken, id, swap, onBehalf, receiver } = operation.args;
751
+ const { params } = dataBefore.getMarket(id);
752
+ actions.push({
753
+ type: "erc20Transfer",
754
+ args: [
755
+ srcToken,
756
+ paraswapAdapter,
757
+ viem_1.maxUint256,
758
+ generalAdapter1,
759
+ operation.skipRevert,
760
+ ],
761
+ }, {
762
+ type: "paraswapBuyMorphoDebt",
763
+ args: [
764
+ swap.to,
765
+ swap.data,
766
+ srcToken,
767
+ params,
768
+ swap.offsets,
769
+ onBehalf,
770
+ receiver === paraswapAdapter ? generalAdapter1 : receiver,
771
+ operation.skipRevert,
772
+ ],
773
+ }, {
774
+ type: "erc20Transfer",
775
+ args: [
776
+ srcToken,
777
+ generalAdapter1,
778
+ viem_1.maxUint256,
779
+ paraswapAdapter,
780
+ operation.skipRevert,
781
+ ],
782
+ });
783
+ break;
784
+ }
627
785
  }
628
786
  return {
629
787
  dataAfter,
package/lib/errors.d.ts CHANGED
@@ -12,6 +12,9 @@ export declare namespace BundlerErrors {
12
12
  class MissingSignature extends Error {
13
13
  constructor();
14
14
  }
15
+ class MissingSwapData extends Error {
16
+ constructor();
17
+ }
15
18
  class UnexpectedAction extends Error {
16
19
  constructor(type: ActionType, chainId: number);
17
20
  }
package/lib/errors.js CHANGED
@@ -24,6 +24,12 @@ var BundlerErrors;
24
24
  }
25
25
  }
26
26
  BundlerErrors.MissingSignature = MissingSignature;
27
+ class MissingSwapData extends Error {
28
+ constructor() {
29
+ super(`missing swap data`);
30
+ }
31
+ }
32
+ BundlerErrors.MissingSwapData = MissingSwapData;
27
33
  class UnexpectedAction extends Error {
28
34
  constructor(type, chainId) {
29
35
  super(`unexpected action "${type}" on chain "${chainId}"`);
@@ -61,7 +61,7 @@ export declare const simulateRequiredTokenAmounts: (operations: Operation[], dat
61
61
  token: `0x${string}`;
62
62
  required: bigint;
63
63
  }[];
64
- export declare const getSimulatedBundlerOperation: (operation: BundlerOperation, { slippage }?: {
64
+ export declare const getSimulatedBundlerOperation: (operation: Omit<BundlerOperation, "sender">, { slippage }?: {
65
65
  slippage?: bigint;
66
66
  }) => Operation;
67
67
  export declare const handleBundlerOperation: (options?: {
package/lib/operations.js CHANGED
@@ -135,7 +135,7 @@ exports.populateInputTransfer = populateInputTransfer;
135
135
  */
136
136
  const populateSubBundle = (inputOperation, data, options = {}) => {
137
137
  const { sender } = inputOperation;
138
- const { morpho, bundler3: { bundler3, generalAdapter1 }, } = (0, blue_sdk_1.getChainAddresses)(data.chainId);
138
+ const { bundler3: { bundler3, generalAdapter1 }, } = (0, blue_sdk_1.getChainAddresses)(data.chainId);
139
139
  const { withSimplePermit = new Set(), publicAllocatorOptions, getRequirementOperations, } = options;
140
140
  const operations = [];
141
141
  const wrappedToken = inputOperation.type === "Erc20_Wrap"
@@ -143,50 +143,53 @@ const populateSubBundle = (inputOperation, data, options = {}) => {
143
143
  : undefined;
144
144
  const isErc20Wrapper = !!wrappedToken &&
145
145
  !!blue_sdk_1.erc20WrapperTokens[data.chainId]?.has(wrappedToken.address);
146
- // Transform input operation to act on behalf of the sender, via the bundler.
147
146
  const mainOperation = (0, simulation_sdk_1.produceImmutable)(inputOperation, (draft) => {
148
- draft.sender = generalAdapter1;
149
- // Redirect MetaMorpho operation owner.
150
- switch (draft.type) {
151
- case "Erc20_Wrap": {
152
- // ERC20Wrapper are skipped because tokens are sent to the caller, not the bundler.
153
- if (isErc20Wrapper) {
154
- draft.args.owner = sender;
155
- break;
156
- }
147
+ if (draft.type === "Erc20_Wrap" && isErc20Wrapper)
148
+ // ERC20Wrapper wrapped tokens are sent to the caller, not the bundler.
149
+ draft.args.owner = sender;
150
+ // Transform input operation to act on behalf of the sender, when sender is not the bundler.
151
+ if (sender !== generalAdapter1) {
152
+ draft.sender = generalAdapter1;
153
+ // Redirect MetaMorpho operation owner.
154
+ switch (draft.type) {
155
+ case "MetaMorpho_Deposit":
156
+ case "MetaMorpho_Withdraw":
157
+ // Only if sender is owner otherwise the owner would be lost.
158
+ if (draft.args.owner === sender)
159
+ draft.args.owner = generalAdapter1;
160
+ }
161
+ // Redirect operation targets.
162
+ switch (draft.type) {
163
+ case "Blue_Borrow":
164
+ case "Blue_Withdraw":
165
+ case "Blue_WithdrawCollateral":
166
+ draft.args.onBehalf = sender;
167
+ case "MetaMorpho_Withdraw":
168
+ case "Paraswap_Buy":
169
+ case "Paraswap_Sell":
170
+ case "Blue_Paraswap_BuyDebt":
171
+ // Only if sender is receiver otherwise the receiver would be lost.
172
+ if (draft.args.receiver === sender)
173
+ draft.args.receiver = generalAdapter1;
157
174
  }
158
- case "MetaMorpho_Deposit":
159
- case "MetaMorpho_Withdraw":
160
- // Only if sender is owner otherwise the owner would be lost.
161
- if (draft.args.owner === sender)
162
- draft.args.owner = generalAdapter1;
163
- }
164
- // Redirect operation targets.
165
- switch (draft.type) {
166
- case "Blue_Borrow":
167
- case "Blue_Withdraw":
168
- case "Blue_WithdrawCollateral":
169
- draft.args.onBehalf = sender;
170
- case "MetaMorpho_Withdraw":
171
- // Only if sender is receiver otherwise the receiver would be lost.
172
- if (draft.args.receiver === sender)
173
- draft.args.receiver = generalAdapter1;
174
175
  }
175
176
  });
176
- const needsBundlerAuthorization = mainOperation.type === "Blue_Borrow" ||
177
+ if (mainOperation.type === "Blue_Borrow" ||
177
178
  mainOperation.type === "Blue_Withdraw" ||
178
- mainOperation.type === "Blue_WithdrawCollateral";
179
- if (needsBundlerAuthorization && !data.getUser(sender).isBundlerAuthorized)
180
- operations.push({
181
- type: "Blue_SetAuthorization",
182
- sender: bundler3,
183
- address: morpho,
184
- args: {
185
- owner: sender,
186
- isAuthorized: true,
187
- authorized: generalAdapter1,
188
- },
189
- });
179
+ mainOperation.type === "Blue_WithdrawCollateral") {
180
+ // Either sender === generalAdapter1 or sender === onBehalf.
181
+ const { onBehalf } = mainOperation.args;
182
+ if (!data.getUser(onBehalf).isBundlerAuthorized)
183
+ operations.push({
184
+ type: "Blue_SetAuthorization",
185
+ sender: bundler3,
186
+ args: {
187
+ owner: onBehalf,
188
+ isAuthorized: true,
189
+ authorized: generalAdapter1,
190
+ },
191
+ });
192
+ }
190
193
  // Reallocate liquidity if necessary.
191
194
  if (!!publicAllocatorOptions?.enabled &&
192
195
  (mainOperation.type === "Blue_Borrow" ||
@@ -284,7 +287,11 @@ const populateSubBundle = (inputOperation, data, options = {}) => {
284
287
  ...(callback && {
285
288
  callback: (data) => {
286
289
  const operations = callback.flatMap((inputOperation) => {
287
- const subBundleOperations = (0, exports.populateSubBundle)(inputOperation, data, options);
290
+ const subBundleOperations = (0, exports.populateSubBundle)({
291
+ ...inputOperation,
292
+ // Inside a callback, the sender is forced to be the generalAdapter1.
293
+ sender: generalAdapter1,
294
+ }, data, options);
288
295
  // Handle to mutate data (not simulate).
289
296
  (0, exports.handleBundlerOperations)(subBundleOperations, data);
290
297
  return subBundleOperations;
@@ -296,9 +303,13 @@ const populateSubBundle = (inputOperation, data, options = {}) => {
296
303
  }),
297
304
  },
298
305
  };
299
- // Operations with callbacks are populated recursively as a side-effect of the simulation, within the callback itself.
300
- let requiredTokenAmounts = (0, exports.simulateRequiredTokenAmounts)(operations.concat([simulatedOperation]), data);
306
+ let requiredTokenAmounts = (0, exports.simulateRequiredTokenAmounts)(
307
+ // Safe cast because operations do not contain callbacks.
308
+ operations.concat([simulatedOperation]), data);
309
+ // Safe cast because operations do not contain callbacks.
301
310
  const allOperations = operations.concat([
311
+ // Safe cast because mainOperation, if including a callback, was transformed to a BundlerOperation
312
+ // within the callback executed through the simulation `simulateRequiredTokenAmounts`.
302
313
  mainOperation,
303
314
  ]);
304
315
  // Skip approvals/transfers if operation only uses available balances (via maxUint256).
@@ -654,6 +665,9 @@ const getSimulatedBundlerOperation = (operation, { slippage } = {}) => {
654
665
  case "Blue_Repay":
655
666
  case "MetaMorpho_Deposit":
656
667
  case "MetaMorpho_Withdraw":
668
+ case "Paraswap_Buy":
669
+ case "Paraswap_Sell":
670
+ case "Blue_Paraswap_BuyDebt":
657
671
  simulatedOperation.args.slippage = slippage;
658
672
  break;
659
673
  }
@@ -1,5 +1,6 @@
1
1
  import type { Account, Chain, Client, Hex, TransactionRequest, Transport } from "viem";
2
2
  import type { Address, InputMarketParams } from "@morpho-org/blue-sdk";
3
+ import type { ParaswapOffsets } from "@morpho-org/simulation-sdk";
3
4
  export interface Authorization {
4
5
  authorizer: Address;
5
6
  authorized: Address;
@@ -163,6 +164,12 @@ export interface ActionArgs {
163
164
  receiver: Address,
164
165
  skipRevert?: boolean
165
166
  ];
167
+ morphoFlashLoan: [
168
+ token: Address,
169
+ assets: bigint,
170
+ onMorphoFlashLoan: Action[],
171
+ skipRevert?: boolean
172
+ ];
166
173
  reallocateTo: [
167
174
  vault: Address,
168
175
  fee: bigint,
@@ -170,6 +177,35 @@ export interface ActionArgs {
170
177
  supplyMarket: InputMarketParams,
171
178
  skipRevert?: boolean
172
179
  ];
180
+ paraswapBuy: [
181
+ augustus: Address,
182
+ callData: Hex,
183
+ srcToken: Address,
184
+ dstToken: Address,
185
+ offsets: ParaswapOffsets,
186
+ receiver: Address,
187
+ skipRevert?: boolean
188
+ ];
189
+ paraswapSell: [
190
+ augustus: Address,
191
+ callData: Hex,
192
+ srcToken: Address,
193
+ dstToken: Address,
194
+ sellEntireBalance: boolean,
195
+ offsets: ParaswapOffsets,
196
+ receiver: Address,
197
+ skipRevert?: boolean
198
+ ];
199
+ paraswapBuyMorphoDebt: [
200
+ augustus: Address,
201
+ callData: Hex,
202
+ srcToken: Address,
203
+ marketParams: InputMarketParams,
204
+ offsets: ParaswapOffsets,
205
+ onBehalf: Address,
206
+ receiver: Address,
207
+ skipRevert?: boolean
208
+ ];
173
209
  urdClaim: [
174
210
  distributor: Address,
175
211
  account: Address,
@@ -1,53 +1,77 @@
1
- import type { BlueOperationArgs, CALLBACK_OPERATIONS, Erc20OperationArgs, MetaMorphoOperationArgs, OperationArgs, OperationType, WithOperationArgs } from "@morpho-org/simulation-sdk";
2
- export declare const BUNDLER_OPERATIONS: readonly ["Blue_SetAuthorization", "Blue_Borrow", "Blue_Repay", "Blue_Supply", "Blue_SupplyCollateral", "Blue_Withdraw", "Blue_WithdrawCollateral", "MetaMorpho_Deposit", "MetaMorpho_Withdraw", "MetaMorpho_PublicReallocate", "Erc20_Approve", "Erc20_Permit", "Erc20_Permit2", "Erc20_Transfer", "Erc20_Transfer2", "Erc20_Wrap", "Erc20_Unwrap"];
3
- export type BundlerOperationType = (typeof BUNDLER_OPERATIONS)[number];
4
- export interface BundlerOperationArgs extends Omit<OperationArgs, (typeof CALLBACK_OPERATIONS)[number]> {
5
- Blue_SupplyCollateral: Omit<BlueOperationArgs["Blue_SupplyCollateral"], "callback"> & {
6
- callback?: BundlerOperation[];
1
+ import { type BlueOperationArgs, CALLBACK_OPERATIONS, type CallbackOperationType, type Erc20OperationArgs, type MetaMorphoOperationArgs, type OperationArgs, type OperationType, type ParaswapOperationArgs, type WithOperationArgs } from "@morpho-org/simulation-sdk";
2
+ import type { UnionOmit } from "viem";
3
+ export declare const BLUE_BUNDLER_OPERATIONS: readonly ["Blue_SetAuthorization", "Blue_Borrow", "Blue_Repay", "Blue_Supply", "Blue_SupplyCollateral", "Blue_Withdraw", "Blue_WithdrawCollateral", "Blue_FlashLoan", "Blue_Paraswap_BuyDebt"];
4
+ export type BlueBundlerOperationType = (typeof BLUE_BUNDLER_OPERATIONS)[number];
5
+ export type BlueBundlerOperationArgs = Omit<BlueOperationArgs, (typeof CALLBACK_OPERATIONS)[number]> & {
6
+ [OperationType in CallbackOperationType]: Omit<BlueOperationArgs[OperationType], "callback"> & {
7
+ /**
8
+ * Inside a callback, the sender is forced to be the generalAdapter1.
9
+ */
10
+ callback?: UnionOmit<BundlerOperation, "sender">[];
7
11
  };
8
- Blue_Supply: Omit<BlueOperationArgs["Blue_Supply"], "callback"> & {
9
- callback?: BundlerOperation[];
10
- };
11
- Blue_Repay: Omit<BlueOperationArgs["Blue_Repay"], "callback"> & {
12
- callback?: BundlerOperation[];
13
- };
14
- }
15
- export type BundlerOperations = {
16
- [OperationType in BundlerOperationType]: WithOperationArgs<OperationType, BundlerOperationArgs>;
17
12
  };
18
- export type BundlerOperation = BundlerOperations[BundlerOperationType];
19
- export type CallbackBundlerOperationType = (typeof CALLBACK_OPERATIONS)[number];
20
- export type CallbackBundlerOperations = {
21
- [OperationType in CallbackBundlerOperationType]: WithOperationArgs<OperationType, BundlerOperationArgs>;
13
+ export type BlueBundlerOperations = {
14
+ [OperationType in BlueBundlerOperationType]: Omit<WithOperationArgs<OperationType, BlueBundlerOperationArgs>, "address">;
15
+ };
16
+ export type BlueBundlerOperation = BlueBundlerOperations[BlueBundlerOperationType];
17
+ export declare const METAMORPHO_BUNDLER_OPERATIONS: readonly ["MetaMorpho_Deposit", "MetaMorpho_Withdraw", "MetaMorpho_PublicReallocate"];
18
+ export type MetaMorphoBundlerOperationType = (typeof METAMORPHO_BUNDLER_OPERATIONS)[number];
19
+ export type MetaMorphoBundlerOperations = {
20
+ [OperationType in MetaMorphoBundlerOperationType]: WithOperationArgs<OperationType, MetaMorphoOperationArgs>;
21
+ };
22
+ export type MetaMorphoBundlerOperation = MetaMorphoBundlerOperations[MetaMorphoBundlerOperationType];
23
+ export declare const PARASWAP_BUNDLER_OPERATIONS: readonly ["Paraswap_Buy", "Paraswap_Sell"];
24
+ export type ParaswapBundlerOperationType = (typeof PARASWAP_BUNDLER_OPERATIONS)[number];
25
+ export type ParaswapBundlerOperations = {
26
+ [OperationType in ParaswapBundlerOperationType]: WithOperationArgs<OperationType, ParaswapOperationArgs>;
27
+ };
28
+ export type ParaswapBundlerOperation = ParaswapBundlerOperations[ParaswapBundlerOperationType];
29
+ export declare const ERC20_BUNDLER_OPERATIONS: readonly ["Erc20_Approve", "Erc20_Permit", "Erc20_Permit2", "Erc20_Transfer", "Erc20_Transfer2", "Erc20_Wrap", "Erc20_Unwrap"];
30
+ export type Erc20BundlerOperationType = (typeof ERC20_BUNDLER_OPERATIONS)[number];
31
+ export type Erc20BundlerOperations = {
32
+ [OperationType in Erc20BundlerOperationType]: WithOperationArgs<OperationType, Erc20OperationArgs>;
22
33
  };
34
+ export type Erc20BundlerOperation = Erc20BundlerOperations[Erc20BundlerOperationType];
35
+ export interface BundlerOperationArgs extends BlueOperationArgs, MetaMorphoOperationArgs, ParaswapOperationArgs, Erc20OperationArgs {
36
+ }
37
+ export type BundlerOperations = BlueBundlerOperations & MetaMorphoBundlerOperations & ParaswapBundlerOperations & Erc20BundlerOperations;
38
+ export type BundlerOperationType = BlueBundlerOperationType | MetaMorphoBundlerOperationType | ParaswapBundlerOperationType | Erc20BundlerOperationType;
39
+ export type BundlerOperation = BlueBundlerOperation | MetaMorphoBundlerOperation | ParaswapBundlerOperation | Erc20BundlerOperation;
40
+ export declare const BUNDLER_OPERATIONS: readonly ["Blue_SetAuthorization", "Blue_Borrow", "Blue_Repay", "Blue_Supply", "Blue_SupplyCollateral", "Blue_Withdraw", "Blue_WithdrawCollateral", "Blue_FlashLoan", "Blue_Paraswap_BuyDebt", "MetaMorpho_Deposit", "MetaMorpho_Withdraw", "MetaMorpho_PublicReallocate", "Erc20_Approve", "Erc20_Permit", "Erc20_Permit2", "Erc20_Transfer", "Erc20_Transfer2", "Erc20_Wrap", "Erc20_Unwrap"];
41
+ export type CallbackBundlerOperationType = (typeof CALLBACK_OPERATIONS)[number];
42
+ export type CallbackBundlerOperations = Pick<BundlerOperations, CallbackBundlerOperationType>;
23
43
  export type CallbackBundlerOperation = CallbackBundlerOperations[CallbackBundlerOperationType];
24
- export declare const BLUE_INPUT_OPERATIONS: readonly ["Blue_Borrow", "Blue_Repay", "Blue_Supply", "Blue_SupplyCollateral", "Blue_Withdraw", "Blue_WithdrawCollateral", "Blue_SetAuthorization"];
44
+ export declare const isBlueBundlerOperation: (operation: BundlerOperation) => operation is BlueBundlerOperation;
45
+ export declare const isMetaMorphoBundlerOperation: (operation: BundlerOperation) => operation is MetaMorphoBundlerOperation;
46
+ export declare const isErc20BundlerOperation: (operation: BundlerOperation) => operation is Erc20BundlerOperation;
47
+ export declare const isCallbackBundlerOperation: (operation: BundlerOperation) => operation is CallbackBundlerOperation;
48
+ export declare const BLUE_INPUT_OPERATIONS: readonly ["Blue_SetAuthorization", "Blue_Borrow", "Blue_Repay", "Blue_Supply", "Blue_SupplyCollateral", "Blue_Withdraw", "Blue_WithdrawCollateral", "Blue_FlashLoan", "Blue_Paraswap_BuyDebt"];
25
49
  export type BlueInputBundlerOperationType = (typeof BLUE_INPUT_OPERATIONS)[number];
26
- export interface BlueInputBundlerOperationArgs extends Omit<OperationArgs, (typeof CALLBACK_OPERATIONS)[number]> {
27
- Blue_SupplyCollateral: Omit<BlueOperationArgs["Blue_SupplyCollateral"], "callback"> & {
28
- callback?: InputBundlerOperation[];
29
- };
30
- Blue_Supply: Omit<BlueOperationArgs["Blue_Supply"], "callback"> & {
31
- callback?: InputBundlerOperation[];
32
- };
33
- Blue_Repay: Omit<BlueOperationArgs["Blue_Repay"], "callback"> & {
34
- callback?: InputBundlerOperation[];
50
+ export type BlueInputBundlerOperationArgs = Omit<OperationArgs, (typeof CALLBACK_OPERATIONS)[number]> & {
51
+ [OperationType in CallbackOperationType]: Omit<OperationArgs[OperationType], "callback"> & {
52
+ /**
53
+ * Inside a callback, the sender is forced to be the generalAdapter1.
54
+ */
55
+ callback?: UnionOmit<InputBundlerOperation, "sender">[];
35
56
  };
36
- }
57
+ };
37
58
  export type BlueInputBundlerOperations = {
38
- [OperationType in BlueInputBundlerOperationType]: WithOperationArgs<OperationType, BlueInputBundlerOperationArgs>;
59
+ [OperationType in BlueInputBundlerOperationType]: Omit<WithOperationArgs<OperationType, BlueInputBundlerOperationArgs>, "address">;
39
60
  };
40
61
  export type BlueInputBundlerOperation = BlueInputBundlerOperations[BlueInputBundlerOperationType];
41
62
  export declare const METAMORPHO_INPUT_OPERATIONS: readonly ["MetaMorpho_Deposit", "MetaMorpho_Withdraw"];
42
63
  export type MetaMorphoInputBundlerOperationType = (typeof METAMORPHO_INPUT_OPERATIONS)[number];
43
- export type MetaMorphoInputBundlerOperation = BundlerOperations[MetaMorphoInputBundlerOperationType];
44
- export declare const ERC20_INPUT_OPERATIONS: readonly ["Erc20_Wrap", "Erc20_Unwrap"];
64
+ export type MetaMorphoInputBundlerOperation = MetaMorphoBundlerOperations[MetaMorphoInputBundlerOperationType];
65
+ export declare const PARASWAP_INPUT_OPERATIONS: readonly ["Paraswap_Buy", "Paraswap_Sell"];
66
+ export type ParaswapInputBundlerOperationType = (typeof PARASWAP_INPUT_OPERATIONS)[number];
67
+ export type ParaswapInputBundlerOperation = BundlerOperations[ParaswapInputBundlerOperationType];
68
+ export declare const ERC20_INPUT_OPERATIONS: readonly ["Erc20_Approve", "Erc20_Permit", "Erc20_Permit2", "Erc20_Transfer", "Erc20_Transfer2", "Erc20_Wrap", "Erc20_Unwrap"];
45
69
  export type Erc20InputBundlerOperationType = (typeof ERC20_INPUT_OPERATIONS)[number];
46
- export type Erc20InputBundlerOperation = BundlerOperations[Erc20InputBundlerOperationType];
47
- export interface InputBundlerOperationArgs extends BlueOperationArgs, MetaMorphoOperationArgs, Erc20OperationArgs {
70
+ export type Erc20InputBundlerOperation = Erc20BundlerOperations[Erc20InputBundlerOperationType];
71
+ export interface InputBundlerOperationArgs extends BlueOperationArgs, MetaMorphoOperationArgs, ParaswapOperationArgs, Erc20OperationArgs {
48
72
  }
49
- export type InputBundlerOperationType = BlueInputBundlerOperationType | MetaMorphoInputBundlerOperationType | Erc20InputBundlerOperationType;
50
- export type InputBundlerOperation = BlueInputBundlerOperation | MetaMorphoInputBundlerOperation | Erc20InputBundlerOperation;
73
+ export type InputBundlerOperationType = BlueInputBundlerOperationType | MetaMorphoInputBundlerOperationType | ParaswapInputBundlerOperationType | Erc20InputBundlerOperationType;
74
+ export type InputBundlerOperation = BlueInputBundlerOperation | MetaMorphoInputBundlerOperation | ParaswapInputBundlerOperation | Erc20InputBundlerOperation;
51
75
  export declare const isBlueInputBundlerOperation: (operation: {
52
76
  type: OperationType;
53
77
  }) => operation is BlueInputBundlerOperation;
@@ -57,3 +81,6 @@ export declare const isMetaMorphoInputBundlerOperation: (operation: {
57
81
  export declare const isErc20InputBundlerOperation: (operation: {
58
82
  type: OperationType;
59
83
  }) => operation is Erc20InputBundlerOperation;
84
+ export declare const isParaswapInputBundlerOperation: (operation: {
85
+ type: OperationType;
86
+ }) => operation is ParaswapInputBundlerOperation;
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isErc20InputBundlerOperation = exports.isMetaMorphoInputBundlerOperation = exports.isBlueInputBundlerOperation = exports.ERC20_INPUT_OPERATIONS = exports.METAMORPHO_INPUT_OPERATIONS = exports.BLUE_INPUT_OPERATIONS = exports.BUNDLER_OPERATIONS = void 0;
4
- exports.BUNDLER_OPERATIONS = [
3
+ exports.isParaswapInputBundlerOperation = exports.isErc20InputBundlerOperation = exports.isMetaMorphoInputBundlerOperation = exports.isBlueInputBundlerOperation = exports.ERC20_INPUT_OPERATIONS = exports.PARASWAP_INPUT_OPERATIONS = exports.METAMORPHO_INPUT_OPERATIONS = exports.BLUE_INPUT_OPERATIONS = exports.isCallbackBundlerOperation = exports.isErc20BundlerOperation = exports.isMetaMorphoBundlerOperation = exports.isBlueBundlerOperation = exports.BUNDLER_OPERATIONS = exports.ERC20_BUNDLER_OPERATIONS = exports.PARASWAP_BUNDLER_OPERATIONS = exports.METAMORPHO_BUNDLER_OPERATIONS = exports.BLUE_BUNDLER_OPERATIONS = void 0;
4
+ const simulation_sdk_1 = require("@morpho-org/simulation-sdk");
5
+ exports.BLUE_BUNDLER_OPERATIONS = [
5
6
  "Blue_SetAuthorization",
6
7
  "Blue_Borrow",
7
8
  "Blue_Repay",
@@ -9,41 +10,44 @@ exports.BUNDLER_OPERATIONS = [
9
10
  "Blue_SupplyCollateral",
10
11
  "Blue_Withdraw",
11
12
  "Blue_WithdrawCollateral",
13
+ "Blue_FlashLoan",
14
+ "Blue_Paraswap_BuyDebt",
15
+ ];
16
+ exports.METAMORPHO_BUNDLER_OPERATIONS = [
12
17
  "MetaMorpho_Deposit",
13
18
  "MetaMorpho_Withdraw",
14
19
  "MetaMorpho_PublicReallocate",
15
- "Erc20_Approve",
16
- "Erc20_Permit",
17
- "Erc20_Permit2",
18
- "Erc20_Transfer",
19
- "Erc20_Transfer2",
20
- "Erc20_Wrap",
21
- "Erc20_Unwrap",
22
20
  ];
23
- exports.BLUE_INPUT_OPERATIONS = [
24
- "Blue_Borrow",
25
- "Blue_Repay",
26
- "Blue_Supply",
27
- "Blue_SupplyCollateral",
28
- "Blue_Withdraw",
29
- "Blue_WithdrawCollateral",
30
- "Blue_SetAuthorization",
21
+ exports.PARASWAP_BUNDLER_OPERATIONS = simulation_sdk_1.PARASWAP_OPERATIONS;
22
+ exports.ERC20_BUNDLER_OPERATIONS = simulation_sdk_1.ERC20_OPERATIONS;
23
+ exports.BUNDLER_OPERATIONS = [
24
+ ...exports.BLUE_BUNDLER_OPERATIONS,
25
+ ...exports.METAMORPHO_BUNDLER_OPERATIONS,
26
+ ...exports.ERC20_BUNDLER_OPERATIONS,
31
27
  ];
28
+ const isBlueBundlerOperation = (operation) => {
29
+ return exports.BLUE_BUNDLER_OPERATIONS.includes(operation.type);
30
+ };
31
+ exports.isBlueBundlerOperation = isBlueBundlerOperation;
32
+ const isMetaMorphoBundlerOperation = (operation) => {
33
+ return exports.METAMORPHO_BUNDLER_OPERATIONS.includes(operation.type);
34
+ };
35
+ exports.isMetaMorphoBundlerOperation = isMetaMorphoBundlerOperation;
36
+ const isErc20BundlerOperation = (operation) => {
37
+ return exports.ERC20_BUNDLER_OPERATIONS.includes(operation.type);
38
+ };
39
+ exports.isErc20BundlerOperation = isErc20BundlerOperation;
40
+ const isCallbackBundlerOperation = (operation) => {
41
+ return simulation_sdk_1.CALLBACK_OPERATIONS.includes(operation.type);
42
+ };
43
+ exports.isCallbackBundlerOperation = isCallbackBundlerOperation;
44
+ exports.BLUE_INPUT_OPERATIONS = exports.BLUE_BUNDLER_OPERATIONS;
32
45
  exports.METAMORPHO_INPUT_OPERATIONS = [
33
46
  "MetaMorpho_Deposit",
34
47
  "MetaMorpho_Withdraw",
35
48
  ];
36
- exports.ERC20_INPUT_OPERATIONS = [
37
- "Erc20_Wrap",
38
- "Erc20_Unwrap",
39
- ];
40
- // export const isBundlerOperation = (
41
- // operation: Operation
42
- // ): operation is BundlerOperation => {
43
- // return (BUNDLER_OPERATIONS as readonly OperationType[]).includes(
44
- // operation.type
45
- // );
46
- // };
49
+ exports.PARASWAP_INPUT_OPERATIONS = exports.PARASWAP_BUNDLER_OPERATIONS;
50
+ exports.ERC20_INPUT_OPERATIONS = exports.ERC20_BUNDLER_OPERATIONS;
47
51
  const isBlueInputBundlerOperation = (operation) => {
48
52
  return exports.BLUE_INPUT_OPERATIONS.includes(operation.type);
49
53
  };
@@ -56,3 +60,7 @@ const isErc20InputBundlerOperation = (operation) => {
56
60
  return exports.ERC20_INPUT_OPERATIONS.includes(operation.type);
57
61
  };
58
62
  exports.isErc20InputBundlerOperation = isErc20InputBundlerOperation;
63
+ const isParaswapInputBundlerOperation = (operation) => {
64
+ return exports.PARASWAP_INPUT_OPERATIONS.includes(operation.type);
65
+ };
66
+ exports.isParaswapInputBundlerOperation = isParaswapInputBundlerOperation;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@morpho-org/bundler-sdk-viem",
3
3
  "description": "Viem-based extension of `@morpho-org/simulation-sdk` that exports utilities to transform simple interactions on Morpho (such as `Blue_Borrow`) and Morpho Vaults (such as `MetaMorpho_Deposit`) into the required bundles (with ERC20 approvals, transfers, etc) to submit to the bundler onchain.",
4
- "version": "3.1.3",
4
+ "version": "3.2.0-next.1",
5
5
  "author": "Morpho Association <contact@morpho.org>",
6
6
  "contributors": [
7
7
  "Rubilmax <rmilon@gmail.com>"
@@ -35,12 +35,12 @@
35
35
  "viem": "^2.23.0",
36
36
  "vitest": "^3.0.5",
37
37
  "@morpho-org/blue-sdk-viem": "^3.0.0",
38
- "@morpho-org/blue-sdk": "^3.0.6",
39
- "@morpho-org/morpho-ts": "^2.3.0",
40
38
  "@morpho-org/morpho-test": "^2.3.0",
39
+ "@morpho-org/morpho-ts": "^2.3.0",
41
40
  "@morpho-org/simulation-sdk": "^3.0.1",
42
- "@morpho-org/test": "^2.1.3",
41
+ "@morpho-org/blue-sdk": "^3.0.6",
43
42
  "@morpho-org/simulation-sdk-wagmi": "^3.0.1",
43
+ "@morpho-org/test": "^2.1.3",
44
44
  "@morpho-org/test-wagmi": "^2.0.4"
45
45
  },
46
46
  "scripts": {