@zoralabs/protocol-sdk 0.11.4 → 0.11.6-COMMENTS.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 (43) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/CHANGELOG.md +32 -0
  3. package/dist/create/mint-from-create.d.ts +2 -1
  4. package/dist/create/mint-from-create.d.ts.map +1 -1
  5. package/dist/create/minter-defaults.d.ts.map +1 -1
  6. package/dist/create/types.d.ts +1 -0
  7. package/dist/create/types.d.ts.map +1 -1
  8. package/dist/index.cjs +235 -58
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.js +239 -58
  11. package/dist/index.js.map +1 -1
  12. package/dist/mint/mint-client.d.ts +3 -1
  13. package/dist/mint/mint-client.d.ts.map +1 -1
  14. package/dist/mint/mint-queries.d.ts +5 -3
  15. package/dist/mint/mint-queries.d.ts.map +1 -1
  16. package/dist/mint/mint-transactions.d.ts +4 -2
  17. package/dist/mint/mint-transactions.d.ts.map +1 -1
  18. package/dist/sdk.d.ts.map +1 -1
  19. package/dist/secondary/secondary-client.d.ts +4 -3
  20. package/dist/secondary/secondary-client.d.ts.map +1 -1
  21. package/dist/secondary/types.d.ts +7 -0
  22. package/dist/secondary/types.d.ts.map +1 -1
  23. package/dist/secondary/utils.d.ts.map +1 -1
  24. package/dist/test-utils.d.ts +3 -1
  25. package/dist/test-utils.d.ts.map +1 -1
  26. package/package.json +2 -2
  27. package/src/comments/comments.test.ts +342 -0
  28. package/src/create/1155-create-helper.test.ts +77 -14
  29. package/src/create/1155-create-helper.ts +2 -0
  30. package/src/create/mint-from-create.ts +3 -0
  31. package/src/create/minter-defaults.ts +22 -8
  32. package/src/create/types.ts +5 -3
  33. package/src/mint/mint-client.test.ts +67 -30
  34. package/src/mint/mint-client.ts +10 -1
  35. package/src/mint/mint-queries.ts +16 -5
  36. package/src/mint/mint-transactions.ts +80 -16
  37. package/src/sdk.ts +1 -0
  38. package/src/secondary/secondary-client.test.ts +149 -25
  39. package/src/secondary/secondary-client.ts +138 -7
  40. package/src/secondary/types.ts +19 -4
  41. package/src/secondary/utils.ts +30 -10
  42. package/src/sparks/sparks-sponsored-sparks-spender.test.ts +1 -1
  43. package/src/test-utils.ts +12 -0
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, vi } from "vitest";
2
- import { parseEther } from "viem";
2
+ import { parseEther, Address, parseEventLogs } from "viem";
3
3
  import { zoraSepolia } from "viem/chains";
4
4
  import {
5
5
  forkUrls,
@@ -7,8 +7,12 @@ import {
7
7
  simulateAndWriteContractWithRetries,
8
8
  } from "src/anvil";
9
9
  import { createCollectorClient } from "src/sdk";
10
- import { zoraCreator1155ImplABI } from "@zoralabs/protocol-deployments";
11
- import { setupContractAndToken } from "src/fixtures/contract-setup";
10
+ import {
11
+ zoraCreator1155ImplABI,
12
+ commentsABI,
13
+ callerAndCommenterABI,
14
+ } from "@zoralabs/protocol-deployments";
15
+ import { SubgraphMintGetter } from "src/mint/subgraph-mint-getter";
12
16
  import { ERROR_SECONDARY_NOT_STARTED } from "./secondary-client";
13
17
  import { ISubgraphQuerier } from "src/apis/subgraph-querier";
14
18
  import { mockTimedSaleStrategyTokenQueryResult } from "src/fixtures/mint-query-results";
@@ -17,7 +21,7 @@ import { advanceToSaleAndAndLaunchMarket } from "src/fixtures/secondary";
17
21
 
18
22
  describe("secondary", () => {
19
23
  makeAnvilTest({
20
- forkBlockNumber: 14653556,
24
+ forkBlockNumber: 16072399,
21
25
  forkUrl: forkUrls.zoraSepolia,
22
26
  anvilChainId: zoraSepolia.id,
23
27
  })(
@@ -25,16 +29,11 @@ describe("secondary", () => {
25
29
  async ({
26
30
  viemClients: { publicClient, chain, walletClient, testClient },
27
31
  }) => {
28
- const creatorAccount = (await walletClient.getAddresses()!)[0]!;
29
32
  const collectorAccount = (await walletClient.getAddresses()!)[1]!;
30
33
 
31
- const { contractAddress, newTokenId } = await setupContractAndToken({
32
- chain,
33
- publicClient,
34
- creatorAccount,
35
- walletClient,
36
- });
37
-
34
+ const contractAddress: Address =
35
+ "0xd42557f24034b53e7340a40bb5813ef9ba88f2b4";
36
+ const newTokenId = 4n;
38
37
  await testClient.setBalance({
39
38
  address: collectorAccount,
40
39
  value: parseEther("100"),
@@ -50,7 +49,10 @@ describe("secondary", () => {
50
49
  tokenId: newTokenId,
51
50
  });
52
51
 
53
- expect(secondaryInfo?.secondaryActivated).toBe(false);
52
+ expect(secondaryInfo).toBeDefined();
53
+
54
+ expect(secondaryInfo!.minimumMintsForCountdown).toBe(1111n);
55
+ expect(secondaryInfo!.secondaryActivated).toBe(false);
54
56
 
55
57
  const buyResult = await collectorClient.buy1155OnSecondary({
56
58
  account: collectorAccount,
@@ -65,7 +67,7 @@ describe("secondary", () => {
65
67
  );
66
68
 
67
69
  makeAnvilTest({
68
- forkBlockNumber: 14653556,
70
+ forkBlockNumber: 16072399,
69
71
  forkUrl: forkUrls.zoraSepolia,
70
72
  anvilChainId: zoraSepolia.id,
71
73
  })(
@@ -73,16 +75,12 @@ describe("secondary", () => {
73
75
  async ({
74
76
  viemClients: { publicClient, chain, walletClient, testClient },
75
77
  }) => {
76
- const creatorAccount = (await walletClient.getAddresses()!)[0]!;
77
78
  const collectorAccount = (await walletClient.getAddresses()!)[1]!;
78
79
 
79
- const { contractAddress, newTokenId, mintGetter } =
80
- await setupContractAndToken({
81
- chain,
82
- publicClient,
83
- creatorAccount,
84
- walletClient,
85
- });
80
+ const mintGetter = new SubgraphMintGetter(chain.id);
81
+ const contractAddress: Address =
82
+ "0xd42557f24034b53e7340a40bb5813ef9ba88f2b4";
83
+ const newTokenId = 4n;
86
84
 
87
85
  await testClient.setBalance({
88
86
  address: collectorAccount,
@@ -109,13 +107,25 @@ describe("secondary", () => {
109
107
  mintGetter,
110
108
  });
111
109
 
110
+ const secondaryInfo = await collectorClient.getSecondaryInfo({
111
+ contract: contractAddress,
112
+ tokenId: newTokenId,
113
+ });
114
+
115
+ expect(secondaryInfo).toBeDefined();
116
+ expect(secondaryInfo!.mintCount).toBeGreaterThan(0n);
117
+
112
118
  // mint 1 less than expected minimum market.
113
119
  // make sure that there is no sale end
120
+ const quantityToMintFirst =
121
+ secondaryInfo!.minimumMintsForCountdown! -
122
+ secondaryInfo!.mintCount -
123
+ 1n;
124
+
114
125
  const { parameters: collectParameters } = await collectorClient.mint({
115
126
  minterAccount: collectorAccount,
116
127
  mintType: "1155",
117
- // mint 1 less than expected minimum market.
118
- quantityToMint: 1111n - 1n,
128
+ quantityToMint: quantityToMintFirst,
119
129
  tokenId: newTokenId,
120
130
  tokenContract: contractAddress,
121
131
  });
@@ -245,8 +255,122 @@ describe("secondary", () => {
245
255
  args: [collectorAccount, newTokenId],
246
256
  });
247
257
 
248
- expect(balance).toBe(1111n + quantityToBuy - quantityToSell);
258
+ expect(balance).toBe(
259
+ quantityToMintFirst + 1n + quantityToBuy - quantityToSell,
260
+ );
249
261
  },
250
262
  30_000,
251
263
  );
264
+
265
+ makeAnvilTest({
266
+ forkBlockNumber: 16123365,
267
+ forkUrl: forkUrls.zoraSepolia,
268
+ anvilChainId: zoraSepolia.id,
269
+ })(
270
+ "it can buy on secondary with a comment",
271
+ async ({
272
+ viemClients: { publicClient, chain, walletClient, testClient },
273
+ }) => {
274
+ const collectorAccount = (await walletClient.getAddresses()!)[1]!;
275
+
276
+ const mintGetter = new SubgraphMintGetter(chain.id);
277
+ const contractAddress: Address =
278
+ "0xd42557f24034b53e7340a40bb5813ef9ba88f2b4";
279
+ const newTokenId = 4n;
280
+
281
+ await testClient.setBalance({
282
+ address: collectorAccount,
283
+ value: parseEther("100"),
284
+ });
285
+
286
+ mintGetter.subgraphQuerier.query = vi
287
+ .fn<ISubgraphQuerier["query"]>()
288
+ .mockResolvedValue({
289
+ zoraCreateToken: mockTimedSaleStrategyTokenQueryResult({
290
+ chainId: chain.id,
291
+ tokenId: newTokenId,
292
+ contractAddress,
293
+ contractVersion:
294
+ new1155ContractVersion[
295
+ chain.id as keyof typeof new1155ContractVersion
296
+ ],
297
+ }),
298
+ });
299
+
300
+ const collectorClient = createCollectorClient({
301
+ chainId: chain.id,
302
+ publicClient,
303
+ mintGetter,
304
+ });
305
+
306
+ const secondaryInfo = await collectorClient.getSecondaryInfo({
307
+ contract: contractAddress,
308
+ tokenId: newTokenId,
309
+ });
310
+
311
+ // mint enough to start the countdown
312
+ const quantityToMint =
313
+ secondaryInfo!.minimumMintsForCountdown! - secondaryInfo!.mintCount;
314
+
315
+ const { parameters: collectParameters } = await collectorClient.mint({
316
+ minterAccount: collectorAccount,
317
+ mintType: "1155",
318
+ quantityToMint: quantityToMint,
319
+ tokenId: newTokenId,
320
+ tokenContract: contractAddress,
321
+ });
322
+
323
+ await simulateAndWriteContractWithRetries({
324
+ parameters: collectParameters,
325
+ walletClient,
326
+ publicClient,
327
+ });
328
+
329
+ await advanceToSaleAndAndLaunchMarket({
330
+ contractAddress,
331
+ tokenId: newTokenId,
332
+ testClient,
333
+ publicClient,
334
+ walletClient,
335
+ collectorClient,
336
+ chainId: chain.id,
337
+ account: collectorAccount,
338
+ });
339
+
340
+ const buyResult = await collectorClient.buy1155OnSecondary({
341
+ account: collectorAccount,
342
+ quantity: 5n,
343
+ contract: contractAddress,
344
+ tokenId: newTokenId,
345
+ comment: "test comment",
346
+ });
347
+
348
+ const receipt = await simulateAndWriteContractWithRetries({
349
+ parameters: buyResult.parameters!,
350
+ walletClient,
351
+ publicClient,
352
+ });
353
+
354
+ const commentedEvent = parseEventLogs({
355
+ abi: commentsABI,
356
+ logs: receipt.logs,
357
+ eventName: "Commented",
358
+ });
359
+
360
+ expect(commentedEvent[0]).toBeDefined();
361
+ expect(commentedEvent[0]!.args.text).toBe("test comment");
362
+
363
+ const boughtAndCommentedEvent = parseEventLogs({
364
+ abi: callerAndCommenterABI,
365
+ logs: receipt.logs,
366
+ eventName: "SwappedOnSecondaryAndCommented",
367
+ });
368
+
369
+ expect(boughtAndCommentedEvent[0]).toBeDefined();
370
+ expect(boughtAndCommentedEvent[0]!.args.comment).toBe("test comment");
371
+ expect(boughtAndCommentedEvent[0]!.args.quantity).toBe(5n);
372
+ expect(boughtAndCommentedEvent[0]!.args.swapDirection).toBe(0);
373
+ },
374
+ 20_000,
375
+ );
252
376
  });
@@ -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";
@@ -15,6 +17,7 @@ import {
15
17
  QuotePrice,
16
18
  BuyWithSlippageInput,
17
19
  SellWithSlippageInput,
20
+ SecondaryInfo,
18
21
  } from "./types";
19
22
 
20
23
  // uniswap's auto slippage for L2s is 0.5% -> 0.005
@@ -26,6 +29,8 @@ const ERROR_INSUFFICIENT_POOL_SUPPLY = "Insufficient pool supply";
26
29
  const ERROR_SECONDARY_NOT_CONFIGURED =
27
30
  "Secondary not configured for given contract and token";
28
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";
29
34
 
30
35
  // Helper function to create error objects
31
36
  function makeError(errorMessage: string) {
@@ -45,6 +50,8 @@ type Call =
45
50
  };
46
51
 
47
52
  async function makeBuy({
53
+ contract,
54
+ tokenId,
48
55
  erc20z,
49
56
  poolBalance,
50
57
  amount,
@@ -54,8 +61,11 @@ async function makeBuy({
54
61
  chainId,
55
62
  slippage,
56
63
  publicClient,
64
+ comment,
57
65
  }: {
58
66
  erc20z: Address;
67
+ contract: Address;
68
+ tokenId: bigint;
59
69
  poolBalance: { erc20z: bigint };
60
70
  amount: bigint;
61
71
  quantity: bigint;
@@ -63,27 +73,144 @@ async function makeBuy({
63
73
  recipient?: Address;
64
74
  chainId: number;
65
75
  slippage: number;
76
+ comment: string | undefined;
66
77
  publicClient: PublicClient;
67
78
  }): Promise<Call> {
68
79
  const costWithSlippage = calculateSlippageUp(amount, slippage);
80
+ const accountAddress = addressOrAccountAddress(account);
69
81
 
70
- // we cannot buy all the available tokens in a pool (the quote fails if we try doing that)
71
- const availableToBuy = poolBalance.erc20z / BigInt(1e18) - 1n;
82
+ const validationResult = await validateBuyConditions({
83
+ poolBalance,
84
+ quantity,
85
+ costWithSlippage,
86
+ accountAddress,
87
+ publicClient,
88
+ });
72
89
 
73
- const accountAddress = addressOrAccountAddress(account);
90
+ if (validationResult.error) {
91
+ return makeError(validationResult.error);
92
+ }
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
+ }
74
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;
75
133
  const availableToSpend = await publicClient.getBalance({
76
134
  address: accountAddress,
77
135
  });
78
136
 
79
137
  if (costWithSlippage > availableToSpend) {
80
- return makeError(ERROR_INSUFFICIENT_WALLET_FUNDS);
138
+ return { error: ERROR_INSUFFICIENT_WALLET_FUNDS };
81
139
  }
82
140
 
83
141
  if (availableToBuy < BigInt(quantity)) {
84
- return makeError(ERROR_INSUFFICIENT_POOL_SUPPLY);
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);
85
171
  }
86
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 {
87
214
  return {
88
215
  parameters: makeContractParameters({
89
216
  abi: secondarySwapABI,
@@ -98,7 +225,7 @@ async function makeBuy({
98
225
  costWithSlippage,
99
226
  0n,
100
227
  ],
101
- account: account,
228
+ account,
102
229
  value: costWithSlippage,
103
230
  }),
104
231
  };
@@ -124,6 +251,7 @@ export async function buyWithSlippage({
124
251
  account,
125
252
  slippage = UNISWAP_SLIPPAGE,
126
253
  recipient,
254
+ comment,
127
255
  }: BuyWithSlippageInput & {
128
256
  chainId: number;
129
257
  publicClient: PublicClient;
@@ -158,6 +286,8 @@ export async function buyWithSlippage({
158
286
 
159
287
  const call = await makeBuy({
160
288
  erc20z,
289
+ contract,
290
+ tokenId,
161
291
  poolBalance,
162
292
  amount,
163
293
  quantity,
@@ -165,6 +295,7 @@ export async function buyWithSlippage({
165
295
  recipient,
166
296
  chainId,
167
297
  slippage,
298
+ comment,
168
299
  publicClient,
169
300
  });
170
301
 
@@ -331,7 +462,7 @@ export class SecondaryClient {
331
462
  }: {
332
463
  contract: Address;
333
464
  tokenId: bigint;
334
- }) {
465
+ }): Promise<SecondaryInfo | undefined> {
335
466
  return getSecondaryInfo({
336
467
  contract,
337
468
  tokenId,
@@ -47,18 +47,33 @@ 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
53
55
  export type SellWithSlippageInput = BuyWithSlippageInput;
54
56
 
57
+ // Base type for shared properties
55
58
  export type SecondaryInfo = {
56
- // Whether the secondary market is activated
59
+ // Boolean if the secondary market has been launched
57
60
  secondaryActivated: boolean;
58
- // Address of the liquidity pool for the erc20z to WETH pair
61
+ // The Uniswap pool address
59
62
  pool: Address;
60
- // Address of the erc20z token
63
+ // The ERC20z address
61
64
  erc20z: Address;
62
- // Timestamp when the secondary market will end
65
+ // The ERC20Z name
66
+ name: string;
67
+ // The ERC20Z symbol
68
+ symbol: string;
69
+ // Earliest time in seconds a token can be minted
70
+ saleStart: bigint;
71
+ // Latest time in seconds a token can be minted. Gets set after the market countdown has started.
63
72
  saleEnd?: bigint;
73
+ // The amount of time after the `minimumMarketEth` is reached until the secondary market can be launched, in seconds.
74
+ marketCountdown?: bigint;
75
+ // minimum quantity of tokens that must have been minted to launch the countdown.
76
+ minimumMintsForCountdown?: bigint;
77
+ // mints so far
78
+ mintCount: bigint;
64
79
  };
@@ -1,4 +1,4 @@
1
- import { Address } from "viem";
1
+ import { Address, parseEther } from "viem";
2
2
  import { PublicClient } from "src/utils";
3
3
  import {
4
4
  zoraTimedSaleStrategyABI,
@@ -16,15 +16,22 @@ export async function getSecondaryInfo({
16
16
  publicClient: PublicClient;
17
17
  chainId: number;
18
18
  }): Promise<SecondaryInfo | undefined> {
19
- const result = await publicClient.readContract({
20
- abi: zoraTimedSaleStrategyABI,
21
- address:
22
- zoraTimedSaleStrategyAddress[
23
- chainId as keyof typeof zoraTimedSaleStrategyAddress
24
- ],
25
- functionName: "sale",
26
- args: [contract, tokenId],
27
- });
19
+ let result;
20
+
21
+ try {
22
+ result = await publicClient.readContract({
23
+ abi: zoraTimedSaleStrategyABI,
24
+ address:
25
+ zoraTimedSaleStrategyAddress[
26
+ chainId as keyof typeof zoraTimedSaleStrategyAddress
27
+ ],
28
+ functionName: "saleV2",
29
+ args: [contract, tokenId],
30
+ });
31
+ } catch (e) {
32
+ console.error(e);
33
+ return undefined;
34
+ }
28
35
 
29
36
  // if there is no erc20zAddress, we can assume that secondary market has not been configured for this contract and token.
30
37
  if (!result.erc20zAddress) {
@@ -36,5 +43,18 @@ export async function getSecondaryInfo({
36
43
  pool: result.poolAddress,
37
44
  secondaryActivated: result.secondaryActivated,
38
45
  saleEnd: result.saleEnd === 0n ? undefined : result.saleEnd,
46
+ saleStart: result.saleStart,
47
+ name: result.name,
48
+ symbol: result.symbol,
49
+ marketCountdown:
50
+ result.marketCountdown === 0n ? undefined : result.marketCountdown,
51
+ minimumMintsForCountdown:
52
+ result.minimumMarketEth === 0n
53
+ ? undefined
54
+ : result.minimumMarketEth / parseEther("0.0000111"),
55
+ mintCount:
56
+ (await publicClient.getBalance({
57
+ address: result.erc20zAddress,
58
+ })) / parseEther("0.0000111"),
39
59
  };
40
60
  }
@@ -19,7 +19,7 @@ import { zoraSparksManagerImplABI } from "@zoralabs/protocol-deployments";
19
19
  const anvilTest = makeAnvilTest({
20
20
  forkUrl: forkUrls.zoraMainnet,
21
21
  anvilChainId: zora.id,
22
- forkBlockNumber: 17667435,
22
+ forkBlockNumber: 22029945,
23
23
  });
24
24
  describe("Sponsored Mints Spender with Relay", () => {
25
25
  anvilTest(
package/src/test-utils.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  encodeAbiParameters,
10
10
  parseAbiParameters,
11
11
  } from "viem";
12
+ import { NewContractParams } from "./create/types";
12
13
  import { expect } from "vitest";
13
14
 
14
15
  export const waitForSuccess = async (hash: Hex, publicClient: PublicClient) => {
@@ -17,6 +18,8 @@ export const waitForSuccess = async (hash: Hex, publicClient: PublicClient) => {
17
18
  });
18
19
 
19
20
  expect(receipt.status).toBe("success");
21
+
22
+ return receipt;
20
23
  };
21
24
 
22
25
  export const getFixedPricedMinter = async ({
@@ -37,3 +40,12 @@ export const fixedPriceMinterMinterArguments = ({
37
40
  }: {
38
41
  mintRecipient: Address;
39
42
  }) => encodeAbiParameters(parseAbiParameters("address"), [mintRecipient]);
43
+
44
+ const demoContractMetadataURI = "ipfs://DUMMY/contract.json";
45
+
46
+ export function randomNewContract(): NewContractParams {
47
+ return {
48
+ name: `testContract-${Math.round(Math.random() * 1_000_000)}`,
49
+ uri: demoContractMetadataURI,
50
+ };
51
+ }