@zoralabs/protocol-sdk 0.7.6 → 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 +17 -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/1155-create-helper.d.ts +14 -11
- package/dist/create/1155-create-helper.d.ts.map +1 -1
- package/dist/create/contract-setup.d.ts +13 -8
- 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 +53 -13
- 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 +1660 -1246
- 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 +1681 -1264
- 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/sdk.d.ts +2 -1
- package/dist/sdk.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 -3
- 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 +269 -113
- package/src/create/1155-create-helper.ts +204 -90
- package/src/create/contract-setup.ts +54 -44
- 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 +94 -25
- 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/sdk.ts +5 -2
- package/src/types.ts +1 -1
- package/src/utils.ts +1 -25
|
@@ -8,13 +8,23 @@ import type {
|
|
|
8
8
|
Address,
|
|
9
9
|
Hex,
|
|
10
10
|
PublicClient,
|
|
11
|
-
SimulateContractParameters,
|
|
12
11
|
TransactionReceipt,
|
|
13
12
|
} from "viem";
|
|
14
13
|
import { decodeEventLog } from "viem";
|
|
15
14
|
import { makeContractParameters } from "src/utils";
|
|
16
|
-
import {
|
|
17
|
-
|
|
15
|
+
import {
|
|
16
|
+
getContractInfoExistingContract,
|
|
17
|
+
getDeterministicContractAddress,
|
|
18
|
+
new1155ContractVersion,
|
|
19
|
+
} from "./contract-setup";
|
|
20
|
+
import {
|
|
21
|
+
CreateNew1155ContractAndTokenReturn,
|
|
22
|
+
CreateNew1155ContractParams,
|
|
23
|
+
CreateNew1155ParamsBase,
|
|
24
|
+
CreateNew1155TokenParams,
|
|
25
|
+
CreateNew1155TokenReturn,
|
|
26
|
+
NewContractParams,
|
|
27
|
+
} from "./types";
|
|
18
28
|
import { constructCreate1155TokenCalls } from "./token-setup";
|
|
19
29
|
|
|
20
30
|
// Default royalty bps
|
|
@@ -22,7 +32,7 @@ const ROYALTY_BPS_DEFAULT = 1000;
|
|
|
22
32
|
|
|
23
33
|
export const getTokenIdFromCreateReceipt = (
|
|
24
34
|
receipt: TransactionReceipt,
|
|
25
|
-
): bigint
|
|
35
|
+
): bigint => {
|
|
26
36
|
for (const data of receipt.logs) {
|
|
27
37
|
try {
|
|
28
38
|
const decodedLog = decodeEventLog({
|
|
@@ -35,73 +45,84 @@ export const getTokenIdFromCreateReceipt = (
|
|
|
35
45
|
}
|
|
36
46
|
} catch (err: any) {}
|
|
37
47
|
}
|
|
48
|
+
|
|
49
|
+
throw new Error(
|
|
50
|
+
"No event found in receipt that could be used to get tokenId",
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const getContractAddressFromReceipt = (
|
|
55
|
+
receipt: TransactionReceipt,
|
|
56
|
+
): Address => {
|
|
57
|
+
for (const data of receipt.logs) {
|
|
58
|
+
try {
|
|
59
|
+
const decodedLog = decodeEventLog({
|
|
60
|
+
abi: zoraCreator1155FactoryImplABI,
|
|
61
|
+
eventName: "SetupNewContract",
|
|
62
|
+
...data,
|
|
63
|
+
});
|
|
64
|
+
if (decodedLog && decodedLog.eventName === "SetupNewContract") {
|
|
65
|
+
return decodedLog.args.newContract;
|
|
66
|
+
}
|
|
67
|
+
} catch (err: any) {}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
throw new Error(
|
|
71
|
+
"No event found in receipt that could be used to get contract address",
|
|
72
|
+
);
|
|
38
73
|
};
|
|
39
74
|
|
|
40
|
-
type
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
any,
|
|
44
|
-
any,
|
|
45
|
-
any,
|
|
46
|
-
any,
|
|
47
|
-
Account | Address
|
|
48
|
-
>;
|
|
75
|
+
type MakeContractParametersBase = {
|
|
76
|
+
account: Address | Account;
|
|
77
|
+
|
|
49
78
|
tokenSetupActions: Hex[];
|
|
50
|
-
collectionAddress: Address;
|
|
51
|
-
newTokenId: bigint;
|
|
52
|
-
newToken: New1155Token;
|
|
53
|
-
minter: Address;
|
|
54
|
-
contractExists: boolean;
|
|
55
79
|
};
|
|
56
80
|
|
|
57
|
-
function makeCreateContractAndTokenCall({
|
|
58
|
-
contractExists,
|
|
59
|
-
contractAddress,
|
|
60
|
-
contract,
|
|
81
|
+
export function makeCreateContractAndTokenCall({
|
|
61
82
|
account,
|
|
83
|
+
contract,
|
|
62
84
|
royaltyBPS,
|
|
63
|
-
tokenSetupActions,
|
|
64
85
|
fundsRecipient,
|
|
86
|
+
tokenSetupActions,
|
|
87
|
+
chainId,
|
|
65
88
|
}: {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
contract: ContractType;
|
|
69
|
-
account: Address | Account;
|
|
89
|
+
chainId: number;
|
|
90
|
+
contract: NewContractParams;
|
|
70
91
|
royaltyBPS?: number;
|
|
71
92
|
fundsRecipient?: Address;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const accountAddress =
|
|
84
|
-
typeof account === "string" ? account : account.address;
|
|
85
|
-
return makeContractParameters({
|
|
86
|
-
abi: zoraCreator1155FactoryImplABI,
|
|
87
|
-
functionName: "createContractDeterministic",
|
|
88
|
-
account,
|
|
89
|
-
address: zoraCreator1155FactoryImplAddress[999],
|
|
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,
|
|
93
|
+
} & MakeContractParametersBase) {
|
|
94
|
+
const accountAddress =
|
|
95
|
+
typeof account === "string" ? account : account.address;
|
|
96
|
+
return makeContractParameters({
|
|
97
|
+
abi: zoraCreator1155FactoryImplABI,
|
|
98
|
+
functionName: "createContractDeterministic",
|
|
99
|
+
account,
|
|
100
|
+
address:
|
|
101
|
+
zoraCreator1155FactoryImplAddress[
|
|
102
|
+
chainId as keyof typeof zoraCreator1155FactoryImplAddress
|
|
101
103
|
],
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
args: [
|
|
105
|
+
contract.uri,
|
|
106
|
+
contract.name,
|
|
107
|
+
{
|
|
108
|
+
// deprecated
|
|
109
|
+
royaltyMintSchedule: 0,
|
|
110
|
+
royaltyBPS: royaltyBPS || ROYALTY_BPS_DEFAULT,
|
|
111
|
+
royaltyRecipient: fundsRecipient || accountAddress,
|
|
112
|
+
},
|
|
113
|
+
contract.defaultAdmin || accountAddress,
|
|
114
|
+
tokenSetupActions,
|
|
115
|
+
],
|
|
116
|
+
});
|
|
117
|
+
}
|
|
104
118
|
|
|
119
|
+
function makeCreateTokenCall({
|
|
120
|
+
contractAddress,
|
|
121
|
+
account,
|
|
122
|
+
tokenSetupActions,
|
|
123
|
+
}: {
|
|
124
|
+
contractAddress: Address;
|
|
125
|
+
} & MakeContractParametersBase) {
|
|
105
126
|
return makeContractParameters({
|
|
106
127
|
abi: zoraCreator1155ImplABI,
|
|
107
128
|
functionName: "multicall",
|
|
@@ -126,73 +147,166 @@ export class Create1155Client {
|
|
|
126
147
|
this.publicClient = publicClient;
|
|
127
148
|
}
|
|
128
149
|
|
|
129
|
-
async
|
|
130
|
-
|
|
150
|
+
async createNew1155(
|
|
151
|
+
props: CreateNew1155ContractParams,
|
|
152
|
+
): Promise<CreateNew1155ContractAndTokenReturn> {
|
|
153
|
+
return createNew1155ContractAndToken({
|
|
131
154
|
...props,
|
|
132
155
|
publicClient: this.publicClient,
|
|
133
156
|
chainId: this.chainId,
|
|
134
157
|
});
|
|
135
158
|
}
|
|
159
|
+
|
|
160
|
+
async createNew1155OnExistingContract({
|
|
161
|
+
contractAddress: contract,
|
|
162
|
+
account,
|
|
163
|
+
token,
|
|
164
|
+
getAdditionalSetupActions,
|
|
165
|
+
}: CreateNew1155TokenParams): Promise<CreateNew1155TokenReturn> {
|
|
166
|
+
return createNew1155Token({
|
|
167
|
+
contractAddress: contract,
|
|
168
|
+
account,
|
|
169
|
+
token,
|
|
170
|
+
getAdditionalSetupActions,
|
|
171
|
+
publicClient: this.publicClient,
|
|
172
|
+
chainId: this.chainId,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
136
175
|
}
|
|
137
176
|
|
|
138
|
-
async function
|
|
177
|
+
async function createNew1155ContractAndToken({
|
|
139
178
|
contract,
|
|
140
179
|
account,
|
|
180
|
+
chainId,
|
|
181
|
+
token,
|
|
182
|
+
publicClient,
|
|
183
|
+
getAdditionalSetupActions,
|
|
184
|
+
}: CreateNew1155ContractParams & {
|
|
185
|
+
publicClient: Pick<PublicClient, "readContract">;
|
|
186
|
+
chainId: number;
|
|
187
|
+
}): Promise<CreateNew1155ContractAndTokenReturn> {
|
|
188
|
+
const nextTokenId = 1n;
|
|
189
|
+
const contractVersion = new1155ContractVersion(chainId);
|
|
190
|
+
|
|
191
|
+
const {
|
|
192
|
+
minter,
|
|
193
|
+
newToken,
|
|
194
|
+
setupActions: tokenSetupActions,
|
|
195
|
+
} = await prepareSetupActions({
|
|
196
|
+
chainId,
|
|
197
|
+
account,
|
|
198
|
+
contractVersion,
|
|
199
|
+
nextTokenId,
|
|
200
|
+
token,
|
|
201
|
+
getAdditionalSetupActions,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const request = makeCreateContractAndTokenCall({
|
|
205
|
+
contract,
|
|
206
|
+
account,
|
|
207
|
+
chainId,
|
|
208
|
+
tokenSetupActions,
|
|
209
|
+
fundsRecipient: token.payoutRecipient,
|
|
210
|
+
royaltyBPS: token.royaltyBPS,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const contractAddress = await getDeterministicContractAddress({
|
|
214
|
+
account,
|
|
215
|
+
publicClient,
|
|
216
|
+
setupActions: tokenSetupActions,
|
|
217
|
+
chainId,
|
|
218
|
+
contract,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
parameters: request,
|
|
223
|
+
tokenSetupActions,
|
|
224
|
+
newTokenId: nextTokenId,
|
|
225
|
+
newToken,
|
|
226
|
+
contractAddress: contractAddress,
|
|
227
|
+
contractVersion,
|
|
228
|
+
minter,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async function createNew1155Token({
|
|
233
|
+
contractAddress: contractAddress,
|
|
234
|
+
account,
|
|
141
235
|
getAdditionalSetupActions,
|
|
142
|
-
token
|
|
236
|
+
token,
|
|
143
237
|
publicClient,
|
|
144
238
|
chainId,
|
|
145
|
-
}:
|
|
239
|
+
}: CreateNew1155TokenParams & {
|
|
146
240
|
publicClient: Pick<PublicClient, "readContract">;
|
|
147
241
|
chainId: number;
|
|
148
242
|
}): Promise<CreateNew1155TokenReturn> {
|
|
149
|
-
const {
|
|
150
|
-
await
|
|
243
|
+
const { nextTokenId, contractVersion } =
|
|
244
|
+
await getContractInfoExistingContract({
|
|
151
245
|
publicClient,
|
|
152
|
-
|
|
153
|
-
contract,
|
|
154
|
-
account,
|
|
246
|
+
contractAddress: contractAddress,
|
|
155
247
|
});
|
|
156
248
|
|
|
157
249
|
const {
|
|
158
250
|
minter,
|
|
159
251
|
newToken,
|
|
160
252
|
setupActions: tokenSetupActions,
|
|
161
|
-
} =
|
|
162
|
-
chainId
|
|
163
|
-
|
|
253
|
+
} = await prepareSetupActions({
|
|
254
|
+
chainId,
|
|
255
|
+
account,
|
|
164
256
|
contractVersion,
|
|
165
257
|
nextTokenId,
|
|
166
|
-
|
|
258
|
+
token,
|
|
259
|
+
getAdditionalSetupActions,
|
|
167
260
|
});
|
|
168
261
|
|
|
169
|
-
const
|
|
170
|
-
? [
|
|
171
|
-
...getAdditionalSetupActions({
|
|
172
|
-
tokenId: nextTokenId,
|
|
173
|
-
contractAddress,
|
|
174
|
-
}),
|
|
175
|
-
...tokenSetupActions,
|
|
176
|
-
]
|
|
177
|
-
: tokenSetupActions;
|
|
178
|
-
|
|
179
|
-
const request = makeCreateContractAndTokenCall({
|
|
180
|
-
contractExists,
|
|
262
|
+
const request = makeCreateTokenCall({
|
|
181
263
|
contractAddress,
|
|
182
|
-
contract,
|
|
183
264
|
account,
|
|
184
|
-
tokenSetupActions
|
|
185
|
-
royaltyBPS: tokenConfig.royaltyBPS,
|
|
186
|
-
fundsRecipient: tokenConfig.payoutRecipient,
|
|
265
|
+
tokenSetupActions,
|
|
187
266
|
});
|
|
188
267
|
|
|
189
268
|
return {
|
|
190
269
|
parameters: request,
|
|
191
270
|
tokenSetupActions,
|
|
192
|
-
collectionAddress: contractAddress,
|
|
193
|
-
contractExists,
|
|
194
271
|
newTokenId: nextTokenId,
|
|
195
272
|
newToken,
|
|
273
|
+
contractVersion,
|
|
196
274
|
minter,
|
|
197
275
|
};
|
|
198
276
|
}
|
|
277
|
+
|
|
278
|
+
async function prepareSetupActions({
|
|
279
|
+
chainId,
|
|
280
|
+
account,
|
|
281
|
+
contractVersion,
|
|
282
|
+
nextTokenId,
|
|
283
|
+
token,
|
|
284
|
+
getAdditionalSetupActions,
|
|
285
|
+
}: {
|
|
286
|
+
chainId: number;
|
|
287
|
+
contractVersion: string;
|
|
288
|
+
nextTokenId: bigint;
|
|
289
|
+
} & CreateNew1155ParamsBase) {
|
|
290
|
+
const {
|
|
291
|
+
minter,
|
|
292
|
+
newToken,
|
|
293
|
+
setupActions: tokenSetupActions,
|
|
294
|
+
} = await constructCreate1155TokenCalls({
|
|
295
|
+
chainId: chainId,
|
|
296
|
+
ownerAddress: account,
|
|
297
|
+
contractVersion,
|
|
298
|
+
nextTokenId,
|
|
299
|
+
...token,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
const setupActions = getAdditionalSetupActions
|
|
303
|
+
? [
|
|
304
|
+
...getAdditionalSetupActions({
|
|
305
|
+
tokenId: nextTokenId,
|
|
306
|
+
}),
|
|
307
|
+
...tokenSetupActions,
|
|
308
|
+
]
|
|
309
|
+
: tokenSetupActions;
|
|
310
|
+
|
|
311
|
+
return { minter, newToken, setupActions };
|
|
312
|
+
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { Address, PublicClient } from "viem";
|
|
2
|
-
import { ContractType } from "./types";
|
|
1
|
+
import { Address, Hex, PublicClient } from "viem";
|
|
3
2
|
import {
|
|
4
3
|
contracts1155,
|
|
5
4
|
zoraCreator1155FactoryImplABI,
|
|
6
5
|
zoraCreator1155FactoryImplAddress,
|
|
7
6
|
zoraCreator1155ImplABI,
|
|
8
7
|
} from "@zoralabs/protocol-deployments";
|
|
8
|
+
import { NewContractParams } from "./types";
|
|
9
9
|
|
|
10
10
|
type contracts1155Address = keyof typeof contracts1155.addresses;
|
|
11
|
-
function new1155ContractVersion(chainId: number): string {
|
|
11
|
+
export function new1155ContractVersion(chainId: number): string {
|
|
12
|
+
// todo: get from subgraph
|
|
12
13
|
const address = contracts1155.addresses[chainId as contracts1155Address];
|
|
13
14
|
if (!address) {
|
|
14
15
|
throw new Error(`No contract address for chainId ${chainId}`);
|
|
@@ -17,72 +18,81 @@ function new1155ContractVersion(chainId: number): string {
|
|
|
17
18
|
return address.CONTRACT_1155_IMPL_VERSION;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
export async function
|
|
21
|
+
export async function getContractInfoExistingContract({
|
|
21
22
|
publicClient,
|
|
22
|
-
|
|
23
|
-
contract,
|
|
24
|
-
account,
|
|
23
|
+
contractAddress,
|
|
25
24
|
}: {
|
|
26
25
|
publicClient: Pick<PublicClient, "readContract">;
|
|
27
|
-
|
|
28
|
-
contract: ContractType;
|
|
26
|
+
contractAddress: Address;
|
|
29
27
|
// Account that is the creator of the contract
|
|
30
|
-
account: Address;
|
|
31
28
|
}): Promise<{
|
|
32
|
-
contractExists: boolean;
|
|
33
|
-
contractAddress: Address;
|
|
34
29
|
contractVersion: string;
|
|
30
|
+
contractName: string;
|
|
35
31
|
nextTokenId: bigint;
|
|
36
32
|
}> {
|
|
37
33
|
// Check if contract exists either from metadata or the static address passed in.
|
|
38
34
|
// 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
35
|
let contractVersion: string;
|
|
59
|
-
let contractExists: boolean;
|
|
60
36
|
try {
|
|
61
37
|
contractVersion = await publicClient.readContract({
|
|
62
38
|
abi: zoraCreator1155ImplABI,
|
|
63
39
|
address: contractAddress,
|
|
64
40
|
functionName: "contractVersion",
|
|
65
41
|
});
|
|
66
|
-
contractExists = true;
|
|
67
42
|
} catch (e: any) {
|
|
68
43
|
// This logic branch is hit if the contract doesn't exist
|
|
69
44
|
// falling back to contractExists to false.
|
|
70
|
-
|
|
71
|
-
contractExists = false;
|
|
45
|
+
throw new Error(`Contract does not exist at ${contractAddress}`);
|
|
72
46
|
}
|
|
73
47
|
|
|
74
|
-
const nextTokenId =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
const nextTokenId = await publicClient.readContract({
|
|
49
|
+
address: contractAddress,
|
|
50
|
+
abi: zoraCreator1155ImplABI,
|
|
51
|
+
functionName: "nextTokenId",
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const contractName = await publicClient.readContract({
|
|
55
|
+
address: contractAddress,
|
|
56
|
+
abi: zoraCreator1155ImplABI,
|
|
57
|
+
functionName: "name",
|
|
58
|
+
});
|
|
81
59
|
|
|
82
60
|
return {
|
|
83
|
-
contractExists,
|
|
84
|
-
contractAddress,
|
|
85
61
|
contractVersion,
|
|
62
|
+
contractName,
|
|
86
63
|
nextTokenId,
|
|
87
64
|
};
|
|
88
65
|
}
|
|
66
|
+
|
|
67
|
+
export async function getDeterministicContractAddress({
|
|
68
|
+
publicClient,
|
|
69
|
+
account,
|
|
70
|
+
setupActions,
|
|
71
|
+
contract,
|
|
72
|
+
chainId,
|
|
73
|
+
}: {
|
|
74
|
+
account: Address;
|
|
75
|
+
publicClient: Pick<PublicClient, "readContract">;
|
|
76
|
+
setupActions: Hex[];
|
|
77
|
+
contract: NewContractParams;
|
|
78
|
+
chainId: number;
|
|
79
|
+
// Account that is the creator of the contract
|
|
80
|
+
}): Promise<Address> {
|
|
81
|
+
const contractAddress = await publicClient.readContract({
|
|
82
|
+
abi: zoraCreator1155FactoryImplABI,
|
|
83
|
+
address:
|
|
84
|
+
zoraCreator1155FactoryImplAddress[
|
|
85
|
+
chainId as keyof typeof zoraCreator1155FactoryImplAddress
|
|
86
|
+
],
|
|
87
|
+
functionName: "deterministicContractAddressWithSetupActions",
|
|
88
|
+
args: [
|
|
89
|
+
account,
|
|
90
|
+
contract.uri,
|
|
91
|
+
contract.name,
|
|
92
|
+
contract.defaultAdmin || account,
|
|
93
|
+
setupActions,
|
|
94
|
+
],
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return contractAddress;
|
|
98
|
+
}
|
|
@@ -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
|
+
};
|