@zoralabs/protocol-sdk 0.11.4-COMMENTS.0 → 0.11.5

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.
@@ -1,7 +1,7 @@
1
1
  import { Address } from "viem";
2
2
  import { PublicClient } from "src/utils";
3
3
  import { SimulateContractParametersWithAccount } from "src/types";
4
- import { QuotePrice, BuyWithSlippageInput, SellWithSlippageInput } from "./types";
4
+ import { QuotePrice, BuyWithSlippageInput, SellWithSlippageInput, SecondaryInfo } from "./types";
5
5
  export declare const ERROR_SECONDARY_NOT_STARTED = "Secondary market has not started";
6
6
  type Call = {
7
7
  parameters: SimulateContractParametersWithAccount;
@@ -49,7 +49,7 @@ export declare class SecondaryClient {
49
49
  getSecondaryInfo({ contract, tokenId, }: {
50
50
  contract: Address;
51
51
  tokenId: bigint;
52
- }): Promise<import("./types").SecondaryInfo | undefined>;
52
+ }): Promise<SecondaryInfo | undefined>;
53
53
  /**
54
54
  * Prepares a buy operation with slippage protection for purchasing a quantity of ERC1155 tokens with ETH on the secondary market.
55
55
  * @param input - The input parameters for the buy operation.
@@ -1 +1 @@
1
- {"version":3,"file":"secondary-client.d.ts","sourceRoot":"","sources":["../../src/secondary/secondary-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAAuB,MAAM,MAAM,CAAC;AAO7D,OAAO,EAA0B,YAAY,EAAE,MAAM,WAAW,CAAC;AAKjE,OAAO,EAAE,qCAAqC,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAUjB,eAAO,MAAM,2BAA2B,qCAAqC,CAAC;AAO9E,KAAK,IAAI,GACL;IAEE,UAAU,EAAE,qCAAqC,CAAC;IAClD,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,GACD;IACE,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AA8DN,KAAK,2BAA2B,GAC5B,CAAC;IAEC,KAAK,EAAE,UAAU,CAAC;CACnB,GAAG,IAAI,CAAC,GACT;IACE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB,CAAC;AAEN,wBAAsB,eAAe,CAAC,EACpC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAA2B,EAC3B,SAAS,GACV,EAAE,oBAAoB,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CA6CvC;AAsED,wBAAsB,gBAAgB,CAAC,EACrC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAA2B,EAC3B,SAAS,GACV,EAAE,qBAAqB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAwCvC;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,OAAO,CAAS;IAExB;;;;OAIG;gBACS,EACV,YAAY,EACZ,OAAO,GACR,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;KACjB;IAKD;;;;;OAKG;IACG,gBAAgB,CAAC,EACrB,QAAQ,EACR,OAAO,GACR,EAAE;QACD,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB;IASD;;;;OAIG;IACG,kBAAkB,CACtB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,2BAA2B,CAAC;IASvC;;;;OAIG;IACG,mBAAmB,CACvB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,2BAA2B,CAAC;CAQxC"}
1
+ {"version":3,"file":"secondary-client.d.ts","sourceRoot":"","sources":["../../src/secondary/secondary-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAAuB,MAAM,MAAM,CAAC;AAO7D,OAAO,EAA0B,YAAY,EAAE,MAAM,WAAW,CAAC;AAKjE,OAAO,EAAE,qCAAqC,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EACd,MAAM,SAAS,CAAC;AAUjB,eAAO,MAAM,2BAA2B,qCAAqC,CAAC;AAO9E,KAAK,IAAI,GACL;IAEE,UAAU,EAAE,qCAAqC,CAAC;IAClD,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,GACD;IACE,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AA8DN,KAAK,2BAA2B,GAC5B,CAAC;IAEC,KAAK,EAAE,UAAU,CAAC;CACnB,GAAG,IAAI,CAAC,GACT;IACE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB,CAAC;AAEN,wBAAsB,eAAe,CAAC,EACpC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAA2B,EAC3B,SAAS,GACV,EAAE,oBAAoB,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CA6CvC;AAsED,wBAAsB,gBAAgB,CAAC,EACrC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAA2B,EAC3B,SAAS,GACV,EAAE,qBAAqB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAwCvC;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,OAAO,CAAS;IAExB;;;;OAIG;gBACS,EACV,YAAY,EACZ,OAAO,GACR,EAAE;QACD,YAAY,EAAE,YAAY,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;KACjB;IAKD;;;;;OAKG;IACG,gBAAgB,CAAC,EACrB,QAAQ,EACR,OAAO,GACR,EAAE;QACD,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAStC;;;;OAIG;IACG,kBAAkB,CACtB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,2BAA2B,CAAC;IASvC;;;;OAIG;IACG,mBAAmB,CACvB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,2BAA2B,CAAC;CAQxC"}
@@ -32,6 +32,12 @@ export type SecondaryInfo = {
32
32
  secondaryActivated: boolean;
33
33
  pool: Address;
34
34
  erc20z: Address;
35
+ name: string;
36
+ symbol: string;
37
+ saleStart: bigint;
35
38
  saleEnd?: bigint;
39
+ marketCountdown?: bigint;
40
+ minimumMintsForCountdown?: bigint;
41
+ mintCount: bigint;
36
42
  };
37
43
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/secondary/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAExC,MAAM,MAAM,cAAc,GAAG;IAE3B,QAAQ,EAAE,MAAM,CAAC;IAEjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IAEvB,GAAG,EAAE,cAAc,CAAC;IAEpB,MAAM,EAAE,cAAc,CAAC;IAEvB,IAAI,EAAE,MAAM,OAAO,CAAC;QAElB,QAAQ,EAAE,MAAM,CAAC;QAEjB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAE3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE;QAEX,MAAM,EAAE,MAAM,CAAC;QAEf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAEF,KAAK,EAAE,UAAU,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAEjC,QAAQ,EAAE,OAAO,CAAC;IAElB,OAAO,EAAE,MAAM,CAAC;IAEhB,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IAE3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAGF,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAEzD,MAAM,MAAM,aAAa,GAAG;IAE1B,kBAAkB,EAAE,OAAO,CAAC;IAE5B,IAAI,EAAE,OAAO,CAAC;IAEd,MAAM,EAAE,OAAO,CAAC;IAEhB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/secondary/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAExC,MAAM,MAAM,cAAc,GAAG;IAE3B,QAAQ,EAAE,MAAM,CAAC;IAEjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IAEvB,GAAG,EAAE,cAAc,CAAC;IAEpB,MAAM,EAAE,cAAc,CAAC;IAEvB,IAAI,EAAE,MAAM,OAAO,CAAC;QAElB,QAAQ,EAAE,MAAM,CAAC;QAEjB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAE3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE;QAEX,MAAM,EAAE,MAAM,CAAC;QAEf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAEF,KAAK,EAAE,UAAU,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAEjC,QAAQ,EAAE,OAAO,CAAC;IAElB,OAAO,EAAE,MAAM,CAAC;IAEhB,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IAE3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAGF,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAGzD,MAAM,MAAM,aAAa,GAAG;IAE1B,kBAAkB,EAAE,OAAO,CAAC;IAE5B,IAAI,EAAE,OAAO,CAAC;IAEd,MAAM,EAAE,OAAO,CAAC;IAEhB,IAAI,EAAE,MAAM,CAAC;IAEb,MAAM,EAAE,MAAM,CAAC;IAEf,SAAS,EAAE,MAAM,CAAC;IAElB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAElC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/secondary/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAKzC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,wBAAsB,gBAAgB,CAAC,EACrC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAsBrC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/secondary/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAc,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAKzC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,wBAAsB,gBAAgB,CAAC,EACrC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CA0CrC"}
@@ -1,7 +1,6 @@
1
1
  import { zoraCreator1155FactoryImplAddress } from "@zoralabs/protocol-deployments";
2
2
  import { Address, Hex, PublicClient } from "viem";
3
- import { NewContractParams } from "./create/types";
4
- export declare const waitForSuccess: (hash: Hex, publicClient: PublicClient) => Promise<import("viem").TransactionReceipt>;
3
+ export declare const waitForSuccess: (hash: Hex, publicClient: PublicClient) => Promise<void>;
5
4
  export declare const getFixedPricedMinter: ({ publicClient, chainId, }: {
6
5
  publicClient: PublicClient;
7
6
  chainId: keyof typeof zoraCreator1155FactoryImplAddress;
@@ -9,5 +8,4 @@ export declare const getFixedPricedMinter: ({ publicClient, chainId, }: {
9
8
  export declare const fixedPriceMinterMinterArguments: ({ mintRecipient, }: {
10
9
  mintRecipient: Address;
11
10
  }) => `0x${string}`;
12
- export declare function randomNewContract(): NewContractParams;
13
11
  //# sourceMappingURL=test-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iCAAiC,EAClC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,OAAO,EACP,GAAG,EACH,YAAY,EAGb,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGnD,eAAO,MAAM,cAAc,SAAgB,GAAG,gBAAgB,YAAY,+CAQzE,CAAC;AAEF,eAAO,MAAM,oBAAoB,+BAG9B;IACD,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,MAAM,OAAO,iCAAiC,CAAC;CACzD,2BAKG,CAAC;AAEL,eAAO,MAAM,+BAA+B,uBAEzC;IACD,aAAa,EAAE,OAAO,CAAC;CACxB,kBAAwE,CAAC;AAI1E,wBAAgB,iBAAiB,IAAI,iBAAiB,CAKrD"}
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iCAAiC,EAClC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,OAAO,EACP,GAAG,EACH,YAAY,EAGb,MAAM,MAAM,CAAC;AAGd,eAAO,MAAM,cAAc,SAAgB,GAAG,gBAAgB,YAAY,kBAMzE,CAAC;AAEF,eAAO,MAAM,oBAAoB,+BAG9B;IACD,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,MAAM,OAAO,iCAAiC,CAAC;CACzD,2BAKG,CAAC;AAEL,eAAO,MAAM,+BAA+B,uBAEzC;IACD,aAAa,EAAE,OAAO,CAAC;CACxB,kBAAwE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zoralabs/protocol-sdk",
3
- "version": "0.11.4-COMMENTS.0",
3
+ "version": "0.11.5",
4
4
  "repository": "https://github.com/ourzora/zora-protocol",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "abitype": "^1.0.2",
20
- "@zoralabs/protocol-deployments": "^0.3.6-COMMENTS.0"
20
+ "@zoralabs/protocol-deployments": "^0.3.7"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "viem": "^2.21.21"
@@ -3,7 +3,7 @@ import {
3
3
  getContractAddressFromReceipt,
4
4
  getTokenIdFromCreateReceipt,
5
5
  } from "./1155-create-helper";
6
- import { createCreatorClient } from "src/sdk";
6
+ import { createCollectorClient, createCreatorClient } from "src/sdk";
7
7
  import {
8
8
  zoraCreator1155ImplABI,
9
9
  zoraTimedSaleStrategyABI,
@@ -12,17 +12,25 @@ import {
12
12
  import { waitForSuccess } from "src/test-utils";
13
13
  import { Address, erc20Abi, parseEther, PublicClient } from "viem";
14
14
  import { makePrepareMint1155TokenParams } from "src/mint/mint-transactions";
15
- import { forkUrls, makeAnvilTest, writeContractWithRetries } from "src/anvil";
15
+ import {
16
+ forkUrls,
17
+ makeAnvilTest,
18
+ simulateAndWriteContractWithRetries,
19
+ writeContractWithRetries,
20
+ } from "src/anvil";
16
21
  import { zora } from "viem/chains";
17
22
  import { AllowList } from "src/allow-list/types";
18
23
  import { createAllowList } from "src/allow-list/allow-list-client";
24
+ import { NewContractParams } from "./types";
19
25
  import { SubgraphContractGetter } from "./contract-getter";
20
26
  import {
21
27
  DEFAULT_MINIMUM_MARKET_ETH,
22
28
  DEFAULT_MARKET_COUNTDOWN,
23
29
  } from "./minter-defaults";
24
- import { randomNewContract } from "src/test-utils";
25
- import { demoTokenMetadataURI } from "src/fixtures/contract-setup";
30
+ import {
31
+ demoContractMetadataURI,
32
+ demoTokenMetadataURI,
33
+ } from "src/fixtures/contract-setup";
26
34
 
27
35
  const anvilTest = makeAnvilTest({
28
36
  forkUrl: forkUrls.zoraMainnet,
@@ -53,6 +61,13 @@ const minterIsMinterOnToken = async ({
53
61
  });
54
62
  };
55
63
 
64
+ function randomNewContract(): NewContractParams {
65
+ return {
66
+ name: `testContract-${Math.round(Math.random() * 1_000_000)}`,
67
+ uri: demoContractMetadataURI,
68
+ };
69
+ }
70
+
56
71
  describe("create-helper", () => {
57
72
  anvilTest(
58
73
  "when no sales config is provided, it creates a new 1155 contract and token using the timed sale strategy",
@@ -133,6 +148,74 @@ describe("create-helper", () => {
133
148
  ],
134
149
  }),
135
150
  ).toBe(true);
151
+
152
+ // get secondary info, minimum mints count should be 1111, sale end should be undefined,
153
+ // market countdown should be 24 hours
154
+
155
+ const collectorClient = createCollectorClient({
156
+ chainId: chain.id,
157
+ publicClient,
158
+ });
159
+
160
+ const secondaryInfo = await collectorClient.getSecondaryInfo({
161
+ contract: contractAddress,
162
+ tokenId: newTokenId,
163
+ });
164
+
165
+ expect(secondaryInfo).toBeDefined();
166
+ expect(secondaryInfo!.minimumMintsForCountdown).toBe(1111n);
167
+ expect(secondaryInfo!.secondaryActivated).toBe(false);
168
+ expect(secondaryInfo!.saleEnd).toBeUndefined();
169
+ expect(secondaryInfo!.marketCountdown).toBe(24n * 60n * 60n);
170
+ },
171
+ 20 * 1000,
172
+ );
173
+ anvilTest(
174
+ "when minimumMintsForCountdown is set, it uses that as the minimum mints for countdown",
175
+ async ({ viemClients: { publicClient, walletClient, chain } }) => {
176
+ const addresses = await walletClient.getAddresses();
177
+ const creatorAddress = addresses[0]!;
178
+
179
+ const creatorClient = createCreatorClient({
180
+ chainId: chain.id,
181
+ publicClient: publicClient,
182
+ });
183
+
184
+ const saleStart = 5n;
185
+ const contract = randomNewContract();
186
+ const { parameters, contractAddress, newTokenId } =
187
+ await creatorClient.create1155({
188
+ contract,
189
+ token: {
190
+ tokenMetadataURI: demoTokenMetadataURI,
191
+ mintToCreatorCount: 1,
192
+ salesConfig: {
193
+ saleStart,
194
+ minimumMintsForCountdown: 500n,
195
+ marketCountdown: 100n,
196
+ type: "timed",
197
+ },
198
+ },
199
+ account: creatorAddress,
200
+ });
201
+
202
+ await simulateAndWriteContractWithRetries({
203
+ parameters,
204
+ walletClient,
205
+ publicClient,
206
+ });
207
+
208
+ const secondaryInfo = await createCollectorClient({
209
+ chainId: chain.id,
210
+ publicClient,
211
+ }).getSecondaryInfo({
212
+ contract: contractAddress,
213
+ tokenId: newTokenId,
214
+ });
215
+
216
+ expect(secondaryInfo).toBeDefined();
217
+ expect(secondaryInfo!.minimumMintsForCountdown).toBe(500n);
218
+ expect(secondaryInfo!.marketCountdown).toBe(100n);
136
219
  },
137
220
  20 * 1000,
138
221
  );
@@ -79,24 +79,38 @@ export const parseNameIntoSymbol = (name: string) => {
79
79
  return result;
80
80
  };
81
81
 
82
+ const getMinimumMarketEth = (
83
+ params: Pick<
84
+ TimedSaleParamsType,
85
+ "minimumMarketEth" | "minimumMintsForCountdown"
86
+ >,
87
+ ) => {
88
+ if (params.minimumMintsForCountdown) {
89
+ return params.minimumMintsForCountdown * parseEther("0.0000111");
90
+ }
91
+ return params.minimumMarketEth || DEFAULT_MINIMUM_MARKET_ETH;
92
+ };
93
+
82
94
  const timedSaleSettingsWithDefaults = (
83
95
  params: TimedSaleParamsType,
84
96
  contractName: string,
85
97
  ): Concrete<TimedSaleParamsType> => {
86
98
  // If the name is not provided, try to fetch it from the metadata
87
99
  const erc20Name = params.erc20Name || contractName;
88
- const symbol = params.erc20Symbol || parseNameIntoSymbol(erc20Name);
89
- const start = params.saleStart || 0n;
90
- const countdown = params.marketCountdown || DEFAULT_MARKET_COUNTDOWN;
91
- const minimumEth = params.minimumMarketEth || DEFAULT_MINIMUM_MARKET_ETH;
100
+ const minimumMarketEth = getMinimumMarketEth({
101
+ minimumMarketEth: params.minimumMarketEth,
102
+ minimumMintsForCountdown: params.minimumMintsForCountdown,
103
+ });
104
+ const minimumMintsForCountdown = minimumMarketEth / parseEther("0.0000111");
92
105
 
93
106
  return {
94
107
  type: "timed",
95
108
  erc20Name: erc20Name,
96
- erc20Symbol: symbol,
97
- saleStart: start,
98
- marketCountdown: countdown,
99
- minimumMarketEth: minimumEth,
109
+ erc20Symbol: params.erc20Symbol || parseNameIntoSymbol(erc20Name),
110
+ saleStart: params.saleStart || 0n,
111
+ marketCountdown: params.marketCountdown || DEFAULT_MARKET_COUNTDOWN,
112
+ minimumMarketEth,
113
+ minimumMintsForCountdown,
100
114
  };
101
115
  };
102
116
 
@@ -33,12 +33,14 @@ export type TimedSaleParamsType = {
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;
36
- // Sale start time
36
+ // Earliest time a token can be minted. If undefined or 0, then it can be minted immediately. Defaults to 0n.
37
37
  saleStart?: bigint;
38
- // Market countdown
38
+ // Market countdown that will start once the minimum mints for countdown is reached. Defaults to 24 hours.
39
39
  marketCountdown?: bigint;
40
- // Minimum market ETH amount
40
+ // Deprecated: Use minimumMintsForCountdown instead.
41
41
  minimumMarketEth?: bigint;
42
+ // Minimum mints that will trigger the countdown. Defaults to 1111
43
+ minimumMintsForCountdown?: bigint;
42
44
  };
43
45
 
44
46
  export type Erc20ParamsType = SaleStartAndEnd &
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, vi } from "vitest";
2
- import { parseEther } from "viem";
2
+ import { parseEther, Address } from "viem";
3
3
  import { zoraSepolia } from "viem/chains";
4
4
  import {
5
5
  forkUrls,
@@ -8,7 +8,7 @@ import {
8
8
  } from "src/anvil";
9
9
  import { createCollectorClient } from "src/sdk";
10
10
  import { zoraCreator1155ImplABI } from "@zoralabs/protocol-deployments";
11
- import { setupContractAndToken } from "src/fixtures/contract-setup";
11
+ import { SubgraphMintGetter } from "src/mint/subgraph-mint-getter";
12
12
  import { ERROR_SECONDARY_NOT_STARTED } from "./secondary-client";
13
13
  import { ISubgraphQuerier } from "src/apis/subgraph-querier";
14
14
  import { mockTimedSaleStrategyTokenQueryResult } from "src/fixtures/mint-query-results";
@@ -17,7 +17,7 @@ import { advanceToSaleAndAndLaunchMarket } from "src/fixtures/secondary";
17
17
 
18
18
  describe("secondary", () => {
19
19
  makeAnvilTest({
20
- forkBlockNumber: 14653556,
20
+ forkBlockNumber: 16072399,
21
21
  forkUrl: forkUrls.zoraSepolia,
22
22
  anvilChainId: zoraSepolia.id,
23
23
  })(
@@ -25,16 +25,11 @@ describe("secondary", () => {
25
25
  async ({
26
26
  viemClients: { publicClient, chain, walletClient, testClient },
27
27
  }) => {
28
- const creatorAccount = (await walletClient.getAddresses()!)[0]!;
29
28
  const collectorAccount = (await walletClient.getAddresses()!)[1]!;
30
29
 
31
- const { contractAddress, newTokenId } = await setupContractAndToken({
32
- chain,
33
- publicClient,
34
- creatorAccount,
35
- walletClient,
36
- });
37
-
30
+ const contractAddress: Address =
31
+ "0xd42557f24034b53e7340a40bb5813ef9ba88f2b4";
32
+ const newTokenId = 4n;
38
33
  await testClient.setBalance({
39
34
  address: collectorAccount,
40
35
  value: parseEther("100"),
@@ -50,7 +45,10 @@ describe("secondary", () => {
50
45
  tokenId: newTokenId,
51
46
  });
52
47
 
53
- expect(secondaryInfo?.secondaryActivated).toBe(false);
48
+ expect(secondaryInfo).toBeDefined();
49
+
50
+ expect(secondaryInfo!.minimumMintsForCountdown).toBe(1111n);
51
+ expect(secondaryInfo!.secondaryActivated).toBe(false);
54
52
 
55
53
  const buyResult = await collectorClient.buy1155OnSecondary({
56
54
  account: collectorAccount,
@@ -65,7 +63,7 @@ describe("secondary", () => {
65
63
  );
66
64
 
67
65
  makeAnvilTest({
68
- forkBlockNumber: 14653556,
66
+ forkBlockNumber: 16072399,
69
67
  forkUrl: forkUrls.zoraSepolia,
70
68
  anvilChainId: zoraSepolia.id,
71
69
  })(
@@ -73,16 +71,12 @@ describe("secondary", () => {
73
71
  async ({
74
72
  viemClients: { publicClient, chain, walletClient, testClient },
75
73
  }) => {
76
- const creatorAccount = (await walletClient.getAddresses()!)[0]!;
77
74
  const collectorAccount = (await walletClient.getAddresses()!)[1]!;
78
75
 
79
- const { contractAddress, newTokenId, mintGetter } =
80
- await setupContractAndToken({
81
- chain,
82
- publicClient,
83
- creatorAccount,
84
- walletClient,
85
- });
76
+ const mintGetter = new SubgraphMintGetter(chain.id);
77
+ const contractAddress: Address =
78
+ "0xd42557f24034b53e7340a40bb5813ef9ba88f2b4";
79
+ const newTokenId = 4n;
86
80
 
87
81
  await testClient.setBalance({
88
82
  address: collectorAccount,
@@ -109,13 +103,25 @@ describe("secondary", () => {
109
103
  mintGetter,
110
104
  });
111
105
 
106
+ const secondaryInfo = await collectorClient.getSecondaryInfo({
107
+ contract: contractAddress,
108
+ tokenId: newTokenId,
109
+ });
110
+
111
+ expect(secondaryInfo).toBeDefined();
112
+ expect(secondaryInfo!.mintCount).toBeGreaterThan(0n);
113
+
112
114
  // mint 1 less than expected minimum market.
113
115
  // make sure that there is no sale end
116
+ const quantityToMintFirst =
117
+ secondaryInfo!.minimumMintsForCountdown! -
118
+ secondaryInfo!.mintCount -
119
+ 1n;
120
+
114
121
  const { parameters: collectParameters } = await collectorClient.mint({
115
122
  minterAccount: collectorAccount,
116
123
  mintType: "1155",
117
- // mint 1 less than expected minimum market.
118
- quantityToMint: 1111n - 1n,
124
+ quantityToMint: quantityToMintFirst,
119
125
  tokenId: newTokenId,
120
126
  tokenContract: contractAddress,
121
127
  });
@@ -245,7 +251,9 @@ describe("secondary", () => {
245
251
  args: [collectorAccount, newTokenId],
246
252
  });
247
253
 
248
- expect(balance).toBe(1111n + quantityToBuy - quantityToSell);
254
+ expect(balance).toBe(
255
+ quantityToMintFirst + 1n + quantityToBuy - quantityToSell,
256
+ );
249
257
  },
250
258
  30_000,
251
259
  );
@@ -15,6 +15,7 @@ import {
15
15
  QuotePrice,
16
16
  BuyWithSlippageInput,
17
17
  SellWithSlippageInput,
18
+ SecondaryInfo,
18
19
  } from "./types";
19
20
 
20
21
  // uniswap's auto slippage for L2s is 0.5% -> 0.005
@@ -331,7 +332,7 @@ export class SecondaryClient {
331
332
  }: {
332
333
  contract: Address;
333
334
  tokenId: bigint;
334
- }) {
335
+ }): Promise<SecondaryInfo | undefined> {
335
336
  return getSecondaryInfo({
336
337
  contract,
337
338
  tokenId,
@@ -52,13 +52,26 @@ export type BuyWithSlippageInput = {
52
52
  // Same structure as BuyWithSlippageInput
53
53
  export type SellWithSlippageInput = BuyWithSlippageInput;
54
54
 
55
+ // Base type for shared properties
55
56
  export type SecondaryInfo = {
56
- // Whether the secondary market is activated
57
+ // Boolean if the secondary market has been launched
57
58
  secondaryActivated: boolean;
58
- // Address of the liquidity pool for the erc20z to WETH pair
59
+ // The Uniswap pool address
59
60
  pool: Address;
60
- // Address of the erc20z token
61
+ // The ERC20z address
61
62
  erc20z: Address;
62
- // Timestamp when the secondary market will end
63
+ // The ERC20Z name
64
+ name: string;
65
+ // The ERC20Z symbol
66
+ symbol: string;
67
+ // Earliest time in seconds a token can be minted
68
+ saleStart: bigint;
69
+ // Latest time in seconds a token can be minted. Gets set after the market countdown has started.
63
70
  saleEnd?: bigint;
71
+ // The amount of time after the `minimumMarketEth` is reached until the secondary market can be launched, in seconds.
72
+ marketCountdown?: bigint;
73
+ // minimum quantity of tokens that must have been minted to launch the countdown.
74
+ minimumMintsForCountdown?: bigint;
75
+ // mints so far
76
+ mintCount: bigint;
64
77
  };
@@ -1,4 +1,4 @@
1
- import { Address } from "viem";
1
+ import { Address, parseEther } from "viem";
2
2
  import { PublicClient } from "src/utils";
3
3
  import {
4
4
  zoraTimedSaleStrategyABI,
@@ -16,15 +16,22 @@ export async function getSecondaryInfo({
16
16
  publicClient: PublicClient;
17
17
  chainId: number;
18
18
  }): Promise<SecondaryInfo | undefined> {
19
- const result = await publicClient.readContract({
20
- abi: zoraTimedSaleStrategyABI,
21
- address:
22
- zoraTimedSaleStrategyAddress[
23
- chainId as keyof typeof zoraTimedSaleStrategyAddress
24
- ],
25
- functionName: "sale",
26
- args: [contract, tokenId],
27
- });
19
+ let result;
20
+
21
+ try {
22
+ result = await publicClient.readContract({
23
+ abi: zoraTimedSaleStrategyABI,
24
+ address:
25
+ zoraTimedSaleStrategyAddress[
26
+ chainId as keyof typeof zoraTimedSaleStrategyAddress
27
+ ],
28
+ functionName: "saleV2",
29
+ args: [contract, tokenId],
30
+ });
31
+ } catch (e) {
32
+ console.error(e);
33
+ return undefined;
34
+ }
28
35
 
29
36
  // if there is no erc20zAddress, we can assume that secondary market has not been configured for this contract and token.
30
37
  if (!result.erc20zAddress) {
@@ -36,5 +43,18 @@ export async function getSecondaryInfo({
36
43
  pool: result.poolAddress,
37
44
  secondaryActivated: result.secondaryActivated,
38
45
  saleEnd: result.saleEnd === 0n ? undefined : result.saleEnd,
46
+ saleStart: result.saleStart,
47
+ name: result.name,
48
+ symbol: result.symbol,
49
+ marketCountdown:
50
+ result.marketCountdown === 0n ? undefined : result.marketCountdown,
51
+ minimumMintsForCountdown:
52
+ result.minimumMarketEth === 0n
53
+ ? undefined
54
+ : result.minimumMarketEth / parseEther("0.0000111"),
55
+ mintCount:
56
+ (await publicClient.getBalance({
57
+ address: result.erc20zAddress,
58
+ })) / parseEther("0.0000111"),
39
59
  };
40
60
  }
package/src/test-utils.ts CHANGED
@@ -9,7 +9,6 @@ import {
9
9
  encodeAbiParameters,
10
10
  parseAbiParameters,
11
11
  } from "viem";
12
- import { NewContractParams } from "./create/types";
13
12
  import { expect } from "vitest";
14
13
 
15
14
  export const waitForSuccess = async (hash: Hex, publicClient: PublicClient) => {
@@ -18,8 +17,6 @@ export const waitForSuccess = async (hash: Hex, publicClient: PublicClient) => {
18
17
  });
19
18
 
20
19
  expect(receipt.status).toBe("success");
21
-
22
- return receipt;
23
20
  };
24
21
 
25
22
  export const getFixedPricedMinter = async ({
@@ -40,12 +37,3 @@ export const fixedPriceMinterMinterArguments = ({
40
37
  }: {
41
38
  mintRecipient: Address;
42
39
  }) => 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
- }