@zoralabs/protocol-sdk 0.9.1 → 0.9.3
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 +12 -0
- package/dist/anvil.d.ts.map +1 -1
- package/dist/apis/http-api-base.d.ts +1 -1
- package/dist/apis/http-api-base.d.ts.map +1 -1
- package/dist/apis/subgraph-querier.d.ts +6 -0
- package/dist/apis/subgraph-querier.d.ts.map +1 -1
- package/dist/create/1155-create-helper.d.ts +4 -1
- package/dist/create/1155-create-helper.d.ts.map +1 -1
- package/dist/create/contract-getter.d.ts +30 -0
- package/dist/create/contract-getter.d.ts.map +1 -0
- package/dist/create/contract-setup.d.ts +4 -8
- package/dist/create/contract-setup.d.ts.map +1 -1
- package/dist/create/mint-from-create.d.ts +3 -3
- package/dist/create/mint-from-create.d.ts.map +1 -1
- package/dist/create/minter-defaults.d.ts +1 -1
- package/dist/create/minter-defaults.d.ts.map +1 -1
- package/dist/create/subgraph-queries.d.ts +13 -0
- package/dist/create/subgraph-queries.d.ts.map +1 -0
- package/dist/create/token-setup.d.ts +2 -0
- package/dist/create/token-setup.d.ts.map +1 -1
- package/dist/index.cjs +2166 -2099
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2188 -2121
- package/dist/index.js.map +1 -1
- package/dist/mint/subgraph-mint-getter.d.ts +2 -2
- package/dist/mint/subgraph-mint-getter.d.ts.map +1 -1
- package/dist/mint/subgraph-queries.d.ts +1 -5
- package/dist/mint/subgraph-queries.d.ts.map +1 -1
- package/dist/retries.d.ts +7 -0
- package/dist/retries.d.ts.map +1 -0
- package/dist/sdk.d.ts +2 -0
- package/dist/sdk.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/apis/http-api-base.ts +12 -20
- package/src/apis/subgraph-querier.ts +7 -0
- package/src/create/1155-create-helper.test.ts +68 -3
- package/src/create/1155-create-helper.ts +23 -9
- package/src/create/contract-getter.ts +90 -0
- package/src/create/contract-setup.ts +17 -46
- package/src/create/mint-from-create.ts +7 -15
- package/src/create/minter-defaults.ts +11 -20
- package/src/create/subgraph-queries.ts +35 -0
- package/src/create/token-setup.ts +5 -1
- package/src/create/types.ts +1 -1
- package/src/mint/subgraph-mint-getter.ts +5 -2
- package/src/mint/subgraph-queries.ts +1 -7
- package/src/retries.ts +49 -0
- package/src/sdk.ts +8 -0
- package/test-integration/create-multiple-tokens-on-contract.ts +104 -0
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
ConcreteSalesConfig,
|
|
10
10
|
TimedSaleParamsType,
|
|
11
11
|
} from "./types";
|
|
12
|
-
import { fetchTokenMetadata } from "src/ipfs/token-metadata";
|
|
13
12
|
|
|
14
13
|
// Sales end forever amount (uint64 max)
|
|
15
14
|
export const SALE_END_FOREVER = 18446744073709551615n;
|
|
@@ -75,30 +74,19 @@ export const parseNameIntoSymbol = (name: string) => {
|
|
|
75
74
|
return result;
|
|
76
75
|
};
|
|
77
76
|
|
|
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
77
|
const timedSaleSettingsWithDefaults = async (
|
|
90
78
|
params: TimedSaleParamsType,
|
|
91
|
-
|
|
79
|
+
contractName: string,
|
|
92
80
|
): Promise<Concrete<TimedSaleParamsType>> => {
|
|
93
81
|
// If the name is not provided, try to fetch it from the metadata
|
|
94
|
-
const erc20Name =
|
|
95
|
-
params.erc20Name || (await fetchTokenNameFromMetadata(tokenMetadataURI));
|
|
82
|
+
const erc20Name = params.erc20Name || contractName;
|
|
96
83
|
const symbol = params.erc20Symbol || parseNameIntoSymbol(erc20Name);
|
|
97
84
|
|
|
98
85
|
return {
|
|
99
86
|
type: "timed",
|
|
100
87
|
...DEFAULT_SALE_START_AND_END,
|
|
101
|
-
|
|
88
|
+
...params,
|
|
89
|
+
erc20Name: erc20Name,
|
|
102
90
|
erc20Symbol: symbol,
|
|
103
91
|
};
|
|
104
92
|
};
|
|
@@ -112,14 +100,17 @@ const isErc20 = (
|
|
|
112
100
|
const isFixedPrice = (
|
|
113
101
|
salesConfig: SalesConfigParamsType,
|
|
114
102
|
): salesConfig is FixedPriceParamsType => {
|
|
115
|
-
return (
|
|
103
|
+
return (
|
|
104
|
+
salesConfig.type === "fixedPrice" ||
|
|
105
|
+
(salesConfig as FixedPriceParamsType).pricePerToken > 0n
|
|
106
|
+
);
|
|
116
107
|
};
|
|
117
108
|
|
|
118
109
|
export const getSalesConfigWithDefaults = async (
|
|
119
110
|
salesConfig: SalesConfigParamsType | undefined,
|
|
120
|
-
|
|
111
|
+
contractName: string,
|
|
121
112
|
): Promise<ConcreteSalesConfig> => {
|
|
122
|
-
if (!salesConfig) return timedSaleSettingsWithDefaults({},
|
|
113
|
+
if (!salesConfig) return timedSaleSettingsWithDefaults({}, contractName);
|
|
123
114
|
if (isAllowList(salesConfig)) {
|
|
124
115
|
return allowListWithDefaults(salesConfig);
|
|
125
116
|
}
|
|
@@ -130,5 +121,5 @@ export const getSalesConfigWithDefaults = async (
|
|
|
130
121
|
return fixedPriceSettingsWithDefaults(salesConfig);
|
|
131
122
|
}
|
|
132
123
|
|
|
133
|
-
return timedSaleSettingsWithDefaults(salesConfig,
|
|
124
|
+
return timedSaleSettingsWithDefaults(salesConfig, contractName);
|
|
134
125
|
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ISubgraphQuery } from "src/apis/subgraph-querier";
|
|
2
|
+
import { Address } from "viem";
|
|
3
|
+
|
|
4
|
+
export function buildContractInfoQuery({
|
|
5
|
+
contractAddress,
|
|
6
|
+
}: {
|
|
7
|
+
contractAddress: Address;
|
|
8
|
+
}): ISubgraphQuery<{
|
|
9
|
+
name: string;
|
|
10
|
+
contractVersion: string;
|
|
11
|
+
mintFeePerQuantity: string;
|
|
12
|
+
tokens: {
|
|
13
|
+
tokenId: Address;
|
|
14
|
+
}[];
|
|
15
|
+
}> {
|
|
16
|
+
return {
|
|
17
|
+
query: `
|
|
18
|
+
query ($contractAddress: Bytes!) {
|
|
19
|
+
zoraCreateContract(id: $contractAddress) {
|
|
20
|
+
contractVersion
|
|
21
|
+
name
|
|
22
|
+
mintFeePerQuantity
|
|
23
|
+
tokens(first: 1, orderBy: tokenId, orderDirection: desc) {
|
|
24
|
+
tokenId
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
`,
|
|
29
|
+
variables: {
|
|
30
|
+
contractAddress: contractAddress.toLowerCase(),
|
|
31
|
+
},
|
|
32
|
+
parseResponseData: (responseData: any | undefined) =>
|
|
33
|
+
responseData.zoraCreateContract,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -9,6 +9,7 @@ import { setupMinters } from "./minter-setup";
|
|
|
9
9
|
async function applyNew1155Defaults(
|
|
10
10
|
props: CreateNew1155TokenProps,
|
|
11
11
|
ownerAddress: Address,
|
|
12
|
+
contractName: string,
|
|
12
13
|
): Promise<New1155Token> {
|
|
13
14
|
const { payoutRecipient: fundsRecipient } = props;
|
|
14
15
|
const fundsRecipientOrOwner =
|
|
@@ -26,7 +27,7 @@ async function applyNew1155Defaults(
|
|
|
26
27
|
tokenMetadataURI: props.tokenMetadataURI,
|
|
27
28
|
salesConfig: await getSalesConfigWithDefaults(
|
|
28
29
|
props.salesConfig,
|
|
29
|
-
|
|
30
|
+
contractName,
|
|
30
31
|
),
|
|
31
32
|
};
|
|
32
33
|
}
|
|
@@ -117,6 +118,8 @@ export async function constructCreate1155TokenCalls(
|
|
|
117
118
|
ContractProps & {
|
|
118
119
|
ownerAddress: Address;
|
|
119
120
|
chainId: number;
|
|
121
|
+
} & {
|
|
122
|
+
contractName: string;
|
|
120
123
|
},
|
|
121
124
|
): Promise<{
|
|
122
125
|
setupActions: `0x${string}`[];
|
|
@@ -134,6 +137,7 @@ export async function constructCreate1155TokenCalls(
|
|
|
134
137
|
const new1155TokenPropsWithDefaults = await applyNew1155Defaults(
|
|
135
138
|
props,
|
|
136
139
|
ownerAddress,
|
|
140
|
+
props.contractName,
|
|
137
141
|
);
|
|
138
142
|
|
|
139
143
|
const verifyTokenIdExpected = encodeFunctionData({
|
package/src/create/types.ts
CHANGED
|
@@ -29,7 +29,7 @@ export type FixedPriceParamsType = SaleStartAndEnd &
|
|
|
29
29
|
|
|
30
30
|
export type TimedSaleParamsType = SaleStartAndEnd & {
|
|
31
31
|
type?: "timed";
|
|
32
|
-
// Name of the erc20z token to create for the secondary sale. If not provided,
|
|
32
|
+
// Name of the erc20z token to create for the secondary sale. If not provided, uses the contract name
|
|
33
33
|
erc20Name?: string;
|
|
34
34
|
// Symbol of the erc20z token to create for the secondary sale. If not provided, extracts it from the name.
|
|
35
35
|
erc20Symbol?: string;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Address } from "viem";
|
|
2
2
|
import { httpClient as defaultHttpClient } from "../apis/http-api-base";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ISubgraphQuerier,
|
|
5
|
+
ISubgraphQuery,
|
|
6
|
+
SubgraphQuerier,
|
|
7
|
+
} from "../apis/subgraph-querier";
|
|
4
8
|
import { NetworkConfig, networkConfigByChain } from "src/apis/chain-constants";
|
|
5
9
|
import { GenericTokenIdTypes } from "src/types";
|
|
6
10
|
import {
|
|
@@ -14,7 +18,6 @@ import {
|
|
|
14
18
|
buildContractTokensQuery,
|
|
15
19
|
buildNftTokenSalesQuery,
|
|
16
20
|
buildPremintsOfContractQuery,
|
|
17
|
-
ISubgraphQuery,
|
|
18
21
|
SalesStrategyResult,
|
|
19
22
|
TokenQueryResult,
|
|
20
23
|
} from "./subgraph-queries";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ISubgraphQuery } from "src/apis/subgraph-querier";
|
|
1
2
|
import { GenericTokenIdTypes } from "src/types";
|
|
2
3
|
import { Address } from "viem";
|
|
3
4
|
|
|
@@ -189,13 +190,6 @@ query ($contract: Bytes!) {
|
|
|
189
190
|
responseData?.zoraCreateTokens,
|
|
190
191
|
};
|
|
191
192
|
}
|
|
192
|
-
|
|
193
|
-
export type ISubgraphQuery<T> = {
|
|
194
|
-
query: string;
|
|
195
|
-
variables: Record<string, any>;
|
|
196
|
-
parseResponseData: (data: any | undefined) => T | undefined;
|
|
197
|
-
};
|
|
198
|
-
|
|
199
193
|
export function buildPremintsOfContractQuery({
|
|
200
194
|
tokenAddress,
|
|
201
195
|
}: {
|
package/src/retries.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
async function wait(delayMs: number) {
|
|
2
|
+
return new Promise((resolve) => {
|
|
3
|
+
setTimeout(resolve, delayMs);
|
|
4
|
+
});
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const retryInternal = async <T>({
|
|
8
|
+
tryFn,
|
|
9
|
+
maxTries = 3,
|
|
10
|
+
atTry,
|
|
11
|
+
linearBackoffMS = 200,
|
|
12
|
+
shouldRetryOnError = () => true,
|
|
13
|
+
}: {
|
|
14
|
+
tryFn: () => T;
|
|
15
|
+
maxTries?: number;
|
|
16
|
+
atTry: number;
|
|
17
|
+
linearBackoffMS?: number;
|
|
18
|
+
shouldRetryOnError?: (err: any) => boolean;
|
|
19
|
+
}): Promise<T> => {
|
|
20
|
+
try {
|
|
21
|
+
return await tryFn();
|
|
22
|
+
} catch (err: any) {
|
|
23
|
+
if (shouldRetryOnError(err)) {
|
|
24
|
+
if (atTry <= maxTries) {
|
|
25
|
+
await wait(atTry * linearBackoffMS);
|
|
26
|
+
return await retryInternal({
|
|
27
|
+
tryFn,
|
|
28
|
+
maxTries,
|
|
29
|
+
atTry: atTry + 1,
|
|
30
|
+
linearBackoffMS,
|
|
31
|
+
shouldRetryOnError,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const retriesGeneric = async <T>(params: {
|
|
40
|
+
tryFn: () => T;
|
|
41
|
+
maxTries?: number;
|
|
42
|
+
linearBackoffMS?: number;
|
|
43
|
+
shouldRetryOnError?: (err: any) => boolean;
|
|
44
|
+
}) => {
|
|
45
|
+
return retryInternal({
|
|
46
|
+
...params,
|
|
47
|
+
atTry: 1,
|
|
48
|
+
});
|
|
49
|
+
};
|
package/src/sdk.ts
CHANGED
|
@@ -8,6 +8,10 @@ import { ClientConfig } from "./utils";
|
|
|
8
8
|
import { IPremintAPI, PremintAPIClient } from "./premint/premint-api-client";
|
|
9
9
|
import { SubgraphMintGetter } from "./mint/subgraph-mint-getter";
|
|
10
10
|
import { IOnchainMintGetter } from "./mint/types";
|
|
11
|
+
import {
|
|
12
|
+
IContractGetter,
|
|
13
|
+
SubgraphContractGetter,
|
|
14
|
+
} from "./create/contract-getter";
|
|
11
15
|
|
|
12
16
|
export type CreatorClient = {
|
|
13
17
|
createPremint: PremintClient["createPremint"];
|
|
@@ -29,6 +33,7 @@ export type CollectorClient = {
|
|
|
29
33
|
export type CreatorClientConfig = ClientConfig & {
|
|
30
34
|
/** API for submitting and getting premints. Defaults to the Zora Premint API */
|
|
31
35
|
premintApi?: IPremintAPI;
|
|
36
|
+
contractGetter?: IContractGetter;
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
/**
|
|
@@ -50,6 +55,9 @@ export function createCreatorClient(
|
|
|
50
55
|
const create1155CreatorClient = new Create1155Client({
|
|
51
56
|
chainId: clientConfig.chainId,
|
|
52
57
|
publicClient: clientConfig.publicClient,
|
|
58
|
+
contractGetter:
|
|
59
|
+
clientConfig.contractGetter ||
|
|
60
|
+
new SubgraphContractGetter(clientConfig.chainId),
|
|
53
61
|
});
|
|
54
62
|
|
|
55
63
|
return {
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createCreatorClient } from "src";
|
|
2
|
+
import {
|
|
3
|
+
Address,
|
|
4
|
+
Chain,
|
|
5
|
+
LocalAccount,
|
|
6
|
+
createPublicClient,
|
|
7
|
+
createWalletClient,
|
|
8
|
+
http,
|
|
9
|
+
} from "viem";
|
|
10
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
11
|
+
import { zoraSepolia } from "viem/chains";
|
|
12
|
+
|
|
13
|
+
const publicClient = createPublicClient({
|
|
14
|
+
chain: zoraSepolia as Chain,
|
|
15
|
+
transport: http(),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const walletClient = createWalletClient({
|
|
19
|
+
chain: zoraSepolia,
|
|
20
|
+
transport: http(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const creatorClient = createCreatorClient({
|
|
24
|
+
chainId: zoraSepolia.id,
|
|
25
|
+
publicClient,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export const createMultipleTokensOnContract = async ({
|
|
29
|
+
creatorAccount,
|
|
30
|
+
}: {
|
|
31
|
+
creatorAccount: LocalAccount;
|
|
32
|
+
}) => {
|
|
33
|
+
console.log({ address: creatorAccount.address });
|
|
34
|
+
const { contractAddress, parameters } = await creatorClient.create1155({
|
|
35
|
+
account: creatorAccount.address,
|
|
36
|
+
contract: {
|
|
37
|
+
name: "testContractD",
|
|
38
|
+
uri: "ipfs://bafkreiainxen4b4wz4ubylvbhons6rembxdet4a262nf2lziclqvv7au3e",
|
|
39
|
+
},
|
|
40
|
+
token: {
|
|
41
|
+
tokenMetadataURI:
|
|
42
|
+
"ipfs://bafkreice23maski3x52tsfqgxstx3kbiifnt5jotg3a5ynvve53c4soi2u",
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
console.log("creating contract and token");
|
|
46
|
+
|
|
47
|
+
const { request: requestA } = await publicClient.simulateContract(parameters);
|
|
48
|
+
|
|
49
|
+
const hashA = await walletClient.writeContract({
|
|
50
|
+
...requestA,
|
|
51
|
+
account: creatorAccount,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const receiptA = await publicClient.waitForTransactionReceipt({
|
|
55
|
+
hash: hashA,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (receiptA.status !== "success") {
|
|
59
|
+
throw new Error("create new contract failed");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log("creating new token on contract");
|
|
63
|
+
|
|
64
|
+
const { parameters: parametersB } =
|
|
65
|
+
await creatorClient.create1155OnExistingContract({
|
|
66
|
+
account: creatorAccount.address,
|
|
67
|
+
contractAddress,
|
|
68
|
+
token: {
|
|
69
|
+
tokenMetadataURI:
|
|
70
|
+
"ipfs://bafkreice23maski3x52tsfqgxstx3kbiifnt5jotg3a5ynvve53c4soi2u",
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const { request: requestB } =
|
|
75
|
+
await publicClient.simulateContract(parametersB);
|
|
76
|
+
|
|
77
|
+
const hashB = await walletClient.writeContract({
|
|
78
|
+
...requestB,
|
|
79
|
+
account: creatorAccount,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const receiptB = await publicClient.waitForTransactionReceipt({
|
|
83
|
+
hash: hashB,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (receiptB.status !== "success") {
|
|
87
|
+
throw new Error("create token on contract failed");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
console.log("created multiple tokens on contract");
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const setupTestContracts = async () => {
|
|
94
|
+
const creatorAccount = privateKeyToAccount(
|
|
95
|
+
process.env.VITE_PRIVATE_KEY! as Address,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// create 2 premints on a contract
|
|
99
|
+
await createMultipleTokensOnContract({
|
|
100
|
+
creatorAccount,
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
setupTestContracts();
|