@zoralabs/protocol-sdk 0.3.0 → 0.3.2
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 +16 -0
- package/dist/anvil.d.ts +14 -0
- package/dist/anvil.d.ts.map +1 -1
- package/dist/apis/generated/discover-api-types.d.ts.map +1 -1
- package/dist/apis/generated/premint-api-types.d.ts.map +1 -1
- package/dist/index.cjs +190 -30
- 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 +180 -14
- package/dist/index.js.map +1 -1
- package/dist/premint/premint-client.d.ts +0 -12
- package/dist/premint/premint-client.d.ts.map +1 -1
- package/dist/preminter.d.ts +36 -0
- package/dist/preminter.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/anvil.ts +64 -47
- package/src/apis/generated/discover-api-types.ts +51 -9
- package/src/apis/generated/premint-api-types.ts +13 -3
- package/src/index.ts +2 -0
- package/src/premint/premint-client.ts +1 -1
- package/src/premint/preminter.test.ts +27 -9
- package/src/preminter.ts +136 -0
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Do not make direct changes to the file.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
export interface paths {
|
|
8
7
|
"/": {
|
|
9
8
|
/** Root */
|
|
@@ -148,7 +147,19 @@ export interface components {
|
|
|
148
147
|
* @description An enumeration.
|
|
149
148
|
* @enum {string}
|
|
150
149
|
*/
|
|
151
|
-
ChainName:
|
|
150
|
+
ChainName:
|
|
151
|
+
| "ETHEREUM-MAINNET"
|
|
152
|
+
| "ETHEREUM-ROPSTEN"
|
|
153
|
+
| "ETHEREUM-RINKEBY"
|
|
154
|
+
| "ETHEREUM-GOERLI"
|
|
155
|
+
| "ETHEREUM-SEPOLIA"
|
|
156
|
+
| "OPTIMISM-MAINNET"
|
|
157
|
+
| "OPTIMISM-GOERLI"
|
|
158
|
+
| "ZORA-GOERLI"
|
|
159
|
+
| "ZORA-MAINNET"
|
|
160
|
+
| "BASE-MAINNET"
|
|
161
|
+
| "BASE-GOERLI"
|
|
162
|
+
| "PGN-MAINNET";
|
|
152
163
|
/** Collection */
|
|
153
164
|
Collection: {
|
|
154
165
|
/** Address */
|
|
@@ -395,7 +406,12 @@ export interface components {
|
|
|
395
406
|
* @description An enumeration.
|
|
396
407
|
* @enum {string}
|
|
397
408
|
*/
|
|
398
|
-
FeedType:
|
|
409
|
+
FeedType:
|
|
410
|
+
| "curated"
|
|
411
|
+
| "most_recent"
|
|
412
|
+
| "heuristic"
|
|
413
|
+
| "trending"
|
|
414
|
+
| "recommendations";
|
|
399
415
|
/**
|
|
400
416
|
* FixedPrice
|
|
401
417
|
* @description ObjectBase extends Pydantic's BaseModel class to support extra functionality
|
|
@@ -691,7 +707,13 @@ export interface components {
|
|
|
691
707
|
/** Token Name */
|
|
692
708
|
token_name?: string;
|
|
693
709
|
/** Mint Context */
|
|
694
|
-
mint_context?:
|
|
710
|
+
mint_context?:
|
|
711
|
+
| components["schemas"]["ManifoldMintContext"]
|
|
712
|
+
| components["schemas"]["ZoraCreateMintContext"]
|
|
713
|
+
| components["schemas"]["FoundationMintContext"]
|
|
714
|
+
| components["schemas"]["ZoraCreate1155MintContext"]
|
|
715
|
+
| components["schemas"]["ZoraCreatePremintContext"]
|
|
716
|
+
| components["schemas"]["InferredMintContext"];
|
|
695
717
|
/** Is Active */
|
|
696
718
|
is_active: boolean;
|
|
697
719
|
cost: components["schemas"]["zora__collect__feed__models__price_at_time__PriceAtTime"];
|
|
@@ -729,13 +751,30 @@ export interface components {
|
|
|
729
751
|
* @description An enumeration.
|
|
730
752
|
* @enum {string}
|
|
731
753
|
*/
|
|
732
|
-
MintableStatus:
|
|
754
|
+
MintableStatus:
|
|
755
|
+
| "ACTIVE"
|
|
756
|
+
| "BLOCKED"
|
|
757
|
+
| "EXPIRED"
|
|
758
|
+
| "INVALID_MEDIA"
|
|
759
|
+
| "MINTED_OUT"
|
|
760
|
+
| "DELETED";
|
|
733
761
|
/**
|
|
734
762
|
* MintableType
|
|
735
763
|
* @description An enumeration.
|
|
736
764
|
* @enum {string}
|
|
737
765
|
*/
|
|
738
|
-
MintableType:
|
|
766
|
+
MintableType:
|
|
767
|
+
| "FOUNDATION_DROP_COLLECTION"
|
|
768
|
+
| "FOUNDATION_TIMED_EDITION"
|
|
769
|
+
| "MANIFOLD_ERC1155"
|
|
770
|
+
| "MANIFOLD_ERC721"
|
|
771
|
+
| "ZORA_CREATE"
|
|
772
|
+
| "ZORA_CREATE_1155"
|
|
773
|
+
| "ZORA_CREATE_1155_B2R_REDEEM_TOKEN"
|
|
774
|
+
| "ZORA_CREATE_1155_PREMINT_TOKEN"
|
|
775
|
+
| "ZORA_EDITION"
|
|
776
|
+
| "ZORA_DROP"
|
|
777
|
+
| "INFERRED";
|
|
739
778
|
/**
|
|
740
779
|
* Network
|
|
741
780
|
* @description An enumeration.
|
|
@@ -743,7 +782,9 @@ export interface components {
|
|
|
743
782
|
*/
|
|
744
783
|
Network: "MAINNET" | "GOERLI";
|
|
745
784
|
/** Notification */
|
|
746
|
-
Notification:
|
|
785
|
+
Notification:
|
|
786
|
+
| components["schemas"]["MintNotification"]
|
|
787
|
+
| components["schemas"]["MintCommentNotification"];
|
|
747
788
|
/**
|
|
748
789
|
* NotificationsResponse
|
|
749
790
|
* @description This is a generic model for pagination in an infitite scrolling context.
|
|
@@ -911,7 +952,9 @@ export interface components {
|
|
|
911
952
|
description?: string;
|
|
912
953
|
entity_type: components["schemas"]["EntityType"];
|
|
913
954
|
/** Entity */
|
|
914
|
-
entity:
|
|
955
|
+
entity:
|
|
956
|
+
| components["schemas"]["SearchCollection"]
|
|
957
|
+
| components["schemas"]["SearchToken"];
|
|
915
958
|
media?: components["schemas"]["Media"];
|
|
916
959
|
/**
|
|
917
960
|
* Rank
|
|
@@ -1377,7 +1420,6 @@ export type $defs = Record<string, never>;
|
|
|
1377
1420
|
export type external = Record<string, never>;
|
|
1378
1421
|
|
|
1379
1422
|
export interface operations {
|
|
1380
|
-
|
|
1381
1423
|
/** Root */
|
|
1382
1424
|
root__get: {
|
|
1383
1425
|
responses: {
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Do not make direct changes to the file.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
export interface paths {
|
|
8
7
|
"/signature": {
|
|
9
8
|
/** Upsert Premint Signature */
|
|
@@ -36,7 +35,19 @@ export interface components {
|
|
|
36
35
|
* @description An enumeration.
|
|
37
36
|
* @enum {string}
|
|
38
37
|
*/
|
|
39
|
-
ChainName:
|
|
38
|
+
ChainName:
|
|
39
|
+
| "ETHEREUM-MAINNET"
|
|
40
|
+
| "ETHEREUM-ROPSTEN"
|
|
41
|
+
| "ETHEREUM-RINKEBY"
|
|
42
|
+
| "ETHEREUM-GOERLI"
|
|
43
|
+
| "ETHEREUM-SEPOLIA"
|
|
44
|
+
| "OPTIMISM-MAINNET"
|
|
45
|
+
| "OPTIMISM-GOERLI"
|
|
46
|
+
| "ZORA-GOERLI"
|
|
47
|
+
| "ZORA-MAINNET"
|
|
48
|
+
| "BASE-MAINNET"
|
|
49
|
+
| "BASE-GOERLI"
|
|
50
|
+
| "PGN-MAINNET";
|
|
40
51
|
/**
|
|
41
52
|
* CollectionCreationConfig
|
|
42
53
|
* @description ObjectBase extends Pydantic's BaseModel class to support extra functionality
|
|
@@ -244,7 +255,6 @@ export type $defs = Record<string, never>;
|
|
|
244
255
|
export type external = Record<string, never>;
|
|
245
256
|
|
|
246
257
|
export interface operations {
|
|
247
|
-
|
|
248
258
|
/** Upsert Premint Signature */
|
|
249
259
|
upsert_premint_signature_signature_post: {
|
|
250
260
|
requestBody: {
|
package/src/index.ts
CHANGED
|
@@ -570,7 +570,7 @@ class PremintClient extends ClientBase {
|
|
|
570
570
|
quantityToMint: number;
|
|
571
571
|
mintComment?: string;
|
|
572
572
|
};
|
|
573
|
-
}): Promise<{request: SimulateContractParameters}> {
|
|
573
|
+
}): Promise<{ request: SimulateContractParameters }> {
|
|
574
574
|
if (mintArguments && mintArguments?.quantityToMint < 1) {
|
|
575
575
|
throw new Error("Quantity to mint cannot be below 1");
|
|
576
576
|
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
keccak256,
|
|
3
|
+
Hex,
|
|
4
|
+
concat,
|
|
5
|
+
recoverAddress,
|
|
6
|
+
hashDomain,
|
|
7
|
+
Address,
|
|
8
|
+
} from "viem";
|
|
2
9
|
import { foundry } from "viem/chains";
|
|
3
10
|
import { describe, expect } from "vitest";
|
|
4
11
|
import { parseEther } from "viem";
|
|
@@ -16,7 +23,12 @@ import {
|
|
|
16
23
|
TokenCreationConfig,
|
|
17
24
|
preminterTypedDataDefinition,
|
|
18
25
|
} from "./preminter";
|
|
19
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
AnvilViemClientsTest,
|
|
28
|
+
anvilTest,
|
|
29
|
+
forkUrls,
|
|
30
|
+
makeAnvilTest,
|
|
31
|
+
} from "src/anvil";
|
|
20
32
|
|
|
21
33
|
// create token and contract creation config:
|
|
22
34
|
const defaultContractConfig = ({
|
|
@@ -133,7 +145,10 @@ describe("ZoraCreator1155Preminter", () => {
|
|
|
133
145
|
},
|
|
134
146
|
20 * 1000,
|
|
135
147
|
);
|
|
136
|
-
|
|
148
|
+
makeAnvilTest({
|
|
149
|
+
forkUrl: forkUrls.zoraGoerli,
|
|
150
|
+
forkBlockNumber: 1676105,
|
|
151
|
+
})(
|
|
137
152
|
"can sign and recover a signature",
|
|
138
153
|
async ({ viemClients }) => {
|
|
139
154
|
const {
|
|
@@ -167,13 +182,15 @@ describe("ZoraCreator1155Preminter", () => {
|
|
|
167
182
|
account: creatorAccount,
|
|
168
183
|
});
|
|
169
184
|
|
|
185
|
+
const preminterAddress = zoraCreator1155PremintExecutorAddress[999];
|
|
170
186
|
// recover and verify address is correct
|
|
171
|
-
const recoveredAddress =
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
187
|
+
const [, , recoveredAddress] =
|
|
188
|
+
await viemClients.publicClient.readContract({
|
|
189
|
+
abi: preminterAbi,
|
|
190
|
+
address: preminterAddress,
|
|
191
|
+
functionName: "isValidSignature",
|
|
192
|
+
args: [contractConfig, premintConfig, signedMessage],
|
|
193
|
+
});
|
|
177
194
|
|
|
178
195
|
expect(recoveredAddress).to.equal(creatorAccount);
|
|
179
196
|
},
|
|
@@ -279,6 +296,7 @@ describe("ZoraCreator1155Preminter", () => {
|
|
|
279
296
|
args: [contractAddress, premintConfig.uid],
|
|
280
297
|
});
|
|
281
298
|
|
|
299
|
+
expect(contractCreated).toBe(true);
|
|
282
300
|
expect(tokenId).not.toBe(0n);
|
|
283
301
|
|
|
284
302
|
// now use what was created, to get the balance from the created contract
|
package/src/preminter.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Address } from "abitype";
|
|
2
|
+
import { ExtractAbiFunction, AbiParametersToPrimitiveTypes } from "abitype";
|
|
3
|
+
import {
|
|
4
|
+
zoraCreator1155PremintExecutorImplABI as preminterAbi,
|
|
5
|
+
zoraCreator1155PremintExecutorImplAddress,
|
|
6
|
+
} from "@zoralabs/protocol-deployments";
|
|
7
|
+
import {
|
|
8
|
+
TypedDataDefinition,
|
|
9
|
+
recoverTypedDataAddress,
|
|
10
|
+
Hex,
|
|
11
|
+
PublicClient,
|
|
12
|
+
} from "viem";
|
|
13
|
+
|
|
14
|
+
type PremintInputs = ExtractAbiFunction<
|
|
15
|
+
typeof preminterAbi,
|
|
16
|
+
"premint"
|
|
17
|
+
>["inputs"];
|
|
18
|
+
|
|
19
|
+
type PreminterHashDataTypes = AbiParametersToPrimitiveTypes<PremintInputs>;
|
|
20
|
+
|
|
21
|
+
export type ContractCreationConfig = PreminterHashDataTypes[0];
|
|
22
|
+
export type PremintConfig = PreminterHashDataTypes[1];
|
|
23
|
+
export type TokenCreationConfig = PremintConfig["tokenConfig"];
|
|
24
|
+
|
|
25
|
+
// Convenience method to create the structured typed data
|
|
26
|
+
// needed to sign for a premint contract and token
|
|
27
|
+
export const preminterTypedDataDefinition = ({
|
|
28
|
+
verifyingContract,
|
|
29
|
+
premintConfig,
|
|
30
|
+
chainId,
|
|
31
|
+
}: {
|
|
32
|
+
verifyingContract: Address;
|
|
33
|
+
premintConfig: PremintConfig;
|
|
34
|
+
chainId: number;
|
|
35
|
+
}) => {
|
|
36
|
+
const { tokenConfig, uid, version, deleted } = premintConfig;
|
|
37
|
+
const types = {
|
|
38
|
+
CreatorAttribution: [
|
|
39
|
+
{ name: "tokenConfig", type: "TokenCreationConfig" },
|
|
40
|
+
// unique id scoped to the contract and token to create.
|
|
41
|
+
// ensure that a signature can be replaced, as long as the replacement
|
|
42
|
+
// has the same uid, and a newer version.
|
|
43
|
+
{ name: "uid", type: "uint32" },
|
|
44
|
+
{ name: "version", type: "uint32" },
|
|
45
|
+
// if this update should result in the signature being deleted.
|
|
46
|
+
{ name: "deleted", type: "bool" },
|
|
47
|
+
],
|
|
48
|
+
TokenCreationConfig: [
|
|
49
|
+
{ name: "tokenURI", type: "string" },
|
|
50
|
+
{ name: "maxSupply", type: "uint256" },
|
|
51
|
+
{ name: "maxTokensPerAddress", type: "uint64" },
|
|
52
|
+
{ name: "pricePerToken", type: "uint96" },
|
|
53
|
+
{ name: "mintStart", type: "uint64" },
|
|
54
|
+
{ name: "mintDuration", type: "uint64" },
|
|
55
|
+
{ name: "royaltyMintSchedule", type: "uint32" },
|
|
56
|
+
{ name: "royaltyBPS", type: "uint32" },
|
|
57
|
+
{ name: "royaltyRecipient", type: "address" },
|
|
58
|
+
{ name: "fixedPriceMinter", type: "address" },
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const result: TypedDataDefinition<typeof types, "CreatorAttribution"> = {
|
|
63
|
+
domain: {
|
|
64
|
+
chainId,
|
|
65
|
+
name: "Preminter",
|
|
66
|
+
version: "1",
|
|
67
|
+
verifyingContract: verifyingContract,
|
|
68
|
+
},
|
|
69
|
+
types,
|
|
70
|
+
message: {
|
|
71
|
+
tokenConfig,
|
|
72
|
+
uid,
|
|
73
|
+
version,
|
|
74
|
+
deleted,
|
|
75
|
+
},
|
|
76
|
+
primaryType: "CreatorAttribution",
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return result;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export async function isValidSignatureV1({
|
|
83
|
+
contractAddress,
|
|
84
|
+
originalContractAdmin,
|
|
85
|
+
premintConfig,
|
|
86
|
+
signature,
|
|
87
|
+
chainId,
|
|
88
|
+
publicClient,
|
|
89
|
+
}: {
|
|
90
|
+
contractAddress: Address;
|
|
91
|
+
originalContractAdmin: Address;
|
|
92
|
+
premintConfig: PremintConfig;
|
|
93
|
+
signature: Hex;
|
|
94
|
+
chainId: number;
|
|
95
|
+
publicClient: PublicClient;
|
|
96
|
+
}): Promise<{
|
|
97
|
+
isAuthorized: boolean;
|
|
98
|
+
recoveredAddress?: Address;
|
|
99
|
+
}> {
|
|
100
|
+
const typedData = preminterTypedDataDefinition({
|
|
101
|
+
verifyingContract: contractAddress,
|
|
102
|
+
premintConfig,
|
|
103
|
+
chainId,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// recover the address from the signature
|
|
107
|
+
let recoveredAddress: Address;
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
recoveredAddress = await recoverTypedDataAddress({
|
|
111
|
+
...typedData,
|
|
112
|
+
signature,
|
|
113
|
+
});
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error(error);
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
isAuthorized: false,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// premint executor is same address on all chains
|
|
123
|
+
const premintExecutorAddress = zoraCreator1155PremintExecutorImplAddress[999];
|
|
124
|
+
|
|
125
|
+
const isAuthorized = await publicClient.readContract({
|
|
126
|
+
abi: preminterAbi,
|
|
127
|
+
address: premintExecutorAddress,
|
|
128
|
+
functionName: "isAuthorizedToCreatePremint",
|
|
129
|
+
args: [recoveredAddress, originalContractAdmin, contractAddress],
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
isAuthorized,
|
|
134
|
+
recoveredAddress,
|
|
135
|
+
};
|
|
136
|
+
}
|