@zoralabs/protocol-sdk 0.11.8 → 0.11.9
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +9 -0
- package/dist/create/mint-from-create.d.ts +2 -1
- package/dist/create/mint-from-create.d.ts.map +1 -1
- package/dist/index.cjs +195 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +201 -43
- package/dist/index.js.map +1 -1
- package/dist/mint/mint-client.d.ts +3 -1
- package/dist/mint/mint-client.d.ts.map +1 -1
- package/dist/mint/mint-queries.d.ts +5 -3
- package/dist/mint/mint-queries.d.ts.map +1 -1
- package/dist/mint/mint-transactions.d.ts +4 -2
- package/dist/mint/mint-transactions.d.ts.map +1 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/secondary/secondary-client.d.ts +2 -1
- package/dist/secondary/secondary-client.d.ts.map +1 -1
- package/dist/secondary/types.d.ts +1 -0
- package/dist/secondary/types.d.ts.map +1 -1
- package/dist/test-utils.d.ts +5 -1
- package/dist/test-utils.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/comments/comments.test.ts +338 -0
- package/src/create/1155-create-helper.test.ts +2 -12
- package/src/create/1155-create-helper.ts +2 -0
- package/src/create/mint-from-create.ts +3 -0
- package/src/mint/mint-client.test.ts +67 -30
- package/src/mint/mint-client.ts +10 -1
- package/src/mint/mint-queries.ts +16 -5
- package/src/mint/mint-transactions.ts +80 -16
- package/src/sdk.ts +1 -0
- package/src/secondary/secondary-client.test.ts +248 -2
- package/src/secondary/secondary-client.ts +136 -6
- package/src/secondary/types.ts +2 -0
- package/src/sparks/sparks-sponsored-sparks-spender.test.ts +1 -0
- package/src/test-utils.ts +19 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, vi } from "vitest";
|
|
2
|
-
import { parseEther, Address } from "viem";
|
|
2
|
+
import { parseEther, Address, parseEventLogs } from "viem";
|
|
3
3
|
import { zoraSepolia } from "viem/chains";
|
|
4
4
|
import {
|
|
5
5
|
forkUrls,
|
|
@@ -7,13 +7,22 @@ import {
|
|
|
7
7
|
simulateAndWriteContractWithRetries,
|
|
8
8
|
} from "src/anvil";
|
|
9
9
|
import { createCollectorClient } from "src/sdk";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
zoraCreator1155ImplABI,
|
|
12
|
+
commentsABI,
|
|
13
|
+
callerAndCommenterABI,
|
|
14
|
+
PermitBuyOnSecondaryAndComment,
|
|
15
|
+
permitBuyOnSecondaryAndCommentTypedDataDefinition,
|
|
16
|
+
callerAndCommenterAddress,
|
|
17
|
+
sparkValue,
|
|
18
|
+
} from "@zoralabs/protocol-deployments";
|
|
11
19
|
import { SubgraphMintGetter } from "src/mint/subgraph-mint-getter";
|
|
12
20
|
import { ERROR_SECONDARY_NOT_STARTED } from "./secondary-client";
|
|
13
21
|
import { ISubgraphQuerier } from "src/apis/subgraph-querier";
|
|
14
22
|
import { mockTimedSaleStrategyTokenQueryResult } from "src/fixtures/mint-query-results";
|
|
15
23
|
import { new1155ContractVersion } from "src/create/contract-setup";
|
|
16
24
|
import { advanceToSaleAndAndLaunchMarket } from "src/fixtures/secondary";
|
|
25
|
+
import { randomNonce } from "src/test-utils";
|
|
17
26
|
|
|
18
27
|
describe("secondary", () => {
|
|
19
28
|
makeAnvilTest({
|
|
@@ -257,4 +266,241 @@ describe("secondary", () => {
|
|
|
257
266
|
},
|
|
258
267
|
30_000,
|
|
259
268
|
);
|
|
269
|
+
|
|
270
|
+
makeAnvilTest({
|
|
271
|
+
forkBlockNumber: 16339853,
|
|
272
|
+
forkUrl: forkUrls.zoraSepolia,
|
|
273
|
+
anvilChainId: zoraSepolia.id,
|
|
274
|
+
})(
|
|
275
|
+
"it can buy on secondary with a comment",
|
|
276
|
+
async ({
|
|
277
|
+
viemClients: { publicClient, chain, walletClient, testClient },
|
|
278
|
+
}) => {
|
|
279
|
+
const collectorAccount = (await walletClient.getAddresses()!)[1]!;
|
|
280
|
+
const executorAccount = (await walletClient.getAddresses()!)[3]!;
|
|
281
|
+
|
|
282
|
+
const mintGetter = new SubgraphMintGetter(chain.id);
|
|
283
|
+
const contractAddress: Address =
|
|
284
|
+
"0xd42557f24034b53e7340a40bb5813ef9ba88f2b4";
|
|
285
|
+
const newTokenId = 4n;
|
|
286
|
+
|
|
287
|
+
await testClient.setBalance({
|
|
288
|
+
address: collectorAccount,
|
|
289
|
+
value: parseEther("100"),
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
mintGetter.subgraphQuerier.query = vi
|
|
293
|
+
.fn<ISubgraphQuerier["query"]>()
|
|
294
|
+
.mockResolvedValue({
|
|
295
|
+
zoraCreateToken: mockTimedSaleStrategyTokenQueryResult({
|
|
296
|
+
chainId: chain.id,
|
|
297
|
+
tokenId: newTokenId,
|
|
298
|
+
contractAddress,
|
|
299
|
+
contractVersion:
|
|
300
|
+
new1155ContractVersion[
|
|
301
|
+
chain.id as keyof typeof new1155ContractVersion
|
|
302
|
+
],
|
|
303
|
+
}),
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
const collectorClient = createCollectorClient({
|
|
307
|
+
chainId: chain.id,
|
|
308
|
+
publicClient,
|
|
309
|
+
mintGetter,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
const secondaryInfo = await collectorClient.getSecondaryInfo({
|
|
313
|
+
contract: contractAddress,
|
|
314
|
+
tokenId: newTokenId,
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// mint enough to start the countdown
|
|
318
|
+
const quantityToMint =
|
|
319
|
+
secondaryInfo!.minimumMintsForCountdown! - secondaryInfo!.mintCount;
|
|
320
|
+
|
|
321
|
+
const { parameters: collectParameters } = await collectorClient.mint({
|
|
322
|
+
minterAccount: collectorAccount,
|
|
323
|
+
mintType: "1155",
|
|
324
|
+
quantityToMint: quantityToMint,
|
|
325
|
+
tokenId: newTokenId,
|
|
326
|
+
tokenContract: contractAddress,
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
await simulateAndWriteContractWithRetries({
|
|
330
|
+
parameters: collectParameters,
|
|
331
|
+
walletClient,
|
|
332
|
+
publicClient,
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
await advanceToSaleAndAndLaunchMarket({
|
|
336
|
+
contractAddress,
|
|
337
|
+
tokenId: newTokenId,
|
|
338
|
+
testClient,
|
|
339
|
+
publicClient,
|
|
340
|
+
walletClient,
|
|
341
|
+
collectorClient,
|
|
342
|
+
chainId: chain.id,
|
|
343
|
+
account: collectorAccount,
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
const buyResult = await collectorClient.buy1155OnSecondary({
|
|
347
|
+
account: collectorAccount,
|
|
348
|
+
quantity: 5n,
|
|
349
|
+
contract: contractAddress,
|
|
350
|
+
tokenId: newTokenId,
|
|
351
|
+
comment: "test comment",
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
const receipt = await simulateAndWriteContractWithRetries({
|
|
355
|
+
parameters: buyResult.parameters!,
|
|
356
|
+
walletClient,
|
|
357
|
+
publicClient,
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
const commentedEvent = parseEventLogs({
|
|
361
|
+
abi: commentsABI,
|
|
362
|
+
logs: receipt.logs,
|
|
363
|
+
eventName: "Commented",
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
expect(commentedEvent[0]).toBeDefined();
|
|
367
|
+
expect(commentedEvent[0]!.args.text).toBe("test comment");
|
|
368
|
+
|
|
369
|
+
const boughtAndCommentedEvent = parseEventLogs({
|
|
370
|
+
abi: callerAndCommenterABI,
|
|
371
|
+
logs: receipt.logs,
|
|
372
|
+
eventName: "SwappedOnSecondaryAndCommented",
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
expect(boughtAndCommentedEvent[0]).toBeDefined();
|
|
376
|
+
expect(boughtAndCommentedEvent[0]!.args.comment).toBe("test comment");
|
|
377
|
+
expect(boughtAndCommentedEvent[0]!.args.quantity).toBe(5n);
|
|
378
|
+
expect(boughtAndCommentedEvent[0]!.args.swapDirection).toBe(0);
|
|
379
|
+
|
|
380
|
+
// PERMIT BUY TEST
|
|
381
|
+
const buyResultASecondTime = await collectorClient.buy1155OnSecondary({
|
|
382
|
+
account: collectorAccount,
|
|
383
|
+
quantity: 5n,
|
|
384
|
+
contract: contractAddress,
|
|
385
|
+
tokenId: newTokenId,
|
|
386
|
+
comment: "test comment",
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
const valueToSend = (buyResultASecondTime.price!.wei.total * 105n) / 100n;
|
|
390
|
+
|
|
391
|
+
const { timestamp } = await publicClient.getBlock();
|
|
392
|
+
|
|
393
|
+
const permitBuy: PermitBuyOnSecondaryAndComment = {
|
|
394
|
+
collection: contractAddress,
|
|
395
|
+
tokenId: newTokenId,
|
|
396
|
+
quantity: 5n,
|
|
397
|
+
commenter: collectorAccount,
|
|
398
|
+
comment: "test comment",
|
|
399
|
+
maxEthToSpend: valueToSend,
|
|
400
|
+
deadline: timestamp + 30n,
|
|
401
|
+
sqrtPriceLimitX96: 0n,
|
|
402
|
+
nonce: randomNonce(),
|
|
403
|
+
sourceChainId: chain.id,
|
|
404
|
+
destinationChainId: chain.id,
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
const permitBuySignature = await walletClient.signTypedData(
|
|
408
|
+
permitBuyOnSecondaryAndCommentTypedDataDefinition(permitBuy),
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
await testClient.setBalance({
|
|
412
|
+
address: executorAccount,
|
|
413
|
+
value: parseEther("1"),
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
const { request } = await publicClient.simulateContract({
|
|
417
|
+
abi: callerAndCommenterABI,
|
|
418
|
+
address:
|
|
419
|
+
callerAndCommenterAddress[
|
|
420
|
+
chain.id as keyof typeof callerAndCommenterAddress
|
|
421
|
+
],
|
|
422
|
+
functionName: "permitBuyOnSecondaryAndComment",
|
|
423
|
+
args: [permitBuy, permitBuySignature],
|
|
424
|
+
value: valueToSend,
|
|
425
|
+
account: executorAccount,
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
await simulateAndWriteContractWithRetries({
|
|
429
|
+
parameters: request,
|
|
430
|
+
walletClient,
|
|
431
|
+
publicClient,
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
// now PERMIT SELL ON SECONDARY TEST
|
|
435
|
+
const quantityToSell = 3n;
|
|
436
|
+
|
|
437
|
+
const sellResult = await collectorClient.sell1155OnSecondary({
|
|
438
|
+
account: collectorAccount,
|
|
439
|
+
quantity: quantityToSell,
|
|
440
|
+
contract: contractAddress,
|
|
441
|
+
tokenId: newTokenId,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
expect(sellResult.error).toBeUndefined();
|
|
445
|
+
|
|
446
|
+
// approve 1155s for callerAndCommenter to transfer, when selling
|
|
447
|
+
await simulateAndWriteContractWithRetries({
|
|
448
|
+
parameters: {
|
|
449
|
+
abi: zoraCreator1155ImplABI,
|
|
450
|
+
address: contractAddress,
|
|
451
|
+
functionName: "setApprovalForAll",
|
|
452
|
+
account: collectorAccount,
|
|
453
|
+
args: [
|
|
454
|
+
callerAndCommenterAddress[
|
|
455
|
+
chain.id as keyof typeof callerAndCommenterAddress
|
|
456
|
+
],
|
|
457
|
+
true,
|
|
458
|
+
],
|
|
459
|
+
},
|
|
460
|
+
walletClient,
|
|
461
|
+
publicClient,
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// now sell on secondary with comment
|
|
465
|
+
// by calling the caller and commenter contract
|
|
466
|
+
// if including a comment, must send sparkValue() as value
|
|
467
|
+
// function signature:
|
|
468
|
+
// function sellOnSecondaryAndComment(
|
|
469
|
+
// address commenter,
|
|
470
|
+
// uint256 quantity,
|
|
471
|
+
// address collection,
|
|
472
|
+
// uint256 tokenId,
|
|
473
|
+
// address payable recipient,
|
|
474
|
+
// uint256 minEthToAcquire,
|
|
475
|
+
// uint160 sqrtPriceLimitX96,
|
|
476
|
+
// string calldata comment
|
|
477
|
+
// )
|
|
478
|
+
await simulateAndWriteContractWithRetries({
|
|
479
|
+
parameters: {
|
|
480
|
+
abi: callerAndCommenterABI,
|
|
481
|
+
address:
|
|
482
|
+
callerAndCommenterAddress[
|
|
483
|
+
chain.id as keyof typeof callerAndCommenterAddress
|
|
484
|
+
],
|
|
485
|
+
functionName: "sellOnSecondaryAndComment",
|
|
486
|
+
account: collectorAccount,
|
|
487
|
+
args: [
|
|
488
|
+
collectorAccount,
|
|
489
|
+
quantityToSell,
|
|
490
|
+
contractAddress,
|
|
491
|
+
newTokenId,
|
|
492
|
+
collectorAccount,
|
|
493
|
+
// sell result with slippage
|
|
494
|
+
(sellResult.price!.wei.total * 95n) / 100n,
|
|
495
|
+
0n,
|
|
496
|
+
"test comment",
|
|
497
|
+
],
|
|
498
|
+
value: sparkValue(),
|
|
499
|
+
},
|
|
500
|
+
walletClient,
|
|
501
|
+
publicClient,
|
|
502
|
+
});
|
|
503
|
+
},
|
|
504
|
+
20_000,
|
|
505
|
+
);
|
|
260
506
|
});
|
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
zoraCreator1155ImplABI,
|
|
5
5
|
safeTransferSwapAbiParameters,
|
|
6
6
|
secondarySwapABI,
|
|
7
|
+
callerAndCommenterABI,
|
|
8
|
+
callerAndCommenterAddress,
|
|
7
9
|
} from "@zoralabs/protocol-deployments";
|
|
8
10
|
import { makeContractParameters, PublicClient } from "src/utils";
|
|
9
11
|
import { getUniswapQuote } from "./uniswap/uniswapQuote";
|
|
@@ -27,6 +29,8 @@ const ERROR_INSUFFICIENT_POOL_SUPPLY = "Insufficient pool supply";
|
|
|
27
29
|
const ERROR_SECONDARY_NOT_CONFIGURED =
|
|
28
30
|
"Secondary not configured for given contract and token";
|
|
29
31
|
export const ERROR_SECONDARY_NOT_STARTED = "Secondary market has not started";
|
|
32
|
+
export const ERROR_RECIPIENT_MISMATCH =
|
|
33
|
+
"Recipient must be the same as the caller if there is a comment";
|
|
30
34
|
|
|
31
35
|
// Helper function to create error objects
|
|
32
36
|
function makeError(errorMessage: string) {
|
|
@@ -46,6 +50,8 @@ type Call =
|
|
|
46
50
|
};
|
|
47
51
|
|
|
48
52
|
async function makeBuy({
|
|
53
|
+
contract,
|
|
54
|
+
tokenId,
|
|
49
55
|
erc20z,
|
|
50
56
|
poolBalance,
|
|
51
57
|
amount,
|
|
@@ -55,8 +61,11 @@ async function makeBuy({
|
|
|
55
61
|
chainId,
|
|
56
62
|
slippage,
|
|
57
63
|
publicClient,
|
|
64
|
+
comment,
|
|
58
65
|
}: {
|
|
59
66
|
erc20z: Address;
|
|
67
|
+
contract: Address;
|
|
68
|
+
tokenId: bigint;
|
|
60
69
|
poolBalance: { erc20z: bigint };
|
|
61
70
|
amount: bigint;
|
|
62
71
|
quantity: bigint;
|
|
@@ -64,27 +73,144 @@ async function makeBuy({
|
|
|
64
73
|
recipient?: Address;
|
|
65
74
|
chainId: number;
|
|
66
75
|
slippage: number;
|
|
76
|
+
comment: string | undefined;
|
|
67
77
|
publicClient: PublicClient;
|
|
68
78
|
}): Promise<Call> {
|
|
69
79
|
const costWithSlippage = calculateSlippageUp(amount, slippage);
|
|
80
|
+
const accountAddress = addressOrAccountAddress(account);
|
|
70
81
|
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
const validationResult = await validateBuyConditions({
|
|
83
|
+
poolBalance,
|
|
84
|
+
quantity,
|
|
85
|
+
costWithSlippage,
|
|
86
|
+
accountAddress,
|
|
87
|
+
publicClient,
|
|
88
|
+
});
|
|
73
89
|
|
|
74
|
-
|
|
90
|
+
if (validationResult.error) {
|
|
91
|
+
return makeError(validationResult.error);
|
|
92
|
+
}
|
|
75
93
|
|
|
94
|
+
if (comment && comment !== "") {
|
|
95
|
+
return handleBuyWithComment({
|
|
96
|
+
accountAddress,
|
|
97
|
+
recipient,
|
|
98
|
+
chainId,
|
|
99
|
+
quantity,
|
|
100
|
+
contract,
|
|
101
|
+
tokenId,
|
|
102
|
+
costWithSlippage,
|
|
103
|
+
comment,
|
|
104
|
+
account,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return handleBuyWithoutComment({
|
|
109
|
+
erc20z,
|
|
110
|
+
quantity,
|
|
111
|
+
recipient,
|
|
112
|
+
accountAddress,
|
|
113
|
+
costWithSlippage,
|
|
114
|
+
chainId,
|
|
115
|
+
account,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function validateBuyConditions({
|
|
120
|
+
poolBalance,
|
|
121
|
+
quantity,
|
|
122
|
+
costWithSlippage,
|
|
123
|
+
accountAddress,
|
|
124
|
+
publicClient,
|
|
125
|
+
}: {
|
|
126
|
+
poolBalance: { erc20z: bigint };
|
|
127
|
+
quantity: bigint;
|
|
128
|
+
costWithSlippage: bigint;
|
|
129
|
+
accountAddress: Address;
|
|
130
|
+
publicClient: PublicClient;
|
|
131
|
+
}): Promise<{ error?: string }> {
|
|
132
|
+
const availableToBuy = poolBalance.erc20z / BigInt(1e18) - 1n;
|
|
76
133
|
const availableToSpend = await publicClient.getBalance({
|
|
77
134
|
address: accountAddress,
|
|
78
135
|
});
|
|
79
136
|
|
|
80
137
|
if (costWithSlippage > availableToSpend) {
|
|
81
|
-
return
|
|
138
|
+
return { error: ERROR_INSUFFICIENT_WALLET_FUNDS };
|
|
82
139
|
}
|
|
83
140
|
|
|
84
141
|
if (availableToBuy < BigInt(quantity)) {
|
|
85
|
-
return
|
|
142
|
+
return { error: ERROR_INSUFFICIENT_POOL_SUPPLY };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return {};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function handleBuyWithComment({
|
|
149
|
+
accountAddress,
|
|
150
|
+
recipient,
|
|
151
|
+
chainId,
|
|
152
|
+
quantity,
|
|
153
|
+
contract,
|
|
154
|
+
tokenId,
|
|
155
|
+
costWithSlippage,
|
|
156
|
+
comment,
|
|
157
|
+
account,
|
|
158
|
+
}: {
|
|
159
|
+
accountAddress: Address;
|
|
160
|
+
recipient?: Address;
|
|
161
|
+
chainId: number;
|
|
162
|
+
quantity: bigint;
|
|
163
|
+
contract: Address;
|
|
164
|
+
tokenId: bigint;
|
|
165
|
+
costWithSlippage: bigint;
|
|
166
|
+
comment: string;
|
|
167
|
+
account: Address | Account;
|
|
168
|
+
}): Call {
|
|
169
|
+
if (recipient && recipient !== accountAddress) {
|
|
170
|
+
return makeError(ERROR_RECIPIENT_MISMATCH);
|
|
86
171
|
}
|
|
87
172
|
|
|
173
|
+
return {
|
|
174
|
+
parameters: makeContractParameters({
|
|
175
|
+
abi: callerAndCommenterABI,
|
|
176
|
+
address:
|
|
177
|
+
callerAndCommenterAddress[
|
|
178
|
+
chainId as keyof typeof callerAndCommenterAddress
|
|
179
|
+
],
|
|
180
|
+
functionName: "buyOnSecondaryAndComment",
|
|
181
|
+
args: [
|
|
182
|
+
accountAddress,
|
|
183
|
+
quantity,
|
|
184
|
+
contract,
|
|
185
|
+
tokenId,
|
|
186
|
+
accountAddress,
|
|
187
|
+
costWithSlippage,
|
|
188
|
+
0n,
|
|
189
|
+
comment,
|
|
190
|
+
],
|
|
191
|
+
account,
|
|
192
|
+
value: costWithSlippage,
|
|
193
|
+
}),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function handleBuyWithoutComment({
|
|
198
|
+
erc20z,
|
|
199
|
+
quantity,
|
|
200
|
+
recipient,
|
|
201
|
+
accountAddress,
|
|
202
|
+
costWithSlippage,
|
|
203
|
+
chainId,
|
|
204
|
+
account,
|
|
205
|
+
}: {
|
|
206
|
+
erc20z: Address;
|
|
207
|
+
quantity: bigint;
|
|
208
|
+
recipient?: Address;
|
|
209
|
+
accountAddress: Address;
|
|
210
|
+
costWithSlippage: bigint;
|
|
211
|
+
chainId: number;
|
|
212
|
+
account: Address | Account;
|
|
213
|
+
}): Call {
|
|
88
214
|
return {
|
|
89
215
|
parameters: makeContractParameters({
|
|
90
216
|
abi: secondarySwapABI,
|
|
@@ -99,7 +225,7 @@ async function makeBuy({
|
|
|
99
225
|
costWithSlippage,
|
|
100
226
|
0n,
|
|
101
227
|
],
|
|
102
|
-
account
|
|
228
|
+
account,
|
|
103
229
|
value: costWithSlippage,
|
|
104
230
|
}),
|
|
105
231
|
};
|
|
@@ -125,6 +251,7 @@ export async function buyWithSlippage({
|
|
|
125
251
|
account,
|
|
126
252
|
slippage = UNISWAP_SLIPPAGE,
|
|
127
253
|
recipient,
|
|
254
|
+
comment,
|
|
128
255
|
}: BuyWithSlippageInput & {
|
|
129
256
|
chainId: number;
|
|
130
257
|
publicClient: PublicClient;
|
|
@@ -159,6 +286,8 @@ export async function buyWithSlippage({
|
|
|
159
286
|
|
|
160
287
|
const call = await makeBuy({
|
|
161
288
|
erc20z,
|
|
289
|
+
contract,
|
|
290
|
+
tokenId,
|
|
162
291
|
poolBalance,
|
|
163
292
|
amount,
|
|
164
293
|
quantity,
|
|
@@ -166,6 +295,7 @@ export async function buyWithSlippage({
|
|
|
166
295
|
recipient,
|
|
167
296
|
chainId,
|
|
168
297
|
slippage,
|
|
298
|
+
comment,
|
|
169
299
|
publicClient,
|
|
170
300
|
});
|
|
171
301
|
|
package/src/secondary/types.ts
CHANGED
|
@@ -47,6 +47,8 @@ export type BuyWithSlippageInput = {
|
|
|
47
47
|
slippage?: number;
|
|
48
48
|
// Optional recipient address (if different from buyer/seller)
|
|
49
49
|
recipient?: Address;
|
|
50
|
+
// Optional comment to add to the swap
|
|
51
|
+
comment?: string;
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
// Same structure as BuyWithSlippageInput
|
package/src/test-utils.ts
CHANGED
|
@@ -7,8 +7,11 @@ import {
|
|
|
7
7
|
Hex,
|
|
8
8
|
PublicClient,
|
|
9
9
|
encodeAbiParameters,
|
|
10
|
+
keccak256,
|
|
11
|
+
toBytes,
|
|
10
12
|
parseAbiParameters,
|
|
11
13
|
} from "viem";
|
|
14
|
+
import { NewContractParams } from "./create/types";
|
|
12
15
|
import { expect } from "vitest";
|
|
13
16
|
|
|
14
17
|
export const waitForSuccess = async (hash: Hex, publicClient: PublicClient) => {
|
|
@@ -17,6 +20,8 @@ export const waitForSuccess = async (hash: Hex, publicClient: PublicClient) => {
|
|
|
17
20
|
});
|
|
18
21
|
|
|
19
22
|
expect(receipt.status).toBe("success");
|
|
23
|
+
|
|
24
|
+
return receipt;
|
|
20
25
|
};
|
|
21
26
|
|
|
22
27
|
export const getFixedPricedMinter = async ({
|
|
@@ -37,3 +42,17 @@ export const fixedPriceMinterMinterArguments = ({
|
|
|
37
42
|
}: {
|
|
38
43
|
mintRecipient: Address;
|
|
39
44
|
}) => encodeAbiParameters(parseAbiParameters("address"), [mintRecipient]);
|
|
45
|
+
|
|
46
|
+
const demoContractMetadataURI = "ipfs://DUMMY/contract.json";
|
|
47
|
+
|
|
48
|
+
export function randomNewContract(): NewContractParams {
|
|
49
|
+
return {
|
|
50
|
+
name: `testContract-${Math.round(Math.random() * 1_000_000)}`,
|
|
51
|
+
uri: demoContractMetadataURI,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const randomNonce = () =>
|
|
56
|
+
keccak256(toBytes(Math.round(Math.random() * 1000)));
|
|
57
|
+
export const thirtySecondsFromNow = () =>
|
|
58
|
+
BigInt(Math.round(new Date().getTime() / 1000)) + 30n;
|