@zoralabs/protocol-sdk 0.8.0 → 0.9.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.
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +11 -0
- package/dist/allow-list/allow-list-client.d.ts +26 -0
- package/dist/allow-list/allow-list-client.d.ts.map +1 -0
- package/dist/allow-list/types.d.ts +14 -0
- package/dist/allow-list/types.d.ts.map +1 -0
- package/dist/apis/generated/allow-list-api-types.d.ts +288 -0
- package/dist/apis/generated/allow-list-api-types.d.ts.map +1 -0
- package/dist/apis/http-api-base.d.ts.map +1 -1
- package/dist/apis/subgraph-querier.d.ts +18 -0
- package/dist/apis/subgraph-querier.d.ts.map +1 -0
- package/dist/create/contract-setup.d.ts +1 -0
- package/dist/create/contract-setup.d.ts.map +1 -1
- package/dist/create/minter-defaults.d.ts +5 -0
- package/dist/create/minter-defaults.d.ts.map +1 -0
- package/dist/create/minter-setup.d.ts +14 -0
- package/dist/create/minter-setup.d.ts.map +1 -0
- package/dist/create/token-setup.d.ts +4 -19
- package/dist/create/token-setup.d.ts.map +1 -1
- package/dist/create/types.d.ts +32 -7
- package/dist/create/types.d.ts.map +1 -1
- package/dist/create/update.d.ts +15 -0
- package/dist/create/update.d.ts.map +1 -0
- package/dist/index.cjs +2249 -1936
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2284 -1966
- package/dist/index.js.map +1 -1
- package/dist/ipfs/token-metadata.d.ts +1 -0
- package/dist/ipfs/token-metadata.d.ts.map +1 -1
- package/dist/mint/mint-client.d.ts +2 -6
- package/dist/mint/mint-client.d.ts.map +1 -1
- package/dist/mint/mint-queries.d.ts +3 -1
- package/dist/mint/mint-queries.d.ts.map +1 -1
- package/dist/mint/mint-transactions.d.ts +9 -7
- package/dist/mint/mint-transactions.d.ts.map +1 -1
- package/dist/mint/subgraph-mint-getter.d.ts +5 -4
- package/dist/mint/subgraph-mint-getter.d.ts.map +1 -1
- package/dist/mint/subgraph-queries.d.ts +42 -15
- package/dist/mint/subgraph-queries.d.ts.map +1 -1
- package/dist/mint/types.d.ts +32 -13
- package/dist/mint/types.d.ts.map +1 -1
- package/dist/sparks/sparks-contracts.d.ts +96 -96
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +1 -8
- package/dist/utils.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/allow-list/allow-list-client.ts +105 -0
- package/src/allow-list/types.ts +15 -0
- package/src/apis/generated/allow-list-api-types.ts +288 -0
- package/src/apis/http-api-base.ts +12 -0
- package/src/apis/subgraph-querier.ts +38 -0
- package/src/create/1155-create-helper.test.ts +216 -66
- package/src/create/1155-create-helper.ts +4 -4
- package/src/create/contract-setup.ts +8 -0
- package/src/create/minter-defaults.test.ts +21 -0
- package/src/create/minter-defaults.ts +134 -0
- package/src/create/minter-setup.ts +293 -0
- package/src/create/token-setup.ts +14 -190
- package/src/create/types.ts +56 -9
- package/src/create/update.ts +93 -0
- package/src/index.ts +4 -0
- package/src/ipfs/token-metadata.ts +18 -0
- package/src/mint/mint-client.test.ts +219 -15
- package/src/mint/mint-client.ts +2 -34
- package/src/mint/mint-queries.ts +34 -13
- package/src/mint/mint-transactions.ts +104 -17
- package/src/mint/subgraph-mint-getter.ts +107 -50
- package/src/mint/subgraph-queries.ts +67 -37
- package/src/mint/types.ts +55 -16
- package/src/premint/premint-client.test.ts +6 -5
- package/src/types.ts +1 -1
- package/src/utils.ts +1 -25
|
@@ -4,18 +4,28 @@ import {
|
|
|
4
4
|
getTokenIdFromCreateReceipt,
|
|
5
5
|
} from "./1155-create-helper";
|
|
6
6
|
import { createCreatorClient } from "src/sdk";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
zoraCreator1155ImplABI,
|
|
9
|
+
zoraTimedSaleStrategyAddress,
|
|
10
|
+
} from "@zoralabs/protocol-deployments";
|
|
8
11
|
import { waitForSuccess } from "src/test-utils";
|
|
9
|
-
import { parseEther } from "viem";
|
|
10
12
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
Address,
|
|
14
|
+
parseEther,
|
|
15
|
+
PublicClient,
|
|
16
|
+
TransactionReceipt,
|
|
17
|
+
zeroAddress,
|
|
18
|
+
} from "viem";
|
|
19
|
+
import { makePrepareMint1155TokenParams } from "src/mint/mint-transactions";
|
|
14
20
|
import { forkUrls, makeAnvilTest } from "src/anvil";
|
|
15
21
|
import { zora } from "viem/chains";
|
|
22
|
+
import { AllowList } from "src/allow-list/types";
|
|
23
|
+
import { createAllowList } from "src/allow-list/allow-list-client";
|
|
24
|
+
import { NewContractParams } from "./types";
|
|
16
25
|
|
|
17
|
-
const demoTokenMetadataURI =
|
|
18
|
-
|
|
26
|
+
export const demoTokenMetadataURI =
|
|
27
|
+
"ipfs://bafkreice23maski3x52tsfqgxstx3kbiifnt5jotg3a5ynvve53c4soi2u";
|
|
28
|
+
export const demoContractMetadataURI = "ipfs://DUMMY/contract.json";
|
|
19
29
|
|
|
20
30
|
const anvilTest = makeAnvilTest({
|
|
21
31
|
forkUrl: forkUrls.zoraMainnet,
|
|
@@ -23,9 +33,46 @@ const anvilTest = makeAnvilTest({
|
|
|
23
33
|
anvilChainId: zora.id,
|
|
24
34
|
});
|
|
25
35
|
|
|
36
|
+
const PERMISSION_BITS = {
|
|
37
|
+
MINTER: 2n ** 2n,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const minterIsMinterOnToken = async ({
|
|
41
|
+
publicClient,
|
|
42
|
+
contractAddress,
|
|
43
|
+
tokenId,
|
|
44
|
+
minter,
|
|
45
|
+
}: {
|
|
46
|
+
publicClient: Pick<PublicClient, "readContract">;
|
|
47
|
+
contractAddress: Address;
|
|
48
|
+
tokenId: bigint;
|
|
49
|
+
minter: Address;
|
|
50
|
+
}) => {
|
|
51
|
+
return await publicClient.readContract({
|
|
52
|
+
abi: zoraCreator1155ImplABI,
|
|
53
|
+
address: contractAddress,
|
|
54
|
+
functionName: "isAdminOrRole",
|
|
55
|
+
args: [minter, tokenId, PERMISSION_BITS.MINTER],
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
function logFailure(receipt: TransactionReceipt) {
|
|
60
|
+
if (receipt.status !== "success") {
|
|
61
|
+
console.log("transaction failed");
|
|
62
|
+
console.log(receipt.logs);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function randomNewContract(): NewContractParams {
|
|
67
|
+
return {
|
|
68
|
+
name: `testContract-${Math.round(Math.random() * 1_000_000)}`,
|
|
69
|
+
uri: demoContractMetadataURI,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
26
73
|
describe("create-helper", () => {
|
|
27
74
|
anvilTest(
|
|
28
|
-
"creates a new 1155 contract and token",
|
|
75
|
+
"when no sales config is provided, it creates a new 1155 contract and token using the timed sale strategy",
|
|
29
76
|
async ({ viemClients: { publicClient, walletClient, chain } }) => {
|
|
30
77
|
const addresses = await walletClient.getAddresses();
|
|
31
78
|
const creatorAddress = addresses[0]!;
|
|
@@ -34,32 +81,89 @@ describe("create-helper", () => {
|
|
|
34
81
|
chainId: chain.id,
|
|
35
82
|
publicClient: publicClient,
|
|
36
83
|
});
|
|
37
|
-
const { parameters, contractAddress
|
|
84
|
+
const { parameters, contractAddress, newTokenId } =
|
|
38
85
|
await creatorClient.create1155({
|
|
39
|
-
contract:
|
|
40
|
-
name: "testContract",
|
|
41
|
-
uri: demoContractMetadataURI,
|
|
42
|
-
},
|
|
86
|
+
contract: randomNewContract(),
|
|
43
87
|
token: {
|
|
44
88
|
tokenMetadataURI: demoTokenMetadataURI,
|
|
45
89
|
mintToCreatorCount: 1,
|
|
46
90
|
},
|
|
47
91
|
account: creatorAddress,
|
|
48
92
|
});
|
|
93
|
+
|
|
49
94
|
const { request } = await publicClient.simulateContract(parameters);
|
|
50
95
|
const hash = await walletClient.writeContract(request);
|
|
51
96
|
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
97
|
+
logFailure(receipt);
|
|
98
|
+
expect(receipt.status).toBe("success");
|
|
52
99
|
expect(receipt).not.toBeNull();
|
|
53
100
|
expect(receipt.to).to.equal("0x777777c338d93e2c7adf08d102d45ca7cc4ed021");
|
|
54
101
|
expect(getTokenIdFromCreateReceipt(receipt)).to.be.equal(1n);
|
|
55
102
|
expect(getContractAddressFromReceipt(receipt)).to.be.equal(
|
|
56
|
-
|
|
103
|
+
contractAddress,
|
|
57
104
|
);
|
|
105
|
+
|
|
106
|
+
expect(
|
|
107
|
+
await minterIsMinterOnToken({
|
|
108
|
+
contractAddress,
|
|
109
|
+
tokenId: newTokenId,
|
|
110
|
+
publicClient,
|
|
111
|
+
minter:
|
|
112
|
+
zoraTimedSaleStrategyAddress[
|
|
113
|
+
chain.id as keyof typeof zoraTimedSaleStrategyAddress
|
|
114
|
+
],
|
|
115
|
+
}),
|
|
116
|
+
).toBe(true);
|
|
117
|
+
},
|
|
118
|
+
20 * 1000,
|
|
119
|
+
);
|
|
120
|
+
anvilTest(
|
|
121
|
+
"when price is set to 0, it creates a new 1155 contract and token using the timed sale strategy",
|
|
122
|
+
async ({ viemClients: { publicClient, walletClient, chain } }) => {
|
|
123
|
+
const addresses = await walletClient.getAddresses();
|
|
124
|
+
const creatorAddress = addresses[0]!;
|
|
125
|
+
|
|
126
|
+
const creatorClient = createCreatorClient({
|
|
127
|
+
chainId: chain.id,
|
|
128
|
+
publicClient: publicClient,
|
|
129
|
+
});
|
|
130
|
+
const { parameters, contractAddress, newTokenId } =
|
|
131
|
+
await creatorClient.create1155({
|
|
132
|
+
contract: randomNewContract(),
|
|
133
|
+
token: {
|
|
134
|
+
tokenMetadataURI: demoTokenMetadataURI,
|
|
135
|
+
salesConfig: {
|
|
136
|
+
pricePerToken: 0n,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
account: creatorAddress,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const { request } = await publicClient.simulateContract(parameters);
|
|
143
|
+
const hash = await walletClient.writeContract(request);
|
|
144
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
145
|
+
|
|
146
|
+
logFailure(receipt);
|
|
147
|
+
|
|
148
|
+
expect(receipt.status).toBe("success");
|
|
149
|
+
|
|
150
|
+
expect(
|
|
151
|
+
await minterIsMinterOnToken({
|
|
152
|
+
contractAddress,
|
|
153
|
+
tokenId: newTokenId,
|
|
154
|
+
minter:
|
|
155
|
+
zoraTimedSaleStrategyAddress[
|
|
156
|
+
chain.id as keyof typeof zoraTimedSaleStrategyAddress
|
|
157
|
+
],
|
|
158
|
+
publicClient,
|
|
159
|
+
}),
|
|
160
|
+
).toBe(true);
|
|
58
161
|
},
|
|
59
162
|
20 * 1000,
|
|
60
163
|
);
|
|
164
|
+
|
|
61
165
|
anvilTest(
|
|
62
|
-
"
|
|
166
|
+
"can create a new contract, then can create a new token on this existing contract",
|
|
63
167
|
async ({ viemClients: { publicClient, walletClient, chain } }) => {
|
|
64
168
|
const addresses = await walletClient.getAddresses();
|
|
65
169
|
const creatorAccount = addresses[0]!;
|
|
@@ -71,10 +175,7 @@ describe("create-helper", () => {
|
|
|
71
175
|
|
|
72
176
|
const { parameters: request, contractAddress: contractAddress } =
|
|
73
177
|
await creatorClient.create1155({
|
|
74
|
-
contract:
|
|
75
|
-
name: "testContract2",
|
|
76
|
-
uri: demoContractMetadataURI,
|
|
77
|
-
},
|
|
178
|
+
contract: randomNewContract(),
|
|
78
179
|
token: {
|
|
79
180
|
tokenMetadataURI: demoTokenMetadataURI,
|
|
80
181
|
mintToCreatorCount: 3,
|
|
@@ -85,6 +186,8 @@ describe("create-helper", () => {
|
|
|
85
186
|
await publicClient.simulateContract(request);
|
|
86
187
|
const hash = await walletClient.writeContract(simulateResponse);
|
|
87
188
|
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
189
|
+
logFailure(receipt);
|
|
190
|
+
expect(receipt.status).toBe("success");
|
|
88
191
|
const firstTokenId = getTokenIdFromCreateReceipt(receipt);
|
|
89
192
|
expect(firstTokenId).to.be.equal(1n);
|
|
90
193
|
expect(receipt).not.toBeNull();
|
|
@@ -115,9 +218,12 @@ describe("create-helper", () => {
|
|
|
115
218
|
const newReceipt = await publicClient.waitForTransactionReceipt({
|
|
116
219
|
hash: newHash,
|
|
117
220
|
});
|
|
221
|
+
|
|
222
|
+
logFailure(receipt);
|
|
223
|
+
|
|
224
|
+
expect(newReceipt.status).toBe("success");
|
|
118
225
|
const tokenId = getTokenIdFromCreateReceipt(newReceipt);
|
|
119
226
|
expect(tokenId).to.be.equal(2n);
|
|
120
|
-
expect(newReceipt).not.toBeNull();
|
|
121
227
|
},
|
|
122
228
|
20 * 1000,
|
|
123
229
|
);
|
|
@@ -137,10 +243,7 @@ describe("create-helper", () => {
|
|
|
137
243
|
contractAddress: collectionAddress,
|
|
138
244
|
newTokenId,
|
|
139
245
|
} = await creatorClient.create1155({
|
|
140
|
-
contract:
|
|
141
|
-
name: "testContract",
|
|
142
|
-
uri: demoContractMetadataURI,
|
|
143
|
-
},
|
|
246
|
+
contract: randomNewContract(),
|
|
144
247
|
token: {
|
|
145
248
|
tokenMetadataURI: demoTokenMetadataURI,
|
|
146
249
|
createReferral,
|
|
@@ -151,7 +254,7 @@ describe("create-helper", () => {
|
|
|
151
254
|
await publicClient.simulateContract(request);
|
|
152
255
|
const hash = await walletClient.writeContract(simulationResponse);
|
|
153
256
|
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
154
|
-
expect(receipt).
|
|
257
|
+
expect(receipt.status).toBe("success");
|
|
155
258
|
expect(receipt.to).to.equal("0x777777c338d93e2c7adf08d102d45ca7cc4ed021");
|
|
156
259
|
expect(getTokenIdFromCreateReceipt(receipt)).to.be.equal(newTokenId);
|
|
157
260
|
|
|
@@ -182,15 +285,11 @@ describe("create-helper", () => {
|
|
|
182
285
|
const {
|
|
183
286
|
parameters: request,
|
|
184
287
|
newTokenId,
|
|
185
|
-
newToken,
|
|
186
288
|
minter,
|
|
187
289
|
contractAddress: collectionAddress,
|
|
188
290
|
contractVersion,
|
|
189
291
|
} = await creatorClient.create1155({
|
|
190
|
-
contract:
|
|
191
|
-
name: "testContract",
|
|
192
|
-
uri: demoContractMetadataURI,
|
|
193
|
-
},
|
|
292
|
+
contract: randomNewContract(),
|
|
194
293
|
token: {
|
|
195
294
|
tokenMetadataURI: demoTokenMetadataURI,
|
|
196
295
|
},
|
|
@@ -203,20 +302,6 @@ describe("create-helper", () => {
|
|
|
203
302
|
publicClient,
|
|
204
303
|
);
|
|
205
304
|
|
|
206
|
-
const salesConfigAndTokenInfo: MintableParameters = {
|
|
207
|
-
mintFeePerQuantity: parseEther("0.000777"),
|
|
208
|
-
contractVersion,
|
|
209
|
-
salesConfig: {
|
|
210
|
-
saleType: "fixedPrice",
|
|
211
|
-
address: minter,
|
|
212
|
-
pricePerToken: newToken.salesConfig.pricePerToken,
|
|
213
|
-
// these dont matter
|
|
214
|
-
maxTokensPerAddress: 0n,
|
|
215
|
-
saleEnd: "",
|
|
216
|
-
saleStart: "",
|
|
217
|
-
},
|
|
218
|
-
};
|
|
219
|
-
|
|
220
305
|
const quantityToMint = 5n;
|
|
221
306
|
|
|
222
307
|
// now try to mint a free mint
|
|
@@ -231,7 +316,21 @@ describe("create-helper", () => {
|
|
|
231
316
|
tokenContract: collectionAddress,
|
|
232
317
|
minterAccount: minterAddress,
|
|
233
318
|
tokenId: newTokenId,
|
|
234
|
-
salesConfigAndTokenInfo
|
|
319
|
+
salesConfigAndTokenInfo: {
|
|
320
|
+
contractVersion,
|
|
321
|
+
salesConfig: {
|
|
322
|
+
saleType: "timed",
|
|
323
|
+
address: minter,
|
|
324
|
+
// below fields arent used when determining mint price for minting
|
|
325
|
+
saleEnd: "",
|
|
326
|
+
saleStart: "",
|
|
327
|
+
erc20Z: zeroAddress,
|
|
328
|
+
pool: zeroAddress,
|
|
329
|
+
secondaryActivated: false,
|
|
330
|
+
mintFeePerQuantity: parseEther("0.000111"),
|
|
331
|
+
mintFee: 0n,
|
|
332
|
+
},
|
|
333
|
+
},
|
|
235
334
|
quantityToMint,
|
|
236
335
|
});
|
|
237
336
|
|
|
@@ -246,7 +345,7 @@ describe("create-helper", () => {
|
|
|
246
345
|
);
|
|
247
346
|
|
|
248
347
|
anvilTest(
|
|
249
|
-
"creates a new 1155 paid mint that can be minted",
|
|
348
|
+
"creates a new 1155 paid mint that can be minted using the fixed price minter",
|
|
250
349
|
async ({
|
|
251
350
|
viemClients: { testClient, publicClient, walletClient, chain },
|
|
252
351
|
}) => {
|
|
@@ -264,14 +363,10 @@ describe("create-helper", () => {
|
|
|
264
363
|
parameters: request,
|
|
265
364
|
contractAddress: collectionAddress,
|
|
266
365
|
newTokenId,
|
|
267
|
-
newToken,
|
|
268
366
|
minter,
|
|
269
367
|
contractVersion,
|
|
270
368
|
} = await creatorClient.create1155({
|
|
271
|
-
contract:
|
|
272
|
-
name: "testContract",
|
|
273
|
-
uri: demoContractMetadataURI,
|
|
274
|
-
},
|
|
369
|
+
contract: randomNewContract(),
|
|
275
370
|
token: {
|
|
276
371
|
tokenMetadataURI: demoTokenMetadataURI,
|
|
277
372
|
salesConfig: {
|
|
@@ -287,20 +382,6 @@ describe("create-helper", () => {
|
|
|
287
382
|
publicClient,
|
|
288
383
|
);
|
|
289
384
|
|
|
290
|
-
const salesConfigAndTokenInfo: MintableParameters = {
|
|
291
|
-
mintFeePerQuantity: parseEther("0.000777"),
|
|
292
|
-
contractVersion,
|
|
293
|
-
salesConfig: {
|
|
294
|
-
saleType: "fixedPrice",
|
|
295
|
-
address: minter,
|
|
296
|
-
pricePerToken: newToken.salesConfig.pricePerToken,
|
|
297
|
-
// these dont matter
|
|
298
|
-
maxTokensPerAddress: 0n,
|
|
299
|
-
saleEnd: "",
|
|
300
|
-
saleStart: "",
|
|
301
|
-
},
|
|
302
|
-
};
|
|
303
|
-
|
|
304
385
|
const quantityToMint = 5n;
|
|
305
386
|
|
|
306
387
|
// now try to mint a free mint
|
|
@@ -315,7 +396,23 @@ describe("create-helper", () => {
|
|
|
315
396
|
tokenContract: collectionAddress,
|
|
316
397
|
minterAccount: minterAddress,
|
|
317
398
|
tokenId: newTokenId,
|
|
318
|
-
salesConfigAndTokenInfo
|
|
399
|
+
salesConfigAndTokenInfo: {
|
|
400
|
+
contractVersion,
|
|
401
|
+
salesConfig: {
|
|
402
|
+
mintFeePerQuantity: await publicClient.readContract({
|
|
403
|
+
abi: zoraCreator1155ImplABI,
|
|
404
|
+
functionName: "mintFee",
|
|
405
|
+
address: collectionAddress,
|
|
406
|
+
}),
|
|
407
|
+
saleType: "fixedPrice",
|
|
408
|
+
address: minter,
|
|
409
|
+
pricePerToken,
|
|
410
|
+
// these dont matter
|
|
411
|
+
maxTokensPerAddress: 0n,
|
|
412
|
+
saleEnd: "",
|
|
413
|
+
saleStart: "",
|
|
414
|
+
},
|
|
415
|
+
},
|
|
319
416
|
quantityToMint,
|
|
320
417
|
});
|
|
321
418
|
|
|
@@ -328,4 +425,57 @@ describe("create-helper", () => {
|
|
|
328
425
|
},
|
|
329
426
|
20 * 1000,
|
|
330
427
|
);
|
|
428
|
+
|
|
429
|
+
anvilTest(
|
|
430
|
+
"creates an allow list mint contract",
|
|
431
|
+
async ({ viemClients: { publicClient, walletClient, chain } }) => {
|
|
432
|
+
const creator = (await walletClient.getAddresses())[0]!;
|
|
433
|
+
const allowList: AllowList = {
|
|
434
|
+
entries: [
|
|
435
|
+
{
|
|
436
|
+
user: "0xf69fEc6d858c77e969509843852178bd24CAd2B6",
|
|
437
|
+
price: 2n,
|
|
438
|
+
maxCanMint: 10000,
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
user: "0xcD08da546414dd463C89705B5E72CE1AeebF1567",
|
|
442
|
+
price: 3n,
|
|
443
|
+
maxCanMint: 10,
|
|
444
|
+
},
|
|
445
|
+
],
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
const root = await createAllowList({
|
|
449
|
+
allowList,
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
const creatorClient = createCreatorClient({
|
|
453
|
+
chainId: chain.id,
|
|
454
|
+
publicClient: publicClient,
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
const { parameters } = await creatorClient.create1155({
|
|
458
|
+
contract: {
|
|
459
|
+
name: "test allowlists",
|
|
460
|
+
uri: "ipfs://bafkreiainxen4b4wz4ubylvbhons6rembxdet4a262nf2lziclqvv7au3e",
|
|
461
|
+
},
|
|
462
|
+
token: {
|
|
463
|
+
tokenMetadataURI:
|
|
464
|
+
"ipfs://bafkreice23maski3x52tsfqgxstx3kbiifnt5jotg3a5ynvve53c4soi2u",
|
|
465
|
+
salesConfig: {
|
|
466
|
+
type: "allowlistMint",
|
|
467
|
+
presaleMerkleRoot: `0x${root}`,
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
account: creator,
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
const { request } = await publicClient.simulateContract(parameters);
|
|
474
|
+
|
|
475
|
+
await waitForSuccess(
|
|
476
|
+
await walletClient.writeContract(request),
|
|
477
|
+
publicClient,
|
|
478
|
+
);
|
|
479
|
+
},
|
|
480
|
+
);
|
|
331
481
|
});
|
|
@@ -192,7 +192,7 @@ async function createNew1155ContractAndToken({
|
|
|
192
192
|
minter,
|
|
193
193
|
newToken,
|
|
194
194
|
setupActions: tokenSetupActions,
|
|
195
|
-
} = prepareSetupActions({
|
|
195
|
+
} = await prepareSetupActions({
|
|
196
196
|
chainId,
|
|
197
197
|
account,
|
|
198
198
|
contractVersion,
|
|
@@ -250,7 +250,7 @@ async function createNew1155Token({
|
|
|
250
250
|
minter,
|
|
251
251
|
newToken,
|
|
252
252
|
setupActions: tokenSetupActions,
|
|
253
|
-
} = prepareSetupActions({
|
|
253
|
+
} = await prepareSetupActions({
|
|
254
254
|
chainId,
|
|
255
255
|
account,
|
|
256
256
|
contractVersion,
|
|
@@ -275,7 +275,7 @@ async function createNew1155Token({
|
|
|
275
275
|
};
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
-
function prepareSetupActions({
|
|
278
|
+
async function prepareSetupActions({
|
|
279
279
|
chainId,
|
|
280
280
|
account,
|
|
281
281
|
contractVersion,
|
|
@@ -291,7 +291,7 @@ function prepareSetupActions({
|
|
|
291
291
|
minter,
|
|
292
292
|
newToken,
|
|
293
293
|
setupActions: tokenSetupActions,
|
|
294
|
-
} = constructCreate1155TokenCalls({
|
|
294
|
+
} = await constructCreate1155TokenCalls({
|
|
295
295
|
chainId: chainId,
|
|
296
296
|
ownerAddress: account,
|
|
297
297
|
contractVersion,
|
|
@@ -27,6 +27,7 @@ export async function getContractInfoExistingContract({
|
|
|
27
27
|
// Account that is the creator of the contract
|
|
28
28
|
}): Promise<{
|
|
29
29
|
contractVersion: string;
|
|
30
|
+
contractName: string;
|
|
30
31
|
nextTokenId: bigint;
|
|
31
32
|
}> {
|
|
32
33
|
// Check if contract exists either from metadata or the static address passed in.
|
|
@@ -50,8 +51,15 @@ export async function getContractInfoExistingContract({
|
|
|
50
51
|
functionName: "nextTokenId",
|
|
51
52
|
});
|
|
52
53
|
|
|
54
|
+
const contractName = await publicClient.readContract({
|
|
55
|
+
address: contractAddress,
|
|
56
|
+
abi: zoraCreator1155ImplABI,
|
|
57
|
+
functionName: "name",
|
|
58
|
+
});
|
|
59
|
+
|
|
53
60
|
return {
|
|
54
61
|
contractVersion,
|
|
62
|
+
contractName,
|
|
55
63
|
nextTokenId,
|
|
56
64
|
};
|
|
57
65
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, it, expect, assert } from "vitest";
|
|
2
|
+
import { parseNameIntoSymbol } from "./minter-defaults";
|
|
3
|
+
|
|
4
|
+
describe("parseNameIntoSymbol", () => {
|
|
5
|
+
it("removes spaces and vowels and converts to uppercase", () => {
|
|
6
|
+
const symbol = parseNameIntoSymbol("My 4 To *5 @-Name");
|
|
7
|
+
|
|
8
|
+
expect(symbol).toBe("$MY4T");
|
|
9
|
+
});
|
|
10
|
+
it("works with less than 4 characters", () => {
|
|
11
|
+
const symbol = parseNameIntoSymbol("M4y a");
|
|
12
|
+
|
|
13
|
+
expect(symbol).toBe("$M4Y");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("works with no characters", () => {
|
|
17
|
+
assert.throws(() => {
|
|
18
|
+
parseNameIntoSymbol("AEIO U");
|
|
19
|
+
}, "Not enough valid characters to generate a symbol");
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { Concrete } from "src/utils";
|
|
2
|
+
import {
|
|
3
|
+
SalesConfigParamsType,
|
|
4
|
+
AllowListParamType,
|
|
5
|
+
Erc20ParamsType,
|
|
6
|
+
FixedPriceParamsType,
|
|
7
|
+
SaleStartAndEnd,
|
|
8
|
+
MaxTokensPerAddress,
|
|
9
|
+
ConcreteSalesConfig,
|
|
10
|
+
TimedSaleParamsType,
|
|
11
|
+
} from "./types";
|
|
12
|
+
import { fetchTokenMetadata } from "src/ipfs/token-metadata";
|
|
13
|
+
|
|
14
|
+
// Sales end forever amount (uint64 max)
|
|
15
|
+
export const SALE_END_FOREVER = 18446744073709551615n;
|
|
16
|
+
|
|
17
|
+
const DEFAULT_SALE_START_AND_END: Concrete<SaleStartAndEnd> = {
|
|
18
|
+
// Sale start time – defaults to beginning of unix time
|
|
19
|
+
saleStart: 0n,
|
|
20
|
+
// This is the end of uint64, plenty of time
|
|
21
|
+
saleEnd: SALE_END_FOREVER,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const DEFAULT_MAX_TOKENS_PER_ADDRESS: Concrete<MaxTokensPerAddress> = {
|
|
25
|
+
maxTokensPerAddress: 0n,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const erc20SaleSettingsWithDefaults = (
|
|
29
|
+
params: Erc20ParamsType,
|
|
30
|
+
): Concrete<Erc20ParamsType> => ({
|
|
31
|
+
...DEFAULT_SALE_START_AND_END,
|
|
32
|
+
...DEFAULT_MAX_TOKENS_PER_ADDRESS,
|
|
33
|
+
...params,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const allowListWithDefaults = (
|
|
37
|
+
allowlist: AllowListParamType,
|
|
38
|
+
): Concrete<AllowListParamType> => {
|
|
39
|
+
return {
|
|
40
|
+
...DEFAULT_SALE_START_AND_END,
|
|
41
|
+
...allowlist,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const fixedPriceSettingsWithDefaults = (
|
|
46
|
+
params: FixedPriceParamsType,
|
|
47
|
+
): Concrete<FixedPriceParamsType> => ({
|
|
48
|
+
...DEFAULT_SALE_START_AND_END,
|
|
49
|
+
...DEFAULT_MAX_TOKENS_PER_ADDRESS,
|
|
50
|
+
type: "fixedPrice",
|
|
51
|
+
...params,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const parseNameIntoSymbol = (name: string) => {
|
|
55
|
+
if (name === "") {
|
|
56
|
+
throw new Error("Name must be provided to generate a symbol");
|
|
57
|
+
}
|
|
58
|
+
const result =
|
|
59
|
+
"$" +
|
|
60
|
+
name
|
|
61
|
+
// Remove all non-alphanumeric characters
|
|
62
|
+
.replace(/[^a-zA-Z0-9]/g, "")
|
|
63
|
+
// and leading dollar signs
|
|
64
|
+
.replace(/^\$+/, "")
|
|
65
|
+
.toUpperCase()
|
|
66
|
+
// Remove all vowels and spaces
|
|
67
|
+
.replace(/[AEIOU\s]/g, "")
|
|
68
|
+
// Strip down to 4 characters
|
|
69
|
+
.slice(0, 4);
|
|
70
|
+
|
|
71
|
+
if (result === "$") {
|
|
72
|
+
throw new Error("Not enough valid characters to generate a symbol");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return result;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
async function fetchTokenNameFromMetadata(
|
|
79
|
+
tokenMetadataURI: string,
|
|
80
|
+
): Promise<string> {
|
|
81
|
+
const tokenMetadata = await fetchTokenMetadata(tokenMetadataURI);
|
|
82
|
+
|
|
83
|
+
if (!tokenMetadata.name) {
|
|
84
|
+
throw new Error("No name found in token metadata");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return tokenMetadata.name;
|
|
88
|
+
}
|
|
89
|
+
const timedSaleSettingsWithDefaults = async (
|
|
90
|
+
params: TimedSaleParamsType,
|
|
91
|
+
tokenMetadataURI: string,
|
|
92
|
+
): Promise<Concrete<TimedSaleParamsType>> => {
|
|
93
|
+
// If the name is not provided, try to fetch it from the metadata
|
|
94
|
+
const erc20Name =
|
|
95
|
+
params.erc20Name || (await fetchTokenNameFromMetadata(tokenMetadataURI));
|
|
96
|
+
const symbol = params.erc20Symbol || parseNameIntoSymbol(erc20Name);
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
type: "timed",
|
|
100
|
+
...DEFAULT_SALE_START_AND_END,
|
|
101
|
+
erc20Name,
|
|
102
|
+
erc20Symbol: symbol,
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const isAllowList = (
|
|
107
|
+
salesConfig: SalesConfigParamsType,
|
|
108
|
+
): salesConfig is AllowListParamType => salesConfig.type === "allowlistMint";
|
|
109
|
+
const isErc20 = (
|
|
110
|
+
salesConfig: SalesConfigParamsType,
|
|
111
|
+
): salesConfig is Erc20ParamsType => salesConfig.type === "erc20Mint";
|
|
112
|
+
const isFixedPrice = (
|
|
113
|
+
salesConfig: SalesConfigParamsType,
|
|
114
|
+
): salesConfig is FixedPriceParamsType => {
|
|
115
|
+
return (salesConfig as FixedPriceParamsType).pricePerToken > 0n;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const getSalesConfigWithDefaults = async (
|
|
119
|
+
salesConfig: SalesConfigParamsType | undefined,
|
|
120
|
+
tokenMetadataURI: string,
|
|
121
|
+
): Promise<ConcreteSalesConfig> => {
|
|
122
|
+
if (!salesConfig) return timedSaleSettingsWithDefaults({}, tokenMetadataURI);
|
|
123
|
+
if (isAllowList(salesConfig)) {
|
|
124
|
+
return allowListWithDefaults(salesConfig);
|
|
125
|
+
}
|
|
126
|
+
if (isErc20(salesConfig)) {
|
|
127
|
+
return erc20SaleSettingsWithDefaults(salesConfig);
|
|
128
|
+
}
|
|
129
|
+
if (isFixedPrice(salesConfig)) {
|
|
130
|
+
return fixedPriceSettingsWithDefaults(salesConfig);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return timedSaleSettingsWithDefaults(salesConfig, tokenMetadataURI);
|
|
134
|
+
};
|