@zoralabs/protocol-sdk 0.5.17 → 0.7.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 (84) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/CHANGELOG.md +19 -0
  3. package/README.md +1 -416
  4. package/dist/constants.d.ts +0 -1
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/create/1155-create-helper.d.ts +16 -55
  7. package/dist/create/1155-create-helper.d.ts.map +1 -1
  8. package/dist/create/contract-setup.d.ts +14 -0
  9. package/dist/create/contract-setup.d.ts.map +1 -0
  10. package/dist/create/token-setup.d.ts +27 -0
  11. package/dist/create/token-setup.d.ts.map +1 -0
  12. package/dist/create/types.d.ts +45 -0
  13. package/dist/create/types.d.ts.map +1 -0
  14. package/dist/index.cjs +1745 -891
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.ts +3 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +1698 -858
  19. package/dist/index.js.map +1 -1
  20. package/dist/mint/mint-client.d.ts +48 -51
  21. package/dist/mint/mint-client.d.ts.map +1 -1
  22. package/dist/mint/mint-queries.d.ts +38 -0
  23. package/dist/mint/mint-queries.d.ts.map +1 -0
  24. package/dist/mint/mint-transactions.d.ts +20 -0
  25. package/dist/mint/mint-transactions.d.ts.map +1 -0
  26. package/dist/mint/subgraph-mint-getter.d.ts +24 -0
  27. package/dist/mint/subgraph-mint-getter.d.ts.map +1 -0
  28. package/dist/mint/subgraph-queries.d.ts +55 -0
  29. package/dist/mint/subgraph-queries.d.ts.map +1 -0
  30. package/dist/mint/types.d.ts +177 -0
  31. package/dist/mint/types.d.ts.map +1 -0
  32. package/dist/mint/utils.d.ts +2 -0
  33. package/dist/mint/utils.d.ts.map +1 -0
  34. package/dist/mints/mints-contracts.d.ts +27 -4518
  35. package/dist/mints/mints-contracts.d.ts.map +1 -1
  36. package/dist/premint/contract-types.d.ts +4 -4
  37. package/dist/premint/contract-types.d.ts.map +1 -1
  38. package/dist/premint/conversions.d.ts +15 -16
  39. package/dist/premint/conversions.d.ts.map +1 -1
  40. package/dist/premint/premint-api-client.d.ts +32 -16
  41. package/dist/premint/premint-api-client.d.ts.map +1 -1
  42. package/dist/premint/premint-client.d.ts +76 -50
  43. package/dist/premint/premint-client.d.ts.map +1 -1
  44. package/dist/premint/preminter.d.ts +20 -8
  45. package/dist/premint/preminter.d.ts.map +1 -1
  46. package/dist/sdk.d.ts +45 -0
  47. package/dist/sdk.d.ts.map +1 -0
  48. package/dist/types.d.ts +3 -0
  49. package/dist/types.d.ts.map +1 -1
  50. package/dist/utils.d.ts +24 -6869
  51. package/dist/utils.d.ts.map +1 -1
  52. package/package.json +3 -2
  53. package/src/constants.ts +0 -36
  54. package/src/create/1155-create-helper.test.ts +236 -55
  55. package/src/create/1155-create-helper.ts +141 -309
  56. package/src/create/contract-setup.ts +88 -0
  57. package/src/create/token-setup.ts +379 -0
  58. package/src/create/types.ts +57 -0
  59. package/src/index.ts +5 -1
  60. package/src/mint/mint-client.test.ts +116 -78
  61. package/src/mint/mint-client.ts +130 -234
  62. package/src/mint/mint-queries.ts +320 -0
  63. package/src/mint/mint-transactions.ts +253 -0
  64. package/src/mint/subgraph-mint-getter.ts +247 -0
  65. package/src/mint/subgraph-queries.ts +170 -0
  66. package/src/mint/types.ts +239 -0
  67. package/src/mint/utils.ts +14 -0
  68. package/src/mints/mints-contracts.test.ts +1 -1
  69. package/src/mints/mints-contracts.ts +4 -4
  70. package/src/premint/contract-types.ts +4 -4
  71. package/src/premint/conversions.ts +38 -4
  72. package/src/premint/premint-api-client.ts +92 -48
  73. package/src/premint/premint-client.test.ts +100 -84
  74. package/src/premint/premint-client.ts +186 -185
  75. package/src/premint/preminter.test.ts +4 -5
  76. package/src/premint/preminter.ts +63 -14
  77. package/src/sdk.ts +101 -0
  78. package/src/types.ts +18 -0
  79. package/src/utils.ts +54 -46
  80. package/test-integration/setup-test-contracts.ts +96 -0
  81. package/dist/mint/mint-api-client.d.ts +0 -35
  82. package/dist/mint/mint-api-client.d.ts.map +0 -1
  83. package/src/mint/mint-api-client.ts +0 -177
  84. package/test-integration/premint-client.test.ts +0 -148
@@ -0,0 +1,379 @@
1
+ import {
2
+ erc20MinterABI,
3
+ erc20MinterAddress as erc20MinterAddresses,
4
+ zoraCreator1155ImplABI,
5
+ zoraCreatorFixedPriceSaleStrategyABI,
6
+ zoraCreatorFixedPriceSaleStrategyAddress,
7
+ } from "@zoralabs/protocol-deployments";
8
+ import { Address, encodeFunctionData, zeroAddress, Hex } from "viem";
9
+ import * as semver from "semver";
10
+ import {
11
+ ContractProps,
12
+ CreateNew1155TokenProps,
13
+ New1155Token,
14
+ SalesConfigParamsType,
15
+ } from "./types";
16
+ import { OPEN_EDITION_MINT_SIZE } from "src/constants";
17
+ import { Concrete } from "src/utils";
18
+
19
+ export const PERMISSION_BITS = {
20
+ MINTER: 2n ** 2n,
21
+ };
22
+
23
+ type SetupMintersProps = {
24
+ tokenId: bigint;
25
+ chainId: number;
26
+ fundsRecipient: Address;
27
+ salesConfig: Concrete<SalesConfigParamsType>;
28
+ };
29
+
30
+ // Sales end forever amount (uint64 max)
31
+
32
+ const saleSettingsOrDefault = (
33
+ saleSettings?: SalesConfigParamsType,
34
+ ): Concrete<SalesConfigParamsType> => {
35
+ const SALE_END_FOREVER = 18446744073709551615n;
36
+
37
+ const DEFAULT_SALE_SETTINGS: Concrete<SalesConfigParamsType> = {
38
+ currency: zeroAddress,
39
+ // Free Mint
40
+ pricePerToken: 0n,
41
+ // Sale start time – defaults to beginning of unix time
42
+ saleStart: 0n,
43
+ // This is the end of uint64, plenty of time
44
+ saleEnd: SALE_END_FOREVER,
45
+ // 0 Here means no limit
46
+ maxTokensPerAddress: 0n,
47
+ };
48
+ return {
49
+ ...DEFAULT_SALE_SETTINGS,
50
+ ...saleSettings,
51
+ };
52
+ };
53
+
54
+ function applyNew1155Defaults(
55
+ props: CreateNew1155TokenProps,
56
+ ownerAddress: Address,
57
+ ): New1155Token {
58
+ const { payoutRecipient: fundsRecipient } = props;
59
+ const fundsRecipientOrOwner =
60
+ fundsRecipient && fundsRecipient !== zeroAddress
61
+ ? fundsRecipient
62
+ : ownerAddress;
63
+ return {
64
+ payoutRecipient: fundsRecipientOrOwner,
65
+ createReferral: props.createReferral || zeroAddress,
66
+ maxSupply:
67
+ typeof props.maxSupply === "undefined"
68
+ ? OPEN_EDITION_MINT_SIZE
69
+ : BigInt(props.maxSupply),
70
+ royaltyBPS: props.royaltyBPS || 1000,
71
+ salesConfig: saleSettingsOrDefault(props.salesConfig),
72
+ tokenMetadataURI: props.tokenMetadataURI,
73
+ };
74
+ }
75
+
76
+ type SetupErc20MinterProps = {
77
+ chainId: number;
78
+ tokenId: bigint;
79
+ fundsRecipient: Address;
80
+ } & Concrete<SalesConfigParamsType>;
81
+
82
+ function setupErc20Minter({
83
+ pricePerToken,
84
+ chainId,
85
+ tokenId: nextTokenId,
86
+ currency,
87
+ saleStart,
88
+ saleEnd,
89
+ maxTokensPerAddress: mintLimit,
90
+ fundsRecipient,
91
+ }: SetupErc20MinterProps): {
92
+ minter: Address;
93
+ setupActions: Hex[];
94
+ } {
95
+ const erc20MinterAddress =
96
+ erc20MinterAddresses[chainId as keyof typeof erc20MinterAddresses];
97
+ if (!erc20MinterAddress)
98
+ throw new Error(`ERC20Minter not deployed on chainId ${chainId}`);
99
+
100
+ const erc20MinterApproval = encodeFunctionData({
101
+ abi: zoraCreator1155ImplABI,
102
+ functionName: "addPermission",
103
+ args: [BigInt(nextTokenId), erc20MinterAddress, PERMISSION_BITS.MINTER],
104
+ });
105
+
106
+ const saleData = encodeFunctionData({
107
+ abi: erc20MinterABI,
108
+ functionName: "setSale",
109
+ args: [
110
+ BigInt(nextTokenId),
111
+ {
112
+ saleStart: saleStart || BigInt(0),
113
+ saleEnd: saleEnd || BigInt(0),
114
+ maxTokensPerAddress: BigInt(mintLimit || 0),
115
+ pricePerToken: pricePerToken,
116
+ fundsRecipient,
117
+ currency: currency,
118
+ },
119
+ ],
120
+ });
121
+
122
+ const callSale = encodeFunctionData({
123
+ abi: zoraCreator1155ImplABI,
124
+ functionName: "callSale",
125
+ args: [BigInt(nextTokenId), erc20MinterAddress, saleData],
126
+ });
127
+
128
+ return {
129
+ minter: erc20MinterAddress,
130
+ setupActions: [erc20MinterApproval, callSale],
131
+ };
132
+ }
133
+
134
+ type SetupFixedPriceMinterProps = {
135
+ fundsRecipient: Address;
136
+ tokenId: bigint;
137
+ chainId: number;
138
+ } & Concrete<Omit<SalesConfigParamsType, "currency">>;
139
+
140
+ function setupFixedPriceMinter({
141
+ pricePerToken: price,
142
+ tokenId: nextTokenId,
143
+ chainId,
144
+ saleStart,
145
+ saleEnd,
146
+ maxTokensPerAddress: mintLimit,
147
+ fundsRecipient,
148
+ }: SetupFixedPriceMinterProps): { minter: Address; setupActions: Hex[] } {
149
+ const fixedPriceStrategyAddress =
150
+ zoraCreatorFixedPriceSaleStrategyAddress[
151
+ chainId as keyof typeof zoraCreatorFixedPriceSaleStrategyAddress
152
+ ];
153
+ const fixedPriceApproval = encodeFunctionData({
154
+ abi: zoraCreator1155ImplABI,
155
+ functionName: "addPermission",
156
+ args: [
157
+ BigInt(nextTokenId),
158
+ fixedPriceStrategyAddress,
159
+ PERMISSION_BITS.MINTER,
160
+ ],
161
+ });
162
+
163
+ const saleData = encodeFunctionData({
164
+ abi: zoraCreatorFixedPriceSaleStrategyABI,
165
+ functionName: "setSale",
166
+ args: [
167
+ BigInt(nextTokenId),
168
+ {
169
+ pricePerToken: price,
170
+ saleStart: saleStart || BigInt(0),
171
+ saleEnd: saleEnd || BigInt(0),
172
+ maxTokensPerAddress: BigInt(mintLimit || 0),
173
+ fundsRecipient,
174
+ },
175
+ ],
176
+ });
177
+
178
+ const callSale = encodeFunctionData({
179
+ abi: zoraCreator1155ImplABI,
180
+ functionName: "callSale",
181
+ args: [BigInt(nextTokenId), fixedPriceStrategyAddress, saleData],
182
+ });
183
+
184
+ return {
185
+ minter: fixedPriceStrategyAddress,
186
+ setupActions: [fixedPriceApproval, callSale],
187
+ };
188
+ }
189
+
190
+ export function setupMinters({ salesConfig, ...rest }: SetupMintersProps): {
191
+ minter: Address;
192
+ setupActions: Hex[];
193
+ } {
194
+ if (!salesConfig) throw new Error("No sales config for token");
195
+ const { currency: currencyAddress } = salesConfig;
196
+
197
+ if (currencyAddress === zeroAddress) {
198
+ return setupFixedPriceMinter({
199
+ ...salesConfig,
200
+ ...rest,
201
+ });
202
+ } else {
203
+ return setupErc20Minter({
204
+ ...salesConfig,
205
+ ...rest,
206
+ });
207
+ }
208
+ }
209
+
210
+ function buildSetupNewToken({
211
+ tokenURI,
212
+ maxSupply = OPEN_EDITION_MINT_SIZE,
213
+ createReferral = zeroAddress,
214
+ contractVersion,
215
+ }: {
216
+ tokenURI: string;
217
+ maxSupply: bigint;
218
+ createReferral: Address;
219
+ contractVersion?: string;
220
+ }): Hex {
221
+ // If we're adding a new token to an existing contract which doesn't support
222
+ // creator rewards, we won't have the 'setupNewTokenWithCreateReferral' method
223
+ // available, so we need to check for that and use the fallback method instead.
224
+ if (contractSupportsMintRewards(contractVersion, "ERC1155")) {
225
+ return encodeFunctionData({
226
+ abi: zoraCreator1155ImplABI,
227
+ functionName: "setupNewTokenWithCreateReferral",
228
+ args: [tokenURI, BigInt(maxSupply), createReferral],
229
+ });
230
+ }
231
+
232
+ if (createReferral !== zeroAddress) {
233
+ throw new Error(
234
+ "Contract does not support create referral, but one was provided",
235
+ );
236
+ }
237
+ return encodeFunctionData({
238
+ abi: zoraCreator1155ImplABI,
239
+ functionName: "setupNewToken",
240
+ args: [tokenURI, BigInt(maxSupply)],
241
+ });
242
+ }
243
+
244
+ function setupRoyaltyConfig({
245
+ royaltyBPS,
246
+ royaltyRecipient,
247
+ nextTokenId,
248
+ }: {
249
+ royaltyBPS: number;
250
+ royaltyRecipient: Address;
251
+ nextTokenId: bigint;
252
+ }) {
253
+ if (royaltyBPS > 0 && royaltyRecipient != zeroAddress) {
254
+ return encodeFunctionData({
255
+ abi: zoraCreator1155ImplABI,
256
+ functionName: "updateRoyaltiesForToken",
257
+ args: [
258
+ nextTokenId,
259
+ {
260
+ royaltyBPS,
261
+ royaltyRecipient,
262
+ royaltyMintSchedule: 0,
263
+ },
264
+ ],
265
+ });
266
+ }
267
+
268
+ return null;
269
+ }
270
+
271
+ function makeAdminMintCall({
272
+ ownerAddress,
273
+ mintQuantity,
274
+ nextTokenId,
275
+ }: {
276
+ ownerAddress: Address;
277
+ mintQuantity?: number;
278
+ nextTokenId: bigint;
279
+ }) {
280
+ if (!mintQuantity || mintQuantity <= 0 || !ownerAddress) {
281
+ return null;
282
+ }
283
+
284
+ return encodeFunctionData({
285
+ abi: zoraCreator1155ImplABI,
286
+ functionName: "adminMint",
287
+ args: [ownerAddress, nextTokenId, BigInt(mintQuantity), zeroAddress],
288
+ });
289
+ }
290
+
291
+ export function constructCreate1155TokenCalls(
292
+ props: CreateNew1155TokenProps &
293
+ ContractProps & {
294
+ ownerAddress: Address;
295
+ chainId: number;
296
+ },
297
+ ): {
298
+ setupActions: `0x${string}`[];
299
+ newToken: New1155Token;
300
+ minter: Address;
301
+ } {
302
+ const {
303
+ chainId,
304
+ nextTokenId,
305
+ mintToCreatorCount,
306
+ ownerAddress,
307
+ contractVersion,
308
+ } = props;
309
+
310
+ const new1155TokenPropsWithDefaults = applyNew1155Defaults(
311
+ props,
312
+ ownerAddress,
313
+ );
314
+
315
+ const verifyTokenIdExpected = encodeFunctionData({
316
+ abi: zoraCreator1155ImplABI,
317
+ functionName: "assumeLastTokenIdMatches",
318
+ args: [nextTokenId - 1n],
319
+ });
320
+
321
+ const setupNewToken = buildSetupNewToken({
322
+ tokenURI: new1155TokenPropsWithDefaults.tokenMetadataURI,
323
+ maxSupply: new1155TokenPropsWithDefaults.maxSupply,
324
+ createReferral: new1155TokenPropsWithDefaults.createReferral,
325
+ contractVersion,
326
+ });
327
+
328
+ const royaltyConfig = setupRoyaltyConfig({
329
+ royaltyBPS: new1155TokenPropsWithDefaults.royaltyBPS,
330
+ royaltyRecipient: new1155TokenPropsWithDefaults.payoutRecipient,
331
+ nextTokenId,
332
+ });
333
+
334
+ const { minter, setupActions: mintersSetup } = setupMinters({
335
+ tokenId: nextTokenId,
336
+ chainId,
337
+ fundsRecipient: new1155TokenPropsWithDefaults.payoutRecipient,
338
+ salesConfig: new1155TokenPropsWithDefaults.salesConfig,
339
+ });
340
+
341
+ const adminMintCall = makeAdminMintCall({
342
+ ownerAddress,
343
+ mintQuantity: mintToCreatorCount,
344
+ nextTokenId,
345
+ });
346
+
347
+ const setupActions = [
348
+ verifyTokenIdExpected,
349
+ setupNewToken,
350
+ ...mintersSetup,
351
+ royaltyConfig,
352
+ adminMintCall,
353
+ ].filter((item) => item !== null) as `0x${string}`[];
354
+
355
+ return {
356
+ setupActions,
357
+ minter,
358
+ newToken: new1155TokenPropsWithDefaults,
359
+ };
360
+ }
361
+
362
+ export const contractSupportsMintRewards = (
363
+ contractVersion?: string | null,
364
+ contractStandard?: "ERC721" | "ERC1155",
365
+ ) => {
366
+ if (!contractStandard || !contractVersion) {
367
+ return false;
368
+ }
369
+
370
+ // Try force-convert version format to semver format
371
+ const semVerContractVersion = semver.coerce(contractVersion)?.raw;
372
+ if (!semVerContractVersion) return false;
373
+
374
+ if (contractStandard === "ERC1155") {
375
+ return semver.gte(semVerContractVersion, "1.3.5");
376
+ } else {
377
+ return semver.gte(semVerContractVersion, "14.0.0");
378
+ }
379
+ };
@@ -0,0 +1,57 @@
1
+ import { Concrete } from "src/utils";
2
+ import { Address, Hex } from "viem";
3
+
4
+ export type ContractType =
5
+ | {
6
+ name: string;
7
+ uri: string;
8
+ defaultAdmin?: Address;
9
+ }
10
+ | Address;
11
+
12
+ export type SalesConfigParamsType = {
13
+ // defaults to 0
14
+ pricePerToken?: bigint;
15
+ // defaults to 0, in seconds
16
+ saleStart?: bigint;
17
+ // defaults to forever, in seconds
18
+ saleEnd?: bigint;
19
+ // max tokens that can be minted per address
20
+ maxTokensPerAddress?: bigint;
21
+ // if an erc20 mint, the erc20 address. Leave null for eth mints
22
+ currency?: Address;
23
+ };
24
+
25
+ export type CreateNew1155Params = {
26
+ account: Address;
27
+ contract: ContractType;
28
+ getAdditionalSetupActions?: (args: {
29
+ tokenId: bigint;
30
+ contractAddress: Address;
31
+ }) => Hex[];
32
+ token: CreateNew1155TokenProps;
33
+ };
34
+
35
+ export interface CreateNew1155TokenProps {
36
+ maxSupply?: bigint | number;
37
+ tokenMetadataURI: string;
38
+ royaltyBPS?: number;
39
+ salesConfig?: SalesConfigParamsType;
40
+ createReferral?: Address;
41
+ mintToCreatorCount?: number;
42
+ payoutRecipient?: Address;
43
+ }
44
+
45
+ export interface ContractProps {
46
+ nextTokenId: bigint;
47
+ contractVersion: string;
48
+ }
49
+
50
+ export type New1155Token = {
51
+ payoutRecipient: Address;
52
+ createReferral: Address;
53
+ maxSupply: bigint;
54
+ royaltyBPS: number;
55
+ salesConfig: Concrete<SalesConfigParamsType>;
56
+ tokenMetadataURI: string;
57
+ };
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ export * from "./premint/premint-api-client";
8
8
 
9
9
  export * from "./premint/conversions";
10
10
 
11
- export * from "./mint/mint-api-client";
11
+ export * from "./mint/subgraph-mint-getter";
12
12
 
13
13
  export * from "./mint/mint-client";
14
14
 
@@ -25,3 +25,7 @@ export {
25
25
  type ContractCreationConfigOrAddress,
26
26
  type ContractCreationConfigAndAddress,
27
27
  } from "./premint/contract-types";
28
+
29
+ export * from "./create/types";
30
+
31
+ export * from "./sdk";