@zoralabs/protocol-sdk 0.11.5 → 0.11.6-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 +13 -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 +3 -1
  21. package/dist/test-utils.d.ts.map +1 -1
  22. package/package.json +2 -2
  23. package/src/comments/comments.test.ts +342 -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 +118 -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 +1 -1
  36. package/src/test-utils.ts +12 -0
@@ -4,6 +4,8 @@ import {
4
4
  zoraCreator1155ImplABI,
5
5
  safeTransferSwapAbiParameters,
6
6
  secondarySwapABI,
7
+ callerAndCommenterABI,
8
+ callerAndCommenterAddress,
7
9
  } from "@zoralabs/protocol-deployments";
8
10
  import { makeContractParameters, PublicClient } from "src/utils";
9
11
  import { getUniswapQuote } from "./uniswap/uniswapQuote";
@@ -27,6 +29,8 @@ const ERROR_INSUFFICIENT_POOL_SUPPLY = "Insufficient pool supply";
27
29
  const ERROR_SECONDARY_NOT_CONFIGURED =
28
30
  "Secondary not configured for given contract and token";
29
31
  export const ERROR_SECONDARY_NOT_STARTED = "Secondary market has not started";
32
+ export const ERROR_RECIPIENT_MISMATCH =
33
+ "Recipient must be the same as the caller if there is a comment";
30
34
 
31
35
  // Helper function to create error objects
32
36
  function makeError(errorMessage: string) {
@@ -46,6 +50,8 @@ type Call =
46
50
  };
47
51
 
48
52
  async function makeBuy({
53
+ contract,
54
+ tokenId,
49
55
  erc20z,
50
56
  poolBalance,
51
57
  amount,
@@ -55,8 +61,11 @@ async function makeBuy({
55
61
  chainId,
56
62
  slippage,
57
63
  publicClient,
64
+ comment,
58
65
  }: {
59
66
  erc20z: Address;
67
+ contract: Address;
68
+ tokenId: bigint;
60
69
  poolBalance: { erc20z: bigint };
61
70
  amount: bigint;
62
71
  quantity: bigint;
@@ -64,27 +73,144 @@ async function makeBuy({
64
73
  recipient?: Address;
65
74
  chainId: number;
66
75
  slippage: number;
76
+ comment: string | undefined;
67
77
  publicClient: PublicClient;
68
78
  }): Promise<Call> {
69
79
  const costWithSlippage = calculateSlippageUp(amount, slippage);
80
+ const accountAddress = addressOrAccountAddress(account);
70
81
 
71
- // we cannot buy all the available tokens in a pool (the quote fails if we try doing that)
72
- const availableToBuy = poolBalance.erc20z / BigInt(1e18) - 1n;
82
+ const validationResult = await validateBuyConditions({
83
+ poolBalance,
84
+ quantity,
85
+ costWithSlippage,
86
+ accountAddress,
87
+ publicClient,
88
+ });
73
89
 
74
- const accountAddress = addressOrAccountAddress(account);
90
+ if (validationResult.error) {
91
+ return makeError(validationResult.error);
92
+ }
75
93
 
94
+ if (comment && comment !== "") {
95
+ return handleBuyWithComment({
96
+ accountAddress,
97
+ recipient,
98
+ chainId,
99
+ quantity,
100
+ contract,
101
+ tokenId,
102
+ costWithSlippage,
103
+ comment,
104
+ account,
105
+ });
106
+ }
107
+
108
+ return handleBuyWithoutComment({
109
+ erc20z,
110
+ quantity,
111
+ recipient,
112
+ accountAddress,
113
+ costWithSlippage,
114
+ chainId,
115
+ account,
116
+ });
117
+ }
118
+
119
+ async function validateBuyConditions({
120
+ poolBalance,
121
+ quantity,
122
+ costWithSlippage,
123
+ accountAddress,
124
+ publicClient,
125
+ }: {
126
+ poolBalance: { erc20z: bigint };
127
+ quantity: bigint;
128
+ costWithSlippage: bigint;
129
+ accountAddress: Address;
130
+ publicClient: PublicClient;
131
+ }): Promise<{ error?: string }> {
132
+ const availableToBuy = poolBalance.erc20z / BigInt(1e18) - 1n;
76
133
  const availableToSpend = await publicClient.getBalance({
77
134
  address: accountAddress,
78
135
  });
79
136
 
80
137
  if (costWithSlippage > availableToSpend) {
81
- return makeError(ERROR_INSUFFICIENT_WALLET_FUNDS);
138
+ return { error: ERROR_INSUFFICIENT_WALLET_FUNDS };
82
139
  }
83
140
 
84
141
  if (availableToBuy < BigInt(quantity)) {
85
- return makeError(ERROR_INSUFFICIENT_POOL_SUPPLY);
142
+ return { error: ERROR_INSUFFICIENT_POOL_SUPPLY };
143
+ }
144
+
145
+ return {};
146
+ }
147
+
148
+ function handleBuyWithComment({
149
+ accountAddress,
150
+ recipient,
151
+ chainId,
152
+ quantity,
153
+ contract,
154
+ tokenId,
155
+ costWithSlippage,
156
+ comment,
157
+ account,
158
+ }: {
159
+ accountAddress: Address;
160
+ recipient?: Address;
161
+ chainId: number;
162
+ quantity: bigint;
163
+ contract: Address;
164
+ tokenId: bigint;
165
+ costWithSlippage: bigint;
166
+ comment: string;
167
+ account: Address | Account;
168
+ }): Call {
169
+ if (recipient && recipient !== accountAddress) {
170
+ return makeError(ERROR_RECIPIENT_MISMATCH);
86
171
  }
87
172
 
173
+ return {
174
+ parameters: makeContractParameters({
175
+ abi: callerAndCommenterABI,
176
+ address:
177
+ callerAndCommenterAddress[
178
+ chainId as keyof typeof callerAndCommenterAddress
179
+ ],
180
+ functionName: "buyOnSecondaryAndComment",
181
+ args: [
182
+ accountAddress,
183
+ quantity,
184
+ contract,
185
+ tokenId,
186
+ accountAddress,
187
+ costWithSlippage,
188
+ 0n,
189
+ comment,
190
+ ],
191
+ account,
192
+ value: costWithSlippage,
193
+ }),
194
+ };
195
+ }
196
+
197
+ function handleBuyWithoutComment({
198
+ erc20z,
199
+ quantity,
200
+ recipient,
201
+ accountAddress,
202
+ costWithSlippage,
203
+ chainId,
204
+ account,
205
+ }: {
206
+ erc20z: Address;
207
+ quantity: bigint;
208
+ recipient?: Address;
209
+ accountAddress: Address;
210
+ costWithSlippage: bigint;
211
+ chainId: number;
212
+ account: Address | Account;
213
+ }): Call {
88
214
  return {
89
215
  parameters: makeContractParameters({
90
216
  abi: secondarySwapABI,
@@ -99,7 +225,7 @@ async function makeBuy({
99
225
  costWithSlippage,
100
226
  0n,
101
227
  ],
102
- account: account,
228
+ account,
103
229
  value: costWithSlippage,
104
230
  }),
105
231
  };
@@ -125,6 +251,7 @@ export async function buyWithSlippage({
125
251
  account,
126
252
  slippage = UNISWAP_SLIPPAGE,
127
253
  recipient,
254
+ comment,
128
255
  }: BuyWithSlippageInput & {
129
256
  chainId: number;
130
257
  publicClient: PublicClient;
@@ -159,6 +286,8 @@ export async function buyWithSlippage({
159
286
 
160
287
  const call = await makeBuy({
161
288
  erc20z,
289
+ contract,
290
+ tokenId,
162
291
  poolBalance,
163
292
  amount,
164
293
  quantity,
@@ -166,6 +295,7 @@ export async function buyWithSlippage({
166
295
  recipient,
167
296
  chainId,
168
297
  slippage,
298
+ comment,
169
299
  publicClient,
170
300
  });
171
301
 
@@ -47,6 +47,8 @@ export type BuyWithSlippageInput = {
47
47
  slippage?: number;
48
48
  // Optional recipient address (if different from buyer/seller)
49
49
  recipient?: Address;
50
+ // Optional comment to add to the swap
51
+ comment?: string;
50
52
  };
51
53
 
52
54
  // Same structure as BuyWithSlippageInput
@@ -19,7 +19,7 @@ import { zoraSparksManagerImplABI } from "@zoralabs/protocol-deployments";
19
19
  const anvilTest = makeAnvilTest({
20
20
  forkUrl: forkUrls.zoraMainnet,
21
21
  anvilChainId: zora.id,
22
- forkBlockNumber: 17667435,
22
+ forkBlockNumber: 22029945,
23
23
  });
24
24
  describe("Sponsored Mints Spender with Relay", () => {
25
25
  anvilTest(
package/src/test-utils.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  encodeAbiParameters,
10
10
  parseAbiParameters,
11
11
  } from "viem";
12
+ import { NewContractParams } from "./create/types";
12
13
  import { expect } from "vitest";
13
14
 
14
15
  export const waitForSuccess = async (hash: Hex, publicClient: PublicClient) => {
@@ -17,6 +18,8 @@ export const waitForSuccess = async (hash: Hex, publicClient: PublicClient) => {
17
18
  });
18
19
 
19
20
  expect(receipt.status).toBe("success");
21
+
22
+ return receipt;
20
23
  };
21
24
 
22
25
  export const getFixedPricedMinter = async ({
@@ -37,3 +40,12 @@ export const fixedPriceMinterMinterArguments = ({
37
40
  }: {
38
41
  mintRecipient: Address;
39
42
  }) => encodeAbiParameters(parseAbiParameters("address"), [mintRecipient]);
43
+
44
+ const demoContractMetadataURI = "ipfs://DUMMY/contract.json";
45
+
46
+ export function randomNewContract(): NewContractParams {
47
+ return {
48
+ name: `testContract-${Math.round(Math.random() * 1_000_000)}`,
49
+ uri: demoContractMetadataURI,
50
+ };
51
+ }