@zoralabs/protocol-sdk 0.8.0 → 0.9.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 (75) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/CHANGELOG.md +11 -0
  3. package/dist/allow-list/allow-list-client.d.ts +26 -0
  4. package/dist/allow-list/allow-list-client.d.ts.map +1 -0
  5. package/dist/allow-list/types.d.ts +14 -0
  6. package/dist/allow-list/types.d.ts.map +1 -0
  7. package/dist/apis/generated/allow-list-api-types.d.ts +288 -0
  8. package/dist/apis/generated/allow-list-api-types.d.ts.map +1 -0
  9. package/dist/apis/http-api-base.d.ts.map +1 -1
  10. package/dist/apis/subgraph-querier.d.ts +18 -0
  11. package/dist/apis/subgraph-querier.d.ts.map +1 -0
  12. package/dist/create/contract-setup.d.ts +1 -0
  13. package/dist/create/contract-setup.d.ts.map +1 -1
  14. package/dist/create/minter-defaults.d.ts +5 -0
  15. package/dist/create/minter-defaults.d.ts.map +1 -0
  16. package/dist/create/minter-setup.d.ts +14 -0
  17. package/dist/create/minter-setup.d.ts.map +1 -0
  18. package/dist/create/token-setup.d.ts +4 -19
  19. package/dist/create/token-setup.d.ts.map +1 -1
  20. package/dist/create/types.d.ts +32 -7
  21. package/dist/create/types.d.ts.map +1 -1
  22. package/dist/create/update.d.ts +15 -0
  23. package/dist/create/update.d.ts.map +1 -0
  24. package/dist/index.cjs +2249 -1936
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2284 -1966
  29. package/dist/index.js.map +1 -1
  30. package/dist/ipfs/token-metadata.d.ts +1 -0
  31. package/dist/ipfs/token-metadata.d.ts.map +1 -1
  32. package/dist/mint/mint-client.d.ts +2 -6
  33. package/dist/mint/mint-client.d.ts.map +1 -1
  34. package/dist/mint/mint-queries.d.ts +3 -1
  35. package/dist/mint/mint-queries.d.ts.map +1 -1
  36. package/dist/mint/mint-transactions.d.ts +9 -7
  37. package/dist/mint/mint-transactions.d.ts.map +1 -1
  38. package/dist/mint/subgraph-mint-getter.d.ts +5 -4
  39. package/dist/mint/subgraph-mint-getter.d.ts.map +1 -1
  40. package/dist/mint/subgraph-queries.d.ts +42 -15
  41. package/dist/mint/subgraph-queries.d.ts.map +1 -1
  42. package/dist/mint/types.d.ts +32 -13
  43. package/dist/mint/types.d.ts.map +1 -1
  44. package/dist/sparks/sparks-contracts.d.ts +96 -96
  45. package/dist/types.d.ts +1 -1
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/utils.d.ts +1 -8
  48. package/dist/utils.d.ts.map +1 -1
  49. package/package.json +2 -2
  50. package/src/allow-list/allow-list-client.ts +105 -0
  51. package/src/allow-list/types.ts +15 -0
  52. package/src/apis/generated/allow-list-api-types.ts +288 -0
  53. package/src/apis/http-api-base.ts +12 -0
  54. package/src/apis/subgraph-querier.ts +38 -0
  55. package/src/create/1155-create-helper.test.ts +216 -66
  56. package/src/create/1155-create-helper.ts +4 -4
  57. package/src/create/contract-setup.ts +8 -0
  58. package/src/create/minter-defaults.test.ts +21 -0
  59. package/src/create/minter-defaults.ts +134 -0
  60. package/src/create/minter-setup.ts +293 -0
  61. package/src/create/token-setup.ts +14 -190
  62. package/src/create/types.ts +56 -9
  63. package/src/create/update.ts +93 -0
  64. package/src/index.ts +4 -0
  65. package/src/ipfs/token-metadata.ts +18 -0
  66. package/src/mint/mint-client.test.ts +219 -15
  67. package/src/mint/mint-client.ts +2 -34
  68. package/src/mint/mint-queries.ts +34 -13
  69. package/src/mint/mint-transactions.ts +104 -17
  70. package/src/mint/subgraph-mint-getter.ts +107 -50
  71. package/src/mint/subgraph-queries.ts +67 -37
  72. package/src/mint/types.ts +55 -16
  73. package/src/premint/premint-client.test.ts +6 -5
  74. package/src/types.ts +1 -1
  75. package/src/utils.ts +1 -25
@@ -0,0 +1,93 @@
1
+ import {
2
+ zoraCreator1155ImplABI,
3
+ zoraCreatorMerkleMinterStrategyABI,
4
+ zoraCreatorMerkleMinterStrategyAddress,
5
+ } from "@zoralabs/protocol-deployments";
6
+ import { Address, PublicClient, WalletClient, encodeFunctionData } from "viem";
7
+
8
+ function constructCallData({
9
+ tokenId,
10
+ saleEnd,
11
+ saleStart,
12
+ merkleRoot,
13
+ fundsRecipient,
14
+ }: {
15
+ mintLimit?: string;
16
+ tokenId: bigint;
17
+ saleEnd: bigint;
18
+ saleStart: bigint;
19
+ merkleRoot: `0x${string}`;
20
+ fundsRecipient: Address;
21
+ }) {
22
+ const saleData = encodeFunctionData({
23
+ abi: zoraCreatorMerkleMinterStrategyABI,
24
+ functionName: "setSale",
25
+ args: [
26
+ tokenId,
27
+ {
28
+ presaleStart: saleStart,
29
+ presaleEnd: saleEnd,
30
+ fundsRecipient,
31
+ merkleRoot,
32
+ },
33
+ ],
34
+ });
35
+
36
+ return saleData;
37
+ }
38
+
39
+ export async function updateAllowListOnContract({
40
+ contractAddress: collectionAddress,
41
+ tokenId,
42
+ chainId,
43
+ saleStart,
44
+ saleEnd,
45
+ merkleRoot,
46
+ fundsRecipient,
47
+ tokenAdmin,
48
+ publicClient,
49
+ walletClient,
50
+ }: {
51
+ contractAddress: Address;
52
+ tokenId: bigint;
53
+ chainId: number;
54
+ address: Address;
55
+ saleStart: bigint;
56
+ saleEnd: bigint;
57
+ merkleRoot: `0x${string}`;
58
+ fundsRecipient: Address;
59
+ tokenAdmin: Address;
60
+ publicClient: PublicClient;
61
+ walletClient: WalletClient;
62
+ }) {
63
+ const saleData = constructCallData({
64
+ fundsRecipient,
65
+ merkleRoot,
66
+ saleEnd,
67
+ saleStart,
68
+ tokenId,
69
+ });
70
+
71
+ const merkleSaleStrategyAddress =
72
+ zoraCreatorMerkleMinterStrategyAddress[
73
+ chainId as keyof typeof zoraCreatorMerkleMinterStrategyAddress
74
+ ];
75
+
76
+ const { request } = await publicClient.simulateContract({
77
+ abi: zoraCreator1155ImplABI,
78
+ address: collectionAddress,
79
+ functionName: "callSale",
80
+ args: [tokenId, merkleSaleStrategyAddress, saleData],
81
+ account: tokenAdmin,
82
+ });
83
+
84
+ const hash = await walletClient.writeContract(request);
85
+
86
+ const receipt = await publicClient.waitForTransactionReceipt({
87
+ hash,
88
+ });
89
+
90
+ if (receipt.status !== "success") {
91
+ throw new Error("Transaction failed");
92
+ }
93
+ }
package/src/index.ts CHANGED
@@ -29,3 +29,7 @@ export * from "./create/types";
29
29
  export * from "./sdk";
30
30
 
31
31
  export * from "./ipfs";
32
+
33
+ export { createAllowList } from "./allow-list/allow-list-client";
34
+
35
+ export * from "./allow-list/types";
@@ -97,3 +97,21 @@ export const makeMediaTokenMetadata = async ({
97
97
  attributes,
98
98
  };
99
99
  };
100
+
101
+ export async function fetchTokenMetadata(tokenMetadataURI: string) {
102
+ const fetchableUrl = getFetchableUrl(tokenMetadataURI);
103
+
104
+ if (!fetchableUrl) {
105
+ throw new Error(`Invalid token metadata URI: ${tokenMetadataURI}`);
106
+ }
107
+
108
+ const json = (await (await fetch(fetchableUrl)).json()) as
109
+ | TokenMetadataJson
110
+ | undefined;
111
+
112
+ if (!json) {
113
+ throw new Error(`Failed to fetch metadata from ${fetchableUrl}`);
114
+ }
115
+
116
+ return json;
117
+ }
@@ -1,9 +1,22 @@
1
- import { describe, expect } from "vitest";
2
- import { Address, erc20Abi, parseAbi, parseEther } from "viem";
1
+ import { describe, expect, vi } from "vitest";
2
+ import { Address, erc20Abi, parseAbi, parseEther, zeroAddress } from "viem";
3
3
  import { zora, zoraSepolia } from "viem/chains";
4
- import { zoraCreator1155ImplABI } from "@zoralabs/protocol-deployments";
4
+ import {
5
+ zoraCreator1155ImplABI,
6
+ zoraTimedSaleStrategyAddress,
7
+ } from "@zoralabs/protocol-deployments";
5
8
  import { forkUrls, makeAnvilTest } from "src/anvil";
6
- import { createCollectorClient } from "src/sdk";
9
+ import { createCollectorClient, createCreatorClient } from "src/sdk";
10
+ import { getAllowListEntry } from "src/allow-list/allow-list-client";
11
+ import {
12
+ demoContractMetadataURI,
13
+ demoTokenMetadataURI,
14
+ } from "src/create/1155-create-helper.test";
15
+ import { SubgraphMintGetter } from "./subgraph-mint-getter";
16
+ import { new1155ContractVersion } from "src/create/contract-setup";
17
+ import { SALE_END_FOREVER } from "src/create/minter-defaults";
18
+ import { ISubgraphQuerier } from "src/apis/subgraph-querier";
19
+ import { TokenQueryResult } from "./subgraph-queries";
7
20
 
8
21
  const erc721ABI = parseAbi([
9
22
  "function balanceOf(address owner) public view returns (uint256)",
@@ -239,25 +252,216 @@ describe("mint-helper", () => {
239
252
 
240
253
  makeAnvilTest({
241
254
  forkUrl: forkUrls.zoraSepolia,
242
- forkBlockNumber: 10294670,
255
+ forkBlockNumber: 10970943,
243
256
  anvilChainId: zoraSepolia.id,
257
+ })("can mint allowlist tokens", async ({ viemClients }) => {
258
+ const { publicClient, chain, testClient, walletClient } = viemClients;
259
+
260
+ const collectorClient = createCollectorClient({
261
+ chainId: chain.id,
262
+ publicClient,
263
+ });
264
+
265
+ const targetContract = "0x440cF6a9f12b2f05Ec4Cee8eE0F317B0eC0c2eCD";
266
+
267
+ const tokenId = 1n;
268
+
269
+ const allowListUser = "0xf69fEc6d858c77e969509843852178bd24CAd2B6";
270
+ const merkleRoot =
271
+ "4d08ab87f97dda8811b4bb32a16a175db65e4c140797c993679a3d58aaadc791";
272
+
273
+ const allowListEntryResult = await getAllowListEntry({
274
+ address: allowListUser,
275
+ merkleRoot,
276
+ });
277
+
278
+ const { prepareMint } = await collectorClient.getToken({
279
+ mintType: "1155",
280
+ tokenContract: targetContract,
281
+ tokenId,
282
+ });
283
+
284
+ const minter = (await walletClient.getAddresses())[0]!;
285
+
286
+ await testClient.setBalance({
287
+ address: minter,
288
+ value: parseEther("10"),
289
+ });
290
+
291
+ const quantityToMint = allowListEntryResult.allowListEntry!.maxCanMint;
292
+
293
+ const { parameters } = prepareMint({
294
+ minterAccount: minter,
295
+ quantityToMint,
296
+ mintRecipient: allowListUser,
297
+ allowListEntry: allowListEntryResult.allowListEntry,
298
+ });
299
+
300
+ const { request } = await publicClient.simulateContract(parameters);
301
+ const hash = await walletClient.writeContract(request);
302
+
303
+ await publicClient.waitForTransactionReceipt({ hash });
304
+
305
+ const balance = await publicClient.readContract({
306
+ abi: zoraCreator1155ImplABI,
307
+ functionName: "balanceOf",
308
+ address: targetContract,
309
+ args: [allowListUser, tokenId],
310
+ });
311
+
312
+ expect(balance).toBe(BigInt(quantityToMint));
313
+ }),
314
+ makeAnvilTest({
315
+ forkUrl: forkUrls.zoraSepolia,
316
+ forkBlockNumber: 10294670,
317
+ anvilChainId: zoraSepolia.id,
318
+ })(
319
+ "gets onchain and premint mintables",
320
+ async ({ viemClients }) => {
321
+ const { publicClient, chain } = viemClients;
322
+
323
+ const targetContract: Address =
324
+ "0xa33e4228843092bb0f2fcbb2eb237bcefc1046b3";
325
+
326
+ const minter = createCollectorClient({
327
+ chainId: chain.id,
328
+ publicClient,
329
+ });
330
+
331
+ const { tokens: mintables, contract } =
332
+ await minter.getTokensOfContract({
333
+ tokenContract: targetContract,
334
+ });
335
+
336
+ expect(mintables.length).toBe(4);
337
+ expect(contract).toBeDefined();
338
+ },
339
+ 12 * 1000,
340
+ );
341
+
342
+ makeAnvilTest({
343
+ forkUrl: forkUrls.zoraMainnet,
344
+ forkBlockNumber: 18145203,
345
+ anvilChainId: zora.id,
244
346
  })(
245
- "gets onchain and premint mintables",
347
+ "can mint a zora timed sale strategy mint",
246
348
  async ({ viemClients }) => {
247
- const { publicClient, chain } = viemClients;
349
+ const { publicClient, chain, walletClient } = viemClients;
248
350
 
249
- const targetContract: Address =
250
- "0xa33e4228843092bb0f2fcbb2eb237bcefc1046b3";
351
+ const creator = (await walletClient.getAddresses())[0]!;
251
352
 
252
- const minter = createCollectorClient({ chainId: chain.id, publicClient });
353
+ const creatorClient = createCreatorClient({
354
+ chainId: chain.id,
355
+ publicClient,
356
+ });
253
357
 
254
- const { tokens: mintables, contract } = await minter.getTokensOfContract({
255
- tokenContract: targetContract,
358
+ const { parameters, contractAddress, newTokenId } =
359
+ await creatorClient.create1155({
360
+ account: creator,
361
+ contract: {
362
+ name: "Test Timed Sale",
363
+ uri: demoContractMetadataURI,
364
+ defaultAdmin: creator,
365
+ },
366
+ token: {
367
+ tokenMetadataURI: demoTokenMetadataURI,
368
+ },
369
+ });
370
+
371
+ const { request: createRequest } =
372
+ await publicClient.simulateContract(parameters);
373
+ const createHash = await walletClient.writeContract(createRequest);
374
+ const createReceipt = await publicClient.waitForTransactionReceipt({
375
+ hash: createHash,
376
+ });
377
+ expect(createReceipt.status).toBe("success");
378
+
379
+ const zoraCreateToken: TokenQueryResult = {
380
+ contract: {
381
+ address: contractAddress,
382
+ contractVersion: new1155ContractVersion(chain.id),
383
+ // not used:
384
+ mintFeePerQuantity: "0",
385
+ name: "",
386
+ contractURI: "",
387
+ salesStrategies: [],
388
+ },
389
+ creator: creator,
390
+ maxSupply: "1000",
391
+ tokenStandard: "ERC1155",
392
+ totalMinted: "0",
393
+ uri: "",
394
+ tokenId: newTokenId.toString(),
395
+ salesStrategies: [
396
+ {
397
+ type: "ZORA_TIMED",
398
+ zoraTimedMinter: {
399
+ address:
400
+ zoraTimedSaleStrategyAddress[
401
+ chain.id as keyof typeof zoraTimedSaleStrategyAddress
402
+ ],
403
+ mintFee: "111000000000000",
404
+ saleEnd: SALE_END_FOREVER.toString(),
405
+ saleStart: "0",
406
+ erc20Z: {
407
+ // not needed
408
+ id: zeroAddress,
409
+ // note needed
410
+ pool: zeroAddress,
411
+ },
412
+ secondaryActivated: false,
413
+ },
414
+ },
415
+ ],
416
+ };
417
+
418
+ const mockQuery = vi.fn<ISubgraphQuerier["query"]>().mockResolvedValue({
419
+ zoraCreateToken,
420
+ });
421
+
422
+ const mintGetter = new SubgraphMintGetter(chain.id);
423
+ mintGetter.subgraphQuerier.query = mockQuery;
424
+
425
+ const collectorClient = createCollectorClient({
426
+ chainId: chain.id,
427
+ publicClient,
428
+ mintGetter,
429
+ });
430
+
431
+ const collector = (await walletClient.getAddresses())[1]!;
432
+
433
+ const { prepareMint } = await collectorClient.getToken({
434
+ mintType: "1155",
435
+ tokenContract: contractAddress,
436
+ tokenId: newTokenId,
437
+ });
438
+
439
+ const quantityToMint = 10n;
440
+
441
+ const { parameters: mintParameters, costs } = prepareMint({
442
+ minterAccount: collector,
443
+ quantityToMint,
256
444
  });
257
445
 
258
- expect(mintables.length).toBe(4);
259
- expect(contract).toBeDefined();
446
+ expect(costs.totalCostEth).toBe(quantityToMint * parseEther("0.000111"));
447
+
448
+ const { request: mintRequest } =
449
+ await publicClient.simulateContract(mintParameters);
450
+ const mintHash = await walletClient.writeContract(mintRequest);
451
+ const mintReceipt = await publicClient.waitForTransactionReceipt({
452
+ hash: mintHash,
453
+ });
454
+ expect(mintReceipt.status).toBe("success");
455
+
456
+ const balance = await publicClient.readContract({
457
+ abi: zoraCreator1155ImplABI,
458
+ address: contractAddress,
459
+ functionName: "balanceOf",
460
+ args: [collector, newTokenId],
461
+ });
462
+
463
+ expect(balance).toBe(quantityToMint);
260
464
  },
261
- 12 * 1000,
465
+ 20_000,
262
466
  );
263
467
  });
@@ -1,4 +1,4 @@
1
- import { Address, Account, SimulateContractParameters } from "viem";
1
+ import { Address } from "viem";
2
2
  import { IPublicClient } from "src/types";
3
3
  import {
4
4
  GetMintParameters,
@@ -7,16 +7,9 @@ import {
7
7
  PrepareMintReturn,
8
8
  SaleType,
9
9
  } from "./types";
10
- import {
11
- MakeMintParametersArguments,
12
- Make1155MintArguments,
13
- Make721MintArguments,
14
- GetMintCostsParameters,
15
- is1155Mint,
16
- } from "./types";
10
+ import { MakeMintParametersArguments, GetMintCostsParameters } from "./types";
17
11
  import { IPremintGetter } from "src/premint/premint-api-client";
18
12
 
19
- import { makeOnchainMintCall } from "./mint-transactions";
20
13
  import { getMint, getMintCosts, getMintsOfContract } from "./mint-queries";
21
14
 
22
15
  class MintError extends Error {}
@@ -139,28 +132,3 @@ async function mint({
139
132
  mintReferral: parameters.mintReferral,
140
133
  });
141
134
  }
142
-
143
- export async function collectOnchain({
144
- chainId,
145
- mintGetter,
146
- ...parameters
147
- }: (Make1155MintArguments | Make721MintArguments) & {
148
- mintGetter: IOnchainMintGetter;
149
- chainId: number;
150
- }): Promise<
151
- SimulateContractParameters<any, any, any, any, any, Account | Address>
152
- > {
153
- const { tokenContract: tokenContract, preferredSaleType: saleType } =
154
- parameters;
155
- const tokenId = is1155Mint(parameters) ? parameters.tokenId : undefined;
156
- const salesConfigAndTokenInfo = await mintGetter.getMintable({
157
- tokenId,
158
- tokenAddress: tokenContract,
159
- preferredSaleType: saleType,
160
- });
161
-
162
- return makeOnchainMintCall({
163
- mintParams: parameters,
164
- token: salesConfigAndTokenInfo,
165
- });
166
- }
@@ -27,6 +27,8 @@ import {
27
27
  import { makeOnchainMintCall, parseMintCosts } from "./mint-transactions";
28
28
  import { buildPremintMintCall } from "src/premint/premint-client";
29
29
  import { IPublicClient } from "src/types";
30
+ import { AllowListEntry } from "src/allow-list/types";
31
+ import { Concrete } from "src/utils";
30
32
 
31
33
  export async function getMint({
32
34
  params,
@@ -42,10 +44,12 @@ export async function getMint({
42
44
  const { tokenContract } = params;
43
45
  if (isOnChainMint(params)) {
44
46
  const tokenId = is1155Mint(params) ? params.tokenId : undefined;
47
+ const blockTime = (await publicClient.getBlock()).timestamp;
45
48
  const result = await mintGetter.getMintable({
46
49
  tokenId,
47
50
  tokenAddress: tokenContract,
48
51
  preferredSaleType: params.preferredSaleType,
52
+ blockTime: blockTime,
49
53
  });
50
54
 
51
55
  return toMintableReturn(result);
@@ -129,11 +133,13 @@ export async function getMintsOfContract({
129
133
 
130
134
  export async function getMintCosts({
131
135
  params,
136
+ allowListEntry,
132
137
  mintGetter,
133
138
  premintGetter,
134
139
  publicClient,
135
140
  }: {
136
141
  params: GetMintCostsParameters;
142
+ allowListEntry?: Pick<AllowListEntry, "price">;
137
143
  mintGetter: IOnchainMintGetter;
138
144
  premintGetter: IPremintGetter;
139
145
  publicClient: IPublicClient;
@@ -141,15 +147,21 @@ export async function getMintCosts({
141
147
  const { quantityMinted: quantityToMint, collection } = params;
142
148
  if (isOnChainMint(params)) {
143
149
  const tokenId = is1155Mint(params) ? params.tokenId : undefined;
150
+ const blockTime = (await publicClient.getBlock()).timestamp;
144
151
  const salesConfigAndTokenInfo = await mintGetter.getMintable({
145
152
  tokenId,
146
153
  tokenAddress: collection,
154
+ blockTime,
147
155
  });
148
156
 
157
+ if (!salesConfigAndTokenInfo.salesConfig) {
158
+ throw new Error("No valid sales config found for token");
159
+ }
160
+
149
161
  return parseMintCosts({
150
- mintFeePerQuantity: salesConfigAndTokenInfo.mintFeePerQuantity,
151
162
  salesConfig: salesConfigAndTokenInfo.salesConfig,
152
163
  quantityToMint: BigInt(quantityToMint),
164
+ allowListEntry,
153
165
  });
154
166
  }
155
167
 
@@ -226,7 +238,6 @@ function parsePremint({
226
238
  return {
227
239
  creator: premint.signer,
228
240
  maxSupply: premint.premint.premintConfig.tokenConfig.maxSupply,
229
- mintFeePerQuantity: mintFee,
230
241
  mintType: "premint",
231
242
  uid: premint.premint.premintConfig.uid,
232
243
  contract: {
@@ -242,6 +253,7 @@ function parsePremint({
242
253
  premint.premint.premintConfig.tokenConfig.maxTokensPerAddress,
243
254
  pricePerToken: premint.premint.premintConfig.tokenConfig.pricePerToken,
244
255
  saleType: "premint",
256
+ mintFeePerQuantity: mintFee,
245
257
  },
246
258
  };
247
259
  }
@@ -251,15 +263,24 @@ function parsePremint({
251
263
 
252
264
  const makeOnchainPrepareMint =
253
265
  (result: OnchainSalesConfigAndTokenInfo): PrepareMint =>
254
- (params: MintParametersBase) => ({
255
- parameters: makeOnchainMintCall({ token: result, mintParams: params }),
256
- erc20Approval: getRequiredErc20Approvals(params, result),
257
- costs: parseMintCosts({
258
- salesConfig: result.salesConfig,
259
- quantityToMint: BigInt(params.quantityToMint),
260
- mintFeePerQuantity: result.mintFeePerQuantity,
261
- }),
262
- });
266
+ (params: MintParametersBase) => {
267
+ if (!result.salesConfig) {
268
+ throw new Error("No valid sales config found for token");
269
+ }
270
+
271
+ return {
272
+ parameters: makeOnchainMintCall({
273
+ token: result as Concrete<OnchainSalesConfigAndTokenInfo>,
274
+ mintParams: params,
275
+ }),
276
+ erc20Approval: getRequiredErc20Approvals(params, result),
277
+ costs: parseMintCosts({
278
+ salesConfig: result.salesConfig,
279
+ quantityToMint: BigInt(params.quantityToMint),
280
+ allowListEntry: params.allowListEntry,
281
+ }),
282
+ };
283
+ };
263
284
 
264
285
  function toMintableReturn(
265
286
  result: OnchainSalesConfigAndTokenInfo,
@@ -283,9 +304,9 @@ const makePremintPrepareMint =
283
304
  premint,
284
305
  }),
285
306
  costs: parseMintCosts({
286
- mintFeePerQuantity: mintFee,
287
307
  quantityToMint: BigInt(params.quantityToMint),
288
308
  salesConfig: mintable.salesConfig,
309
+ allowListEntry: params.allowListEntry,
289
310
  }),
290
311
  });
291
312
 
@@ -310,7 +331,7 @@ function getRequiredErc20Approvals(
310
331
  params: MintParametersBase,
311
332
  result: OnchainSalesConfigAndTokenInfo,
312
333
  ): Erc20Approval | undefined {
313
- if (result.salesConfig.saleType !== "erc20") return undefined;
334
+ if (result.salesConfig?.saleType !== "erc20") return undefined;
314
335
 
315
336
  return {
316
337
  quantity: result.salesConfig.pricePerToken * BigInt(params.quantityToMint),