@bosonprotocol/core-sdk 1.47.1-alpha.0 → 1.48.0-alpha.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.
- package/dist/cjs/erc20/handler.d.ts +73 -0
- package/dist/cjs/erc20/handler.d.ts.map +1 -1
- package/dist/cjs/erc20/handler.js +198 -0
- package/dist/cjs/erc20/handler.js.map +1 -1
- package/dist/cjs/erc20/mixin.d.ts +76 -1
- package/dist/cjs/erc20/mixin.d.ts.map +1 -1
- package/dist/cjs/erc20/mixin.js +67 -0
- package/dist/cjs/erc20/mixin.js.map +1 -1
- package/dist/cjs/exchanges/handler.d.ts +6 -0
- package/dist/cjs/exchanges/handler.d.ts.map +1 -1
- package/dist/cjs/exchanges/handler.js +1 -0
- package/dist/cjs/exchanges/handler.js.map +1 -1
- package/dist/cjs/meta-tx/handler.d.ts +32 -0
- package/dist/cjs/meta-tx/handler.d.ts.map +1 -1
- package/dist/cjs/meta-tx/handler.js +68 -19
- package/dist/cjs/meta-tx/handler.js.map +1 -1
- package/dist/cjs/meta-tx/mixin.d.ts +38 -0
- package/dist/cjs/meta-tx/mixin.d.ts.map +1 -1
- package/dist/cjs/meta-tx/mixin.js +29 -1
- package/dist/cjs/meta-tx/mixin.js.map +1 -1
- package/dist/cjs/native-meta-tx/handler.d.ts +1 -1
- package/dist/cjs/native-meta-tx/handler.d.ts.map +1 -1
- package/dist/cjs/orchestration/handler.d.ts +59 -1
- package/dist/cjs/orchestration/handler.d.ts.map +1 -1
- package/dist/cjs/orchestration/handler.js +114 -0
- package/dist/cjs/orchestration/handler.js.map +1 -1
- package/dist/cjs/orchestration/interface.d.ts +4 -1
- package/dist/cjs/orchestration/interface.d.ts.map +1 -1
- package/dist/cjs/orchestration/interface.js +23 -5
- package/dist/cjs/orchestration/interface.js.map +1 -1
- package/dist/cjs/orchestration/mixin.d.ts +49 -1
- package/dist/cjs/orchestration/mixin.d.ts.map +1 -1
- package/dist/cjs/orchestration/mixin.js +62 -0
- package/dist/cjs/orchestration/mixin.js.map +1 -1
- package/dist/cjs/utils/signature.d.ts +9 -0
- package/dist/cjs/utils/signature.d.ts.map +1 -1
- package/dist/cjs/utils/signature.js.map +1 -1
- package/dist/esm/erc20/handler.d.ts +73 -0
- package/dist/esm/erc20/handler.d.ts.map +1 -1
- package/dist/esm/erc20/handler.js +217 -0
- package/dist/esm/erc20/handler.js.map +1 -1
- package/dist/esm/erc20/mixin.d.ts +76 -1
- package/dist/esm/erc20/mixin.d.ts.map +1 -1
- package/dist/esm/erc20/mixin.js +79 -1
- package/dist/esm/erc20/mixin.js.map +1 -1
- package/dist/esm/exchanges/handler.d.ts +6 -0
- package/dist/esm/exchanges/handler.d.ts.map +1 -1
- package/dist/esm/exchanges/handler.js +1 -1
- package/dist/esm/exchanges/handler.js.map +1 -1
- package/dist/esm/meta-tx/handler.d.ts +32 -0
- package/dist/esm/meta-tx/handler.d.ts.map +1 -1
- package/dist/esm/meta-tx/handler.js +66 -12
- package/dist/esm/meta-tx/handler.js.map +1 -1
- package/dist/esm/meta-tx/mixin.d.ts +38 -0
- package/dist/esm/meta-tx/mixin.d.ts.map +1 -1
- package/dist/esm/meta-tx/mixin.js +63 -1
- package/dist/esm/meta-tx/mixin.js.map +1 -1
- package/dist/esm/native-meta-tx/handler.d.ts +1 -1
- package/dist/esm/native-meta-tx/handler.d.ts.map +1 -1
- package/dist/esm/orchestration/handler.d.ts +59 -1
- package/dist/esm/orchestration/handler.d.ts.map +1 -1
- package/dist/esm/orchestration/handler.js +126 -2
- package/dist/esm/orchestration/handler.js.map +1 -1
- package/dist/esm/orchestration/interface.d.ts +4 -1
- package/dist/esm/orchestration/interface.d.ts.map +1 -1
- package/dist/esm/orchestration/interface.js +15 -0
- package/dist/esm/orchestration/interface.js.map +1 -1
- package/dist/esm/orchestration/mixin.d.ts +49 -1
- package/dist/esm/orchestration/mixin.d.ts.map +1 -1
- package/dist/esm/orchestration/mixin.js +74 -0
- package/dist/esm/orchestration/mixin.js.map +1 -1
- package/dist/esm/utils/signature.d.ts +9 -0
- package/dist/esm/utils/signature.d.ts.map +1 -1
- package/dist/esm/utils/signature.js.map +1 -1
- package/package.json +3 -3
- package/src/erc20/handler.ts +354 -0
- package/src/erc20/mixin.ts +206 -1
- package/src/exchanges/handler.ts +1 -1
- package/src/meta-tx/handler.ts +157 -12
- package/src/meta-tx/mixin.ts +149 -1
- package/src/native-meta-tx/handler.ts +1 -1
- package/src/orchestration/handler.ts +267 -1
- package/src/orchestration/interface.ts +31 -1
- package/src/orchestration/mixin.ts +187 -0
- package/src/utils/signature.ts +18 -6
package/src/erc20/handler.ts
CHANGED
|
@@ -3,8 +3,92 @@ import {
|
|
|
3
3
|
TransactionRequest,
|
|
4
4
|
TransactionResponse
|
|
5
5
|
} from "@bosonprotocol/common";
|
|
6
|
+
import { defaultAbiCoder } from "@ethersproject/abi";
|
|
6
7
|
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
|
|
8
|
+
import { hexlify } from "@ethersproject/bytes";
|
|
9
|
+
import { randomBytes } from "@ethersproject/random";
|
|
7
10
|
import { erc20Iface } from "./interface";
|
|
11
|
+
import type { ApproveExchangeTokenBaseArgs } from "../native-meta-tx/handler";
|
|
12
|
+
import { alternativeNonceIface } from "../native-meta-tx/interface";
|
|
13
|
+
import {
|
|
14
|
+
prepareDataSignatureParameters,
|
|
15
|
+
StructuredData
|
|
16
|
+
} from "../utils/signature";
|
|
17
|
+
|
|
18
|
+
export type UnsignedTransferAuthorization =
|
|
19
|
+
| {
|
|
20
|
+
strategy: "ERC3009";
|
|
21
|
+
data: {
|
|
22
|
+
validAfter: BigNumberish;
|
|
23
|
+
validBefore: BigNumberish;
|
|
24
|
+
nonce: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
strategy: "EIP2612";
|
|
29
|
+
data: { deadline: BigNumberish };
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
strategy: "Permit2";
|
|
33
|
+
data: { nonce: BigNumberish; deadline: BigNumberish };
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type TransferAuthorization = UnsignedTransferAuthorization & {
|
|
37
|
+
r: string;
|
|
38
|
+
s: string;
|
|
39
|
+
v: number;
|
|
40
|
+
signature: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const TRANSFER_STRATEGY_ID = {
|
|
44
|
+
ERC3009: 1,
|
|
45
|
+
EIP2612: 2,
|
|
46
|
+
Permit2: 3
|
|
47
|
+
} as const;
|
|
48
|
+
|
|
49
|
+
function encodeTransferAuthorizationEntry(auth: TransferAuthorization): string {
|
|
50
|
+
let innerData: string;
|
|
51
|
+
switch (auth.strategy) {
|
|
52
|
+
case "ERC3009":
|
|
53
|
+
innerData = defaultAbiCoder.encode(
|
|
54
|
+
["uint256", "uint256", "bytes32", "uint8", "bytes32", "bytes32"],
|
|
55
|
+
[
|
|
56
|
+
auth.data.validAfter,
|
|
57
|
+
auth.data.validBefore,
|
|
58
|
+
auth.data.nonce,
|
|
59
|
+
auth.v,
|
|
60
|
+
auth.r,
|
|
61
|
+
auth.s
|
|
62
|
+
]
|
|
63
|
+
);
|
|
64
|
+
break;
|
|
65
|
+
case "EIP2612":
|
|
66
|
+
innerData = defaultAbiCoder.encode(
|
|
67
|
+
["uint256", "uint8", "bytes32", "bytes32"],
|
|
68
|
+
[auth.data.deadline, auth.v, auth.r, auth.s]
|
|
69
|
+
);
|
|
70
|
+
break;
|
|
71
|
+
case "Permit2":
|
|
72
|
+
innerData = defaultAbiCoder.encode(
|
|
73
|
+
["uint256", "uint256", "bytes"],
|
|
74
|
+
[auth.data.nonce, auth.data.deadline, auth.signature]
|
|
75
|
+
);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
return defaultAbiCoder.encode(
|
|
79
|
+
["uint8", "bytes"],
|
|
80
|
+
[TRANSFER_STRATEGY_ID[auth.strategy], innerData]
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function encodeTransferAuthorizationQueue(
|
|
85
|
+
auths: TransferAuthorization[]
|
|
86
|
+
): string {
|
|
87
|
+
return defaultAbiCoder.encode(
|
|
88
|
+
["bytes[]"],
|
|
89
|
+
[auths.map(encodeTransferAuthorizationEntry)]
|
|
90
|
+
);
|
|
91
|
+
}
|
|
8
92
|
|
|
9
93
|
// Overload: returnTxInfo is true -> returns TransactionRequest
|
|
10
94
|
export async function approve(args: {
|
|
@@ -130,3 +214,273 @@ export async function balanceOf(args: {
|
|
|
130
214
|
const [balance] = erc20Iface.decodeFunctionResult("balanceOf", result);
|
|
131
215
|
return String(balance);
|
|
132
216
|
}
|
|
217
|
+
|
|
218
|
+
type SignReceiveWithErc3009AuthorizationArgs = ApproveExchangeTokenBaseArgs & {
|
|
219
|
+
tokenDomain: { name: string; version: string };
|
|
220
|
+
validAfter: BigNumberish;
|
|
221
|
+
validBefore: BigNumberish;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// Overload: returnTypedDataToSign is true → returns StructuredData
|
|
225
|
+
export async function signReceiveWithErc3009Authorization(
|
|
226
|
+
args: SignReceiveWithErc3009AuthorizationArgs & {
|
|
227
|
+
returnTypedDataToSign: true;
|
|
228
|
+
}
|
|
229
|
+
): Promise<StructuredData>;
|
|
230
|
+
// Overload: returnTypedDataToSign is false or undefined → returns TransferAuthorization (ERC3009)
|
|
231
|
+
export async function signReceiveWithErc3009Authorization(
|
|
232
|
+
args: SignReceiveWithErc3009AuthorizationArgs & {
|
|
233
|
+
returnTypedDataToSign?: false | undefined;
|
|
234
|
+
}
|
|
235
|
+
): Promise<TransferAuthorization & { strategy: "ERC3009" }>;
|
|
236
|
+
// Implementation
|
|
237
|
+
export async function signReceiveWithErc3009Authorization(
|
|
238
|
+
args: SignReceiveWithErc3009AuthorizationArgs & {
|
|
239
|
+
returnTypedDataToSign?: boolean;
|
|
240
|
+
}
|
|
241
|
+
): Promise<(TransferAuthorization & { strategy: "ERC3009" }) | StructuredData> {
|
|
242
|
+
const nonce = hexlify(randomBytes(32));
|
|
243
|
+
|
|
244
|
+
const customSignatureType = {
|
|
245
|
+
EIP712Domain: [
|
|
246
|
+
{ name: "name", type: "string" },
|
|
247
|
+
{ name: "version", type: "string" },
|
|
248
|
+
{ name: "chainId", type: "uint256" },
|
|
249
|
+
{ name: "verifyingContract", type: "address" }
|
|
250
|
+
],
|
|
251
|
+
ReceiveWithAuthorization: [
|
|
252
|
+
{ name: "from", type: "address" },
|
|
253
|
+
{ name: "to", type: "address" },
|
|
254
|
+
{ name: "value", type: "uint256" },
|
|
255
|
+
{ name: "validAfter", type: "uint256" },
|
|
256
|
+
{ name: "validBefore", type: "uint256" },
|
|
257
|
+
{ name: "nonce", type: "bytes32" }
|
|
258
|
+
]
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const customDomainData = {
|
|
262
|
+
name: args.tokenDomain.name,
|
|
263
|
+
version: args.tokenDomain.version,
|
|
264
|
+
chainId: args.chainId,
|
|
265
|
+
salt: undefined
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const message = {
|
|
269
|
+
from: args.user,
|
|
270
|
+
to: args.spender,
|
|
271
|
+
value: args.value.toString(),
|
|
272
|
+
validAfter: args.validAfter.toString(),
|
|
273
|
+
validBefore: args.validBefore.toString(),
|
|
274
|
+
nonce
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const baseParams = {
|
|
278
|
+
web3Lib: args.web3Lib,
|
|
279
|
+
chainId: args.chainId,
|
|
280
|
+
verifyingContractAddress: args.exchangeToken,
|
|
281
|
+
customSignatureType,
|
|
282
|
+
customDomainData,
|
|
283
|
+
primaryType: "ReceiveWithAuthorization",
|
|
284
|
+
message
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
if (args.returnTypedDataToSign) {
|
|
288
|
+
return prepareDataSignatureParameters({
|
|
289
|
+
...baseParams,
|
|
290
|
+
returnTypedDataToSign: true
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const sig = await prepareDataSignatureParameters({
|
|
295
|
+
...baseParams,
|
|
296
|
+
returnTypedDataToSign: false
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
return {
|
|
300
|
+
...sig,
|
|
301
|
+
strategy: "ERC3009",
|
|
302
|
+
data: {
|
|
303
|
+
validAfter: args.validAfter,
|
|
304
|
+
validBefore: args.validBefore,
|
|
305
|
+
nonce
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
type SignReceiveWithErc2612PermitArgs = ApproveExchangeTokenBaseArgs & {
|
|
311
|
+
tokenDomain: { name: string; version: string };
|
|
312
|
+
deadline: BigNumberish;
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
// Overload: returnTypedDataToSign is true → returns StructuredData
|
|
316
|
+
export async function signReceiveWithErc2612Permit(
|
|
317
|
+
args: SignReceiveWithErc2612PermitArgs & {
|
|
318
|
+
returnTypedDataToSign: true;
|
|
319
|
+
}
|
|
320
|
+
): Promise<StructuredData>;
|
|
321
|
+
// Overload: returnTypedDataToSign is false or undefined → returns TransferAuthorization (EIP2612)
|
|
322
|
+
export async function signReceiveWithErc2612Permit(
|
|
323
|
+
args: SignReceiveWithErc2612PermitArgs & {
|
|
324
|
+
returnTypedDataToSign?: false | undefined;
|
|
325
|
+
}
|
|
326
|
+
): Promise<TransferAuthorization & { strategy: "EIP2612" }>;
|
|
327
|
+
// Implementation
|
|
328
|
+
export async function signReceiveWithErc2612Permit(
|
|
329
|
+
args: SignReceiveWithErc2612PermitArgs & {
|
|
330
|
+
returnTypedDataToSign?: boolean;
|
|
331
|
+
}
|
|
332
|
+
): Promise<(TransferAuthorization & { strategy: "EIP2612" }) | StructuredData> {
|
|
333
|
+
const nonceResult = await args.web3Lib.call({
|
|
334
|
+
to: args.exchangeToken,
|
|
335
|
+
data: alternativeNonceIface.encodeFunctionData("nonces", [args.user])
|
|
336
|
+
});
|
|
337
|
+
const [nonce] = alternativeNonceIface.decodeFunctionResult(
|
|
338
|
+
"nonces",
|
|
339
|
+
nonceResult
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const customSignatureType = {
|
|
343
|
+
EIP712Domain: [
|
|
344
|
+
{ name: "name", type: "string" },
|
|
345
|
+
{ name: "version", type: "string" },
|
|
346
|
+
{ name: "chainId", type: "uint256" },
|
|
347
|
+
{ name: "verifyingContract", type: "address" }
|
|
348
|
+
],
|
|
349
|
+
Permit: [
|
|
350
|
+
{ name: "owner", type: "address" },
|
|
351
|
+
{ name: "spender", type: "address" },
|
|
352
|
+
{ name: "value", type: "uint256" },
|
|
353
|
+
{ name: "nonce", type: "uint256" },
|
|
354
|
+
{ name: "deadline", type: "uint256" }
|
|
355
|
+
]
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
const customDomainData = {
|
|
359
|
+
name: args.tokenDomain.name,
|
|
360
|
+
version: args.tokenDomain.version,
|
|
361
|
+
chainId: args.chainId,
|
|
362
|
+
salt: undefined
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
const message = {
|
|
366
|
+
owner: args.user,
|
|
367
|
+
spender: args.spender,
|
|
368
|
+
value: args.value.toString(),
|
|
369
|
+
nonce: nonce.toString(),
|
|
370
|
+
deadline: args.deadline.toString()
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
const baseParams = {
|
|
374
|
+
web3Lib: args.web3Lib,
|
|
375
|
+
chainId: args.chainId,
|
|
376
|
+
verifyingContractAddress: args.exchangeToken,
|
|
377
|
+
customSignatureType,
|
|
378
|
+
customDomainData,
|
|
379
|
+
primaryType: "Permit",
|
|
380
|
+
message
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
if (args.returnTypedDataToSign) {
|
|
384
|
+
return prepareDataSignatureParameters({
|
|
385
|
+
...baseParams,
|
|
386
|
+
returnTypedDataToSign: true
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const sig = await prepareDataSignatureParameters({
|
|
391
|
+
...baseParams,
|
|
392
|
+
returnTypedDataToSign: false
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
return {
|
|
396
|
+
...sig,
|
|
397
|
+
strategy: "EIP2612",
|
|
398
|
+
data: { deadline: args.deadline }
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
type SignReceiveWithPermit2Args = ApproveExchangeTokenBaseArgs & {
|
|
403
|
+
permit2Address: string;
|
|
404
|
+
deadline: BigNumberish;
|
|
405
|
+
permit2Nonce?: BigNumberish;
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
// Overload: returnTypedDataToSign is true → returns StructuredData
|
|
409
|
+
export async function signReceiveWithPermit2(
|
|
410
|
+
args: SignReceiveWithPermit2Args & { returnTypedDataToSign: true }
|
|
411
|
+
): Promise<StructuredData>;
|
|
412
|
+
// Overload: returnTypedDataToSign is false or undefined → returns TransferAuthorization (Permit2)
|
|
413
|
+
export async function signReceiveWithPermit2(
|
|
414
|
+
args: SignReceiveWithPermit2Args & {
|
|
415
|
+
returnTypedDataToSign?: false | undefined;
|
|
416
|
+
}
|
|
417
|
+
): Promise<TransferAuthorization & { strategy: "Permit2" }>;
|
|
418
|
+
// Implementation
|
|
419
|
+
export async function signReceiveWithPermit2(
|
|
420
|
+
args: SignReceiveWithPermit2Args & { returnTypedDataToSign?: boolean }
|
|
421
|
+
): Promise<(TransferAuthorization & { strategy: "Permit2" }) | StructuredData> {
|
|
422
|
+
const permit2Nonce = args.permit2Nonce ?? BigNumber.from(randomBytes(32));
|
|
423
|
+
|
|
424
|
+
const customSignatureType = {
|
|
425
|
+
EIP712Domain: [
|
|
426
|
+
{ name: "name", type: "string" },
|
|
427
|
+
{ name: "chainId", type: "uint256" },
|
|
428
|
+
{ name: "verifyingContract", type: "address" }
|
|
429
|
+
],
|
|
430
|
+
PermitTransferFrom: [
|
|
431
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
432
|
+
{ name: "spender", type: "address" },
|
|
433
|
+
{ name: "nonce", type: "uint256" },
|
|
434
|
+
{ name: "deadline", type: "uint256" }
|
|
435
|
+
],
|
|
436
|
+
TokenPermissions: [
|
|
437
|
+
{ name: "token", type: "address" },
|
|
438
|
+
{ name: "amount", type: "uint256" }
|
|
439
|
+
]
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
const customDomainData = {
|
|
443
|
+
name: "Permit2",
|
|
444
|
+
chainId: args.chainId,
|
|
445
|
+
version: undefined,
|
|
446
|
+
salt: undefined
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
const message = {
|
|
450
|
+
permitted: {
|
|
451
|
+
token: args.exchangeToken,
|
|
452
|
+
amount: args.value.toString()
|
|
453
|
+
},
|
|
454
|
+
spender: args.spender,
|
|
455
|
+
nonce: permit2Nonce.toString(),
|
|
456
|
+
deadline: args.deadline.toString()
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
const baseParams = {
|
|
460
|
+
web3Lib: args.web3Lib,
|
|
461
|
+
chainId: args.chainId,
|
|
462
|
+
verifyingContractAddress: args.permit2Address,
|
|
463
|
+
customSignatureType,
|
|
464
|
+
customDomainData,
|
|
465
|
+
primaryType: "PermitTransferFrom",
|
|
466
|
+
message
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
if (args.returnTypedDataToSign) {
|
|
470
|
+
return prepareDataSignatureParameters({
|
|
471
|
+
...baseParams,
|
|
472
|
+
returnTypedDataToSign: true
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const sig = await prepareDataSignatureParameters({
|
|
477
|
+
...baseParams,
|
|
478
|
+
returnTypedDataToSign: false
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
return {
|
|
482
|
+
...sig,
|
|
483
|
+
strategy: "Permit2",
|
|
484
|
+
data: { nonce: permit2Nonce, deadline: args.deadline }
|
|
485
|
+
};
|
|
486
|
+
}
|
package/src/erc20/mixin.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
TransactionResponse,
|
|
4
4
|
TransactionRequest
|
|
5
5
|
} from "@bosonprotocol/common";
|
|
6
|
+
import { BigNumberish } from "@ethersproject/bignumber";
|
|
6
7
|
import { BaseCoreSDK } from "./../mixins/base-core-sdk";
|
|
7
8
|
import {
|
|
8
9
|
approve,
|
|
@@ -11,8 +12,13 @@ import {
|
|
|
11
12
|
getSymbol,
|
|
12
13
|
getName,
|
|
13
14
|
ensureAllowance,
|
|
14
|
-
balanceOf
|
|
15
|
+
balanceOf,
|
|
16
|
+
signReceiveWithErc3009Authorization,
|
|
17
|
+
signReceiveWithErc2612Permit,
|
|
18
|
+
signReceiveWithPermit2,
|
|
19
|
+
TransferAuthorization
|
|
15
20
|
} from "./handler";
|
|
21
|
+
import { StructuredData } from "../utils/signature";
|
|
16
22
|
|
|
17
23
|
export class ERC20Mixin<T extends Web3LibAdapter> extends BaseCoreSDK<T> {
|
|
18
24
|
/* -------------------------------------------------------------------------- */
|
|
@@ -121,4 +127,203 @@ export class ERC20Mixin<T extends Web3LibAdapter> extends BaseCoreSDK<T> {
|
|
|
121
127
|
): Promise<ReturnType<typeof balanceOf>> {
|
|
122
128
|
return balanceOf({ web3Lib: this._web3Lib, ...args });
|
|
123
129
|
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Signs an ERC-3009 `ReceiveWithAuthorization` payload that authorizes the
|
|
133
|
+
* spender (default: protocol diamond) to pull `value` units of `exchangeToken`
|
|
134
|
+
* from the signer. Returns a `TransferAuthorization` tagged with strategy
|
|
135
|
+
* `"ERC3009"`, ready to feed into `relayMetaTransaction` via
|
|
136
|
+
* `transferAuthorizations`.
|
|
137
|
+
*/
|
|
138
|
+
// Overload: returnTypedDataToSign is true → returns StructuredData
|
|
139
|
+
public async signReceiveWithErc3009Authorization(
|
|
140
|
+
exchangeToken: string,
|
|
141
|
+
tokenDomain: { name: string; version: string },
|
|
142
|
+
value: BigNumberish,
|
|
143
|
+
validAfter: BigNumberish,
|
|
144
|
+
validBefore: BigNumberish,
|
|
145
|
+
overrides: Partial<{ spender: string }> & { returnTypedDataToSign: true }
|
|
146
|
+
): Promise<StructuredData>;
|
|
147
|
+
// Overload: returnTypedDataToSign is false or undefined → returns TransferAuthorization (ERC3009)
|
|
148
|
+
public async signReceiveWithErc3009Authorization(
|
|
149
|
+
exchangeToken: string,
|
|
150
|
+
tokenDomain: { name: string; version: string },
|
|
151
|
+
value: BigNumberish,
|
|
152
|
+
validAfter: BigNumberish,
|
|
153
|
+
validBefore: BigNumberish,
|
|
154
|
+
overrides?: Partial<{ spender: string; returnTypedDataToSign?: false }>
|
|
155
|
+
): Promise<TransferAuthorization & { strategy: "ERC3009" }>;
|
|
156
|
+
// Implementation
|
|
157
|
+
public async signReceiveWithErc3009Authorization(
|
|
158
|
+
exchangeToken: string,
|
|
159
|
+
tokenDomain: { name: string; version: string },
|
|
160
|
+
value: BigNumberish,
|
|
161
|
+
validAfter: BigNumberish,
|
|
162
|
+
validBefore: BigNumberish,
|
|
163
|
+
overrides: Partial<{
|
|
164
|
+
spender: string;
|
|
165
|
+
returnTypedDataToSign: boolean;
|
|
166
|
+
}> = {}
|
|
167
|
+
): Promise<
|
|
168
|
+
(TransferAuthorization & { strategy: "ERC3009" }) | StructuredData
|
|
169
|
+
> {
|
|
170
|
+
const user = await this._web3Lib.getSignerAddress();
|
|
171
|
+
const baseArgs = {
|
|
172
|
+
web3Lib: this._web3Lib,
|
|
173
|
+
chainId: this._chainId,
|
|
174
|
+
user,
|
|
175
|
+
exchangeToken,
|
|
176
|
+
spender: overrides.spender || this._protocolDiamond,
|
|
177
|
+
value,
|
|
178
|
+
tokenDomain,
|
|
179
|
+
validAfter,
|
|
180
|
+
validBefore
|
|
181
|
+
};
|
|
182
|
+
if (overrides.returnTypedDataToSign) {
|
|
183
|
+
return signReceiveWithErc3009Authorization({
|
|
184
|
+
...baseArgs,
|
|
185
|
+
returnTypedDataToSign: true
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return signReceiveWithErc3009Authorization({
|
|
189
|
+
...baseArgs,
|
|
190
|
+
returnTypedDataToSign: false
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Signs an EIP-2612 `Permit` payload that authorizes the spender (default:
|
|
196
|
+
* protocol diamond) to pull `value` units of `exchangeToken` from the signer
|
|
197
|
+
* up to `deadline`. Returns a `TransferAuthorization` tagged with strategy
|
|
198
|
+
* `"EIP2612"`, ready to feed into `relayMetaTransaction` via
|
|
199
|
+
* `transferAuthorizations`.
|
|
200
|
+
*/
|
|
201
|
+
// Overload: returnTypedDataToSign is true → returns StructuredData
|
|
202
|
+
public async signReceiveWithErc2612Permit(
|
|
203
|
+
exchangeToken: string,
|
|
204
|
+
tokenDomain: { name: string; version: string },
|
|
205
|
+
value: BigNumberish,
|
|
206
|
+
deadline: BigNumberish,
|
|
207
|
+
overrides: Partial<{ spender: string }> & { returnTypedDataToSign: true }
|
|
208
|
+
): Promise<StructuredData>;
|
|
209
|
+
// Overload: returnTypedDataToSign is false or undefined → returns TransferAuthorization (EIP2612)
|
|
210
|
+
public async signReceiveWithErc2612Permit(
|
|
211
|
+
exchangeToken: string,
|
|
212
|
+
tokenDomain: { name: string; version: string },
|
|
213
|
+
value: BigNumberish,
|
|
214
|
+
deadline: BigNumberish,
|
|
215
|
+
overrides?: Partial<{ spender: string; returnTypedDataToSign?: false }>
|
|
216
|
+
): Promise<TransferAuthorization & { strategy: "EIP2612" }>;
|
|
217
|
+
// Implementation
|
|
218
|
+
public async signReceiveWithErc2612Permit(
|
|
219
|
+
exchangeToken: string,
|
|
220
|
+
tokenDomain: { name: string; version: string },
|
|
221
|
+
value: BigNumberish,
|
|
222
|
+
deadline: BigNumberish,
|
|
223
|
+
overrides: Partial<{
|
|
224
|
+
spender: string;
|
|
225
|
+
returnTypedDataToSign: boolean;
|
|
226
|
+
}> = {}
|
|
227
|
+
): Promise<
|
|
228
|
+
(TransferAuthorization & { strategy: "EIP2612" }) | StructuredData
|
|
229
|
+
> {
|
|
230
|
+
const user = await this._web3Lib.getSignerAddress();
|
|
231
|
+
const baseArgs = {
|
|
232
|
+
web3Lib: this._web3Lib,
|
|
233
|
+
chainId: this._chainId,
|
|
234
|
+
user,
|
|
235
|
+
exchangeToken,
|
|
236
|
+
spender: overrides.spender || this._protocolDiamond,
|
|
237
|
+
value,
|
|
238
|
+
tokenDomain,
|
|
239
|
+
deadline
|
|
240
|
+
};
|
|
241
|
+
if (overrides.returnTypedDataToSign) {
|
|
242
|
+
return signReceiveWithErc2612Permit({
|
|
243
|
+
...baseArgs,
|
|
244
|
+
returnTypedDataToSign: true
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return signReceiveWithErc2612Permit({
|
|
248
|
+
...baseArgs,
|
|
249
|
+
returnTypedDataToSign: false
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Signs a Uniswap Permit2 `PermitTransferFrom` payload authorizing the
|
|
255
|
+
* spender (default: protocol diamond) to pull `value` units of
|
|
256
|
+
* `exchangeToken` from the signer up to `deadline`. The Permit2 contract
|
|
257
|
+
* address defaults to `contracts.permit2` from SDK config and can be
|
|
258
|
+
* overridden via `overrides.permit2Address`. If `overrides.permit2Nonce`
|
|
259
|
+
* is omitted, a random uint256 is generated. Returns a `TransferAuthorization`
|
|
260
|
+
* tagged with strategy `"Permit2"`, ready to feed into `relayMetaTransaction`
|
|
261
|
+
* via `transferAuthorizations`.
|
|
262
|
+
*/
|
|
263
|
+
// Overload: returnTypedDataToSign is true → returns StructuredData
|
|
264
|
+
public async signReceiveWithPermit2(
|
|
265
|
+
exchangeToken: string,
|
|
266
|
+
value: BigNumberish,
|
|
267
|
+
deadline: BigNumberish,
|
|
268
|
+
overrides: Partial<{
|
|
269
|
+
spender: string;
|
|
270
|
+
permit2Address: string;
|
|
271
|
+
permit2Nonce: BigNumberish;
|
|
272
|
+
}> & { returnTypedDataToSign: true }
|
|
273
|
+
): Promise<StructuredData>;
|
|
274
|
+
// Overload: returnTypedDataToSign is false or undefined → returns TransferAuthorization (Permit2)
|
|
275
|
+
public async signReceiveWithPermit2(
|
|
276
|
+
exchangeToken: string,
|
|
277
|
+
value: BigNumberish,
|
|
278
|
+
deadline: BigNumberish,
|
|
279
|
+
overrides?: Partial<{
|
|
280
|
+
spender: string;
|
|
281
|
+
permit2Address: string;
|
|
282
|
+
permit2Nonce: BigNumberish;
|
|
283
|
+
returnTypedDataToSign?: false;
|
|
284
|
+
}>
|
|
285
|
+
): Promise<TransferAuthorization & { strategy: "Permit2" }>;
|
|
286
|
+
// Implementation
|
|
287
|
+
public async signReceiveWithPermit2(
|
|
288
|
+
exchangeToken: string,
|
|
289
|
+
value: BigNumberish,
|
|
290
|
+
deadline: BigNumberish,
|
|
291
|
+
overrides: Partial<{
|
|
292
|
+
spender: string;
|
|
293
|
+
permit2Address: string;
|
|
294
|
+
permit2Nonce: BigNumberish;
|
|
295
|
+
returnTypedDataToSign: boolean;
|
|
296
|
+
}> = {}
|
|
297
|
+
): Promise<
|
|
298
|
+
(TransferAuthorization & { strategy: "Permit2" }) | StructuredData
|
|
299
|
+
> {
|
|
300
|
+
const user = await this._web3Lib.getSignerAddress();
|
|
301
|
+
const permit2Address = overrides.permit2Address || this._contracts?.permit2;
|
|
302
|
+
if (!permit2Address) {
|
|
303
|
+
throw new Error(
|
|
304
|
+
"Permit2 contract address not configured. Provide overrides.permit2Address or initialize CoreSDK with contracts.permit2."
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
const baseArgs = {
|
|
308
|
+
web3Lib: this._web3Lib,
|
|
309
|
+
chainId: this._chainId,
|
|
310
|
+
user,
|
|
311
|
+
exchangeToken,
|
|
312
|
+
spender: overrides.spender || this._protocolDiamond,
|
|
313
|
+
value,
|
|
314
|
+
permit2Address,
|
|
315
|
+
deadline,
|
|
316
|
+
permit2Nonce: overrides.permit2Nonce
|
|
317
|
+
};
|
|
318
|
+
if (overrides.returnTypedDataToSign) {
|
|
319
|
+
return signReceiveWithPermit2({
|
|
320
|
+
...baseArgs,
|
|
321
|
+
returnTypedDataToSign: true
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
return signReceiveWithPermit2({
|
|
325
|
+
...baseArgs,
|
|
326
|
+
returnTypedDataToSign: false
|
|
327
|
+
});
|
|
328
|
+
}
|
|
124
329
|
}
|
package/src/exchanges/handler.ts
CHANGED
|
@@ -403,7 +403,7 @@ export async function createOfferAndCommit(args: {
|
|
|
403
403
|
}
|
|
404
404
|
}
|
|
405
405
|
|
|
406
|
-
async function isFullOfferVoided(args: {
|
|
406
|
+
export async function isFullOfferVoided(args: {
|
|
407
407
|
fullOfferArgsUnsigned: Omit<FullOfferArgs, "signature">;
|
|
408
408
|
contractAddress: string;
|
|
409
409
|
web3Lib: Web3LibAdapter;
|