@zoralabs/protocol-sdk 0.5.16 → 0.5.17

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.
@@ -9,7 +9,12 @@ import type {
9
9
  TypedDataDefinition,
10
10
  WalletClient,
11
11
  } from "viem";
12
- import { zoraCreator1155PremintExecutorImplABI } from "@zoralabs/protocol-deployments";
12
+ import {
13
+ PremintConfigAndVersion,
14
+ TokenConfigWithVersion,
15
+ encodePremintConfig,
16
+ zoraCreator1155PremintExecutorImplABI,
17
+ } from "@zoralabs/protocol-deployments";
13
18
  import {
14
19
  getPremintCollectionAddress,
15
20
  isValidSignature,
@@ -17,15 +22,17 @@ import {
17
22
  getPremintExecutorAddress,
18
23
  applyUpdateToPremint,
19
24
  makeNewPremint,
20
- supportsPremintVersion,
25
+ supportedPremintVersions,
21
26
  getPremintMintCosts,
22
27
  makeMintRewardsRecipient,
23
28
  getDefaultFixedPriceMinterAddress,
29
+ emptyContractCreationConfig,
30
+ defaultAdditionalAdmins,
31
+ toContractCreationConfigOrAddress,
24
32
  } from "./preminter";
25
33
  import {
26
34
  PremintConfigVersion,
27
35
  ContractCreationConfig,
28
- TokenConfigForVersion,
29
36
  TokenCreationConfigV1,
30
37
  TokenCreationConfigV2,
31
38
  TokenCreationConfig,
@@ -46,6 +53,10 @@ import {
46
53
  PublicClient,
47
54
  setupClient,
48
55
  } from "src/utils";
56
+ import {
57
+ ContractCreationConfigAndAddress,
58
+ ContractCreationConfigOrAddress,
59
+ } from "./contract-types";
49
60
 
50
61
  type PremintedV2LogType = DecodeEventLogReturnType<
51
62
  typeof zoraCreator1155PremintExecutorImplABI,
@@ -71,6 +82,47 @@ export const defaultTokenConfigV1MintArguments = (): Omit<
71
82
  royaltyBPS: 1000, // 10%,
72
83
  });
73
84
 
85
+ const pickTokenConfigV1 = (tokenConfig: TokenConfigInput) => ({
86
+ maxSupply: tokenConfig.maxSupply,
87
+ maxTokensPerAddress: tokenConfig.maxTokensPerAddress,
88
+ pricePerToken: tokenConfig.pricePerToken,
89
+ mintDuration: tokenConfig.mintDuration,
90
+ mintStart: tokenConfig.mintStart,
91
+ royaltyBPS: tokenConfig.royaltyBPS,
92
+ tokenURI: tokenConfig.tokenURI,
93
+ royaltyRecipient: tokenConfig.payoutRecipient,
94
+ });
95
+
96
+ const pickTokenConfigV2 = (tokenConfig: TokenConfigInput) => ({
97
+ maxSupply: tokenConfig.maxSupply,
98
+ maxTokensPerAddress: tokenConfig.maxTokensPerAddress,
99
+ pricePerToken: tokenConfig.pricePerToken,
100
+ mintDuration: tokenConfig.mintDuration,
101
+ mintStart: tokenConfig.mintStart,
102
+ royaltyBPS: tokenConfig.royaltyBPS,
103
+ tokenURI: tokenConfig.tokenURI,
104
+ payoutRecipient: tokenConfig.payoutRecipient,
105
+ createReferral: tokenConfig.createReferral || zeroAddress,
106
+ });
107
+
108
+ const tokenConfigV1WithDefault = (
109
+ tokenConfig: TokenConfigInput,
110
+ fixedPriceMinter: Address,
111
+ ): TokenCreationConfigV1 => ({
112
+ ...pickTokenConfigV1(tokenConfig),
113
+ ...defaultTokenConfigV1MintArguments(),
114
+ fixedPriceMinter,
115
+ });
116
+
117
+ const tokenConfigV2WithDefault = (
118
+ tokenConfig: TokenConfigInput,
119
+ fixedPriceMinter: Address,
120
+ ): TokenCreationConfigV2 => ({
121
+ ...pickTokenConfigV2(tokenConfig),
122
+ ...defaultTokenConfigV2MintArguments(),
123
+ fixedPriceMinter,
124
+ });
125
+
74
126
  export const defaultTokenConfigV2MintArguments = (): Omit<
75
127
  TokenCreationConfigV2,
76
128
  "fixedPriceMinter" | "tokenURI" | "payoutRecipient" | "createReferral"
@@ -83,46 +135,53 @@ export const defaultTokenConfigV2MintArguments = (): Omit<
83
135
  royaltyBPS: 1000, // 10%,
84
136
  });
85
137
 
86
- const makeTokenConfigWithDefaults = <T extends PremintConfigVersion>({
138
+ type TokenConfigInput = {
139
+ tokenURI: string;
140
+ payoutRecipient: Address;
141
+ createReferral?: Address;
142
+ maxSupply?: bigint;
143
+ maxTokensPerAddress?: bigint;
144
+ pricePerToken?: bigint;
145
+ mintDuration?: bigint;
146
+ mintStart?: bigint;
147
+ royaltyBPS?: number;
148
+ };
149
+
150
+ const makeTokenConfigWithDefaults = ({
87
151
  chainId,
88
- premintConfigVersion,
89
152
  tokenCreationConfig,
90
- payoutRecipient,
153
+ supportedPremintVersions,
91
154
  }: {
92
155
  chainId: number;
93
- premintConfigVersion: T;
94
- tokenCreationConfig: Partial<TokenConfigForVersion<T>> & { tokenURI: string };
95
- payoutRecipient: Address;
96
- }): TokenConfigForVersion<T> => {
97
- if (premintConfigVersion === PremintConfigVersion.V3) {
98
- throw new Error("PremintV3 not supported in SDK");
99
- }
100
-
101
- const fixedPriceMinter =
102
- (
103
- tokenCreationConfig as
104
- | Partial<TokenCreationConfigV1>
105
- | Partial<TokenCreationConfigV2>
106
- ).fixedPriceMinter || getDefaultFixedPriceMinterAddress(chainId);
156
+ tokenCreationConfig: TokenConfigInput;
157
+ supportedPremintVersions: PremintConfigVersion[];
158
+ }): TokenConfigWithVersion<
159
+ PremintConfigVersion.V1 | PremintConfigVersion.V2
160
+ > => {
161
+ const fixedPriceMinter = getDefaultFixedPriceMinterAddress(chainId);
162
+
163
+ if (!supportedPremintVersions.includes(PremintConfigVersion.V2)) {
164
+ // we need to return a token config v1
165
+ if (tokenCreationConfig.createReferral) {
166
+ throw new Error("Contract does not support create referral");
167
+ }
107
168
 
108
- if (premintConfigVersion === PremintConfigVersion.V1) {
109
169
  return {
110
- fixedPriceMinter,
111
- ...defaultTokenConfigV1MintArguments(),
112
- royaltyRecipient: payoutRecipient,
113
- ...(tokenCreationConfig as Partial<TokenCreationConfigV1>),
114
- } as TokenCreationConfigV1;
115
- } else if (premintConfigVersion === PremintConfigVersion.V2) {
116
- return {
117
- fixedPriceMinter,
118
- ...defaultTokenConfigV2MintArguments(),
119
- payoutRecipient: payoutRecipient,
120
- createReferral: zeroAddress,
121
- ...tokenCreationConfig,
170
+ premintConfigVersion: PremintConfigVersion.V1,
171
+ tokenConfig: tokenConfigV1WithDefault(
172
+ tokenCreationConfig,
173
+ fixedPriceMinter,
174
+ ),
122
175
  };
123
- } else {
124
- throw new Error(`Invalid premint config version ${premintConfigVersion}`);
125
176
  }
177
+
178
+ return {
179
+ premintConfigVersion: PremintConfigVersion.V2,
180
+ tokenConfig: tokenConfigV2WithDefault(
181
+ tokenCreationConfig,
182
+ fixedPriceMinter,
183
+ ),
184
+ };
126
185
  };
127
186
 
128
187
  /**
@@ -214,8 +273,8 @@ class PremintClient {
214
273
  * @param parameters - Parameters for creating the premint {@link CreatePremintParameters}
215
274
  * @returns A PremintReturn. {@link PremintReturn}
216
275
  */
217
- async createPremint<T extends PremintConfigVersion = PremintConfigVersion.V2>(
218
- parameters: CreatePremintParameters<T>,
276
+ async createPremint(
277
+ parameters: CreatePremintParameters,
219
278
  ): Promise<PremintReturn<any>> {
220
279
  return createPremint({
221
280
  ...parameters,
@@ -265,25 +324,30 @@ class PremintClient {
265
324
  */
266
325
  async isValidSignature<T extends PremintConfigVersion>({
267
326
  signature,
268
- collection,
269
327
  premintConfig,
270
328
  premintConfigVersion,
329
+ ...collectionAndOrAddress
271
330
  }: {
272
331
  signature: Hex;
273
- collection: ContractCreationConfig;
274
332
  premintConfig: PremintConfigForVersion<T>;
275
333
  premintConfigVersion?: T;
276
- }): Promise<{
334
+ } & ContractCreationConfigOrAddress): Promise<{
277
335
  isValid: boolean;
278
336
  recoveredSigner: Address | undefined;
279
337
  }> {
338
+ const collectionAddressToUse = await getPremintCollectionAddress({
339
+ ...collectionAndOrAddress,
340
+ publicClient: this.publicClient,
341
+ });
342
+
280
343
  const { isAuthorized, recoveredAddress } = await isValidSignature({
281
344
  chainId: this.chain.id,
282
345
  signature: signature as Hex,
283
- collection: collection,
284
346
  publicClient: this.publicClient,
285
347
  premintConfig,
286
348
  premintConfigVersion: premintConfigVersion || PremintConfigVersion.V1,
349
+ collectionAddress: collectionAddressToUse,
350
+ collection: collectionAndOrAddress.collection,
287
351
  });
288
352
 
289
353
  return { isValid: isAuthorized, recoveredSigner: recoveredAddress };
@@ -344,11 +408,6 @@ export function createPremintClient(clientConfig: ClientConfig) {
344
408
  return new PremintClient(chain, publicClient, httpClient);
345
409
  }
346
410
 
347
- type ContractCreationConfigWithoutAdditionalAdmins = Omit<
348
- ContractCreationConfig,
349
- "additionalAdmins"
350
- >;
351
-
352
411
  type PremintContext = {
353
412
  publicClient: PublicClient;
354
413
  apiClient: PremintAPIClient;
@@ -396,15 +455,14 @@ type PremintReturn<T extends PremintConfigVersion> = {
396
455
  function makePremintReturn<T extends PremintConfigVersion>({
397
456
  premintConfig,
398
457
  premintConfigVersion,
399
- collectionAddress,
400
- collection,
401
458
  publicClient,
402
459
  apiClient,
403
460
  chainId,
404
- }: PremintConfigWithVersion<T> & {
405
- collectionAddress: Address;
406
- collection: ContractCreationConfigWithoutAdditionalAdmins;
407
- } & PremintContext): PremintReturn<T> {
461
+ ...collectionAndAddress
462
+ }: PremintConfigWithVersion<T> &
463
+ ContractCreationConfigAndAddress &
464
+ PremintContext): PremintReturn<T> {
465
+ const { collection, collectionAddress } = collectionAndAddress;
408
466
  const typedDataDefinition = premintTypedDataDefinition({
409
467
  verifyingContract: collectionAddress,
410
468
  premintConfig,
@@ -445,21 +503,21 @@ function makePremintReturn<T extends PremintConfigVersion>({
445
503
  signerAccount: Account | Address;
446
504
  }) => {
447
505
  if (checkSignature) {
448
- await validateSignature({
449
- collection: {
450
- ...collection,
451
- additionalAdmins: [],
452
- },
506
+ const isAuthorized = await isAuthorizedToCreatePremint({
507
+ collectionAddress,
508
+ additionalAdmins: collection?.additionalAdmins,
509
+ contractAdmin: collection?.contractAdmin,
453
510
  publicClient,
454
- signerAccount,
511
+ signer: signerAccount,
455
512
  });
513
+
514
+ if (!isAuthorized) {
515
+ throw new Error("Not authorized to create premint");
516
+ }
456
517
  }
457
518
 
458
519
  await apiClient.postSignature({
459
- collection: {
460
- ...collection,
461
- additionalAdmins: [],
462
- },
520
+ ...toContractCreationConfigOrAddress(collectionAndAddress),
463
521
  signature: signature,
464
522
  premintConfig,
465
523
  premintConfigVersion,
@@ -506,66 +564,30 @@ async function signPremint({
506
564
  };
507
565
  }
508
566
 
509
- const validateSignature = async ({
510
- collection,
511
- publicClient,
512
- signerAccount,
513
- }: {
514
- collection: ContractCreationConfig;
515
- publicClient: PublicClient;
516
- signerAccount: Address | Account;
517
- }) => {
518
- const isAuthorized = await isAuthorizedToCreatePremint({
519
- collection,
520
- publicClient,
521
- signer:
522
- typeof signerAccount === "string" ? signerAccount : signerAccount.address,
523
- collectionAddress: await getPremintCollectionAddress({
524
- collection,
525
- publicClient,
526
- }),
527
- });
528
- if (!isAuthorized) {
529
- throw new Error("Not authorized to create premint");
530
- }
531
- };
532
-
533
567
  /** CREATE */
534
568
 
535
- type CreatePremintParameters<T extends PremintConfigVersion> = {
536
- /** The account to receive the creator reward if it's a free mint, and the paid mint fee if it's a paid mint */
537
- payoutRecipient: Address;
538
- /** Collection information for the mint */
539
- collection: ContractCreationConfigWithoutAdditionalAdmins;
569
+ type CreatePremintParameters = {
540
570
  /** tokenCreationConfig Token creation settings, optional settings are overridden with sensible defaults */
541
- tokenCreationConfig: Partial<TokenConfigForVersion<T>> & {
542
- tokenURI: string;
543
- };
544
- /** Premint config version to use, defaults to V2 */
545
- premintConfigVersion?: T;
571
+ tokenCreationConfig: TokenConfigInput;
546
572
  /** uid the UID to use – optional and retrieved as a fresh UID from ZORA by default. */
547
573
  uid?: number;
548
- };
574
+ } & ContractCreationConfigOrAddress;
549
575
 
550
- async function createPremint<T extends PremintConfigVersion>({
551
- payoutRecipient: creatorAccount,
552
- collection,
576
+ async function createPremint({
553
577
  tokenCreationConfig,
554
- premintConfigVersion,
555
578
  uid,
556
579
  publicClient,
557
580
  apiClient,
558
581
  chainId,
559
- }: CreatePremintParameters<T> & PremintContext) {
582
+ ...collectionOrAddress
583
+ }: CreatePremintParameters & PremintContext) {
560
584
  const {
561
585
  premintConfig,
562
- premintConfigVersion: actualVersion,
563
- collectionAddress,
564
- } = await prepareCreatePremintConfig<T>({
565
- payoutRecipient: creatorAccount,
566
- collection,
567
- tokenCreationConfig,
568
586
  premintConfigVersion,
587
+ collectionAddress: collectionAddressToUse,
588
+ } = await prepareCreatePremintConfig({
589
+ ...collectionOrAddress,
590
+ tokenCreationConfig,
569
591
  uid,
570
592
  publicClient,
571
593
  apiClient,
@@ -574,42 +596,34 @@ async function createPremint<T extends PremintConfigVersion>({
574
596
 
575
597
  return makePremintReturn({
576
598
  premintConfig,
577
- premintConfigVersion: actualVersion,
578
- collectionAddress,
579
- collection,
599
+ premintConfigVersion,
600
+ collectionAddress: collectionAddressToUse,
601
+ collection: collectionOrAddress.collection,
580
602
  publicClient,
581
603
  apiClient,
582
604
  chainId,
583
605
  });
584
606
  }
585
607
 
586
- async function prepareCreatePremintConfig<T extends PremintConfigVersion>({
587
- payoutRecipient,
588
- collection,
608
+ type PreparePremintReturn = {
609
+ collectionAddress: Address;
610
+ } & PremintConfigAndVersion;
611
+
612
+ async function prepareCreatePremintConfig({
589
613
  tokenCreationConfig,
590
- premintConfigVersion,
591
614
  uid,
592
615
  publicClient,
593
616
  apiClient,
594
617
  chainId,
618
+ ...collectionOrAddress
595
619
  }: {
596
- payoutRecipient: Address | Account;
597
- collection: Omit<ContractCreationConfig, "additionalAdmins"> & {
598
- additionalAdmins?: Address[];
599
- };
600
- tokenCreationConfig: Partial<TokenConfigForVersion<T>> & {
601
- tokenURI: string;
602
- };
603
- premintConfigVersion?: T;
620
+ tokenCreationConfig: TokenConfigInput;
604
621
  uid?: number;
605
- } & PremintContext) {
606
- const collectionWithAdditionalAdmins: ContractCreationConfig = {
607
- ...collection,
608
- additionalAdmins: collection.additionalAdmins || [],
609
- };
622
+ } & PremintContext &
623
+ ContractCreationConfigOrAddress): Promise<PreparePremintReturn> {
610
624
  const newContractAddress = await getPremintCollectionAddress({
611
625
  publicClient,
612
- collection: collectionWithAdditionalAdmins,
626
+ ...collectionOrAddress,
613
627
  });
614
628
 
615
629
  let uidToUse = uid;
@@ -618,37 +632,29 @@ async function prepareCreatePremintConfig<T extends PremintConfigVersion>({
618
632
  uidToUse = await apiClient.getNextUID(newContractAddress);
619
633
  }
620
634
 
621
- const actualVersion = premintConfigVersion || PremintConfigVersion.V1;
635
+ const supportedVersions = await supportedPremintVersions({
636
+ tokenContract: newContractAddress,
637
+ publicClient,
638
+ });
622
639
 
623
- if (
624
- !(await supportsPremintVersion({
625
- version: actualVersion,
626
- publicClient,
627
- tokenContract: newContractAddress,
628
- }))
629
- ) {
630
- throw new Error(
631
- `Premint version ${actualVersion} not supported by contract`,
632
- );
633
- }
640
+ const tokenConfigAndVersion = makeTokenConfigWithDefaults({
641
+ tokenCreationConfig,
642
+ chainId,
643
+ supportedPremintVersions: supportedVersions,
644
+ });
634
645
 
635
646
  const premintConfig = makeNewPremint({
636
- tokenConfig: makeTokenConfigWithDefaults({
637
- // @ts-ignore
638
- premintConfigVersion: actualVersion,
639
- tokenCreationConfig,
640
- payoutRecipient:
641
- typeof payoutRecipient === "string"
642
- ? payoutRecipient
643
- : payoutRecipient.address,
644
- chainId,
645
- }),
647
+ ...tokenConfigAndVersion,
646
648
  uid: uidToUse,
647
649
  });
648
650
 
649
- return {
651
+ const premintConfigAndVersion = {
650
652
  premintConfig,
651
- premintConfigVersion: actualVersion,
653
+ premintConfigVersion: tokenConfigAndVersion.premintConfigVersion,
654
+ } as PremintConfigAndVersion;
655
+
656
+ return {
657
+ ...premintConfigAndVersion,
652
658
  collectionAddress: newContractAddress,
653
659
  };
654
660
  }
@@ -727,6 +733,7 @@ async function deletePremint({
727
733
  premintConfig,
728
734
  premintConfigVersion,
729
735
  collection: collectionCreationConfig,
736
+ collectionAddress,
730
737
  } = await apiClient.getSignature({
731
738
  collectionAddress: collection,
732
739
  uid: uid,
@@ -741,7 +748,7 @@ async function deletePremint({
741
748
  return makePremintReturn({
742
749
  premintConfig: deletedPremint,
743
750
  premintConfigVersion,
744
- collectionAddress: collection,
751
+ collectionAddress,
745
752
  collection: collectionCreationConfig,
746
753
  publicClient,
747
754
  apiClient,
@@ -767,6 +774,8 @@ export type MakeMintParametersArguments = {
767
774
  /** Address to receive the minted tokens */
768
775
  mintRecipient?: Address;
769
776
  };
777
+ /** Account to receive first minter reward, if this mint brings the premint onchain */
778
+ firstMinter?: Address;
770
779
  };
771
780
 
772
781
  /** ======== MINTING ======== */
@@ -776,6 +785,7 @@ async function makeMintParameters({
776
785
  tokenContract,
777
786
  minterAccount,
778
787
  mintArguments,
788
+ firstMinter,
779
789
  apiClient,
780
790
  publicClient,
781
791
  }: MakeMintParametersArguments & {
@@ -799,11 +809,16 @@ async function makeMintParameters({
799
809
  throw new Error("Wallet not passed in");
800
810
  }
801
811
 
802
- const { premintConfig, premintConfigVersion, collection, signature } =
803
- await apiClient.getSignature({
804
- collectionAddress: tokenContract,
805
- uid,
806
- });
812
+ const {
813
+ premintConfig,
814
+ premintConfigVersion,
815
+ collection,
816
+ collectionAddress,
817
+ signature,
818
+ } = await apiClient.getSignature({
819
+ collectionAddress: tokenContract,
820
+ uid,
821
+ });
807
822
 
808
823
  const numberToMint = BigInt(mintArguments?.quantityToMint || 1);
809
824
 
@@ -832,39 +847,37 @@ async function makeMintParameters({
832
847
  }),
833
848
  };
834
849
 
835
- if (premintConfigVersion === PremintConfigVersion.V1) {
836
- return makeSimulateContractParamaters({
837
- account: minterAccount,
838
- abi: zoraCreator1155PremintExecutorImplABI,
839
- functionName: "premintV1",
840
- value,
841
- address: getPremintExecutorAddress(),
842
- args: [
843
- collection,
844
- premintConfig,
845
- signature,
846
- numberToMint,
847
- mintArgumentsContract,
848
- ],
849
- });
850
- } else if (premintConfigVersion === PremintConfigVersion.V2) {
851
- return makeSimulateContractParamaters({
852
- account: minterAccount,
853
- abi: zoraCreator1155PremintExecutorImplABI,
854
- functionName: "premintV2",
855
- value,
856
- address: getPremintExecutorAddress(),
857
- args: [
858
- collection,
850
+ const collectionOrEmpty: ContractCreationConfig = collection
851
+ ? defaultAdditionalAdmins(collection)
852
+ : emptyContractCreationConfig();
853
+ const collectionAddressToSubmit = collection
854
+ ? zeroAddress
855
+ : collectionAddress;
856
+
857
+ const firstMinterToSubmit: Address =
858
+ firstMinter ||
859
+ (typeof minterAccount === "string" ? minterAccount : minterAccount.address);
860
+
861
+ return makeSimulateContractParamaters({
862
+ account: minterAccount,
863
+ abi: zoraCreator1155PremintExecutorImplABI,
864
+ functionName: "premint",
865
+ value,
866
+ address: getPremintExecutorAddress(),
867
+ args: [
868
+ collectionOrEmpty,
869
+ collectionAddressToSubmit,
870
+ encodePremintConfig({
859
871
  premintConfig,
860
- signature,
861
- numberToMint,
862
- mintArgumentsContract,
863
- ],
864
- });
865
- }
866
-
867
- throw new Error(`Invalid premint config version ${premintConfigVersion}`);
872
+ premintConfigVersion,
873
+ }),
874
+ signature,
875
+ numberToMint,
876
+ mintArgumentsContract,
877
+ firstMinterToSubmit,
878
+ zeroAddress,
879
+ ],
880
+ });
868
881
  }
869
882
 
870
883
  export function makeUrls({