@zoralabs/protocol-sdk 0.11.6 → 0.11.7-COMMENTS.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.
Files changed (36) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/CHANGELOG.md +12 -0
  3. package/dist/create/mint-from-create.d.ts +2 -1
  4. package/dist/create/mint-from-create.d.ts.map +1 -1
  5. package/dist/index.cjs +195 -41
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.js +201 -43
  8. package/dist/index.js.map +1 -1
  9. package/dist/mint/mint-client.d.ts +3 -1
  10. package/dist/mint/mint-client.d.ts.map +1 -1
  11. package/dist/mint/mint-queries.d.ts +5 -3
  12. package/dist/mint/mint-queries.d.ts.map +1 -1
  13. package/dist/mint/mint-transactions.d.ts +4 -2
  14. package/dist/mint/mint-transactions.d.ts.map +1 -1
  15. package/dist/sdk.d.ts.map +1 -1
  16. package/dist/secondary/secondary-client.d.ts +2 -1
  17. package/dist/secondary/secondary-client.d.ts.map +1 -1
  18. package/dist/secondary/types.d.ts +1 -0
  19. package/dist/secondary/types.d.ts.map +1 -1
  20. package/dist/test-utils.d.ts +5 -1
  21. package/dist/test-utils.d.ts.map +1 -1
  22. package/package.json +4 -4
  23. package/src/comments/comments.test.ts +338 -0
  24. package/src/create/1155-create-helper.test.ts +2 -12
  25. package/src/create/1155-create-helper.ts +2 -0
  26. package/src/create/mint-from-create.ts +3 -0
  27. package/src/mint/mint-client.test.ts +67 -30
  28. package/src/mint/mint-client.ts +10 -1
  29. package/src/mint/mint-queries.ts +16 -5
  30. package/src/mint/mint-transactions.ts +80 -16
  31. package/src/sdk.ts +1 -0
  32. package/src/secondary/secondary-client.test.ts +248 -2
  33. package/src/secondary/secondary-client.ts +136 -6
  34. package/src/secondary/types.ts +2 -0
  35. package/src/sparks/sparks-sponsored-sparks-spender.test.ts +2 -1
  36. package/src/test-utils.ts +19 -0
@@ -1,16 +1,28 @@
1
1
  import { describe, expect, vi } from "vitest";
2
- import { Address, erc20Abi, parseAbi, parseEther } from "viem";
2
+ import {
3
+ Address,
4
+ erc20Abi,
5
+ parseAbi,
6
+ parseEther,
7
+ TransactionReceipt,
8
+ parseEventLogs,
9
+ } from "viem";
3
10
  import { zora, zoraSepolia } from "viem/chains";
4
- import { zoraCreator1155ImplABI } from "@zoralabs/protocol-deployments";
11
+ import {
12
+ zoraCreator1155ImplABI,
13
+ CommentIdentifier,
14
+ commentsABI,
15
+ callerAndCommenterABI,
16
+ } from "@zoralabs/protocol-deployments";
5
17
  import { forkUrls, makeAnvilTest, writeContractWithRetries } from "src/anvil";
6
18
  import { createCollectorClient, createCreatorClient } from "src/sdk";
7
19
  import { getAllowListEntry } from "src/allow-list/allow-list-client";
20
+ import { SubgraphMintGetter } from "./subgraph-mint-getter";
21
+ import { new1155ContractVersion } from "src/create/contract-setup";
8
22
  import {
9
23
  demoContractMetadataURI,
10
24
  demoTokenMetadataURI,
11
- } from "src/create/1155-create-helper.test";
12
- import { SubgraphMintGetter } from "./subgraph-mint-getter";
13
- import { new1155ContractVersion } from "src/create/contract-setup";
25
+ } from "src/fixtures/contract-setup";
14
26
  import { ISubgraphQuerier } from "src/apis/subgraph-querier";
15
27
  import { mockTimedSaleStrategyTokenQueryResult } from "src/fixtures/mint-query-results";
16
28
 
@@ -18,52 +30,64 @@ const erc721ABI = parseAbi([
18
30
  "function balanceOf(address owner) public view returns (uint256)",
19
31
  ] as const);
20
32
 
33
+ const getCommentIdentifierFromReceipt = (
34
+ receipt: TransactionReceipt,
35
+ ): CommentIdentifier => {
36
+ const logs = parseEventLogs({
37
+ abi: commentsABI,
38
+ logs: receipt.logs,
39
+ eventName: "Commented",
40
+ });
41
+
42
+ if (logs.length === 0) {
43
+ throw new Error("No Commented event found in receipt");
44
+ }
45
+
46
+ return logs[0]!.args.commentIdentifier;
47
+ };
48
+
21
49
  describe("mint-helper", () => {
22
50
  makeAnvilTest({
23
- forkBlockNumber: 16028671,
24
- forkUrl: forkUrls.zoraMainnet,
25
- anvilChainId: zora.id,
51
+ forkBlockNumber: 16028124,
52
+ forkUrl: forkUrls.zoraSepolia,
53
+ anvilChainId: zoraSepolia.id,
26
54
  })(
27
- "mints a new 1155 token",
55
+ "mints a new 1155 token with a comment",
28
56
  async ({ viemClients }) => {
29
- const { testClient, walletClient, publicClient } = viemClients;
57
+ const { testClient, walletClient, publicClient, chain } = viemClients;
30
58
  const creatorAccount = (await walletClient.getAddresses())[0]!;
31
59
  await testClient.setBalance({
32
60
  address: creatorAccount,
33
61
  value: parseEther("2000"),
34
62
  });
35
63
  const targetContract: Address =
36
- "0xa2fea3537915dc6c7c7a97a82d1236041e6feb2e";
37
- const targetTokenId = 1n;
64
+ "0xD42557F24034b53e7340A40bb5813eF9Ba88F2b4";
65
+ const targetTokenId = 3n;
38
66
  const collectorClient = createCollectorClient({
39
- chainId: zora.id,
67
+ chainId: chain.id,
40
68
  publicClient,
41
69
  });
42
70
 
43
- const {
44
- token: mintable,
45
- prepareMint,
46
- primaryMintActive,
47
- } = await collectorClient.getToken({
48
- tokenContract: targetContract,
49
- mintType: "1155",
50
- tokenId: targetTokenId,
51
- });
52
-
53
- mintable.maxSupply;
54
- mintable.totalMinted;
55
- mintable.tokenURI;
56
- mintable;
71
+ const { prepareMint, primaryMintActive } = await collectorClient.getToken(
72
+ {
73
+ tokenContract: targetContract,
74
+ mintType: "1155",
75
+ tokenId: targetTokenId,
76
+ },
77
+ );
57
78
 
58
79
  expect(primaryMintActive).toBe(true);
59
80
  expect(prepareMint).toBeDefined();
60
81
 
82
+ const quantityToMint = 5n;
83
+
61
84
  const { parameters, costs } = prepareMint!({
62
85
  minterAccount: creatorAccount,
63
- quantityToMint: 1,
86
+ quantityToMint,
87
+ mintComment: "This is a fun comment :)",
64
88
  });
65
89
 
66
- expect(costs.totalCostEth).toBe(1n * parseEther("0.000777"));
90
+ expect(costs.totalCostEth).toBe(quantityToMint * parseEther("0.000111"));
67
91
 
68
92
  const oldBalance = await publicClient.readContract({
69
93
  abi: zoraCreator1155ImplABI,
@@ -84,7 +108,20 @@ describe("mint-helper", () => {
84
108
  });
85
109
  expect(receipt).to.not.be.null;
86
110
  expect(oldBalance).to.be.equal(0n);
87
- expect(newBalance).to.be.equal(1n);
111
+ expect(newBalance).to.be.equal(quantityToMint);
112
+
113
+ // search for the Commented event in the logs
114
+ const commentIdentifier = getCommentIdentifierFromReceipt(receipt);
115
+
116
+ expect(commentIdentifier).toBeDefined();
117
+
118
+ const logs = parseEventLogs({
119
+ abi: callerAndCommenterABI,
120
+ logs: receipt.logs,
121
+ eventName: "MintedAndCommented",
122
+ });
123
+
124
+ expect(logs.length).toBe(1);
88
125
  },
89
126
  12 * 1000,
90
127
  );
@@ -24,19 +24,22 @@ export class MintClient {
24
24
  private readonly publicClient: IPublicClient;
25
25
  private readonly mintGetter: IOnchainMintGetter;
26
26
  private readonly premintGetter: IPremintGetter;
27
-
27
+ private readonly chainId: number;
28
28
  constructor({
29
29
  publicClient,
30
30
  premintGetter,
31
31
  mintGetter,
32
+ chainId,
32
33
  }: {
33
34
  publicClient: IPublicClient;
34
35
  premintGetter: IPremintGetter;
35
36
  mintGetter: IOnchainMintGetter;
37
+ chainId: number;
36
38
  }) {
37
39
  this.publicClient = publicClient;
38
40
  this.mintGetter = mintGetter;
39
41
  this.premintGetter = premintGetter;
42
+ this.chainId = chainId;
40
43
  }
41
44
 
42
45
  /**
@@ -54,6 +57,7 @@ export class MintClient {
54
57
  publicClient: this.publicClient,
55
58
  mintGetter: this.mintGetter,
56
59
  premintGetter: this.premintGetter,
60
+ chainId: this.chainId,
57
61
  });
58
62
  }
59
63
 
@@ -69,6 +73,7 @@ export class MintClient {
69
73
  mintGetter: this.mintGetter,
70
74
  premintGetter: this.premintGetter,
71
75
  publicClient: this.publicClient,
76
+ chainId: this.chainId,
72
77
  });
73
78
  }
74
79
 
@@ -87,6 +92,7 @@ export class MintClient {
87
92
  mintGetter: this.mintGetter,
88
93
  premintGetter: this.premintGetter,
89
94
  publicClient: this.publicClient,
95
+ chainId: this.chainId,
90
96
  });
91
97
  }
92
98
 
@@ -110,17 +116,20 @@ async function mint({
110
116
  publicClient,
111
117
  mintGetter,
112
118
  premintGetter,
119
+ chainId,
113
120
  }: {
114
121
  parameters: MakeMintParametersArguments;
115
122
  publicClient: IPublicClient;
116
123
  mintGetter: IOnchainMintGetter;
117
124
  premintGetter: IPremintGetter;
125
+ chainId: number;
118
126
  }): Promise<PrepareMintReturn> {
119
127
  const { prepareMint, primaryMintActive } = await getMint({
120
128
  params: parameters,
121
129
  mintGetter,
122
130
  premintGetter,
123
131
  publicClient,
132
+ chainId,
124
133
  });
125
134
 
126
135
  if (!primaryMintActive) {
@@ -36,11 +36,13 @@ export async function getMint({
36
36
  mintGetter,
37
37
  premintGetter,
38
38
  publicClient,
39
+ chainId,
39
40
  }: {
40
41
  params: GetMintParameters;
41
42
  mintGetter: IOnchainMintGetter;
42
43
  premintGetter: IPremintGetter;
43
44
  publicClient: IPublicClient;
45
+ chainId: number;
44
46
  }): Promise<MintableReturn> {
45
47
  const { tokenContract } = params;
46
48
  if (isOnChainMint(params)) {
@@ -53,7 +55,7 @@ export async function getMint({
53
55
  blockTime: blockTime,
54
56
  });
55
57
 
56
- return toMintableReturn(result);
58
+ return toMintableReturn(result, chainId);
57
59
  }
58
60
 
59
61
  const premint = await premintGetter.get({
@@ -103,17 +105,19 @@ export async function getMintsOfContract({
103
105
  mintGetter,
104
106
  premintGetter,
105
107
  publicClient,
108
+ chainId,
106
109
  }: {
107
110
  params: GetMintsOfContractParameters;
108
111
  mintGetter: IOnchainMintGetter;
109
112
  premintGetter: IPremintGetter;
110
113
  publicClient: IPublicClient;
114
+ chainId: number;
111
115
  }): Promise<{ contract?: ContractInfo; tokens: MintableReturn[] }> {
112
116
  const onchainMints = (
113
117
  await mintGetter.getContractMintable({
114
118
  tokenAddress: params.tokenContract,
115
119
  })
116
- ).map(toMintableReturn);
120
+ ).map((result) => toMintableReturn(result, chainId));
117
121
 
118
122
  const offchainMints = await getPremintsOfContractMintable({
119
123
  mintGetter,
@@ -270,7 +274,7 @@ function parsePremint({
270
274
  }
271
275
 
272
276
  export const makeOnchainPrepareMint =
273
- (result: OnchainSalesConfigAndTokenInfo): PrepareMint =>
277
+ (result: OnchainSalesConfigAndTokenInfo, chainId: number): PrepareMint =>
274
278
  (params: MintParametersBase) => {
275
279
  if (!result.salesConfig) {
276
280
  throw new Error("No valid sales config found for token");
@@ -280,6 +284,7 @@ export const makeOnchainPrepareMint =
280
284
  parameters: makeOnchainMintCall({
281
285
  token: result as Concrete<OnchainSalesConfigAndTokenInfo>,
282
286
  mintParams: params,
287
+ chainId,
283
288
  }),
284
289
  erc20Approval: getRequiredErc20Approvals(params, result.salesConfig),
285
290
  costs: parseMintCosts({
@@ -290,7 +295,10 @@ export const makeOnchainPrepareMint =
290
295
  };
291
296
  };
292
297
 
293
- function toMintableReturn(result: GetMintableReturn): MintableReturn {
298
+ function toMintableReturn(
299
+ result: GetMintableReturn,
300
+ chainId: number,
301
+ ): MintableReturn {
294
302
  const primaryMintActive = result.primaryMintActive;
295
303
  if (!primaryMintActive) {
296
304
  return {
@@ -306,7 +314,10 @@ function toMintableReturn(result: GetMintableReturn): MintableReturn {
306
314
  primaryMintActive,
307
315
  primaryMintEnd: result.primaryMintEnd,
308
316
  secondaryMarketActive: result.secondaryMarketActive,
309
- prepareMint: makeOnchainPrepareMint(result.salesConfigAndTokenInfo),
317
+ prepareMint: makeOnchainPrepareMint(
318
+ result.salesConfigAndTokenInfo,
319
+ chainId,
320
+ ),
310
321
  };
311
322
  }
312
323
 
@@ -11,6 +11,8 @@ import {
11
11
  erc20MinterABI,
12
12
  zoraCreator1155ImplABI,
13
13
  zoraTimedSaleStrategyABI,
14
+ callerAndCommenterABI,
15
+ callerAndCommenterAddress,
14
16
  } from "@zoralabs/protocol-deployments";
15
17
  import { zora721Abi, zora1155LegacyAbi } from "src/constants";
16
18
  import {
@@ -32,9 +34,11 @@ import { AllowListEntry } from "src/allow-list/types";
32
34
  export function makeOnchainMintCall({
33
35
  token,
34
36
  mintParams,
37
+ chainId,
35
38
  }: {
36
39
  token: Concrete<OnchainSalesConfigAndTokenInfo>;
37
40
  mintParams: Omit<MakeMintParametersArgumentsBase, "tokenContract">;
41
+ chainId: number;
38
42
  }): SimulateContractParametersWithAccount {
39
43
  if (token.mintType === "721") {
40
44
  return makePrepareMint721TokenParams({
@@ -48,6 +52,7 @@ export function makeOnchainMintCall({
48
52
  salesConfigAndTokenInfo: token,
49
53
  tokenContract: token.contract.address,
50
54
  tokenId: token.tokenId!,
55
+ chainId,
51
56
  ...mintParams,
52
57
  });
53
58
  }
@@ -57,6 +62,69 @@ export type MintableParameters = Pick<
57
62
  "contractVersion" | "salesConfig"
58
63
  >;
59
64
 
65
+ function makeZoraTimedSaleStrategyMintCall({
66
+ minterAccount,
67
+ salesConfigAndTokenInfo,
68
+ mintQuantity,
69
+ mintTo,
70
+ tokenContract,
71
+ tokenId,
72
+ mintReferral,
73
+ mintComment,
74
+ chainId,
75
+ }: {
76
+ minterAccount: Address | Account;
77
+ salesConfigAndTokenInfo: Concrete<MintableParameters>;
78
+ mintQuantity: bigint;
79
+ mintTo: Address;
80
+ tokenContract: Address;
81
+ tokenId: GenericTokenIdTypes;
82
+ mintReferral?: Address;
83
+ mintComment?: string;
84
+ chainId: number;
85
+ }) {
86
+ // if there is a mint comment, use the caller and commenter
87
+ if (mintComment && mintComment !== "") {
88
+ return makeContractParameters({
89
+ abi: callerAndCommenterABI,
90
+ address:
91
+ callerAndCommenterAddress[
92
+ chainId as keyof typeof callerAndCommenterAddress
93
+ ],
94
+ functionName: "timedSaleMintAndComment",
95
+ account: minterAccount,
96
+ value:
97
+ salesConfigAndTokenInfo.salesConfig.mintFeePerQuantity * mintQuantity,
98
+ args: [
99
+ mintTo,
100
+ mintQuantity,
101
+ tokenContract,
102
+ tokenId,
103
+ mintReferral || zeroAddress,
104
+ mintComment,
105
+ ],
106
+ });
107
+ }
108
+
109
+ return makeContractParameters({
110
+ abi: zoraTimedSaleStrategyABI,
111
+ functionName: "mint",
112
+ account: minterAccount,
113
+ address: salesConfigAndTokenInfo.salesConfig.address,
114
+ value:
115
+ salesConfigAndTokenInfo.salesConfig.mintFeePerQuantity * mintQuantity,
116
+ /* args: mintTo, quantity, collection, tokenId, mintReferral, comment */
117
+ args: [
118
+ mintTo,
119
+ mintQuantity,
120
+ tokenContract,
121
+ BigInt(tokenId),
122
+ mintReferral || zeroAddress,
123
+ "",
124
+ ],
125
+ });
126
+ }
127
+
60
128
  export function makePrepareMint1155TokenParams({
61
129
  tokenContract: tokenContract,
62
130
  tokenId,
@@ -67,9 +135,11 @@ export function makePrepareMint1155TokenParams({
67
135
  mintRecipient,
68
136
  quantityToMint,
69
137
  allowListEntry,
138
+ chainId,
70
139
  }: {
71
140
  salesConfigAndTokenInfo: Concrete<MintableParameters>;
72
141
  tokenId: GenericTokenIdTypes;
142
+ chainId: number;
73
143
  } & Pick<
74
144
  MakeMintParametersArgumentsBase,
75
145
  | "minterAccount"
@@ -101,22 +171,16 @@ export function makePrepareMint1155TokenParams({
101
171
  }
102
172
 
103
173
  if (saleType === "timed") {
104
- return makeContractParameters({
105
- abi: zoraTimedSaleStrategyABI,
106
- functionName: "mint",
107
- account: minterAccount,
108
- address: salesConfigAndTokenInfo.salesConfig.address,
109
- value:
110
- salesConfigAndTokenInfo.salesConfig.mintFeePerQuantity * mintQuantity,
111
- /* args: mintTo, quantity, collection, tokenId, mintReferral, comment */
112
- args: [
113
- mintTo,
114
- mintQuantity,
115
- tokenContract,
116
- BigInt(tokenId),
117
- mintReferral || zeroAddress,
118
- mintComment || "",
119
- ],
174
+ return makeZoraTimedSaleStrategyMintCall({
175
+ minterAccount,
176
+ salesConfigAndTokenInfo,
177
+ mintQuantity,
178
+ mintTo,
179
+ tokenContract,
180
+ tokenId,
181
+ mintReferral,
182
+ mintComment,
183
+ chainId,
120
184
  });
121
185
  }
122
186
 
package/src/sdk.ts CHANGED
@@ -116,6 +116,7 @@ export function createCollectorClient(
116
116
  publicClient: params.publicClient,
117
117
  premintGetter: premintGetterToUse,
118
118
  mintGetter: mintGetterToUse,
119
+ chainId: params.chainId,
119
120
  });
120
121
  const secondaryClient = new SecondaryClient({
121
122
  publicClient: params.publicClient,