@zoralabs/protocol-sdk 0.2.0 → 0.3.1
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 +6 -6
- package/CHANGELOG.md +19 -1
- package/README.md +42 -11
- package/dist/create/1155-create-helper.d.ts +24 -25
- package/dist/create/1155-create-helper.d.ts.map +1 -1
- package/dist/index.cjs +296 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +287 -115
- package/dist/index.js.map +1 -1
- package/dist/mint/mint-client.d.ts +5 -1
- package/dist/mint/mint-client.d.ts.map +1 -1
- package/dist/premint/premint-client.d.ts +51 -12
- package/dist/premint/premint-client.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/create/1155-create-helper.test.ts +40 -26
- package/src/create/1155-create-helper.ts +120 -103
- package/src/index.ts +2 -0
- package/src/mint/mint-client.test.ts +3 -3
- package/src/mint/mint-client.ts +12 -2
- package/src/premint/premint-client.test.ts +22 -9
- package/src/premint/premint-client.ts +29 -31
- package/dist/preminter.d.ts +0 -25
- package/dist/preminter.d.ts.map +0 -1
- package/dist/preminter.test.d.ts +0 -451
- package/dist/preminter.test.d.ts.map +0 -1
- package/src/preminter.test.ts +0 -510
- package/src/preminter.ts +0 -72
package/src/preminter.test.ts
DELETED
|
@@ -1,510 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createTestClient,
|
|
3
|
-
http,
|
|
4
|
-
createWalletClient,
|
|
5
|
-
createPublicClient,
|
|
6
|
-
keccak256,
|
|
7
|
-
Hex,
|
|
8
|
-
concat,
|
|
9
|
-
recoverAddress,
|
|
10
|
-
hashDomain,
|
|
11
|
-
} from "viem";
|
|
12
|
-
import { foundry, zora } from "viem/chains";
|
|
13
|
-
import { describe, it, beforeEach, expect, afterEach } from "vitest";
|
|
14
|
-
import { parseEther } from "viem";
|
|
15
|
-
import {
|
|
16
|
-
zoraCreator1155PremintExecutorImplABI as preminterAbi,
|
|
17
|
-
zoraCreator1155PremintExecutorImplAddress as zoraCreator1155PremintExecutorAddress,
|
|
18
|
-
zoraCreator1155ImplABI,
|
|
19
|
-
zoraCreator1155FactoryImplAddress,
|
|
20
|
-
zoraCreator1155FactoryImplConfig,
|
|
21
|
-
} from "@zoralabs/protocol-deployments";
|
|
22
|
-
|
|
23
|
-
import {
|
|
24
|
-
ContractCreationConfig,
|
|
25
|
-
PremintConfig,
|
|
26
|
-
TokenCreationConfig,
|
|
27
|
-
preminterTypedDataDefinition,
|
|
28
|
-
} from "./preminter";
|
|
29
|
-
|
|
30
|
-
const walletClient = createWalletClient({
|
|
31
|
-
chain: foundry,
|
|
32
|
-
transport: http(),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
export const walletClientWithAccount = createWalletClient({
|
|
36
|
-
chain: foundry,
|
|
37
|
-
transport: http(),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
const testClient = createTestClient({
|
|
41
|
-
chain: foundry,
|
|
42
|
-
mode: "anvil",
|
|
43
|
-
transport: http(),
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const publicClient = createPublicClient({
|
|
47
|
-
chain: foundry,
|
|
48
|
-
transport: http(),
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
type Address = `0x${string}`;
|
|
52
|
-
|
|
53
|
-
// JSON-RPC Account
|
|
54
|
-
const [deployerAccount, creatorAccount, collectorAccount] =
|
|
55
|
-
(await walletClient.getAddresses()) as [Address, Address, Address, Address];
|
|
56
|
-
|
|
57
|
-
type TestContext = {
|
|
58
|
-
preminterAddress: `0x${string}`;
|
|
59
|
-
forkedChainId: keyof typeof zoraCreator1155FactoryImplAddress;
|
|
60
|
-
anvilChainId: number;
|
|
61
|
-
zoraMintFee: bigint;
|
|
62
|
-
fixedPriceMinterAddress: Address;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
// create token and contract creation config:
|
|
66
|
-
const defaultContractConfig = ({
|
|
67
|
-
contractAdmin,
|
|
68
|
-
}: {
|
|
69
|
-
contractAdmin: Address;
|
|
70
|
-
}): ContractCreationConfig => ({
|
|
71
|
-
contractAdmin,
|
|
72
|
-
contractURI: "ipfs://asdfasdfasdf",
|
|
73
|
-
contractName: "My fun NFT",
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const defaultTokenConfig = (
|
|
77
|
-
fixedPriceMinterAddress: Address,
|
|
78
|
-
): TokenCreationConfig => ({
|
|
79
|
-
tokenURI: "ipfs://tokenIpfsId0",
|
|
80
|
-
maxSupply: 100n,
|
|
81
|
-
maxTokensPerAddress: 10n,
|
|
82
|
-
pricePerToken: 0n,
|
|
83
|
-
mintStart: 0n,
|
|
84
|
-
mintDuration: 100n,
|
|
85
|
-
royaltyMintSchedule: 30,
|
|
86
|
-
royaltyBPS: 200,
|
|
87
|
-
royaltyRecipient: creatorAccount,
|
|
88
|
-
fixedPriceMinter: fixedPriceMinterAddress,
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
const defaultPremintConfig = (fixedPriceMinter: Address): PremintConfig => ({
|
|
92
|
-
tokenConfig: defaultTokenConfig(fixedPriceMinter),
|
|
93
|
-
deleted: false,
|
|
94
|
-
uid: 105,
|
|
95
|
-
version: 0,
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe("ZoraCreator1155Preminter", () => {
|
|
99
|
-
beforeEach<TestContext>(async (ctx) => {
|
|
100
|
-
// deploy signature minter contract
|
|
101
|
-
await testClient.setBalance({
|
|
102
|
-
address: deployerAccount,
|
|
103
|
-
value: parseEther("10"),
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
ctx.forkedChainId = zora.id;
|
|
107
|
-
ctx.anvilChainId = foundry.id;
|
|
108
|
-
|
|
109
|
-
ctx.fixedPriceMinterAddress = await publicClient.readContract({
|
|
110
|
-
abi: zoraCreator1155FactoryImplConfig.abi,
|
|
111
|
-
address: zoraCreator1155FactoryImplAddress[ctx.forkedChainId],
|
|
112
|
-
functionName: "fixedPriceMinter",
|
|
113
|
-
});
|
|
114
|
-
ctx.zoraMintFee = parseEther("0.000777");
|
|
115
|
-
|
|
116
|
-
ctx.preminterAddress =
|
|
117
|
-
zoraCreator1155PremintExecutorAddress[ctx.forkedChainId];
|
|
118
|
-
}, 20 * 1000);
|
|
119
|
-
|
|
120
|
-
afterEach(() => {
|
|
121
|
-
testClient.reset();
|
|
122
|
-
}, 4 * 1000);
|
|
123
|
-
|
|
124
|
-
// skip for now - we need to make this work on zora testnet chain too
|
|
125
|
-
it<TestContext>(
|
|
126
|
-
"can sign on the forked premint contract",
|
|
127
|
-
async ({ fixedPriceMinterAddress, forkedChainId }) => {
|
|
128
|
-
const premintConfig = defaultPremintConfig(fixedPriceMinterAddress);
|
|
129
|
-
const contractConfig = defaultContractConfig({
|
|
130
|
-
contractAdmin: creatorAccount,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const preminterAddress = zoraCreator1155PremintExecutorAddress[
|
|
134
|
-
forkedChainId as keyof typeof zoraCreator1155PremintExecutorAddress
|
|
135
|
-
] as Address;
|
|
136
|
-
|
|
137
|
-
const contractAddress = await publicClient.readContract({
|
|
138
|
-
abi: preminterAbi,
|
|
139
|
-
address: preminterAddress,
|
|
140
|
-
functionName: "getContractAddress",
|
|
141
|
-
args: [contractConfig],
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
const signedMessage = await walletClient.signTypedData({
|
|
145
|
-
...preminterTypedDataDefinition({
|
|
146
|
-
verifyingContract: contractAddress,
|
|
147
|
-
chainId: 999,
|
|
148
|
-
premintConfig,
|
|
149
|
-
}),
|
|
150
|
-
account: creatorAccount,
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
console.log({
|
|
154
|
-
creatorAccount,
|
|
155
|
-
signedMessage,
|
|
156
|
-
contractConfig,
|
|
157
|
-
premintConfig,
|
|
158
|
-
contractAddress,
|
|
159
|
-
});
|
|
160
|
-
},
|
|
161
|
-
20 * 1000,
|
|
162
|
-
);
|
|
163
|
-
it<TestContext>(
|
|
164
|
-
"can sign and recover a signature",
|
|
165
|
-
async ({
|
|
166
|
-
preminterAddress: preminterAddress,
|
|
167
|
-
anvilChainId,
|
|
168
|
-
fixedPriceMinterAddress,
|
|
169
|
-
}) => {
|
|
170
|
-
const premintConfig = defaultPremintConfig(fixedPriceMinterAddress);
|
|
171
|
-
const contractConfig = defaultContractConfig({
|
|
172
|
-
contractAdmin: creatorAccount,
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
const contractAddress = await publicClient.readContract({
|
|
176
|
-
abi: preminterAbi,
|
|
177
|
-
address: preminterAddress,
|
|
178
|
-
functionName: "getContractAddress",
|
|
179
|
-
args: [contractConfig],
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// sign message containing contract and token creation config and uid
|
|
183
|
-
const signedMessage = await walletClient.signTypedData({
|
|
184
|
-
...preminterTypedDataDefinition({
|
|
185
|
-
verifyingContract: contractAddress,
|
|
186
|
-
// we need to sign here for the anvil chain, cause thats where it is run on
|
|
187
|
-
chainId: anvilChainId,
|
|
188
|
-
premintConfig,
|
|
189
|
-
}),
|
|
190
|
-
account: creatorAccount,
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
// recover and verify address is correct
|
|
194
|
-
const recoveredAddress = await publicClient.readContract({
|
|
195
|
-
abi: preminterAbi,
|
|
196
|
-
address: preminterAddress,
|
|
197
|
-
functionName: "recoverSigner",
|
|
198
|
-
args: [premintConfig, contractAddress, signedMessage],
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
expect(recoveredAddress).to.equal(creatorAccount);
|
|
202
|
-
},
|
|
203
|
-
|
|
204
|
-
20 * 1000,
|
|
205
|
-
);
|
|
206
|
-
it<TestContext>(
|
|
207
|
-
"can sign and mint multiple tokens",
|
|
208
|
-
async ({
|
|
209
|
-
zoraMintFee,
|
|
210
|
-
anvilChainId,
|
|
211
|
-
preminterAddress: preminterAddress,
|
|
212
|
-
fixedPriceMinterAddress,
|
|
213
|
-
}) => {
|
|
214
|
-
// setup contract and token creation parameters
|
|
215
|
-
const premintConfig = defaultPremintConfig(fixedPriceMinterAddress);
|
|
216
|
-
const contractConfig = defaultContractConfig({
|
|
217
|
-
contractAdmin: creatorAccount,
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
// lets make it a random number to not break the existing tests that expect fresh data
|
|
221
|
-
premintConfig.uid = Math.round(Math.random() * 1000000);
|
|
222
|
-
|
|
223
|
-
let contractAddress = await publicClient.readContract({
|
|
224
|
-
abi: preminterAbi,
|
|
225
|
-
address: preminterAddress,
|
|
226
|
-
functionName: "getContractAddress",
|
|
227
|
-
args: [contractConfig],
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
// have creator sign the message to create the contract
|
|
231
|
-
// and the token
|
|
232
|
-
const signedMessage = await walletClient.signTypedData({
|
|
233
|
-
...preminterTypedDataDefinition({
|
|
234
|
-
verifyingContract: contractAddress,
|
|
235
|
-
// we need to sign here for the anvil chain, cause thats where it is run on
|
|
236
|
-
chainId: anvilChainId,
|
|
237
|
-
premintConfig,
|
|
238
|
-
}),
|
|
239
|
-
account: creatorAccount,
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
const quantityToMint = 2n;
|
|
243
|
-
|
|
244
|
-
const valueToSend =
|
|
245
|
-
(zoraMintFee + premintConfig.tokenConfig.pricePerToken) *
|
|
246
|
-
quantityToMint;
|
|
247
|
-
|
|
248
|
-
const comment = "I love this!";
|
|
249
|
-
|
|
250
|
-
await testClient.setBalance({
|
|
251
|
-
address: collectorAccount,
|
|
252
|
-
value: parseEther("10"),
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
// get the premint status - it should not be minted
|
|
256
|
-
let [contractCreated, tokenId] = await publicClient.readContract({
|
|
257
|
-
abi: preminterAbi,
|
|
258
|
-
address: preminterAddress,
|
|
259
|
-
functionName: "premintStatus",
|
|
260
|
-
args: [contractAddress, premintConfig.uid],
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
expect(contractCreated).toBe(false);
|
|
264
|
-
expect(tokenId).toBe(0n);
|
|
265
|
-
|
|
266
|
-
// now have the collector execute the first signed message;
|
|
267
|
-
// it should create the contract, the token,
|
|
268
|
-
// and min the quantity to mint tokens to the collector
|
|
269
|
-
// the signature along with contract + token creation
|
|
270
|
-
// parameters are required to call this function
|
|
271
|
-
const mintHash = await walletClient.writeContract({
|
|
272
|
-
abi: preminterAbi,
|
|
273
|
-
functionName: "premint",
|
|
274
|
-
account: collectorAccount,
|
|
275
|
-
address: preminterAddress,
|
|
276
|
-
args: [
|
|
277
|
-
contractConfig,
|
|
278
|
-
premintConfig,
|
|
279
|
-
signedMessage,
|
|
280
|
-
quantityToMint,
|
|
281
|
-
comment,
|
|
282
|
-
],
|
|
283
|
-
value: valueToSend,
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
// ensure it succeeded
|
|
287
|
-
const receipt = await publicClient.waitForTransactionReceipt({
|
|
288
|
-
hash: mintHash,
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
expect(receipt.status).toBe("success");
|
|
292
|
-
|
|
293
|
-
// fetch the premint token id
|
|
294
|
-
[contractCreated, tokenId] = await publicClient.readContract({
|
|
295
|
-
abi: preminterAbi,
|
|
296
|
-
address: preminterAddress,
|
|
297
|
-
functionName: "premintStatus",
|
|
298
|
-
args: [contractAddress, premintConfig.uid],
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
expect(tokenId).not.toBe(0n);
|
|
302
|
-
|
|
303
|
-
// now use what was created, to get the balance from the created contract
|
|
304
|
-
const tokenBalance = await publicClient.readContract({
|
|
305
|
-
abi: zoraCreator1155ImplABI,
|
|
306
|
-
address: contractAddress,
|
|
307
|
-
functionName: "balanceOf",
|
|
308
|
-
args: [collectorAccount, tokenId],
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
// get token balance - should be amount that was created
|
|
312
|
-
expect(tokenBalance).toBe(quantityToMint);
|
|
313
|
-
|
|
314
|
-
const premintConfig2 = {
|
|
315
|
-
...premintConfig,
|
|
316
|
-
uid: premintConfig.uid + 1,
|
|
317
|
-
tokenConfig: {
|
|
318
|
-
...premintConfig.tokenConfig,
|
|
319
|
-
tokenURI: "ipfs://tokenIpfsId2",
|
|
320
|
-
pricePerToken: parseEther("0.05"),
|
|
321
|
-
},
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
// sign the message to create the second token
|
|
325
|
-
const signedMessage2 = await walletClient.signTypedData({
|
|
326
|
-
...preminterTypedDataDefinition({
|
|
327
|
-
verifyingContract: contractAddress,
|
|
328
|
-
chainId: foundry.id,
|
|
329
|
-
premintConfig: premintConfig2,
|
|
330
|
-
}),
|
|
331
|
-
account: creatorAccount,
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
const quantityToMint2 = 4n;
|
|
335
|
-
|
|
336
|
-
const valueToSend2 =
|
|
337
|
-
(zoraMintFee + premintConfig2.tokenConfig.pricePerToken) *
|
|
338
|
-
quantityToMint2;
|
|
339
|
-
|
|
340
|
-
// now have the collector execute the second signed message.
|
|
341
|
-
// it should create a new token against the existing contract
|
|
342
|
-
const mintHash2 = await walletClient.writeContract({
|
|
343
|
-
abi: preminterAbi,
|
|
344
|
-
functionName: "premint",
|
|
345
|
-
account: collectorAccount,
|
|
346
|
-
address: preminterAddress,
|
|
347
|
-
args: [
|
|
348
|
-
contractConfig,
|
|
349
|
-
premintConfig2,
|
|
350
|
-
signedMessage2,
|
|
351
|
-
quantityToMint2,
|
|
352
|
-
comment,
|
|
353
|
-
],
|
|
354
|
-
value: valueToSend2,
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
expect(
|
|
358
|
-
(await publicClient.waitForTransactionReceipt({ hash: mintHash2 }))
|
|
359
|
-
.status,
|
|
360
|
-
).toBe("success");
|
|
361
|
-
|
|
362
|
-
// now premint status for the second mint, it should be minted
|
|
363
|
-
[, tokenId] = await publicClient.readContract({
|
|
364
|
-
abi: preminterAbi,
|
|
365
|
-
address: preminterAddress,
|
|
366
|
-
functionName: "premintStatus",
|
|
367
|
-
args: [contractAddress, premintConfig2.uid],
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
expect(tokenId).not.toBe(0n);
|
|
371
|
-
|
|
372
|
-
// get balance of second token
|
|
373
|
-
const tokenBalance2 = await publicClient.readContract({
|
|
374
|
-
abi: zoraCreator1155ImplABI,
|
|
375
|
-
address: contractAddress,
|
|
376
|
-
functionName: "balanceOf",
|
|
377
|
-
args: [collectorAccount, tokenId],
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
expect(tokenBalance2).toBe(quantityToMint2);
|
|
381
|
-
},
|
|
382
|
-
// 10 second timeout
|
|
383
|
-
40 * 1000,
|
|
384
|
-
);
|
|
385
|
-
|
|
386
|
-
it<TestContext>("can decode the CreatorAttribution event", async ({
|
|
387
|
-
zoraMintFee,
|
|
388
|
-
anvilChainId,
|
|
389
|
-
preminterAddress: preminterAddress,
|
|
390
|
-
fixedPriceMinterAddress,
|
|
391
|
-
}) => {
|
|
392
|
-
const premintConfig = defaultPremintConfig(fixedPriceMinterAddress);
|
|
393
|
-
const contractConfig = defaultContractConfig({
|
|
394
|
-
contractAdmin: creatorAccount,
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
// lets make it a random number to not break the existing tests that expect fresh data
|
|
398
|
-
premintConfig.uid = Math.round(Math.random() * 1000000);
|
|
399
|
-
|
|
400
|
-
let contractAddress = await publicClient.readContract({
|
|
401
|
-
abi: preminterAbi,
|
|
402
|
-
address: preminterAddress,
|
|
403
|
-
functionName: "getContractAddress",
|
|
404
|
-
args: [contractConfig],
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
// have creator sign the message to create the contract
|
|
408
|
-
// and the token
|
|
409
|
-
const signedMessage = await walletClient.signTypedData({
|
|
410
|
-
...preminterTypedDataDefinition({
|
|
411
|
-
verifyingContract: contractAddress,
|
|
412
|
-
// we need to sign here for the anvil chain, cause thats where it is run on
|
|
413
|
-
chainId: anvilChainId,
|
|
414
|
-
premintConfig,
|
|
415
|
-
}),
|
|
416
|
-
account: creatorAccount,
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
const quantityToMint = 2n;
|
|
420
|
-
|
|
421
|
-
const valueToSend =
|
|
422
|
-
(zoraMintFee + premintConfig.tokenConfig.pricePerToken) * quantityToMint;
|
|
423
|
-
|
|
424
|
-
const comment = "I love this!";
|
|
425
|
-
|
|
426
|
-
await testClient.setBalance({
|
|
427
|
-
address: collectorAccount,
|
|
428
|
-
value: parseEther("10"),
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
// now have the collector execute the first signed message;
|
|
432
|
-
// it should create the contract, the token,
|
|
433
|
-
// and min the quantity to mint tokens to the collector
|
|
434
|
-
// the signature along with contract + token creation
|
|
435
|
-
// parameters are required to call this function
|
|
436
|
-
const mintHash = await walletClient.writeContract({
|
|
437
|
-
abi: preminterAbi,
|
|
438
|
-
functionName: "premint",
|
|
439
|
-
account: collectorAccount,
|
|
440
|
-
address: preminterAddress,
|
|
441
|
-
args: [
|
|
442
|
-
contractConfig,
|
|
443
|
-
premintConfig,
|
|
444
|
-
signedMessage,
|
|
445
|
-
quantityToMint,
|
|
446
|
-
comment,
|
|
447
|
-
],
|
|
448
|
-
value: valueToSend,
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
// ensure it succeeded
|
|
452
|
-
const receipt = await publicClient.waitForTransactionReceipt({
|
|
453
|
-
hash: mintHash,
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
expect(receipt.status).toBe("success");
|
|
457
|
-
|
|
458
|
-
// get the CreatorAttribution event from the erc1155 contract:
|
|
459
|
-
const topics = await publicClient.getContractEvents({
|
|
460
|
-
abi: zoraCreator1155ImplABI,
|
|
461
|
-
address: contractAddress,
|
|
462
|
-
eventName: "CreatorAttribution",
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
expect(topics.length).toBe(1);
|
|
466
|
-
|
|
467
|
-
const creatorAttributionEvent = topics[0]!;
|
|
468
|
-
|
|
469
|
-
const { creator, domainName, signature, structHash, version } =
|
|
470
|
-
creatorAttributionEvent.args;
|
|
471
|
-
|
|
472
|
-
const chainId = anvilChainId;
|
|
473
|
-
|
|
474
|
-
// hash the eip712 domain based on the parameters emitted from the event:
|
|
475
|
-
const hashedDomain = hashDomain({
|
|
476
|
-
domain: {
|
|
477
|
-
chainId,
|
|
478
|
-
name: domainName,
|
|
479
|
-
verifyingContract: contractAddress,
|
|
480
|
-
version,
|
|
481
|
-
},
|
|
482
|
-
types: {
|
|
483
|
-
EIP712Domain: [
|
|
484
|
-
{ name: "name", type: "string" },
|
|
485
|
-
{ name: "version", type: "string" },
|
|
486
|
-
{
|
|
487
|
-
name: "chainId",
|
|
488
|
-
type: "uint256",
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
name: "verifyingContract",
|
|
492
|
-
type: "address",
|
|
493
|
-
},
|
|
494
|
-
],
|
|
495
|
-
},
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
// re-build the eip-712 typed data hash, consisting of the hashed domain and the structHash emitted from the event:
|
|
499
|
-
const parts: Hex[] = ["0x1901", hashedDomain, structHash!];
|
|
500
|
-
|
|
501
|
-
const hashedTypedData = keccak256(concat(parts));
|
|
502
|
-
|
|
503
|
-
const recoveredSigner = await recoverAddress({
|
|
504
|
-
hash: hashedTypedData,
|
|
505
|
-
signature: signature!,
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
expect(recoveredSigner).toBe(creator);
|
|
509
|
-
});
|
|
510
|
-
});
|
package/src/preminter.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { Address } from "abitype";
|
|
2
|
-
import { ExtractAbiFunction, AbiParametersToPrimitiveTypes } from "abitype";
|
|
3
|
-
import { zoraCreator1155PremintExecutorImplABI as preminterAbi } from "@zoralabs/protocol-deployments";
|
|
4
|
-
import { TypedDataDefinition } from "viem";
|
|
5
|
-
|
|
6
|
-
type PremintInputs = ExtractAbiFunction<
|
|
7
|
-
typeof preminterAbi,
|
|
8
|
-
"premint"
|
|
9
|
-
>["inputs"];
|
|
10
|
-
|
|
11
|
-
type PreminterHashDataTypes = AbiParametersToPrimitiveTypes<PremintInputs>;
|
|
12
|
-
|
|
13
|
-
export type ContractCreationConfig = PreminterHashDataTypes[0];
|
|
14
|
-
export type PremintConfig = PreminterHashDataTypes[1];
|
|
15
|
-
export type TokenCreationConfig = PremintConfig["tokenConfig"];
|
|
16
|
-
|
|
17
|
-
// Convenience method to create the structured typed data
|
|
18
|
-
// needed to sign for a premint contract and token
|
|
19
|
-
export const preminterTypedDataDefinition = ({
|
|
20
|
-
verifyingContract,
|
|
21
|
-
premintConfig,
|
|
22
|
-
chainId,
|
|
23
|
-
}: {
|
|
24
|
-
verifyingContract: Address;
|
|
25
|
-
premintConfig: PremintConfig;
|
|
26
|
-
chainId: number;
|
|
27
|
-
}) => {
|
|
28
|
-
const { tokenConfig, uid, version, deleted } = premintConfig;
|
|
29
|
-
const types = {
|
|
30
|
-
CreatorAttribution: [
|
|
31
|
-
{ name: "tokenConfig", type: "TokenCreationConfig" },
|
|
32
|
-
// unique id scoped to the contract and token to create.
|
|
33
|
-
// ensure that a signature can be replaced, as long as the replacement
|
|
34
|
-
// has the same uid, and a newer version.
|
|
35
|
-
{ name: "uid", type: "uint32" },
|
|
36
|
-
{ name: "version", type: "uint32" },
|
|
37
|
-
// if this update should result in the signature being deleted.
|
|
38
|
-
{ name: "deleted", type: "bool" },
|
|
39
|
-
],
|
|
40
|
-
TokenCreationConfig: [
|
|
41
|
-
{ name: "tokenURI", type: "string" },
|
|
42
|
-
{ name: "maxSupply", type: "uint256" },
|
|
43
|
-
{ name: "maxTokensPerAddress", type: "uint64" },
|
|
44
|
-
{ name: "pricePerToken", type: "uint96" },
|
|
45
|
-
{ name: "mintStart", type: "uint64" },
|
|
46
|
-
{ name: "mintDuration", type: "uint64" },
|
|
47
|
-
{ name: "royaltyMintSchedule", type: "uint32" },
|
|
48
|
-
{ name: "royaltyBPS", type: "uint32" },
|
|
49
|
-
{ name: "royaltyRecipient", type: "address" },
|
|
50
|
-
{ name: "fixedPriceMinter", type: "address" },
|
|
51
|
-
],
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const result: TypedDataDefinition<typeof types, "CreatorAttribution"> = {
|
|
55
|
-
domain: {
|
|
56
|
-
chainId,
|
|
57
|
-
name: "Preminter",
|
|
58
|
-
version: "1",
|
|
59
|
-
verifyingContract: verifyingContract,
|
|
60
|
-
},
|
|
61
|
-
types,
|
|
62
|
-
message: {
|
|
63
|
-
tokenConfig,
|
|
64
|
-
uid,
|
|
65
|
-
version,
|
|
66
|
-
deleted,
|
|
67
|
-
},
|
|
68
|
-
primaryType: "CreatorAttribution",
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
return result;
|
|
72
|
-
};
|