@zoralabs/protocol-sdk 0.5.15 → 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.
Files changed (46) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/CHANGELOG.md +19 -0
  3. package/dist/anvil.d.ts +4 -4
  4. package/dist/anvil.d.ts.map +1 -1
  5. package/dist/apis/generated/premint-api-types.d.ts +9 -2
  6. package/dist/apis/generated/premint-api-types.d.ts.map +1 -1
  7. package/dist/create/1155-create-helper.d.ts +3 -4
  8. package/dist/create/1155-create-helper.d.ts.map +1 -1
  9. package/dist/index.cjs +495 -371
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +478 -352
  14. package/dist/index.js.map +1 -1
  15. package/dist/mint/mint-client.d.ts +22 -17
  16. package/dist/mint/mint-client.d.ts.map +1 -1
  17. package/dist/mints/mints-contracts.d.ts +688 -3
  18. package/dist/mints/mints-contracts.d.ts.map +1 -1
  19. package/dist/premint/contract-types.d.ts +21 -0
  20. package/dist/premint/contract-types.d.ts.map +1 -1
  21. package/dist/premint/conversions.d.ts +10 -22
  22. package/dist/premint/conversions.d.ts.map +1 -1
  23. package/dist/premint/premint-api-client.d.ts +5 -4
  24. package/dist/premint/premint-api-client.d.ts.map +1 -1
  25. package/dist/premint/premint-client.d.ts +122 -1476
  26. package/dist/premint/premint-client.d.ts.map +1 -1
  27. package/dist/premint/preminter.d.ts +29 -16
  28. package/dist/premint/preminter.d.ts.map +1 -1
  29. package/dist/utils.d.ts +6872 -1
  30. package/dist/utils.d.ts.map +1 -1
  31. package/package.json +2 -2
  32. package/src/apis/generated/premint-api-types.ts +9 -2
  33. package/src/create/1155-create-helper.test.ts +10 -3
  34. package/src/create/1155-create-helper.ts +8 -7
  35. package/src/index.ts +6 -0
  36. package/src/mint/mint-client.ts +31 -30
  37. package/src/mints/mints-contracts.test.ts +2 -2
  38. package/src/premint/contract-types.ts +32 -1
  39. package/src/premint/conversions.ts +20 -8
  40. package/src/premint/premint-api-client.ts +7 -7
  41. package/src/premint/premint-client.test.ts +112 -88
  42. package/src/premint/premint-client.ts +614 -409
  43. package/src/premint/preminter.test.ts +154 -2
  44. package/src/premint/preminter.ts +87 -36
  45. package/src/utils.ts +25 -0
  46. package/test-integration/premint-client.test.ts +2 -2
@@ -1,14 +1,20 @@
1
- import { createPublicClient, decodeEventLog, http, zeroAddress } from "viem";
1
+ import { decodeEventLog, zeroAddress } from "viem";
2
2
  import type {
3
3
  Account,
4
4
  Address,
5
5
  Chain,
6
6
  Hex,
7
- PublicClient,
7
+ SimulateContractParameters,
8
8
  TransactionReceipt,
9
+ TypedDataDefinition,
9
10
  WalletClient,
10
11
  } from "viem";
11
- import { zoraCreator1155PremintExecutorImplABI } from "@zoralabs/protocol-deployments";
12
+ import {
13
+ PremintConfigAndVersion,
14
+ TokenConfigWithVersion,
15
+ encodePremintConfig,
16
+ zoraCreator1155PremintExecutorImplABI,
17
+ } from "@zoralabs/protocol-deployments";
12
18
  import {
13
19
  getPremintCollectionAddress,
14
20
  isValidSignature,
@@ -16,15 +22,17 @@ import {
16
22
  getPremintExecutorAddress,
17
23
  applyUpdateToPremint,
18
24
  makeNewPremint,
19
- supportsPremintVersion,
25
+ supportedPremintVersions,
20
26
  getPremintMintCosts,
21
27
  makeMintRewardsRecipient,
22
28
  getDefaultFixedPriceMinterAddress,
29
+ emptyContractCreationConfig,
30
+ defaultAdditionalAdmins,
31
+ toContractCreationConfigOrAddress,
23
32
  } from "./preminter";
24
33
  import {
25
34
  PremintConfigVersion,
26
35
  ContractCreationConfig,
27
- TokenConfigForVersion,
28
36
  TokenCreationConfigV1,
29
37
  TokenCreationConfigV2,
30
38
  TokenCreationConfig,
@@ -39,7 +47,16 @@ import { OPEN_EDITION_MINT_SIZE } from "../constants";
39
47
  import { IHttpClient } from "src/apis/http-api-base";
40
48
  import { getApiNetworkConfigForChain } from "src/mint/mint-api-client";
41
49
  import { MintCosts } from "src/mint/mint-client";
42
- import { makeSimulateContractParamaters } from "src/utils";
50
+ import {
51
+ ClientConfig,
52
+ makeSimulateContractParamaters,
53
+ PublicClient,
54
+ setupClient,
55
+ } from "src/utils";
56
+ import {
57
+ ContractCreationConfigAndAddress,
58
+ ContractCreationConfigOrAddress,
59
+ } from "./contract-types";
43
60
 
44
61
  type PremintedV2LogType = DecodeEventLogReturnType<
45
62
  typeof zoraCreator1155PremintExecutorImplABI,
@@ -52,12 +69,6 @@ type URLSReturnType = {
52
69
  zoraManage: null | string;
53
70
  };
54
71
 
55
- type SignedPremintResponse = {
56
- urls: URLSReturnType;
57
- uid: number;
58
- verifyingContract: Address;
59
- };
60
-
61
72
  export const defaultTokenConfigV1MintArguments = (): Omit<
62
73
  TokenCreationConfigV1,
63
74
  "fixedPriceMinter" | "tokenURI" | "royaltyRecipient"
@@ -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
- creatorAccount,
153
+ supportedPremintVersions,
91
154
  }: {
92
155
  chainId: number;
93
- premintConfigVersion: T;
94
- tokenCreationConfig: Partial<TokenConfigForVersion<T>> & { tokenURI: string };
95
- creatorAccount: 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
- return {
110
- fixedPriceMinter,
111
- ...defaultTokenConfigV1MintArguments(),
112
- royaltyRecipient: creatorAccount,
113
- ...(tokenCreationConfig as Partial<TokenCreationConfigV1>),
114
- } as TokenCreationConfigV1;
115
- } else if (premintConfigVersion === PremintConfigVersion.V2) {
116
169
  return {
117
- fixedPriceMinter,
118
- ...defaultTokenConfigV2MintArguments(),
119
- payoutRecipient: creatorAccount,
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
  /**
@@ -149,7 +208,6 @@ export function getPremintedLogFromReceipt(
149
208
  }
150
209
  /**
151
210
  * Preminter API to access ZORA Premint functionality.
152
- * Currently only supports V1 premints.
153
211
  */
154
212
  class PremintClient {
155
213
  readonly apiClient: PremintAPIClient;
@@ -158,13 +216,12 @@ class PremintClient {
158
216
 
159
217
  constructor(
160
218
  chain: Chain,
161
- publicClient?: PublicClient,
162
- httpClient?: IHttpClient,
219
+ publicClient: PublicClient,
220
+ httpClient: IHttpClient,
163
221
  ) {
164
222
  this.chain = chain;
165
223
  this.apiClient = new PremintAPIClient(chain.id, httpClient);
166
- this.publicClient =
167
- publicClient || createPublicClient({ chain, transport: http() });
224
+ this.publicClient = publicClient;
168
225
  }
169
226
 
170
227
  getDataFromPremintReceipt(receipt: TransactionReceipt) {
@@ -179,219 +236,51 @@ class PremintClient {
179
236
  }
180
237
 
181
238
  /**
182
- * Update existing premint given collection address and UID of existing premint.
183
- *
184
- * 1. Loads existing premint token
185
- * 2. Updates with settings passed into function
186
- * 3. Increments the version field
187
- * 4. Re-signs the premint
188
- * 5. Uploads the premint to the ZORA API
189
- *
190
- * Updates existing premint
191
- * @param settings Settings for the new premint
192
- * @param settings.account Account to sign the premint update from. Taken from walletClient if none passed in.
193
- * @param settings.collection Collection information for the mint
194
- * @param settings.walletClient viem wallet client to use to sign
195
- * @param settings.uid UID
196
- * @param settings.token Mint argument settings, optional settings are overridden with sensible defaults.
197
- *
198
- */
199
- async updatePremint({
200
- walletClient,
201
- uid,
202
- collection,
203
- account,
204
- tokenConfigUpdates,
205
- }: {
206
- walletClient: WalletClient;
207
- uid: number;
208
- account?: Account | Address;
209
- collection: Address;
210
- tokenConfigUpdates: Partial<TokenCreationConfig>;
211
- }): Promise<SignedPremintResponse> {
212
- const {
213
- premintConfig,
214
- collection: collectionCreationConfig,
215
- premintConfigVersion,
216
- } = await this.apiClient.getSignature({
217
- collectionAddress: collection,
218
- uid: uid,
219
- });
220
-
221
- const updatedPremint = applyUpdateToPremint({
222
- uid: premintConfig.uid,
223
- version: premintConfig.version,
224
- tokenConfig: premintConfig.tokenConfig,
225
- tokenConfigUpdates: tokenConfigUpdates,
226
- });
227
-
228
- return await this.signAndSubmitPremint({
229
- walletClient,
230
- account,
231
- checkSignature: true,
232
- verifyingContract: collection,
233
- collection: collectionCreationConfig,
234
- premintConfig: updatedPremint,
235
- premintConfigVersion: premintConfigVersion,
236
- });
237
- }
238
-
239
- /**
240
- * Delete premint.
241
- *
242
- * 1. Loads current premint from collection address with UID
243
- * 2. Increments version and marks as deleted
244
- * 3. Signs new premint version
245
- * 4. Sends to ZORA Premint API
246
- *
247
- * Deletes existing premint
248
- * @param settings.collection collection address
249
- * @param settings.uid UID
250
- * @param settings.walletClient viem wallet client to use to sign
239
+ * Prepares data for updating a premint
251
240
  *
241
+ * @param parameters - Parameters for updating the premint {@link UpdatePremintParams}
242
+ * @returns A PremintReturn. {@link PremintReturn}
252
243
  */
253
- async deletePremint({
254
- walletClient,
255
- uid,
256
- account,
257
- collection,
258
- }: {
259
- walletClient: WalletClient;
260
- uid: number;
261
- account?: Account | Address;
262
- collection: Address;
263
- }) {
264
- const {
265
- premintConfig,
266
- premintConfigVersion,
267
- collection: collectionCreationConfig,
268
- } = await this.apiClient.getSignature({
269
- collectionAddress: collection,
270
- uid: uid,
271
- });
272
-
273
- const deletedPremint = {
274
- ...premintConfig,
275
- version: premintConfig.version + 1,
276
- deleted: true,
277
- };
278
-
279
- return await this.signAndSubmitPremint({
280
- walletClient,
281
- account,
282
- checkSignature: false,
283
- verifyingContract: collection,
284
- collection: collectionCreationConfig,
285
- premintConfig: deletedPremint,
286
- premintConfigVersion,
244
+ async updatePremint(args: UpdatePremintParams): Promise<PremintReturn<any>> {
245
+ return await updatePremint({
246
+ ...args,
247
+ apiClient: this.apiClient,
248
+ publicClient: this.publicClient,
249
+ chainId: this.chain.id,
287
250
  });
288
251
  }
289
252
 
290
253
  /**
291
- * Internal function to sign and submit a premint request.
254
+ * Prepares data for deleting a premint
292
255
  *
293
- * @param premintArguments Arguments to premint
294
- * @returns
256
+ * @param parameters - Parameters for deleting the premint {@link DeletePremintParams}
257
+ * @returns A PremintReturn. {@link PremintReturn}
295
258
  */
296
- private async signAndSubmitPremint<T extends PremintConfigVersion>(
297
- params: SignAndSubmitPremintParams<T>,
298
- ): Promise<SignedPremintResponse> {
299
- const { verifyingContract } = await signAndSubmitPremint({
259
+ async deletePremint(
260
+ params: DeletePremintParams,
261
+ ): Promise<PremintReturn<any>> {
262
+ return deletePremint({
300
263
  ...params,
301
- chainId: this.chain.id,
302
264
  apiClient: this.apiClient,
303
265
  publicClient: this.publicClient,
266
+ chainId: this.chain.id,
304
267
  });
305
-
306
- const uid = params.premintConfig.uid;
307
-
308
- return {
309
- urls: this.makeUrls({ address: verifyingContract, uid }),
310
- uid,
311
- verifyingContract,
312
- };
313
268
  }
314
269
 
315
270
  /**
316
- * Create premint
271
+ * Prepares data for creating a premint
317
272
  *
318
- * @param settings Settings for the new premint
319
- * @param settings.account Account to sign the premint with. Taken from walletClient if none passed in.
320
- * @param settings.collection Collection information for the mint
321
- * @param settings.tokenCreationConfig Mint argument settings, optional settings are overridden with sensible defaults.
322
- * @param setings.premintConfigVersion Premint config version to use, defaults to V2
323
- * @param settings.uid the UID to use – optional and retrieved as a fresh UID from ZORA by default.
324
- * @param settings.checkSignature if the signature should have a pre-flight check. Not required but helpful for debugging.
325
- * @returns premint url, uid, newContractAddress, and premint object
273
+ * @param parameters - Parameters for creating the premint {@link CreatePremintParameters}
274
+ * @returns A PremintReturn. {@link PremintReturn}
326
275
  */
327
- async createPremint<
328
- T extends PremintConfigVersion = PremintConfigVersion.V2,
329
- >({
330
- creatorAccount,
331
- collection,
332
- tokenCreationConfig,
333
- premintConfigVersion,
334
- walletClient,
335
- uid,
336
- checkSignature = false,
337
- }: {
338
- creatorAccount: Address | Account;
339
- checkSignature?: boolean;
340
- walletClient: WalletClient;
341
- collection: ContractCreationConfig;
342
- tokenCreationConfig: Partial<TokenConfigForVersion<T>> & {
343
- tokenURI: string;
344
- };
345
- premintConfigVersion?: T;
346
- uid?: number;
347
- }) {
348
- const newContractAddress = await getPremintCollectionAddress({
276
+ async createPremint(
277
+ parameters: CreatePremintParameters,
278
+ ): Promise<PremintReturn<any>> {
279
+ return createPremint({
280
+ ...parameters,
349
281
  publicClient: this.publicClient,
350
- collection,
351
- });
352
-
353
- let uidToUse = uid;
354
-
355
- if (typeof uidToUse !== "number") {
356
- uidToUse = await this.apiClient.getNextUID(newContractAddress);
357
- }
358
-
359
- const actualVersion = premintConfigVersion || PremintConfigVersion.V1;
360
-
361
- if (
362
- !(await supportsPremintVersion({
363
- version: actualVersion,
364
- publicClient: this.publicClient,
365
- tokenContract: newContractAddress,
366
- }))
367
- ) {
368
- throw new Error(
369
- `Premint version ${actualVersion} not supported by contract`,
370
- );
371
- }
372
-
373
- const premintConfig = makeNewPremint({
374
- tokenConfig: makeTokenConfigWithDefaults({
375
- // @ts-ignore
376
- premintConfigVersion: actualVersion,
377
- tokenCreationConfig,
378
- creatorAccount:
379
- typeof creatorAccount === "string"
380
- ? creatorAccount
381
- : creatorAccount.address,
382
- chainId: this.chain.id,
383
- }),
384
- uid: uidToUse,
385
- });
386
-
387
- return await this.signAndSubmitPremint({
388
- verifyingContract: newContractAddress,
389
- premintConfig,
390
- premintConfigVersion: actualVersion,
391
- checkSignature,
392
- account: creatorAccount,
393
- walletClient,
394
- collection,
282
+ apiClient: this.apiClient,
283
+ chainId: this.chain.id,
395
284
  });
396
285
  }
397
286
 
@@ -435,25 +324,30 @@ class PremintClient {
435
324
  */
436
325
  async isValidSignature<T extends PremintConfigVersion>({
437
326
  signature,
438
- collection,
439
327
  premintConfig,
440
328
  premintConfigVersion,
329
+ ...collectionAndOrAddress
441
330
  }: {
442
331
  signature: Hex;
443
- collection: ContractCreationConfig;
444
332
  premintConfig: PremintConfigForVersion<T>;
445
333
  premintConfigVersion?: T;
446
- }): Promise<{
334
+ } & ContractCreationConfigOrAddress): Promise<{
447
335
  isValid: boolean;
448
336
  recoveredSigner: Address | undefined;
449
337
  }> {
338
+ const collectionAddressToUse = await getPremintCollectionAddress({
339
+ ...collectionAndOrAddress,
340
+ publicClient: this.publicClient,
341
+ });
342
+
450
343
  const { isAuthorized, recoveredAddress } = await isValidSignature({
451
344
  chainId: this.chain.id,
452
345
  signature: signature as Hex,
453
- collection: collection,
454
346
  publicClient: this.publicClient,
455
347
  premintConfig,
456
348
  premintConfigVersion: premintConfigVersion || PremintConfigVersion.V1,
349
+ collectionAddress: collectionAddressToUse,
350
+ collection: collectionAndOrAddress.collection,
457
351
  });
458
352
 
459
353
  return { isValid: isAuthorized, recoveredSigner: recoveredAddress };
@@ -494,125 +388,499 @@ class PremintClient {
494
388
  }
495
389
 
496
390
  /**
497
- * Execute premint on-chain
391
+ * Prepares the parameters to collect a premint; it brings the contract and token onchain, then collects
392
+ * tokens on that contract for the mint recipient.
498
393
  *
499
- * @param settings.data Data from the API for the mint
500
- * @param settings.account Optional account (if omitted taken from wallet client) for the account executing the premint.
501
- * @param settings.walletClient WalletClient to send execution from.
502
- * @param settings.mintArguments User minting arguments.
503
- * @param settings.mintArguments.quantityToMint Quantity to mint, optional, defaults to 1.
504
- * @param settings.mintArguments.mintComment Optional mint comment, optional, omits when not included.
505
- * @param settings.publicClient Optional public client for preflight checks.
394
+ * @param parameters - Parameters for collecting the Premint {@link MakeMintParametersArguments}
506
395
  * @returns receipt, log, zoraURL
507
396
  */
508
- async makeMintParameters({
509
- uid,
510
- tokenContract,
511
- minterAccount,
512
- mintArguments,
513
- }: {
514
- uid: number;
515
- tokenContract: Address;
516
- minterAccount: Account | Address;
517
- mintArguments?: {
518
- quantityToMint: number;
519
- mintComment?: string;
520
- mintReferral?: Address;
521
- platformReferral?: Address;
522
- mintRecipient?: Address;
523
- };
524
- }) {
525
- if (mintArguments && mintArguments?.quantityToMint < 1) {
526
- throw new Error("Quantity to mint cannot be below 1");
527
- }
397
+ async makeMintParameters(parameters: MakeMintParametersArguments) {
398
+ return await makeMintParameters({
399
+ ...parameters,
400
+ apiClient: this.apiClient,
401
+ publicClient: this.publicClient,
402
+ });
403
+ }
404
+ }
528
405
 
529
- if (!minterAccount) {
530
- throw new Error("Wallet not passed in");
531
- }
406
+ export function createPremintClient(clientConfig: ClientConfig) {
407
+ const { chain, httpClient, publicClient } = setupClient(clientConfig);
408
+ return new PremintClient(chain, publicClient, httpClient);
409
+ }
532
410
 
533
- const { premintConfig, premintConfigVersion, collection, signature } =
534
- await this.getPremintSignature({
535
- address: tokenContract,
536
- uid,
537
- });
411
+ type PremintContext = {
412
+ publicClient: PublicClient;
413
+ apiClient: PremintAPIClient;
414
+ chainId: number;
415
+ };
538
416
 
539
- const numberToMint = BigInt(mintArguments?.quantityToMint || 1);
417
+ /** ======= ADMIN ======= */
540
418
 
541
- if (premintConfigVersion === PremintConfigVersion.V3) {
542
- throw new Error("PremintV3 not supported in premint SDK");
543
- }
419
+ export type SignAndSubmitParams = {
420
+ /** The WalletClient used to sign the premint */
421
+ walletClient: WalletClient;
422
+ /** The account that is to sign the premint */
423
+ account: Account | Address;
424
+ /** If the signature should be checked before submitting it to the api */
425
+ checkSignature?: boolean;
426
+ };
544
427
 
545
- const value = (
546
- await getPremintMintCosts({
547
- tokenContract,
548
- quantityToMint: numberToMint,
549
- publicClient: this.publicClient,
550
- tokenPrice: premintConfig.tokenConfig.pricePerToken,
551
- })
552
- ).totalCost;
553
-
554
- const mintArgumentsContract: PremintMintArguments = {
555
- mintComment: mintArguments?.mintComment || "",
556
- mintRecipient:
557
- mintArguments?.mintRecipient ||
558
- (typeof minterAccount === "string"
559
- ? minterAccount
560
- : minterAccount.address),
561
- mintRewardsRecipients: makeMintRewardsRecipient({
562
- mintReferral: mintArguments?.mintReferral,
563
- platformReferral: mintArguments?.platformReferral,
564
- }),
428
+ export type SignAndSubmitReturn = {
429
+ /** The signature of the Premint */
430
+ signature: Hex;
431
+ /** The account that signed the Premint */
432
+ signerAccount: Account | Address;
433
+ };
434
+
435
+ export type SubmitParams = {
436
+ /** The signature of the Premint */
437
+ signature: Hex;
438
+ /** If the premint signature should be validated before submitting to the API */
439
+ checkSignature?: boolean;
440
+ /** The account that signed the premint */
441
+ signerAccount: Account | Address;
442
+ };
443
+
444
+ type PremintReturn<T extends PremintConfigVersion> = {
445
+ /** The typedDataDefinition of the Premint which is to be signed the creator. */
446
+ typedDataDefinition: TypedDataDefinition;
447
+ /** The deterministic collection address of the Premint */
448
+ collectionAddress: Address;
449
+ /** Signs the Premint, and submits it and the signature to the Zora Premint API */
450
+ signAndSubmit: (params: SignAndSubmitParams) => Promise<SignAndSubmitReturn>;
451
+ /** For the case where the premint is signed externally, takes the signature for the Premint, and submits it and the Premint to the Zora Premint API */
452
+ submit: (params: SubmitParams) => void;
453
+ } & PremintConfigWithVersion<T>;
454
+
455
+ function makePremintReturn<T extends PremintConfigVersion>({
456
+ premintConfig,
457
+ premintConfigVersion,
458
+ publicClient,
459
+ apiClient,
460
+ chainId,
461
+ ...collectionAndAddress
462
+ }: PremintConfigWithVersion<T> &
463
+ ContractCreationConfigAndAddress &
464
+ PremintContext): PremintReturn<T> {
465
+ const { collection, collectionAddress } = collectionAndAddress;
466
+ const typedDataDefinition = premintTypedDataDefinition({
467
+ verifyingContract: collectionAddress,
468
+ premintConfig,
469
+ premintConfigVersion,
470
+ chainId,
471
+ });
472
+
473
+ const signAndSubmit = async ({
474
+ walletClient,
475
+ account,
476
+ checkSignature,
477
+ }: SignAndSubmitParams): Promise<SignAndSubmitReturn> => {
478
+ const { signature, signerAccount } = await signPremint({
479
+ account,
480
+ walletClient,
481
+ typedDataDefinition,
482
+ });
483
+
484
+ await submit({
485
+ signature,
486
+ checkSignature,
487
+ signerAccount,
488
+ });
489
+
490
+ return {
491
+ signature,
492
+ signerAccount,
565
493
  };
494
+ };
566
495
 
567
- if (premintConfigVersion === PremintConfigVersion.V1) {
568
- return makeSimulateContractParamaters({
569
- account: minterAccount,
570
- abi: zoraCreator1155PremintExecutorImplABI,
571
- functionName: "premintV1",
572
- value,
573
- address: getPremintExecutorAddress(),
574
- args: [
575
- collection,
576
- premintConfig,
577
- signature,
578
- numberToMint,
579
- mintArgumentsContract,
580
- ],
581
- });
582
- } else if (premintConfigVersion === PremintConfigVersion.V2) {
583
- return makeSimulateContractParamaters({
584
- account: minterAccount,
585
- abi: zoraCreator1155PremintExecutorImplABI,
586
- functionName: "premintV2",
587
- value,
588
- address: getPremintExecutorAddress(),
589
- args: [
590
- collection,
591
- premintConfig,
592
- signature,
593
- numberToMint,
594
- mintArgumentsContract,
595
- ],
496
+ const submit = async ({
497
+ signature,
498
+ checkSignature,
499
+ signerAccount,
500
+ }: {
501
+ signature: Hex;
502
+ checkSignature?: boolean;
503
+ signerAccount: Account | Address;
504
+ }) => {
505
+ if (checkSignature) {
506
+ const isAuthorized = await isAuthorizedToCreatePremint({
507
+ collectionAddress,
508
+ additionalAdmins: collection?.additionalAdmins,
509
+ contractAdmin: collection?.contractAdmin,
510
+ publicClient,
511
+ signer: signerAccount,
596
512
  });
513
+
514
+ if (!isAuthorized) {
515
+ throw new Error("Not authorized to create premint");
516
+ }
597
517
  }
598
518
 
599
- throw new Error(`Invalid premint config version ${premintConfigVersion}`);
519
+ await apiClient.postSignature({
520
+ ...toContractCreationConfigOrAddress(collectionAndAddress),
521
+ signature: signature,
522
+ premintConfig,
523
+ premintConfigVersion,
524
+ });
525
+ };
526
+
527
+ return {
528
+ premintConfig,
529
+ premintConfigVersion,
530
+ typedDataDefinition,
531
+ collectionAddress,
532
+ signAndSubmit,
533
+ submit,
534
+ };
535
+ }
536
+
537
+ async function signPremint({
538
+ account,
539
+ walletClient,
540
+ typedDataDefinition,
541
+ }: {
542
+ /** The account that is to sign the premint */
543
+ account?: Address | Account;
544
+ /** WalletClient used to sign the premint */
545
+ walletClient: WalletClient;
546
+ /** Data */
547
+ typedDataDefinition: TypedDataDefinition;
548
+ }) {
549
+ if (!account) {
550
+ account = walletClient.account;
600
551
  }
552
+ if (!account) {
553
+ throw new Error("No account provided");
554
+ }
555
+
556
+ const signature = await walletClient.signTypedData({
557
+ account,
558
+ ...typedDataDefinition,
559
+ });
560
+
561
+ return {
562
+ signature,
563
+ signerAccount: account,
564
+ };
601
565
  }
602
566
 
603
- export function createPremintClient({
604
- chain,
605
- httpClient,
567
+ /** CREATE */
568
+
569
+ type CreatePremintParameters = {
570
+ /** tokenCreationConfig Token creation settings, optional settings are overridden with sensible defaults */
571
+ tokenCreationConfig: TokenConfigInput;
572
+ /** uid the UID to use – optional and retrieved as a fresh UID from ZORA by default. */
573
+ uid?: number;
574
+ } & ContractCreationConfigOrAddress;
575
+
576
+ async function createPremint({
577
+ tokenCreationConfig,
578
+ uid,
606
579
  publicClient,
580
+ apiClient,
581
+ chainId,
582
+ ...collectionOrAddress
583
+ }: CreatePremintParameters & PremintContext) {
584
+ const {
585
+ premintConfig,
586
+ premintConfigVersion,
587
+ collectionAddress: collectionAddressToUse,
588
+ } = await prepareCreatePremintConfig({
589
+ ...collectionOrAddress,
590
+ tokenCreationConfig,
591
+ uid,
592
+ publicClient,
593
+ apiClient,
594
+ chainId,
595
+ });
596
+
597
+ return makePremintReturn({
598
+ premintConfig,
599
+ premintConfigVersion,
600
+ collectionAddress: collectionAddressToUse,
601
+ collection: collectionOrAddress.collection,
602
+ publicClient,
603
+ apiClient,
604
+ chainId,
605
+ });
606
+ }
607
+
608
+ type PreparePremintReturn = {
609
+ collectionAddress: Address;
610
+ } & PremintConfigAndVersion;
611
+
612
+ async function prepareCreatePremintConfig({
613
+ tokenCreationConfig,
614
+ uid,
615
+ publicClient,
616
+ apiClient,
617
+ chainId,
618
+ ...collectionOrAddress
607
619
  }: {
608
- chain: Chain;
609
- publicClient?: PublicClient;
610
- httpClient?: IHttpClient;
620
+ tokenCreationConfig: TokenConfigInput;
621
+ uid?: number;
622
+ } & PremintContext &
623
+ ContractCreationConfigOrAddress): Promise<PreparePremintReturn> {
624
+ const newContractAddress = await getPremintCollectionAddress({
625
+ publicClient,
626
+ ...collectionOrAddress,
627
+ });
628
+
629
+ let uidToUse = uid;
630
+
631
+ if (typeof uidToUse !== "number") {
632
+ uidToUse = await apiClient.getNextUID(newContractAddress);
633
+ }
634
+
635
+ const supportedVersions = await supportedPremintVersions({
636
+ tokenContract: newContractAddress,
637
+ publicClient,
638
+ });
639
+
640
+ const tokenConfigAndVersion = makeTokenConfigWithDefaults({
641
+ tokenCreationConfig,
642
+ chainId,
643
+ supportedPremintVersions: supportedVersions,
644
+ });
645
+
646
+ const premintConfig = makeNewPremint({
647
+ ...tokenConfigAndVersion,
648
+ uid: uidToUse,
649
+ });
650
+
651
+ const premintConfigAndVersion = {
652
+ premintConfig,
653
+ premintConfigVersion: tokenConfigAndVersion.premintConfigVersion,
654
+ } as PremintConfigAndVersion;
655
+
656
+ return {
657
+ ...premintConfigAndVersion,
658
+ collectionAddress: newContractAddress,
659
+ };
660
+ }
661
+
662
+ /** UPDATE */
663
+
664
+ export type UpdatePremintParams = {
665
+ /** uid of the Premint to update */
666
+ uid: number;
667
+ /** address of the Premint to update */
668
+ collection: Address;
669
+ /** update to apply to the Premint */
670
+ tokenConfigUpdates: Partial<TokenCreationConfig>;
671
+ };
672
+
673
+ async function updatePremint({
674
+ uid,
675
+ collection,
676
+ tokenConfigUpdates,
677
+ apiClient,
678
+ publicClient,
679
+ chainId,
680
+ }: UpdatePremintParams & {
681
+ apiClient: PremintAPIClient;
682
+ publicClient: PublicClient;
683
+ chainId: number;
611
684
  }) {
612
- return new PremintClient(chain, publicClient, httpClient);
685
+ const {
686
+ premintConfig,
687
+ collection: collectionCreationConfig,
688
+ premintConfigVersion,
689
+ } = await apiClient.getSignature({
690
+ collectionAddress: collection,
691
+ uid: uid,
692
+ });
693
+
694
+ const updatedPremint = applyUpdateToPremint({
695
+ uid: premintConfig.uid,
696
+ version: premintConfig.version,
697
+ tokenConfig: premintConfig.tokenConfig,
698
+ tokenConfigUpdates: tokenConfigUpdates,
699
+ });
700
+
701
+ return makePremintReturn({
702
+ premintConfig: updatedPremint,
703
+ premintConfigVersion,
704
+ collectionAddress: collection,
705
+ collection: collectionCreationConfig,
706
+ publicClient,
707
+ apiClient,
708
+ chainId,
709
+ });
710
+ }
711
+
712
+ /** DELETE */
713
+
714
+ export type DeletePremintParams = {
715
+ /** id of the premint to delete */
716
+ uid: number;
717
+ /** collection address of the Premint to delete */
718
+ collection: Address;
719
+ };
720
+
721
+ async function deletePremint({
722
+ uid,
723
+ collection,
724
+ publicClient,
725
+ apiClient,
726
+ chainId,
727
+ }: DeletePremintParams & {
728
+ apiClient: PremintAPIClient;
729
+ publicClient: PublicClient;
730
+ chainId: number;
731
+ }) {
732
+ const {
733
+ premintConfig,
734
+ premintConfigVersion,
735
+ collection: collectionCreationConfig,
736
+ collectionAddress,
737
+ } = await apiClient.getSignature({
738
+ collectionAddress: collection,
739
+ uid: uid,
740
+ });
741
+
742
+ const deletedPremint = {
743
+ ...premintConfig,
744
+ version: premintConfig.version + 1,
745
+ deleted: true,
746
+ };
747
+
748
+ return makePremintReturn({
749
+ premintConfig: deletedPremint,
750
+ premintConfigVersion,
751
+ collectionAddress,
752
+ collection: collectionCreationConfig,
753
+ publicClient,
754
+ apiClient,
755
+ chainId,
756
+ });
757
+ }
758
+
759
+ export type MakeMintParametersArguments = {
760
+ /** uid of the Premint to mint */
761
+ uid: number;
762
+ /** Premint contract address */
763
+ tokenContract: Address;
764
+ /** Account to execute the mint */
765
+ minterAccount: Account | Address;
766
+ /** Minting settings */
767
+ mintArguments?: {
768
+ /** Quantity of tokens to mint */
769
+ quantityToMint: number;
770
+ /** Comment to add to the mint */
771
+ mintComment?: string;
772
+ /** Address to receive the mint referral reward */
773
+ mintReferral?: Address;
774
+ /** Address to receive the minted tokens */
775
+ mintRecipient?: Address;
776
+ };
777
+ /** Account to receive first minter reward, if this mint brings the premint onchain */
778
+ firstMinter?: Address;
779
+ };
780
+
781
+ /** ======== MINTING ======== */
782
+
783
+ async function makeMintParameters({
784
+ uid,
785
+ tokenContract,
786
+ minterAccount,
787
+ mintArguments,
788
+ firstMinter,
789
+ apiClient,
790
+ publicClient,
791
+ }: MakeMintParametersArguments & {
792
+ apiClient: PremintAPIClient;
793
+ publicClient: PublicClient;
794
+ }): Promise<
795
+ SimulateContractParameters<
796
+ typeof zoraCreator1155PremintExecutorImplABI,
797
+ "premintV1" | "premintV2",
798
+ any,
799
+ any,
800
+ any,
801
+ Account | Address
802
+ >
803
+ > {
804
+ if (mintArguments && mintArguments?.quantityToMint < 1) {
805
+ throw new Error("Quantity to mint cannot be below 1");
806
+ }
807
+
808
+ if (!minterAccount) {
809
+ throw new Error("Wallet not passed in");
810
+ }
811
+
812
+ const {
813
+ premintConfig,
814
+ premintConfigVersion,
815
+ collection,
816
+ collectionAddress,
817
+ signature,
818
+ } = await apiClient.getSignature({
819
+ collectionAddress: tokenContract,
820
+ uid,
821
+ });
822
+
823
+ const numberToMint = BigInt(mintArguments?.quantityToMint || 1);
824
+
825
+ if (premintConfigVersion === PremintConfigVersion.V3) {
826
+ throw new Error("PremintV3 not supported in premint SDK");
827
+ }
828
+
829
+ const value = (
830
+ await getPremintMintCosts({
831
+ tokenContract,
832
+ quantityToMint: numberToMint,
833
+ publicClient,
834
+ tokenPrice: premintConfig.tokenConfig.pricePerToken,
835
+ })
836
+ ).totalCost;
837
+
838
+ const mintArgumentsContract: PremintMintArguments = {
839
+ mintComment: mintArguments?.mintComment || "",
840
+ mintRecipient:
841
+ mintArguments?.mintRecipient ||
842
+ (typeof minterAccount === "string"
843
+ ? minterAccount
844
+ : minterAccount.address),
845
+ mintRewardsRecipients: makeMintRewardsRecipient({
846
+ mintReferral: mintArguments?.mintReferral,
847
+ }),
848
+ };
849
+
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({
871
+ premintConfig,
872
+ premintConfigVersion,
873
+ }),
874
+ signature,
875
+ numberToMint,
876
+ mintArgumentsContract,
877
+ firstMinterToSubmit,
878
+ zeroAddress,
879
+ ],
880
+ });
613
881
  }
614
882
 
615
- function makeUrls({
883
+ export function makeUrls({
616
884
  uid,
617
885
  address,
618
886
  tokenId,
@@ -647,66 +915,3 @@ function makeUrls({
647
915
  }:${address}/${zoraTokenPath}`,
648
916
  };
649
917
  }
650
-
651
- type SignAndSubmitPremintParams<T extends PremintConfigVersion> = {
652
- walletClient: WalletClient;
653
- verifyingContract: Address;
654
- checkSignature: boolean;
655
- account?: Address | Account;
656
- collection: ContractCreationConfig;
657
- } & PremintConfigWithVersion<T>;
658
-
659
- async function signAndSubmitPremint<T extends PremintConfigVersion>({
660
- walletClient,
661
- verifyingContract,
662
- account,
663
- checkSignature,
664
- collection,
665
- chainId,
666
- publicClient,
667
- apiClient,
668
- ...premintConfigAndVersion
669
- }: SignAndSubmitPremintParams<T> & {
670
- chainId: number;
671
- publicClient: PublicClient;
672
- apiClient: PremintAPIClient;
673
- }) {
674
- if (!account) {
675
- account = walletClient.account;
676
- }
677
- if (!account) {
678
- throw new Error("No account provided");
679
- }
680
-
681
- const signature = await walletClient.signTypedData({
682
- account,
683
- ...premintTypedDataDefinition({
684
- verifyingContract,
685
- ...premintConfigAndVersion,
686
- chainId,
687
- }),
688
- });
689
-
690
- if (checkSignature) {
691
- const isAuthorized = await isAuthorizedToCreatePremint({
692
- collection,
693
- publicClient,
694
- signer: typeof account === "string" ? account : account.address,
695
- collectionAddress: await getPremintCollectionAddress({
696
- collection,
697
- publicClient,
698
- }),
699
- });
700
- if (!isAuthorized) {
701
- throw new Error("Not authorized to create premint");
702
- }
703
- }
704
-
705
- const premint = await apiClient.postSignature({
706
- collection: collection,
707
- signature: signature,
708
- ...premintConfigAndVersion,
709
- });
710
-
711
- return { premint, verifyingContract };
712
- }