@zoralabs/protocol-sdk 0.3.5 → 0.4.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.
@@ -1,4 +1,4 @@
1
- import { createPublicClient, decodeEventLog, http } from "viem";
1
+ import { createPublicClient, decodeEventLog, http, zeroAddress } from "viem";
2
2
  import type {
3
3
  Account,
4
4
  Address,
@@ -14,40 +14,36 @@ import {
14
14
  zoraCreatorFixedPriceSaleStrategyAddress,
15
15
  } from "@zoralabs/protocol-deployments";
16
16
  import {
17
- PremintConfigAndVersion,
18
- PremintConfigV1,
19
- PremintConfigV2,
20
- PremintConfigVersion,
21
17
  getPremintCollectionAddress,
22
18
  premintTypedDataDefinition,
23
- ContractCreationConfig,
24
19
  isValidSignature,
25
20
  isAuthorizedToCreatePremint,
26
21
  getPremintExecutorAddress,
22
+ applyUpdateToPremint,
23
+ markPremintDeleted,
24
+ makeNewPremint,
25
+ supportsPremintVersion,
26
+ getPremintMintCosts,
27
+ makeMintRewardsRecipient,
27
28
  } from "./preminter";
28
- import type {
29
- PremintSignatureGetResponse,
30
- PremintSignatureResponse,
31
- } from "./premint-api-client";
29
+ import {
30
+ PremintConfigV2,
31
+ PremintConfigVersion,
32
+ ContractCreationConfig,
33
+ TokenConfigForVersion,
34
+ PremintConfigWithVersion,
35
+ TokenCreationConfigV1,
36
+ TokenCreationConfigV2,
37
+ TokenCreationConfig,
38
+ PremintConfigForVersion,
39
+ } from "./contract-types";
40
+ import type { PremintSignatureResponse } from "./premint-api-client";
32
41
  import { PremintAPIClient } from "./premint-api-client";
33
42
  import type { DecodeEventLogReturnType } from "viem";
34
43
  import { OPEN_EDITION_MINT_SIZE } from "../constants";
35
- import { REWARD_PER_TOKEN } from "src/apis/chain-constants";
36
44
  import { IHttpClient } from "src/apis/http-api-base";
37
45
  import { getApiNetworkConfigForChain } from "src/mint/mint-api-client";
38
-
39
- type MintArgumentsSettings = {
40
- tokenURI: string;
41
- maxSupply?: bigint;
42
- maxTokensPerAddress?: bigint;
43
- pricePerToken?: bigint;
44
- mintStart?: bigint;
45
- mintDuration?: bigint;
46
- royaltyMintSchedule?: number;
47
- royaltyBPS?: number;
48
- royaltyRecipient?: Address;
49
- fixedPriceMinter?: Address;
50
- };
46
+ import { MintCosts } from "src/mint/mint-client";
51
47
 
52
48
  type PremintedLogType = DecodeEventLogReturnType<
53
49
  typeof zoraCreator1155PremintExecutorImplABI,
@@ -67,7 +63,10 @@ type SignedPremintResponse = {
67
63
  premint: PremintSignatureResponse;
68
64
  };
69
65
 
70
- export const DefaultMintArguments = {
66
+ export const defaultTokenConfigV1MintArguments = (): Omit<
67
+ TokenCreationConfigV1,
68
+ "fixedPriceMinter" | "tokenURI" | "royaltyRecipient"
69
+ > => ({
71
70
  maxSupply: OPEN_EDITION_MINT_SIZE,
72
71
  maxTokensPerAddress: 0n,
73
72
  pricePerToken: 0n,
@@ -75,6 +74,50 @@ export const DefaultMintArguments = {
75
74
  mintStart: 0n,
76
75
  royaltyMintSchedule: 0,
77
76
  royaltyBPS: 1000, // 10%,
77
+ });
78
+
79
+ export const defaultTokenConfigV2MintArguments = (): Omit<
80
+ TokenCreationConfigV2,
81
+ "fixedPriceMinter" | "tokenURI" | "payoutRecipient" | "createReferral"
82
+ > => ({
83
+ maxSupply: OPEN_EDITION_MINT_SIZE,
84
+ maxTokensPerAddress: 0n,
85
+ pricePerToken: 0n,
86
+ mintDuration: BigInt(60 * 60 * 24 * 7), // 1 week
87
+ mintStart: 0n,
88
+ royaltyBPS: 1000, // 10%,
89
+ });
90
+
91
+ const makeTokenConfigWithDefaults = <T extends PremintConfigVersion>({
92
+ premintConfigVersion,
93
+ tokenCreationConfig,
94
+ creatorAccount,
95
+ }: {
96
+ premintConfigVersion: PremintConfigVersion;
97
+ tokenCreationConfig: Partial<TokenConfigForVersion<T>> & { tokenURI: string };
98
+ creatorAccount: Address;
99
+ }): TokenConfigForVersion<T> => {
100
+ const fixedPriceMinter =
101
+ tokenCreationConfig.fixedPriceMinter || getDefaultFixedPriceMinterAddress();
102
+
103
+ if (premintConfigVersion === PremintConfigVersion.V1) {
104
+ return {
105
+ fixedPriceMinter,
106
+ ...defaultTokenConfigV1MintArguments(),
107
+ royaltyRecipient: creatorAccount,
108
+ ...tokenCreationConfig,
109
+ };
110
+ } else if (premintConfigVersion === PremintConfigVersion.V2) {
111
+ return {
112
+ fixedPriceMinter,
113
+ ...defaultTokenConfigV2MintArguments(),
114
+ payoutRecipient: creatorAccount,
115
+ createReferral: zeroAddress,
116
+ ...tokenCreationConfig,
117
+ };
118
+ } else {
119
+ throw new Error(`Invalid premint config version ${premintConfigVersion}`);
120
+ }
78
121
  };
79
122
 
80
123
  /**
@@ -99,85 +142,6 @@ export function getPremintedLogFromReceipt(
99
142
  } catch (err: any) {}
100
143
  }
101
144
  }
102
-
103
- /**
104
- * Convert server to on-chain types for a premint
105
- *
106
- * @param premint Premint object from the server to convert to one that's compatible with viem
107
- * @returns Viem type-compatible premint object
108
- */
109
- export const convertPremintV1 = (
110
- premint: PremintSignatureGetResponse["premint"],
111
- ) => ({
112
- ...premint,
113
- tokenConfig: {
114
- ...premint.tokenConfig,
115
- fixedPriceMinter: premint.tokenConfig.fixedPriceMinter as Address,
116
- royaltyRecipient: premint.tokenConfig.royaltyRecipient as Address,
117
- maxSupply: BigInt(premint.tokenConfig.maxSupply),
118
- pricePerToken: BigInt(premint.tokenConfig.pricePerToken),
119
- mintStart: BigInt(premint.tokenConfig.mintStart),
120
- mintDuration: BigInt(premint.tokenConfig.mintDuration),
121
- maxTokensPerAddress: BigInt(premint.tokenConfig.maxTokensPerAddress),
122
- },
123
- });
124
-
125
- export const convertCollection = (
126
- collection: PremintSignatureGetResponse["collection"],
127
- ) => ({
128
- ...collection,
129
- contractAdmin: collection.contractAdmin as Address,
130
- });
131
-
132
- /**
133
- * Convert on-chain types for a premint to a server safe type
134
- *
135
- * @param premint Premint object from viem to convert to a JSON compatible type.
136
- * @returns JSON compatible premint
137
- */
138
- export const encodePremintV1ForAPI = ({
139
- tokenConfig,
140
- ...premint
141
- }: PremintConfigV1) => ({
142
- ...premint,
143
- tokenConfig: {
144
- ...tokenConfig,
145
- maxSupply: tokenConfig.maxSupply.toString(),
146
- pricePerToken: tokenConfig.pricePerToken.toString(),
147
- mintStart: tokenConfig.mintStart.toString(),
148
- mintDuration: tokenConfig.mintDuration.toString(),
149
- maxTokensPerAddress: tokenConfig.maxTokensPerAddress.toString(),
150
- },
151
- });
152
-
153
- export const encodePremintV2ForAPI = ({
154
- tokenConfig,
155
- ...premint
156
- }: PremintConfigV2) => ({
157
- ...premint,
158
- tokenConfig: {
159
- ...tokenConfig,
160
- maxSupply: tokenConfig.maxSupply.toString(),
161
- pricePerToken: tokenConfig.pricePerToken.toString(),
162
- mintStart: tokenConfig.mintStart.toString(),
163
- mintDuration: tokenConfig.mintDuration.toString(),
164
- maxTokensPerAddress: tokenConfig.maxTokensPerAddress.toString(),
165
- },
166
- });
167
-
168
- export const encodePremintForAPI = ({
169
- premintConfig,
170
- premintConfigVersion,
171
- }: PremintConfigAndVersion) => {
172
- if (premintConfigVersion === PremintConfigVersion.V1) {
173
- return encodePremintV1ForAPI(premintConfig);
174
- }
175
- if (premintConfigVersion === PremintConfigVersion.V2) {
176
- return encodePremintV2ForAPI(premintConfig);
177
- }
178
- throw new Error(`Invalid premint config version ${premintConfigVersion}`);
179
- };
180
-
181
145
  /**
182
146
  * Preminter API to access ZORA Premint functionality.
183
147
  * Currently only supports V1 premints.
@@ -198,17 +162,6 @@ class PremintClient {
198
162
  publicClient || createPublicClient({ chain, transport: http() });
199
163
  }
200
164
 
201
- /**
202
- * The fixed price minter address is the same across all chains for our current
203
- * deployer strategy.
204
- * Can be overridden as needed by making a parent class.
205
- *
206
- * @returns Fixed price sale strategy
207
- */
208
- getFixedPriceMinterAddress() {
209
- return zoraCreatorFixedPriceSaleStrategyAddress[999];
210
- }
211
-
212
165
  getDataFromPremintReceipt(receipt: TransactionReceipt) {
213
166
  const premintedLog = getPremintedLogFromReceipt(receipt);
214
167
  return {
@@ -242,44 +195,39 @@ class PremintClient {
242
195
  walletClient,
243
196
  uid,
244
197
  collection,
245
- token,
246
198
  account,
199
+ tokenConfigUpdates,
247
200
  }: {
248
201
  walletClient: WalletClient;
249
202
  uid: number;
250
- token: MintArgumentsSettings;
251
203
  account?: Account | Address;
252
204
  collection: Address;
205
+ tokenConfigUpdates: Partial<TokenCreationConfig>;
253
206
  }): Promise<SignedPremintResponse> {
254
- const signatureResponse = await this.apiClient.getSignature({
255
- collection_address: collection.toLowerCase(),
207
+ const {
208
+ premintConfig,
209
+ collection: collectionCreationConfig,
210
+ premintConfigVersion,
211
+ } = await this.apiClient.getSignature({
212
+ collectionAddress: collection,
256
213
  uid: uid,
257
214
  });
258
215
 
259
- const convertedPremint = convertPremintV1(signatureResponse.premint);
260
- const signerData = {
261
- ...signatureResponse,
262
- premint: {
263
- ...convertedPremint,
264
- tokenConfig: {
265
- ...convertedPremint.tokenConfig,
266
- ...token,
267
- },
268
- },
269
- };
216
+ const updatedPremint = applyUpdateToPremint({
217
+ uid: premintConfig.uid,
218
+ version: premintConfig.version,
219
+ tokenConfig: premintConfig.tokenConfig,
220
+ tokenConfigUpdates: tokenConfigUpdates,
221
+ });
270
222
 
271
223
  return await this.signAndSubmitPremint({
272
224
  walletClient,
273
225
  account,
274
- checkSignature: false,
226
+ checkSignature: true,
275
227
  verifyingContract: collection,
276
- uid: uid,
277
- collection: {
278
- ...signerData.collection,
279
- contractAdmin: signerData.collection.contractAdmin as Address,
280
- },
281
- premintConfig: signerData.premint,
282
- premintConfigVersion: PremintConfigVersion.V1,
228
+ collection: collectionCreationConfig,
229
+ premintConfig: updatedPremint,
230
+ premintConfigVersion: premintConfigVersion,
283
231
  });
284
232
  }
285
233
 
@@ -308,29 +256,25 @@ class PremintClient {
308
256
  account?: Account | Address;
309
257
  collection: Address;
310
258
  }) {
311
- const signatureResponse = await this.apiClient.getSignature({
312
- collection_address: collection.toLowerCase(),
259
+ const {
260
+ premintConfig,
261
+ premintConfigVersion,
262
+ collection: collectionCreationConfig,
263
+ } = await this.apiClient.getSignature({
264
+ collectionAddress: collection,
313
265
  uid: uid,
314
266
  });
315
267
 
316
- const signerData = {
317
- ...signatureResponse,
318
- collection: convertCollection(signatureResponse.collection),
319
- premint: {
320
- ...convertPremintV1(signatureResponse.premint),
321
- deleted: true,
322
- },
323
- };
268
+ const deletedPremint = markPremintDeleted(premintConfig);
324
269
 
325
270
  return await this.signAndSubmitPremint({
326
271
  walletClient,
327
272
  account,
328
273
  checkSignature: false,
329
274
  verifyingContract: collection,
330
- uid: uid,
331
- collection: signerData.collection,
332
- premintConfig: signerData.premint,
333
- premintConfigVersion: PremintConfigVersion.V1,
275
+ collection: collectionCreationConfig,
276
+ premintConfig: deletedPremint,
277
+ premintConfigVersion,
334
278
  });
335
279
  }
336
280
 
@@ -340,66 +284,17 @@ class PremintClient {
340
284
  * @param premintArguments Arguments to premint
341
285
  * @returns
342
286
  */
343
- private async signAndSubmitPremint({
344
- walletClient,
345
- verifyingContract,
346
- uid,
347
- account,
348
- checkSignature,
349
- collection,
350
- ...premintConfigAndVersion
351
- }: {
352
- uid: number;
353
- walletClient: WalletClient;
354
- verifyingContract: Address;
355
- checkSignature: boolean;
356
- account?: Address | Account;
357
- collection: PremintSignatureGetResponse["collection"];
358
- } & PremintConfigAndVersion) {
359
- if (!account) {
360
- account = walletClient.account;
361
- }
362
- if (!account) {
363
- throw new Error("No account provided");
364
- }
365
-
366
- const signature = await walletClient.signTypedData({
367
- account,
368
- ...premintTypedDataDefinition({
369
- verifyingContract,
370
- ...premintConfigAndVersion,
371
- chainId: this.chain.id,
372
- }),
287
+ private async signAndSubmitPremint<T extends PremintConfigVersion>(
288
+ params: SignAndSubmitPremintParams<T>,
289
+ ) {
290
+ const { premint, verifyingContract } = await signAndSubmitPremint({
291
+ ...params,
292
+ chainId: this.chain.id,
293
+ apiClient: this.apiClient,
294
+ publicClient: this.publicClient,
373
295
  });
374
296
 
375
- if (checkSignature) {
376
- const convertedCollection = convertCollection(collection);
377
- const isAuthorized = await isAuthorizedToCreatePremint({
378
- collection: convertCollection(collection),
379
- signature,
380
- publicClient: this.publicClient,
381
- signer: typeof account === "string" ? account : account.address,
382
- collectionAddress: await this.getCollectionAddress(convertedCollection),
383
- ...premintConfigAndVersion,
384
- });
385
- if (!isAuthorized) {
386
- throw new Error("Not authorized to create premint");
387
- }
388
- }
389
-
390
- if (
391
- premintConfigAndVersion.premintConfigVersion === PremintConfigVersion.V2
392
- ) {
393
- throw new Error("premint config v2 not supported yet");
394
- }
395
-
396
- const apiData = {
397
- collection,
398
- premint: encodePremintV1ForAPI(premintConfigAndVersion.premintConfig),
399
- signature: signature,
400
- };
401
-
402
- const premint = await this.apiClient.postSignature(apiData);
297
+ const uid = params.premintConfig.uid;
403
298
 
404
299
  return {
405
300
  urls: this.makeUrls({ address: verifyingContract, uid }),
@@ -415,73 +310,73 @@ class PremintClient {
415
310
  * @param settings Settings for the new premint
416
311
  * @param settings.account Account to sign the premint with. Taken from walletClient if none passed in.
417
312
  * @param settings.collection Collection information for the mint
418
- * @param settings.token Mint argument settings, optional settings are overridden with sensible defaults.
419
- * @param settings.publicClient Public client (optional) – instantiated if not passed in with defaults.
420
- * @param settings.walletClient Required wallet client for signing the premint message.
421
- * @param settings.executionSettings Execution settings for premint options
422
- * @param settings.executionSettings.deleted If this UID should be deleted. If omitted, set to false.
423
- * @param settings.executionSettings.uid the UID to use – optional and retrieved as a fresh UID from ZORA by default.
313
+ * @param settings.tokenCreationConfig Mint argument settings, optional settings are overridden with sensible defaults.
314
+ * @param setings.premintConfigVersion Premint config version to use, defaults to V2
315
+ * @param settings.uid the UID to use – optional and retrieved as a fresh UID from ZORA by default.
424
316
  * @param settings.checkSignature if the signature should have a pre-flight check. Not required but helpful for debugging.
425
317
  * @returns premint url, uid, newContractAddress, and premint object
426
318
  */
427
- async createPremint({
428
- account,
319
+ async createPremint<
320
+ T extends PremintConfigVersion = PremintConfigVersion.V1,
321
+ >({
322
+ creatorAccount,
429
323
  collection,
430
- token,
324
+ tokenCreationConfig,
325
+ premintConfigVersion,
431
326
  walletClient,
432
- executionSettings,
327
+ uid,
433
328
  checkSignature = false,
434
329
  }: {
435
- account: Address;
330
+ creatorAccount: Address;
436
331
  checkSignature?: boolean;
437
332
  walletClient: WalletClient;
438
- collection: PremintSignatureGetResponse["collection"];
439
- token: MintArgumentsSettings;
440
- executionSettings?: {
441
- deleted?: boolean;
442
- uid?: number;
333
+ collection: ContractCreationConfig;
334
+ tokenCreationConfig: Partial<TokenConfigForVersion<T>> & {
335
+ tokenURI: string;
443
336
  };
337
+ premintConfigVersion?: T;
338
+ uid?: number;
444
339
  }) {
445
340
  const newContractAddress = await getPremintCollectionAddress({
446
341
  publicClient: this.publicClient,
447
- collection: convertCollection(collection),
342
+ collection,
448
343
  });
449
344
 
450
- const tokenConfig = {
451
- ...DefaultMintArguments,
452
- fixedPriceMinter: this.getFixedPriceMinterAddress(),
453
- royaltyRecipient: account,
454
- ...token,
455
- };
345
+ let uidToUse = uid;
456
346
 
457
- let uid = executionSettings?.uid;
458
- if (!uid) {
459
- const uidResponse = await this.apiClient.getNextUID({
460
- collection_address: newContractAddress.toLowerCase(),
461
- });
462
- uid = uidResponse.next_uid;
347
+ if (typeof uidToUse !== "number") {
348
+ uidToUse = await this.apiClient.getNextUID(newContractAddress);
463
349
  }
464
350
 
465
- if (!uid) {
466
- throw new Error("UID is missing but required");
467
- }
351
+ const actualVersion = premintConfigVersion || PremintConfigVersion.V1;
468
352
 
469
- let deleted = executionSettings?.deleted || false;
353
+ if (
354
+ !(await supportsPremintVersion({
355
+ version: actualVersion,
356
+ publicClient: this.publicClient,
357
+ tokenContract: newContractAddress,
358
+ }))
359
+ ) {
360
+ throw new Error(
361
+ `Premint version ${actualVersion} not supported by contract`,
362
+ );
363
+ }
470
364
 
471
- const premintConfig: PremintConfigV1 = {
472
- tokenConfig: tokenConfig,
473
- uid,
474
- version: 1,
475
- deleted,
476
- };
365
+ const premintConfig = makeNewPremint({
366
+ tokenConfig: makeTokenConfigWithDefaults({
367
+ premintConfigVersion: actualVersion,
368
+ tokenCreationConfig,
369
+ creatorAccount,
370
+ }),
371
+ uid: uidToUse,
372
+ });
477
373
 
478
374
  return await this.signAndSubmitPremint({
479
- uid,
480
375
  verifyingContract: newContractAddress,
481
376
  premintConfig,
482
- premintConfigVersion: PremintConfigVersion.V1,
377
+ premintConfigVersion: actualVersion,
483
378
  checkSignature,
484
- account,
379
+ account: creatorAccount,
485
380
  walletClient,
486
381
  collection,
487
382
  });
@@ -494,15 +389,15 @@ class PremintClient {
494
389
  * @param uid UID for the desired premint
495
390
  * @returns PremintSignatureGetResponse of premint data from the API
496
391
  */
497
- async getPremintData({
392
+ async getPremintSignature({
498
393
  address,
499
394
  uid,
500
395
  }: {
501
- address: string;
396
+ address: Address;
502
397
  uid: number;
503
- }): Promise<PremintSignatureGetResponse> {
398
+ }) {
504
399
  return await this.apiClient.getSignature({
505
- collection_address: address,
400
+ collectionAddress: address,
506
401
  uid,
507
402
  });
508
403
  }
@@ -525,21 +420,27 @@ class PremintClient {
525
420
  * @param data Signature data from the API
526
421
  * @returns isValid = signature is valid or not, recoveredSigner = signer from contract
527
422
  */
528
- async isValidSignature({
423
+ async isValidSignature<T extends PremintConfigVersion>({
529
424
  signature,
530
- premint,
531
425
  collection,
532
- }: PremintSignatureResponse): Promise<{
426
+ premintConfig,
427
+ premintConfigVersion,
428
+ }: {
429
+ signature: Hex;
430
+ collection: ContractCreationConfig;
431
+ premintConfig: PremintConfigForVersion<T>;
432
+ premintConfigVersion?: T;
433
+ }): Promise<{
533
434
  isValid: boolean;
534
435
  recoveredSigner: Address | undefined;
535
436
  }> {
536
437
  const { isAuthorized, recoveredAddress } = await isValidSignature({
537
438
  chainId: this.chain.id,
538
439
  signature: signature as Hex,
539
- premintConfig: convertPremintV1(premint),
540
- premintConfigVersion: PremintConfigVersion.V1,
541
- collection: convertCollection(collection),
440
+ collection: collection,
542
441
  publicClient: this.publicClient,
442
+ premintConfig,
443
+ premintConfigVersion: premintConfigVersion || PremintConfigVersion.V1,
543
444
  });
544
445
 
545
446
  return { isValid: isAuthorized, recoveredSigner: recoveredAddress };
@@ -554,29 +455,29 @@ class PremintClient {
554
455
  tokenId?: bigint;
555
456
  address?: Address;
556
457
  }): URLSReturnType {
557
- if ((!uid || !tokenId) && !address) {
558
- return { explorer: null, zoraCollect: null, zoraManage: null };
559
- }
560
-
561
- const zoraTokenPath = uid ? `premint-${uid}` : tokenId;
562
-
563
- const network = getApiNetworkConfigForChain(this.chain.id);
458
+ return makeUrls({
459
+ uid,
460
+ address,
461
+ tokenId,
462
+ chain: this.chain,
463
+ });
464
+ }
564
465
 
565
- return {
566
- explorer: tokenId
567
- ? `https://${this.chain.blockExplorers?.default.url}/token/${address}/instance/${tokenId}`
568
- : null,
569
- zoraCollect: `https://${
570
- network.isTestnet ? "testnet." : ""
571
- }zora.co/collect/${
572
- network.zoraPathChainName
573
- }:${address}/${zoraTokenPath}`,
574
- zoraManage: `https://${
575
- network.isTestnet ? "testnet." : ""
576
- }zora.co/collect/${
577
- network.zoraPathChainName
578
- }:${address}/${zoraTokenPath}`,
579
- };
466
+ async getMintCosts({
467
+ tokenContract,
468
+ quantityToMint,
469
+ tokenCreationConfig,
470
+ }: {
471
+ quantityToMint: bigint;
472
+ tokenContract: Address;
473
+ tokenCreationConfig: TokenCreationConfig;
474
+ }): Promise<MintCosts> {
475
+ return await getPremintMintCosts({
476
+ publicClient: this.publicClient,
477
+ quantityToMint,
478
+ tokenContract,
479
+ tokenPrice: tokenCreationConfig.pricePerToken,
480
+ });
580
481
  }
581
482
 
582
483
  /**
@@ -592,54 +493,98 @@ class PremintClient {
592
493
  * @returns receipt, log, zoraURL
593
494
  */
594
495
  async makeMintParameters({
595
- data,
496
+ uid,
497
+ tokenContract,
596
498
  account,
597
499
  mintArguments,
598
500
  }: {
599
- data: PremintSignatureGetResponse;
501
+ uid: number;
502
+ tokenContract: Address;
600
503
  account: Account | Address;
601
504
  mintArguments?: {
602
505
  quantityToMint: number;
603
506
  mintComment?: string;
507
+ mintReferral?: Address;
508
+ platformReferral?: Address;
509
+ mintRecipient?: Address;
604
510
  };
605
- }): Promise<
606
- SimulateContractParameters<
607
- typeof zoraCreator1155PremintExecutorImplABI,
608
- "premint"
609
- >
610
- > {
511
+ }): Promise<SimulateContractParameters> {
611
512
  if (mintArguments && mintArguments?.quantityToMint < 1) {
612
513
  throw new Error("Quantity to mint cannot be below 1");
613
514
  }
614
515
 
615
- const numberToMint = BigInt(mintArguments?.quantityToMint || 1);
616
- const args = [
617
- convertCollection(data.collection),
618
- convertPremintV1(data.premint),
619
- data.signature as Hex,
620
- numberToMint,
621
- mintArguments?.mintComment || "",
622
- ] as const;
623
-
624
516
  if (!account) {
625
517
  throw new Error("Wallet not passed in");
626
518
  }
627
519
 
628
- const value = numberToMint * REWARD_PER_TOKEN;
520
+ const { premintConfig, premintConfigVersion, collection, signature } =
521
+ await this.getPremintSignature({
522
+ address: tokenContract,
523
+ uid,
524
+ });
629
525
 
630
- const request = {
631
- account,
632
- abi: zoraCreator1155PremintExecutorImplABI,
633
- functionName: "premint",
634
- value,
635
- address: getPremintExecutorAddress(),
636
- args,
637
- } satisfies SimulateContractParameters<
638
- typeof zoraCreator1155PremintExecutorImplABI,
639
- "premint"
640
- >;
641
-
642
- return request;
526
+ const numberToMint = BigInt(mintArguments?.quantityToMint || 1);
527
+
528
+ const value = (
529
+ await getPremintMintCosts({
530
+ tokenContract,
531
+ quantityToMint: numberToMint,
532
+ publicClient: this.publicClient,
533
+ tokenPrice: premintConfig.tokenConfig.pricePerToken,
534
+ })
535
+ ).totalCost;
536
+
537
+ if (premintConfigVersion === PremintConfigVersion.V1) {
538
+ return {
539
+ account,
540
+ abi: zoraCreator1155PremintExecutorImplABI,
541
+ functionName: "premint",
542
+ value,
543
+ address: getPremintExecutorAddress(),
544
+ args: [
545
+ collection,
546
+ premintConfig,
547
+ signature,
548
+ numberToMint,
549
+ mintArguments?.mintComment || "",
550
+ ],
551
+ } satisfies SimulateContractParameters<
552
+ typeof zoraCreator1155PremintExecutorImplABI,
553
+ "premint"
554
+ >;
555
+ } else if (premintConfigVersion === PremintConfigVersion.V2) {
556
+ const toPost = premintConfig as PremintConfigV2;
557
+ const accountAddress =
558
+ typeof account === "string" ? account : account.address;
559
+
560
+ return {
561
+ account,
562
+ abi: zoraCreator1155PremintExecutorImplABI,
563
+ functionName: "premintV2",
564
+ value,
565
+ address: getPremintExecutorAddress(),
566
+ // args are: ContractCreationConfig calldata contractConfig, PremintConfigV2 calldata premintConfig, bytes calldata signature, uint256 quantityToMint, MintArguments calldata mintArguments
567
+ args: [
568
+ collection,
569
+ toPost,
570
+ signature,
571
+ numberToMint,
572
+ {
573
+ mintComment: mintArguments?.mintComment || "",
574
+ mintRecipient: mintArguments?.mintRecipient || accountAddress,
575
+ mintRewardsRecipients: makeMintRewardsRecipient({
576
+ mintReferral: mintArguments?.mintReferral,
577
+ platformReferral: mintArguments?.platformReferral,
578
+ }),
579
+ },
580
+ ],
581
+ } satisfies SimulateContractParameters<
582
+ typeof zoraCreator1155PremintExecutorImplABI,
583
+ "premintV2"
584
+ >;
585
+ }
586
+
587
+ throw new Error(`Invalid premint config version ${premintConfigVersion}`);
643
588
  }
644
589
  }
645
590
 
@@ -654,3 +599,104 @@ export function createPremintClient({
654
599
  }) {
655
600
  return new PremintClient(chain, publicClient, httpClient);
656
601
  }
602
+
603
+ function makeUrls({
604
+ uid,
605
+ address,
606
+ tokenId,
607
+ chain,
608
+ }: {
609
+ uid?: number;
610
+ tokenId?: bigint;
611
+ address?: Address;
612
+ chain: Chain;
613
+ }): URLSReturnType {
614
+ if ((!uid || !tokenId) && !address) {
615
+ return { explorer: null, zoraCollect: null, zoraManage: null };
616
+ }
617
+
618
+ const zoraTokenPath = uid ? `premint-${uid}` : tokenId;
619
+
620
+ const network = getApiNetworkConfigForChain(chain.id);
621
+
622
+ return {
623
+ explorer: tokenId
624
+ ? `https://${chain.blockExplorers?.default.url}/token/${address}/instance/${tokenId}`
625
+ : null,
626
+ zoraCollect: `https://${
627
+ network.isTestnet ? "testnet." : ""
628
+ }zora.co/collect/${network.zoraPathChainName}:${address}/${zoraTokenPath}`,
629
+ zoraManage: `https://${
630
+ network.isTestnet ? "testnet." : ""
631
+ }zora.co/collect/${network.zoraPathChainName}:${address}/${zoraTokenPath}`,
632
+ };
633
+ }
634
+
635
+ type SignAndSubmitPremintParams<T extends PremintConfigVersion> = {
636
+ walletClient: WalletClient;
637
+ verifyingContract: Address;
638
+ checkSignature: boolean;
639
+ account?: Address | Account;
640
+ collection: ContractCreationConfig;
641
+ } & PremintConfigWithVersion<T>;
642
+
643
+ async function signAndSubmitPremint<T extends PremintConfigVersion>({
644
+ walletClient,
645
+ verifyingContract,
646
+ account,
647
+ checkSignature,
648
+ collection,
649
+ chainId,
650
+ publicClient,
651
+ apiClient,
652
+ ...premintConfigAndVersion
653
+ }: SignAndSubmitPremintParams<T> & {
654
+ chainId: number;
655
+ publicClient: PublicClient;
656
+ apiClient: PremintAPIClient;
657
+ }) {
658
+ if (!account) {
659
+ account = walletClient.account;
660
+ }
661
+ if (!account) {
662
+ throw new Error("No account provided");
663
+ }
664
+
665
+ const signature = await walletClient.signTypedData({
666
+ account,
667
+ ...premintTypedDataDefinition({
668
+ verifyingContract,
669
+ ...premintConfigAndVersion,
670
+ chainId,
671
+ }),
672
+ });
673
+
674
+ if (checkSignature) {
675
+ const isAuthorized = await isAuthorizedToCreatePremint({
676
+ collection,
677
+ signature,
678
+ publicClient,
679
+ signer: typeof account === "string" ? account : account.address,
680
+ collectionAddress: await getPremintCollectionAddress({
681
+ collection,
682
+ publicClient,
683
+ }),
684
+ ...premintConfigAndVersion,
685
+ });
686
+ if (!isAuthorized) {
687
+ throw new Error("Not authorized to create premint");
688
+ }
689
+ }
690
+
691
+ const premint = await apiClient.postSignature({
692
+ collection: collection,
693
+ signature: signature,
694
+ ...premintConfigAndVersion,
695
+ });
696
+
697
+ return { premint, verifyingContract };
698
+ }
699
+
700
+ function getDefaultFixedPriceMinterAddress() {
701
+ return zoraCreatorFixedPriceSaleStrategyAddress[999];
702
+ }