@1inch/fusion-sdk 2.4.6 → 2.4.7-rc.0

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.
Files changed (34) hide show
  1. package/README.md +174 -25
  2. package/dist/cjs/api/quoter/quoter.api.spec.js +1 -2
  3. package/dist/cjs/constants.js +17 -3
  4. package/dist/cjs/fusion-order/fusion-order.js +94 -0
  5. package/dist/cjs/fusion-order/fusion-order.spec.js +87 -0
  6. package/dist/cjs/fusion-order/index.js +1 -0
  7. package/dist/cjs/fusion-order/permit/constants.js +98 -0
  8. package/dist/cjs/fusion-order/permit/index.js +34 -0
  9. package/dist/cjs/fusion-order/permit/permit-transfer-from.js +115 -0
  10. package/dist/cjs/fusion-order/permit/permit-transfer-from.spec.js +232 -0
  11. package/dist/cjs/fusion-order/permit/transfer-from-suffix.js +76 -0
  12. package/dist/cjs/fusion-order/permit/utils.js +35 -0
  13. package/dist/esm/api/quoter/quoter.api.spec.js +1 -2
  14. package/dist/esm/constants.js +15 -1
  15. package/dist/esm/fusion-order/fusion-order.js +95 -1
  16. package/dist/esm/fusion-order/fusion-order.spec.js +87 -0
  17. package/dist/esm/fusion-order/index.js +1 -0
  18. package/dist/esm/fusion-order/permit/constants.js +71 -0
  19. package/dist/esm/fusion-order/permit/index.js +3 -0
  20. package/dist/esm/fusion-order/permit/permit-transfer-from.js +105 -0
  21. package/dist/esm/fusion-order/permit/permit-transfer-from.spec.js +228 -0
  22. package/dist/esm/fusion-order/permit/transfer-from-suffix.js +53 -0
  23. package/dist/esm/fusion-order/permit/utils.js +12 -0
  24. package/dist/esm/package.json +1 -1
  25. package/dist/types/src/constants.d.ts +1 -1
  26. package/dist/types/src/fusion-order/fusion-order.d.ts +5 -0
  27. package/dist/types/src/fusion-order/index.d.ts +1 -0
  28. package/dist/types/src/fusion-order/permit/constants.d.ts +7 -0
  29. package/dist/types/src/fusion-order/permit/index.d.ts +3 -0
  30. package/dist/types/src/fusion-order/permit/permit-transfer-from.d.ts +11 -0
  31. package/dist/types/src/fusion-order/permit/transfer-from-suffix.d.ts +10 -0
  32. package/dist/types/src/fusion-order/permit/utils.d.ts +3 -0
  33. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  34. package/package.json +1 -1
package/README.md CHANGED
@@ -16,16 +16,22 @@ yarn add @1inch/fusion-sdk@2
16
16
 
17
17
  ## Modules docs
18
18
 
19
- - [auction-details](src/fusion-order/auction-details/README.md)
20
- - [fusion-order](src/fusion-order/README.md)
21
- - [sdk](src/sdk/README.md)
22
- - [ws-api](src/ws-api/README.md)
19
+ - [auction-details](src/fusion-order/auction-details/README.md)
20
+ - [fusion-order](src/fusion-order/README.md)
21
+ - [sdk](src/sdk/README.md)
22
+ - [ws-api](src/ws-api/README.md)
23
23
 
24
24
  ## How to swap with Fusion Mode
25
25
 
26
26
  ```typescript
27
- import {FusionSDK, NetworkEnum, OrderStatus, PrivateKeyProviderConnector, Web3Like,} from "@1inch/fusion-sdk";
28
- import {computeAddress, formatUnits, JsonRpcProvider} from "ethers";
27
+ import {
28
+ FusionSDK,
29
+ NetworkEnum,
30
+ OrderStatus,
31
+ PrivateKeyProviderConnector,
32
+ Web3Like
33
+ } from '@1inch/fusion-sdk'
34
+ import {computeAddress, formatUnits, JsonRpcProvider} from 'ethers'
29
35
 
30
36
  const PRIVATE_KEY = 'YOUR_PRIVATE_KEY'
31
37
  const NODE_URL = 'YOUR_WEB3_NODE_URL'
@@ -48,7 +54,7 @@ const connector = new PrivateKeyProviderConnector(
48
54
  )
49
55
 
50
56
  const sdk = new FusionSDK({
51
- url: 'https://api.1inch.dev/fusion',
57
+ url: 'https://api.1inch.com/fusion',
52
58
  network: NetworkEnum.BINANCE,
53
59
  blockchainProvider: connector,
54
60
  authKey: DEV_PORTAL_API_TOKEN
@@ -57,7 +63,7 @@ const sdk = new FusionSDK({
57
63
  async function main() {
58
64
  const params = {
59
65
  fromTokenAddress: '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', // USDC
60
- toTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', // BNB
66
+ toTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', // BNB
61
67
  amount: '10000000000000000000', // 10 USDC
62
68
  walletAddress: computeAddress(PRIVATE_KEY),
63
69
  source: 'sdk-test'
@@ -66,12 +72,25 @@ async function main() {
66
72
  const quote = await sdk.getQuote(params)
67
73
 
68
74
  const dstTokenDecimals = 18
69
- console.log('Auction start amount', formatUnits(quote.presets[quote.recommendedPreset].auctionStartAmount, dstTokenDecimals))
70
- console.log('Auction end amount', formatUnits(quote.presets[quote.recommendedPreset].auctionEndAmount), dstTokenDecimals)
75
+ console.log(
76
+ 'Auction start amount',
77
+ formatUnits(
78
+ quote.presets[quote.recommendedPreset].auctionStartAmount,
79
+ dstTokenDecimals
80
+ )
81
+ )
82
+ console.log(
83
+ 'Auction end amount',
84
+ formatUnits(quote.presets[quote.recommendedPreset].auctionEndAmount),
85
+ dstTokenDecimals
86
+ )
71
87
 
72
88
  const preparedOrder = await sdk.createOrder(params)
73
89
 
74
- const info = await sdk.submitOrder(preparedOrder.order, preparedOrder.quoteId)
90
+ const info = await sdk.submitOrder(
91
+ preparedOrder.order,
92
+ preparedOrder.quoteId
93
+ )
75
94
 
76
95
  console.log('OrderHash', info.orderHash)
77
96
 
@@ -90,7 +109,7 @@ async function main() {
90
109
  console.log('Order Expired')
91
110
  break
92
111
  }
93
-
112
+
94
113
  if (data.status === OrderStatus.Cancelled) {
95
114
  console.log('Order Cancelled')
96
115
  break
@@ -98,7 +117,6 @@ async function main() {
98
117
  } catch (e) {
99
118
  console.log(e)
100
119
  }
101
-
102
120
  }
103
121
 
104
122
  console.log('Order executed for', (Date.now() - start) / 1000, 'sec')
@@ -108,9 +126,18 @@ main()
108
126
  ```
109
127
 
110
128
  ## How to swap with Fusion mode from Native asset
129
+
111
130
  ```typescript
112
- import {FusionSDK, NetworkEnum, OrderStatus, PrivateKeyProviderConnector, Web3Like, Address, NativeOrdersFactory} from "@1inch/fusion-sdk";
113
- import {computeAddress, formatUnits, JsonRpcProvider, Wallet} from "ethers";
131
+ import {
132
+ FusionSDK,
133
+ NetworkEnum,
134
+ OrderStatus,
135
+ PrivateKeyProviderConnector,
136
+ Web3Like,
137
+ Address,
138
+ NativeOrdersFactory
139
+ } from '@1inch/fusion-sdk'
140
+ import {computeAddress, formatUnits, JsonRpcProvider, Wallet} from 'ethers'
114
141
 
115
142
  const PRIVATE_KEY = 'YOUR_PRIVATE_KEY'
116
143
  const NODE_URL = 'YOUR_WEB3_NODE_URL'
@@ -133,7 +160,7 @@ const connector = new PrivateKeyProviderConnector(
133
160
  )
134
161
 
135
162
  const sdk = new FusionSDK({
136
- url: 'https://api.1inch.dev/fusion',
163
+ url: 'https://api.1inch.com/fusion',
137
164
  network: NetworkEnum.BINANCE,
138
165
  blockchainProvider: connector,
139
166
  authKey: DEV_PORTAL_API_TOKEN
@@ -144,26 +171,43 @@ const wallet = new Wallet(PRIVATE_KEY, ethersRpcProvider)
144
171
  async function main() {
145
172
  const params = {
146
173
  fromTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', // ETH
147
- toTokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
174
+ toTokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
148
175
  amount: '2000000000000000', // 0.002 ETH
149
176
  walletAddress: computeAddress(PRIVATE_KEY),
150
177
  source: 'sdk-test'
151
178
  }
152
-
179
+
153
180
  const quote = await sdk.getQuote(params)
154
181
 
155
182
  const dstTokenDecimals = 6
156
- console.log('Auction start amount', formatUnits(quote.presets[quote.recommendedPreset].auctionStartAmount, dstTokenDecimals))
157
- console.log('Auction end amount', formatUnits(quote.presets[quote.recommendedPreset].auctionEndAmount), dstTokenDecimals)
183
+ console.log(
184
+ 'Auction start amount',
185
+ formatUnits(
186
+ quote.presets[quote.recommendedPreset].auctionStartAmount,
187
+ dstTokenDecimals
188
+ )
189
+ )
190
+ console.log(
191
+ 'Auction end amount',
192
+ formatUnits(quote.presets[quote.recommendedPreset].auctionEndAmount),
193
+ dstTokenDecimals
194
+ )
158
195
 
159
196
  const preparedOrder = await sdk.createOrder(params)
160
197
 
161
- const info = await sdk.submitNativeOrder(preparedOrder.order, new Address(params.walletAddress), preparedOrder.quoteId)
198
+ const info = await sdk.submitNativeOrder(
199
+ preparedOrder.order,
200
+ new Address(params.walletAddress),
201
+ preparedOrder.quoteId
202
+ )
162
203
 
163
204
  console.log('OrderHash', info.orderHash)
164
205
 
165
206
  const factory = NativeOrdersFactory.default(NetworkEnum.BINANCE)
166
- const call = factory.create(new Address(wallet.address), preparedOrder.order.build())
207
+ const call = factory.create(
208
+ new Address(wallet.address),
209
+ preparedOrder.order.build()
210
+ )
167
211
 
168
212
  const txRes = await wallet.sendTransaction({
169
213
  to: call.to.toString(),
@@ -175,7 +219,6 @@ async function main() {
175
219
 
176
220
  await wallet.provider.waitForTransaction(txRes.hash)
177
221
 
178
-
179
222
  const start = Date.now()
180
223
 
181
224
  while (true) {
@@ -191,7 +234,7 @@ async function main() {
191
234
  console.log('Order Expired')
192
235
  break
193
236
  }
194
-
237
+
195
238
  if (data.status === OrderStatus.Cancelled) {
196
239
  console.log('Order Cancelled')
197
240
  break
@@ -199,7 +242,6 @@ async function main() {
199
242
  } catch (e) {
200
243
  console.log(e)
201
244
  }
202
-
203
245
  }
204
246
 
205
247
  console.log('Order executed for', (Date.now() - start) / 1000, 'sec')
@@ -208,6 +250,113 @@ async function main() {
208
250
  main()
209
251
  ```
210
252
 
253
+ ## How to swap with Fusion Mode using TransferPermit
254
+
255
+ Instead of granting a token approval to the 1inch Limit Order Protocol, you can use a `TransferPermit` for signature-based transfers via a Permit2Proxy contract.
256
+
257
+ The maker only needs to approve tokens to the Permit2 contract once. Each order then carries a single-use `PermitTransferFrom` signature instead of an on-chain allowance to the protocol.
258
+
259
+ ```typescript
260
+ import {
261
+ FusionSDK,
262
+ NetworkEnum,
263
+ OrderStatus,
264
+ PrivateKeyProviderConnector,
265
+ Web3Like,
266
+ getPermit2Address
267
+ } from '@1inch/fusion-sdk'
268
+ import {computeAddress, JsonRpcProvider, Wallet} from 'ethers'
269
+
270
+ const PRIVATE_KEY = 'YOUR_PRIVATE_KEY'
271
+ const NODE_URL = 'YOUR_WEB3_NODE_URL'
272
+ const DEV_PORTAL_API_TOKEN = 'YOUR_DEV_PORTAL_API_TOKEN'
273
+
274
+ const ethersRpcProvider = new JsonRpcProvider(NODE_URL)
275
+
276
+ const ethersProviderConnector: Web3Like = {
277
+ eth: {
278
+ call(transactionConfig): Promise<string> {
279
+ return ethersRpcProvider.call(transactionConfig)
280
+ }
281
+ },
282
+ extend(): void {}
283
+ }
284
+
285
+ const connector = new PrivateKeyProviderConnector(
286
+ PRIVATE_KEY,
287
+ ethersProviderConnector
288
+ )
289
+
290
+ const sdk = new FusionSDK({
291
+ url: 'https://api.1inch.com/fusion',
292
+ network: NetworkEnum.ETHEREUM,
293
+ blockchainProvider: connector,
294
+ authKey: DEV_PORTAL_API_TOKEN
295
+ })
296
+
297
+ const wallet = new Wallet(PRIVATE_KEY, ethersRpcProvider)
298
+
299
+ async function main() {
300
+ // Step 1: Approve token to the Permit2 contract (one-time, can be unlimited)
301
+ // This replaces the usual approval to the 1inch Limit Order Protocol
302
+ const permit2Address = getPermit2Address(NetworkEnum.ETHEREUM)
303
+ // await approveToken(fromTokenAddress, permit2Address, MAX_UINT256)
304
+
305
+ // Step 2: Get quote and create order
306
+ const params = {
307
+ fromTokenAddress: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // WETH
308
+ toTokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
309
+ amount: '50000000000000000', // 0.05 WETH
310
+ walletAddress: computeAddress(PRIVATE_KEY)
311
+ }
312
+
313
+ const {order, quoteId} = await sdk.createOrder(params)
314
+
315
+ // Step 3: Create a transfer permit for the order
316
+ const permit = order.createTransferPermit(NetworkEnum.ETHEREUM)
317
+
318
+ // Step 4: Sign the transfer permit
319
+ const permitTypedData = permit.getTypedData(NetworkEnum.ETHEREUM)
320
+ const permitSignature = await connector.signTypedData(
321
+ params.walletAddress,
322
+ permitTypedData
323
+ )
324
+
325
+ // Step 5: Attach the signed permit to the order
326
+ const orderWithPermit = order.withTransferPermit(permit, permitSignature)
327
+
328
+ // Step 6: Submit the order (the SDK signs the order and sends it to the relayer)
329
+ const info = await sdk.submitOrder(orderWithPermit, quoteId)
330
+
331
+ console.log('OrderHash', info.orderHash)
332
+
333
+ while (true) {
334
+ const data = await sdk.getOrderStatus(info.orderHash)
335
+
336
+ if (data.status === OrderStatus.Filled) {
337
+ console.log('fills', data.fills)
338
+ break
339
+ }
340
+
341
+ if (
342
+ data.status === OrderStatus.Expired ||
343
+ data.status === OrderStatus.Cancelled
344
+ ) {
345
+ console.log('Order', data.status)
346
+ break
347
+ }
348
+ }
349
+ }
350
+
351
+ main()
352
+ ```
353
+
354
+ **Key differences from a standard swap:**
355
+
356
+ - Token approval goes to `Permit2` instead of the 1inch protocol
357
+ - Create and sign a `PermitTransferFrom` using the Permit2Proxy address as spender
358
+ - Call `withTransferPermit` before submitting — this modifies the order to route through the Permit2Proxy
359
+
211
360
  ## Resolvers
212
361
 
213
362
  `settleOrders` function usage and Resolver contract examples you can find [here](https://github.com/1inch/fusion-resolver-example)
@@ -8,7 +8,6 @@ var _quoterrequest = require("./quoter.request.js");
8
8
  var _index = require("./quote/index.js");
9
9
  var _types = require("./types.js");
10
10
  var _quotercustompresetrequest = require("./quoter-custom-preset.request.js");
11
- var _constants = require("../../constants.js");
12
11
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
13
12
  try {
14
13
  var info = gen[key](arg);
@@ -244,7 +243,7 @@ describe('Quoter API', function() {
244
243
  ],
245
244
  fee: {
246
245
  whitelistDiscountPercent: 1,
247
- receiver: _constants.ONE_INCH_LIMIT_ORDER_V4,
246
+ receiver: '0x02f92800F57BCD74066F5709F1Daa1A4302Df875',
248
247
  bps: 10
249
248
  },
250
249
  marketAmount: '626772029219852913'
@@ -12,8 +12,8 @@ _export(exports, {
12
12
  NetworkEnum: function() {
13
13
  return NetworkEnum;
14
14
  },
15
- ONE_INCH_LIMIT_ORDER_V4: function() {
16
- return ONE_INCH_LIMIT_ORDER_V4;
15
+ ONE_INCH_LIMIT_ORDER_V4_ADDRESSES: function() {
16
+ return ONE_INCH_LIMIT_ORDER_V4_ADDRESSES;
17
17
  },
18
18
  UINT_160_MAX: function() {
19
19
  return UINT_160_MAX;
@@ -40,6 +40,19 @@ _export(exports, {
40
40
  return ZX;
41
41
  }
42
42
  });
43
+ function _define_property(obj, key, value) {
44
+ if (key in obj) {
45
+ Object.defineProperty(obj, key, {
46
+ value: value,
47
+ enumerable: true,
48
+ configurable: true,
49
+ writable: true
50
+ });
51
+ } else {
52
+ obj[key] = value;
53
+ }
54
+ return obj;
55
+ }
43
56
  var ZX = '0x';
44
57
  var NetworkEnum = /*#__PURE__*/ function(NetworkEnum) {
45
58
  NetworkEnum[NetworkEnum["ETHEREUM"] = 1] = "ETHEREUM";
@@ -57,7 +70,8 @@ var NetworkEnum = /*#__PURE__*/ function(NetworkEnum) {
57
70
  NetworkEnum[NetworkEnum["UNICHAIN"] = 130] = "UNICHAIN";
58
71
  return NetworkEnum;
59
72
  }({});
60
- var ONE_INCH_LIMIT_ORDER_V4 = '0x111111125421ca6dc452d289314280a0f8842a65';
73
+ var _obj;
74
+ var ONE_INCH_LIMIT_ORDER_V4_ADDRESSES = (_obj = {}, _define_property(_obj, 324, '0x6fd4383cb451173d5f9304f041c7bcbf27d561ff'), _define_property(_obj, 1, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 137, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 56, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 42161, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 43114, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 10, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 250, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 100, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 8453, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 59144, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 146, '0x111111125421ca6dc452d289314280a0f8842a65'), _define_property(_obj, 130, '0x111111125421ca6dc452d289314280a0f8842a65'), _obj);
61
75
  var UINT_160_MAX = (1n << 160n) - 1n;
62
76
  var UINT_16_MAX = (1n << 16n) - 1n;
63
77
  var UINT_80_MAX = (1n << 80n) - 1n;
@@ -9,10 +9,14 @@ Object.defineProperty(exports, "FusionOrder", {
9
9
  }
10
10
  });
11
11
  var _limitordersdk = require("@1inch/limit-order-sdk");
12
+ var _byteutils = require("@1inch/byte-utils");
12
13
  var _assert = /*#__PURE__*/ _interop_require_default(require("assert"));
13
14
  var _fusionextension = require("./fusion-extension.js");
14
15
  var _sourcetrack = require("./source-track.js");
15
16
  var _surplusparams = require("./surplus-params.js");
17
+ var _permittransferfrom = require("./permit/permit-transfer-from.js");
18
+ var _utils = require("./permit/utils.js");
19
+ var _transferfromsuffix = require("./permit/transfer-from-suffix.js");
16
20
  var _index = require("../amount-calculator/auction-calculator/index.js");
17
21
  var _constants = require("../constants.js");
18
22
  var _amounts = require("../utils/amounts.js");
@@ -50,6 +54,13 @@ function _define_property(obj, key, value) {
50
54
  }
51
55
  return obj;
52
56
  }
57
+ function _instanceof(left, right) {
58
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
59
+ return !!right[Symbol.hasInstance](left);
60
+ } else {
61
+ return left instanceof right;
62
+ }
63
+ }
53
64
  function _interop_require_default(obj) {
54
65
  return obj && obj.__esModule ? obj : {
55
66
  default: obj
@@ -177,6 +188,9 @@ var FusionOrder = /*#__PURE__*/ function() {
177
188
  {
178
189
  key: "makerAsset",
179
190
  get: function get() {
191
+ if (this.isTransferPermit()) {
192
+ return this.decodeTransferPermitSuffix().token;
193
+ }
180
194
  return this.inner.makerAsset;
181
195
  }
182
196
  },
@@ -273,6 +287,48 @@ var FusionOrder = /*#__PURE__*/ function() {
273
287
  return this.inner.salt;
274
288
  }
275
289
  },
290
+ {
291
+ key: "isTransferPermit",
292
+ value: /**
293
+ * Returns true if the order uses a Permit2 transfer permit via Permit2Proxy.
294
+ * Decodes `makerAssetSuffix` and validates the Permit2 ABI structure.
295
+ *
296
+ * @see FusionOrder.withTransferPermit
297
+ * @see FusionOrder.createTransferPermit
298
+ */ function isTransferPermit() {
299
+ try {
300
+ this.decodeTransferPermitSuffix();
301
+ return true;
302
+ } catch (e) {
303
+ return false;
304
+ }
305
+ }
306
+ },
307
+ {
308
+ key: "withTransferPermit",
309
+ value: function withTransferPermit(permit, signature) {
310
+ var suffix = permit.getTransferFromSuffix(signature);
311
+ var currentExtension = this.inner.extension;
312
+ var newExtension = new _limitordersdk.Extension(_object_spread_props(_object_spread({}, currentExtension), {
313
+ makerAssetSuffix: suffix
314
+ }));
315
+ this.inner.makerTraits.disablePermit2();
316
+ var baseSalt = this.inner.salt >> 160n;
317
+ var newSalt = _limitordersdk.LimitOrder.buildSalt(newExtension, baseSalt);
318
+ this.inner = new _limitordersdk.LimitOrder({
319
+ maker: this.inner.maker,
320
+ makerAsset: permit.spender,
321
+ takerAsset: this.inner.takerAsset,
322
+ makingAmount: this.inner.makingAmount,
323
+ takingAmount: this.inner.takingAmount,
324
+ receiver: this.inner.receiver,
325
+ salt: newSalt
326
+ }, this.inner.makerTraits, newExtension, {
327
+ optimizeReceiverAddress: false
328
+ });
329
+ return this;
330
+ }
331
+ },
276
332
  {
277
333
  key: "build",
278
334
  value: function build() {
@@ -468,6 +524,44 @@ var FusionOrder = /*#__PURE__*/ function() {
468
524
  */ function nativeSignature(maker) {
469
525
  return this.inner.nativeSignature(maker);
470
526
  }
527
+ },
528
+ {
529
+ key: "createTransferPermit",
530
+ value: /**
531
+ * Creates a Permit2 `PermitTransferFrom` object for the order's maker asset.
532
+ *
533
+ * Can only be used for orders where `multipleFillsAllowed` is `false`.
534
+ *
535
+ * The returned permit authorizes the `permit2Proxy` address (as spender)
536
+ * to transfer up to `makingAmount` of the `makerAsset` token,
537
+ * with a random 256-bit nonce and the order's deadline.
538
+ *
539
+ * The resulting permit can be signed and then attached to the order
540
+ * via {@link FusionOrder.withTransferPermit}.
541
+ *
542
+ * @param chainId - The chain ID used to resolve the default Permit2Proxy address
543
+ * @param permit2Proxy - Optional address of the Permit2Proxy contract that will act as spender.
544
+ * Defaults to the built-in address for the given `chainId`.
545
+ * @returns A {@link PermitTransferFrom} instance that can be signed and attached to the order
546
+ *
547
+ * @throws If `multipleFillsAllowed` is `true`
548
+ *
549
+ * @see FusionOrder.withTransferPermit
550
+ */ function createTransferPermit(chainIdOrPermit2Proxy, permit2Proxy) {
551
+ (0, _assert.default)(!this.multipleFillsAllowed, 'transfer permit can be used only for orders where multipleFillsAllowed=false');
552
+ var spender = _instanceof(chainIdOrPermit2Proxy, _limitordersdk.Address) ? chainIdOrPermit2Proxy : permit2Proxy !== null && permit2Proxy !== void 0 ? permit2Proxy : (0, _utils.getPermit2ProxyAddress)(chainIdOrPermit2Proxy);
553
+ return new _permittransferfrom.PermitTransferFrom(this.makerAsset, this.makingAmount, spender, (0, _limitordersdk.randBigInt)(_byteutils.UINT_256_MAX), this.deadline);
554
+ }
555
+ },
556
+ {
557
+ key: "decodeTransferPermitSuffix",
558
+ value: function decodeTransferPermitSuffix() {
559
+ var suffix = this.inner.extension.makerAssetSuffix;
560
+ if (suffix === _constants.ZX) {
561
+ throw new Error('no makerAssetSuffix');
562
+ }
563
+ return (0, _transferfromsuffix.decodeTransferFromSuffix)(suffix);
564
+ }
471
565
  }
472
566
  ], [
473
567
  {
@@ -465,4 +465,91 @@ describe('FusionOrder Native', function() {
465
465
  });
466
466
  expect(nativeOrder.build().receiver).toEqual(settlementExt.toString());
467
467
  });
468
+ describe('isTransferPermit', function() {
469
+ var extensionContract = new _limitordersdk.Address('0x8273f37417da37c4a6c3995e82cf442f87a25d9c');
470
+ var permit2Proxy = new _limitordersdk.Address('0x1234567890abcdef1234567890abcdef12345678');
471
+ var baseOrder = function() {
472
+ return _fusionorder.FusionOrder.new(extensionContract, {
473
+ makerAsset: new _limitordersdk.Address('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'),
474
+ takerAsset: new _limitordersdk.Address('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'),
475
+ makingAmount: (0, _ethers.parseEther)('1'),
476
+ takingAmount: (0, _ethers.parseUnits)('1000', 6),
477
+ maker: new _limitordersdk.Address('0x00000000219ab540356cbb839cbe05303d7705fa')
478
+ }, {
479
+ auction: new _index.AuctionDetails({
480
+ duration: 180n,
481
+ startTime: 1673548149n,
482
+ initialRateBump: 0,
483
+ points: []
484
+ }),
485
+ whitelist: _index1.Whitelist.new(1673548139n, [
486
+ {
487
+ address: new _limitordersdk.Address('0x00000000219ab540356cbb839cbe05303d7705fa'),
488
+ allowFrom: 0n
489
+ }
490
+ ]),
491
+ surplus: _surplusparams.SurplusParams.NO_FEE
492
+ }, {
493
+ allowPartialFills: false,
494
+ allowMultipleFills: false,
495
+ nonce: 1n
496
+ });
497
+ };
498
+ it('should return false for regular order', function() {
499
+ var order = _fusionorder.FusionOrder.new(extensionContract, {
500
+ makerAsset: new _limitordersdk.Address('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'),
501
+ takerAsset: new _limitordersdk.Address('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'),
502
+ makingAmount: (0, _ethers.parseEther)('1'),
503
+ takingAmount: (0, _ethers.parseUnits)('1000', 6),
504
+ maker: new _limitordersdk.Address('0x00000000219ab540356cbb839cbe05303d7705fa')
505
+ }, {
506
+ auction: new _index.AuctionDetails({
507
+ duration: 180n,
508
+ startTime: 1673548149n,
509
+ initialRateBump: 0,
510
+ points: []
511
+ }),
512
+ whitelist: _index1.Whitelist.new(1673548139n, [
513
+ {
514
+ address: new _limitordersdk.Address('0x00000000219ab540356cbb839cbe05303d7705fa'),
515
+ allowFrom: 0n
516
+ }
517
+ ]),
518
+ surplus: _surplusparams.SurplusParams.NO_FEE
519
+ });
520
+ expect(order.isTransferPermit()).toBe(false);
521
+ });
522
+ it('should return true after withTransferPermit', function() {
523
+ var order = baseOrder();
524
+ var permit = order.createTransferPermit(permit2Proxy);
525
+ var fakeSignature = '0x' + 'ab'.repeat(65);
526
+ var orderWithPermit = order.withTransferPermit(permit, fakeSignature);
527
+ expect(orderWithPermit.isTransferPermit()).toBe(true);
528
+ });
529
+ it('should return real token as makerAsset after withTransferPermit', function() {
530
+ var weth = new _limitordersdk.Address('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2');
531
+ var order = baseOrder();
532
+ var permit = order.createTransferPermit(permit2Proxy);
533
+ var fakeSignature = '0x' + 'ab'.repeat(65);
534
+ var orderWithPermit = order.withTransferPermit(permit, fakeSignature);
535
+ expect(orderWithPermit.makerAsset).toEqual(weth);
536
+ });
537
+ it('should return false for non-permit2 suffix data', function() {
538
+ var order = baseOrder();
539
+ var ext = order.extension;
540
+ var tampered = new _limitordersdk.Extension({
541
+ makerAssetSuffix: '0xdeadbeef',
542
+ takerAssetSuffix: ext.takerAssetSuffix,
543
+ makingAmountData: ext.makingAmountData,
544
+ takingAmountData: ext.takingAmountData,
545
+ predicate: ext.predicate,
546
+ makerPermit: ext.makerPermit,
547
+ preInteraction: ext.preInteraction,
548
+ postInteraction: ext.postInteraction,
549
+ customData: ext.customData
550
+ });
551
+ var rebuilt = _fusionorder.FusionOrder.fromDataAndExtension(order.build(), tampered);
552
+ expect(rebuilt.isTransferPermit()).toBe(false);
553
+ });
554
+ });
468
555
  });
@@ -16,6 +16,7 @@ _export_star(require("./fees/index.js"), exports);
16
16
  var _constants = require("./constants.js");
17
17
  _export_star(require("./surplus-params.js"), exports);
18
18
  _export_star(require("./cancellation-auction.js"), exports);
19
+ _export_star(require("./permit/index.js"), exports);
19
20
  function _export_star(from, to) {
20
21
  Object.keys(from).forEach(function(k) {
21
22
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {