@zoralabs/protocol-sdk 0.5.17 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/CHANGELOG.md +13 -0
  3. package/README.md +1 -416
  4. package/dist/create/1155-create-helper.d.ts +16 -55
  5. package/dist/create/1155-create-helper.d.ts.map +1 -1
  6. package/dist/create/contract-setup.d.ts +14 -0
  7. package/dist/create/contract-setup.d.ts.map +1 -0
  8. package/dist/create/token-setup.d.ts +27 -0
  9. package/dist/create/token-setup.d.ts.map +1 -0
  10. package/dist/create/types.d.ts +45 -0
  11. package/dist/create/types.d.ts.map +1 -0
  12. package/dist/index.cjs +1273 -857
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.ts +3 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1233 -831
  17. package/dist/index.js.map +1 -1
  18. package/dist/mint/mint-client.d.ts +4083 -43
  19. package/dist/mint/mint-client.d.ts.map +1 -1
  20. package/dist/mint/subgraph-mint-getter.d.ts +17 -0
  21. package/dist/mint/subgraph-mint-getter.d.ts.map +1 -0
  22. package/dist/mint/types.d.ts +79 -0
  23. package/dist/mint/types.d.ts.map +1 -0
  24. package/dist/mints/mints-contracts.d.ts +24 -24
  25. package/dist/premint/contract-types.d.ts +4 -4
  26. package/dist/premint/contract-types.d.ts.map +1 -1
  27. package/dist/premint/conversions.d.ts +3 -1
  28. package/dist/premint/conversions.d.ts.map +1 -1
  29. package/dist/premint/premint-api-client.d.ts +27 -14
  30. package/dist/premint/premint-api-client.d.ts.map +1 -1
  31. package/dist/premint/premint-client.d.ts +62 -46
  32. package/dist/premint/premint-client.d.ts.map +1 -1
  33. package/dist/premint/preminter.d.ts +19 -7
  34. package/dist/premint/preminter.d.ts.map +1 -1
  35. package/dist/sdk.d.ts +43 -0
  36. package/dist/sdk.d.ts.map +1 -0
  37. package/dist/utils.d.ts +17 -6870
  38. package/dist/utils.d.ts.map +1 -1
  39. package/package.json +3 -2
  40. package/src/create/1155-create-helper.test.ts +235 -56
  41. package/src/create/1155-create-helper.ts +141 -309
  42. package/src/create/contract-setup.ts +88 -0
  43. package/src/create/token-setup.ts +379 -0
  44. package/src/create/types.ts +57 -0
  45. package/src/index.ts +5 -1
  46. package/src/mint/mint-client.test.ts +50 -61
  47. package/src/mint/mint-client.ts +321 -157
  48. package/src/mint/{mint-api-client.ts → subgraph-mint-getter.ts} +2 -25
  49. package/src/mint/types.ts +122 -0
  50. package/src/mints/mints-contracts.test.ts +1 -1
  51. package/src/mints/mints-contracts.ts +4 -4
  52. package/src/premint/contract-types.ts +4 -4
  53. package/src/premint/conversions.ts +12 -2
  54. package/src/premint/premint-api-client.ts +55 -43
  55. package/src/premint/premint-client.test.ts +75 -65
  56. package/src/premint/premint-client.ts +126 -153
  57. package/src/premint/preminter.test.ts +4 -5
  58. package/src/premint/preminter.ts +63 -13
  59. package/src/sdk.ts +98 -0
  60. package/src/utils.ts +30 -23
  61. package/test-integration/premint-client.test.ts +8 -8
  62. package/dist/mint/mint-api-client.d.ts +0 -35
  63. package/dist/mint/mint-api-client.d.ts.map +0 -1
@@ -2,177 +2,24 @@ import {
2
2
  zoraCreator1155FactoryImplABI,
3
3
  zoraCreator1155FactoryImplAddress,
4
4
  zoraCreator1155ImplABI,
5
- zoraCreatorFixedPriceSaleStrategyABI,
6
5
  } from "@zoralabs/protocol-deployments";
7
6
  import type {
8
7
  Account,
9
8
  Address,
10
9
  Hex,
10
+ PublicClient,
11
11
  SimulateContractParameters,
12
12
  TransactionReceipt,
13
13
  } from "viem";
14
- import { decodeEventLog, encodeFunctionData, zeroAddress } from "viem";
15
- import { OPEN_EDITION_MINT_SIZE } from "../constants";
16
- import {
17
- makeSimulateContractParamaters,
18
- ClientConfig,
19
- PublicClient,
20
- setupClient,
21
- } from "src/utils";
22
-
23
- // Sales end forever amount (uint64 max)
24
- const SALE_END_FOREVER = 18446744073709551615n;
14
+ import { decodeEventLog } from "viem";
15
+ import { makeContractParameters } from "src/utils";
16
+ import { getContractInfo } from "./contract-setup";
17
+ import { ContractType, CreateNew1155Params, New1155Token } from "./types";
18
+ import { constructCreate1155TokenCalls } from "./token-setup";
25
19
 
26
20
  // Default royalty bps
27
21
  const ROYALTY_BPS_DEFAULT = 1000;
28
22
 
29
- type SalesConfigParamsType = {
30
- // defaults to 0
31
- pricePerToken?: bigint;
32
- // defaults to 0, in seconds
33
- saleStart?: bigint;
34
- // defaults to forever, in seconds
35
- saleEnd?: bigint;
36
- // max tokens that can be minted per address
37
- maxTokensPerAddress?: bigint;
38
- fundsRecipient?: Address;
39
- };
40
-
41
- export const DEFAULT_SALE_SETTINGS = {
42
- fundsRecipient: zeroAddress,
43
- // Free Mint
44
- pricePerToken: 0n,
45
- // Sale start time – defaults to beginning of unix time
46
- saleStart: 0n,
47
- // This is the end of uint64, plenty of time
48
- saleEnd: SALE_END_FOREVER,
49
- // 0 Here means no limit
50
- maxTokensPerAddress: 0n,
51
- };
52
-
53
- // Hardcode the permission bit for the minter
54
- const PERMISSION_BIT_MINTER = 4n;
55
-
56
- type ContractType =
57
- | {
58
- name: string;
59
- uri: string;
60
- defaultAdmin?: Address;
61
- }
62
- | Address;
63
-
64
- type RoyaltySettingsType = {
65
- royaltyBPS: number;
66
- royaltyRecipient: Address;
67
- };
68
-
69
- export function create1155TokenSetupArgs({
70
- nextTokenId,
71
- // How many NFTs upon initialization to mint to the creator
72
- mintToCreatorCount,
73
- tokenMetadataURI,
74
- // Fixed price minter address – required minter
75
- fixedPriceMinterAddress,
76
- // Address to use as the create referral, optional.
77
- createReferral,
78
- // Optional max supply of the token. Default unlimited
79
- maxSupply,
80
- // wallet sending the transaction
81
- account,
82
- salesConfig,
83
- royaltySettings,
84
- }: {
85
- maxSupply?: bigint | number;
86
- createReferral?: Address;
87
- nextTokenId: bigint;
88
- mintToCreatorCount: bigint | number;
89
- // wallet sending the transaction
90
- account: Address;
91
- tokenMetadataURI: string;
92
- fixedPriceMinterAddress: Address;
93
- salesConfig: SalesConfigParamsType;
94
- royaltySettings?: RoyaltySettingsType;
95
- }) {
96
- if (!maxSupply) {
97
- maxSupply = OPEN_EDITION_MINT_SIZE;
98
- }
99
- maxSupply = BigInt(maxSupply);
100
- mintToCreatorCount = BigInt(mintToCreatorCount);
101
-
102
- const salesConfigWithDefaults = {
103
- // Set static sales default.
104
- ...DEFAULT_SALE_SETTINGS,
105
- // Override with user settings.
106
- ...salesConfig,
107
- };
108
-
109
- const setupActions = [
110
- encodeFunctionData({
111
- abi: zoraCreator1155ImplABI,
112
- functionName: "assumeLastTokenIdMatches",
113
- args: [nextTokenId - 1n],
114
- }),
115
- createReferral
116
- ? encodeFunctionData({
117
- abi: zoraCreator1155ImplABI,
118
- functionName: "setupNewTokenWithCreateReferral",
119
- args: [tokenMetadataURI, maxSupply, createReferral],
120
- })
121
- : encodeFunctionData({
122
- abi: zoraCreator1155ImplABI,
123
- functionName: "setupNewToken",
124
- args: [tokenMetadataURI, maxSupply],
125
- }),
126
- encodeFunctionData({
127
- abi: zoraCreator1155ImplABI,
128
- functionName: "addPermission",
129
- args: [0n, fixedPriceMinterAddress, PERMISSION_BIT_MINTER],
130
- }),
131
- encodeFunctionData({
132
- abi: zoraCreator1155ImplABI,
133
- functionName: "callSale",
134
- args: [
135
- nextTokenId,
136
- fixedPriceMinterAddress,
137
- encodeFunctionData({
138
- abi: zoraCreatorFixedPriceSaleStrategyABI,
139
- functionName: "setSale",
140
- args: [nextTokenId, salesConfigWithDefaults],
141
- }),
142
- ],
143
- }),
144
- ];
145
-
146
- if (mintToCreatorCount) {
147
- setupActions.push(
148
- encodeFunctionData({
149
- abi: zoraCreator1155ImplABI,
150
- functionName: "adminMint",
151
- args: [account, nextTokenId, mintToCreatorCount, "0x"],
152
- }),
153
- );
154
- }
155
-
156
- if (royaltySettings) {
157
- setupActions.push(
158
- encodeFunctionData({
159
- abi: zoraCreator1155ImplABI,
160
- functionName: "updateRoyaltiesForToken",
161
- args: [
162
- nextTokenId,
163
- {
164
- royaltyMintSchedule: 0,
165
- royaltyBPS: royaltySettings?.royaltyBPS || ROYALTY_BPS_DEFAULT,
166
- royaltyRecipient: royaltySettings?.royaltyRecipient || account,
167
- },
168
- ],
169
- }),
170
- );
171
- }
172
-
173
- return setupActions;
174
- }
175
-
176
23
  export const getTokenIdFromCreateReceipt = (
177
24
  receipt: TransactionReceipt,
178
25
  ): bigint | undefined => {
@@ -190,50 +37,8 @@ export const getTokenIdFromCreateReceipt = (
190
37
  }
191
38
  };
192
39
 
193
- async function getContractExists(
194
- publicClient: PublicClient,
195
- contract: ContractType,
196
- // Account that is the creator of the contract
197
- account: Address,
198
- ) {
199
- let contractAddress;
200
- let contractExists = false;
201
- if (typeof contract !== "string") {
202
- contractAddress = await publicClient.readContract({
203
- abi: zoraCreator1155FactoryImplABI,
204
- // Since this address is deterministic we can hardcode a chain id safely here.
205
- address: zoraCreator1155FactoryImplAddress[999],
206
- functionName: "deterministicContractAddress",
207
- args: [
208
- account,
209
- contract.uri,
210
- contract.name,
211
- contract.defaultAdmin || account,
212
- ],
213
- });
214
-
215
- try {
216
- await publicClient.readContract({
217
- abi: zoraCreator1155ImplABI,
218
- address: contractAddress,
219
- functionName: "contractVersion",
220
- });
221
- contractExists = true;
222
- } catch (e: any) {
223
- // This logic branch is hit if the contract doesn't exist
224
- // falling back to contractExists to false.
225
- }
226
- return { contractAddress, contractExists };
227
- }
228
-
229
- return {
230
- contractExists: true,
231
- contractAddress: contract,
232
- };
233
- }
234
-
235
40
  type CreateNew1155TokenReturn = {
236
- request: SimulateContractParameters<
41
+ parameters: SimulateContractParameters<
237
42
  any,
238
43
  any,
239
44
  any,
@@ -242,125 +47,152 @@ type CreateNew1155TokenReturn = {
242
47
  Account | Address
243
48
  >;
244
49
  tokenSetupActions: Hex[];
245
- contractAddress: Address;
50
+ collectionAddress: Address;
51
+ newTokenId: bigint;
52
+ newToken: New1155Token;
53
+ minter: Address;
246
54
  contractExists: boolean;
247
55
  };
248
56
 
249
- export function create1155CreatorClient(clientConfig: ClientConfig) {
250
- const { publicClient } = setupClient(clientConfig);
251
- async function createNew1155Token({
252
- contract,
253
- tokenMetadataURI,
254
- mintToCreatorCount = 1,
255
- salesConfig = {},
256
- maxSupply,
257
- account,
258
- royaltySettings,
259
- createReferral,
260
- getAdditionalSetupActions,
261
- }: {
262
- account: Address;
263
- maxSupply?: bigint | number;
264
- royaltySettings?: RoyaltySettingsType;
265
- royaltyBPS?: number;
266
- contract: ContractType;
267
- tokenMetadataURI: string;
268
- mintToCreatorCount?: bigint | number;
269
- salesConfig?: SalesConfigParamsType;
270
- createReferral?: Address;
271
- getAdditionalSetupActions?: (args: {
272
- tokenId: bigint;
273
- contractAddress: Address;
274
- }) => Hex[];
275
- }): Promise<CreateNew1155TokenReturn> {
276
- // Check if contract exists either from metadata or the static address passed in.
277
- // If a static address is passed in, this fails if that contract does not exist.
278
- const { contractExists, contractAddress } = await getContractExists(
279
- publicClient,
280
- contract,
281
- account,
282
- );
283
-
284
- // Assume the next token id is the first token available for a new contract.
285
- let nextTokenId = 1n;
57
+ function makeCreateContractAndTokenCall({
58
+ contractExists,
59
+ contractAddress,
60
+ contract,
61
+ account,
62
+ royaltyBPS,
63
+ tokenSetupActions,
64
+ fundsRecipient,
65
+ }: {
66
+ contractExists: boolean;
67
+ contractAddress: Address;
68
+ contract: ContractType;
69
+ account: Address | Account;
70
+ royaltyBPS?: number;
71
+ fundsRecipient?: Address;
72
+ tokenSetupActions: Hex[];
73
+ }) {
74
+ if (!contractAddress && typeof contract === "string") {
75
+ throw new Error("Invariant: contract cannot be missing and an address");
76
+ }
286
77
 
287
- if (contractExists) {
288
- nextTokenId = await publicClient.readContract({
289
- abi: zoraCreator1155ImplABI,
290
- functionName: "nextTokenId",
291
- address: contractAddress,
292
- });
78
+ if (!contractExists) {
79
+ if (typeof contract === "string") {
80
+ throw new Error("Invariant: expected contract object");
293
81
  }
294
82
 
295
- // Get the fixed price minter to use within the new token to set the sales configuration.
296
- const fixedPriceMinterAddress = await publicClient.readContract({
83
+ const accountAddress =
84
+ typeof account === "string" ? account : account.address;
85
+ return makeContractParameters({
297
86
  abi: zoraCreator1155FactoryImplABI,
87
+ functionName: "createContractDeterministic",
88
+ account,
298
89
  address: zoraCreator1155FactoryImplAddress[999],
299
- functionName: "fixedPriceMinter",
90
+ args: [
91
+ contract.uri,
92
+ contract.name,
93
+ {
94
+ // deprecated
95
+ royaltyMintSchedule: 0,
96
+ royaltyBPS: royaltyBPS || ROYALTY_BPS_DEFAULT,
97
+ royaltyRecipient: fundsRecipient || accountAddress,
98
+ },
99
+ contract.defaultAdmin || accountAddress,
100
+ tokenSetupActions,
101
+ ],
300
102
  });
103
+ }
104
+
105
+ return makeContractParameters({
106
+ abi: zoraCreator1155ImplABI,
107
+ functionName: "multicall",
108
+ account,
109
+ address: contractAddress,
110
+ args: [tokenSetupActions],
111
+ });
112
+ }
113
+
114
+ export class Create1155Client {
115
+ private readonly chainId: number;
116
+ private readonly publicClient: Pick<PublicClient, "readContract">;
301
117
 
302
- let tokenSetupActions = create1155TokenSetupArgs({
303
- tokenMetadataURI,
304
- nextTokenId,
305
- salesConfig,
306
- maxSupply,
307
- fixedPriceMinterAddress,
118
+ constructor({
119
+ chainId,
120
+ publicClient,
121
+ }: {
122
+ chainId: number;
123
+ publicClient: Pick<PublicClient, "readContract">;
124
+ }) {
125
+ this.chainId = chainId;
126
+ this.publicClient = publicClient;
127
+ }
128
+
129
+ async createNew1155Token(props: CreateNew1155Params) {
130
+ return createNew1155Token({
131
+ ...props,
132
+ publicClient: this.publicClient,
133
+ chainId: this.chainId,
134
+ });
135
+ }
136
+ }
137
+
138
+ async function createNew1155Token({
139
+ contract,
140
+ account,
141
+ getAdditionalSetupActions,
142
+ token: tokenConfig,
143
+ publicClient,
144
+ chainId,
145
+ }: CreateNew1155Params & {
146
+ publicClient: Pick<PublicClient, "readContract">;
147
+ chainId: number;
148
+ }): Promise<CreateNew1155TokenReturn> {
149
+ const { contractExists, contractAddress, nextTokenId, contractVersion } =
150
+ await getContractInfo({
151
+ publicClient,
152
+ chainId: chainId,
153
+ contract,
308
154
  account,
309
- mintToCreatorCount,
310
- royaltySettings,
311
- createReferral,
312
155
  });
313
- if (getAdditionalSetupActions) {
314
- tokenSetupActions = [
315
- ...getAdditionalSetupActions({ tokenId: nextTokenId, contractAddress }),
156
+
157
+ const {
158
+ minter,
159
+ newToken,
160
+ setupActions: tokenSetupActions,
161
+ } = constructCreate1155TokenCalls({
162
+ chainId: chainId,
163
+ ownerAddress: account,
164
+ contractVersion,
165
+ nextTokenId,
166
+ ...tokenConfig,
167
+ });
168
+
169
+ const setupActions = getAdditionalSetupActions
170
+ ? [
171
+ ...getAdditionalSetupActions({
172
+ tokenId: nextTokenId,
173
+ contractAddress,
174
+ }),
316
175
  ...tokenSetupActions,
317
- ];
318
- }
176
+ ]
177
+ : tokenSetupActions;
319
178
 
320
- if (!contractAddress && typeof contract === "string") {
321
- throw new Error("Invariant: contract cannot be missing and an address");
322
- }
323
- if (!contractExists && typeof contract !== "string") {
324
- const request = makeSimulateContractParamaters({
325
- abi: zoraCreator1155FactoryImplABI,
326
- functionName: "createContractDeterministic",
327
- account,
328
- address: zoraCreator1155FactoryImplAddress[999],
329
- args: [
330
- contract.uri,
331
- contract.name,
332
- {
333
- // deprecated
334
- royaltyMintSchedule: 0,
335
- royaltyBPS: royaltySettings?.royaltyBPS || ROYALTY_BPS_DEFAULT,
336
- royaltyRecipient: royaltySettings?.royaltyRecipient || account,
337
- },
338
- contract.defaultAdmin || account,
339
- tokenSetupActions,
340
- ],
341
- });
342
- return {
343
- request,
344
- tokenSetupActions,
345
- contractAddress,
346
- contractExists,
347
- };
348
- } else if (contractExists) {
349
- const request = makeSimulateContractParamaters({
350
- abi: zoraCreator1155ImplABI,
351
- functionName: "multicall",
352
- account,
353
- address: contractAddress,
354
- args: [tokenSetupActions],
355
- });
356
- return {
357
- request,
358
- tokenSetupActions,
359
- contractAddress,
360
- contractExists,
361
- };
362
- }
363
- throw new Error("Unsupported contract argument type");
364
- }
365
- return { createNew1155Token };
179
+ const request = makeCreateContractAndTokenCall({
180
+ contractExists,
181
+ contractAddress,
182
+ contract,
183
+ account,
184
+ tokenSetupActions: setupActions,
185
+ royaltyBPS: tokenConfig.royaltyBPS,
186
+ fundsRecipient: tokenConfig.payoutRecipient,
187
+ });
188
+
189
+ return {
190
+ parameters: request,
191
+ tokenSetupActions,
192
+ collectionAddress: contractAddress,
193
+ contractExists,
194
+ newTokenId: nextTokenId,
195
+ newToken,
196
+ minter,
197
+ };
366
198
  }
@@ -0,0 +1,88 @@
1
+ import { Address, PublicClient } from "viem";
2
+ import { ContractType } from "./types";
3
+ import {
4
+ contracts1155,
5
+ zoraCreator1155FactoryImplABI,
6
+ zoraCreator1155FactoryImplAddress,
7
+ zoraCreator1155ImplABI,
8
+ } from "@zoralabs/protocol-deployments";
9
+
10
+ type contracts1155Address = keyof typeof contracts1155.addresses;
11
+ function new1155ContractVersion(chainId: number): string {
12
+ const address = contracts1155.addresses[chainId as contracts1155Address];
13
+ if (!address) {
14
+ throw new Error(`No contract address for chainId ${chainId}`);
15
+ }
16
+
17
+ return address.CONTRACT_1155_IMPL_VERSION;
18
+ }
19
+
20
+ export async function getContractInfo({
21
+ publicClient,
22
+ chainId,
23
+ contract,
24
+ account,
25
+ }: {
26
+ publicClient: Pick<PublicClient, "readContract">;
27
+ chainId: number;
28
+ contract: ContractType;
29
+ // Account that is the creator of the contract
30
+ account: Address;
31
+ }): Promise<{
32
+ contractExists: boolean;
33
+ contractAddress: Address;
34
+ contractVersion: string;
35
+ nextTokenId: bigint;
36
+ }> {
37
+ // Check if contract exists either from metadata or the static address passed in.
38
+ // If a static address is passed in, this fails if that contract does not exist.
39
+ const contractAddress =
40
+ typeof contract === "string"
41
+ ? contract
42
+ : await publicClient.readContract({
43
+ abi: zoraCreator1155FactoryImplABI,
44
+ // Since this address is deterministic we can hardcode a chain id safely here.
45
+ address:
46
+ zoraCreator1155FactoryImplAddress[
47
+ chainId as keyof typeof zoraCreator1155FactoryImplAddress
48
+ ],
49
+ functionName: "deterministicContractAddress",
50
+ args: [
51
+ account,
52
+ contract.uri,
53
+ contract.name,
54
+ contract.defaultAdmin || account,
55
+ ],
56
+ });
57
+
58
+ let contractVersion: string;
59
+ let contractExists: boolean;
60
+ try {
61
+ contractVersion = await publicClient.readContract({
62
+ abi: zoraCreator1155ImplABI,
63
+ address: contractAddress,
64
+ functionName: "contractVersion",
65
+ });
66
+ contractExists = true;
67
+ } catch (e: any) {
68
+ // This logic branch is hit if the contract doesn't exist
69
+ // falling back to contractExists to false.
70
+ contractVersion = new1155ContractVersion(chainId);
71
+ contractExists = false;
72
+ }
73
+
74
+ const nextTokenId = contractExists
75
+ ? await publicClient.readContract({
76
+ address: contractAddress,
77
+ abi: zoraCreator1155ImplABI,
78
+ functionName: "nextTokenId",
79
+ })
80
+ : 1n;
81
+
82
+ return {
83
+ contractExists,
84
+ contractAddress,
85
+ contractVersion,
86
+ nextTokenId,
87
+ };
88
+ }