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