From a8b7ba46b4083dacca1ecec664620efada2c0e33 Mon Sep 17 00:00:00 2001 From: Dan Oved Date: Tue, 28 Nov 2023 13:01:24 -0800 Subject: [PATCH] premint client now follows standard mint client functinoality --- .../src/premint/premint-api-client.ts | 90 +++++++++++++++---- .../src/premint/premint-client.test.ts | 7 +- .../src/premint/premint-client.ts | 69 ++++++-------- 3 files changed, 100 insertions(+), 66 deletions(-) diff --git a/packages/protocol-sdk/src/premint/premint-api-client.ts b/packages/protocol-sdk/src/premint/premint-api-client.ts index c4be78df2..cb78cc42d 100644 --- a/packages/protocol-sdk/src/premint/premint-api-client.ts +++ b/packages/protocol-sdk/src/premint/premint-api-client.ts @@ -1,6 +1,11 @@ -import { post, retries, get } from "../apis/http-api-base"; +import { + IHttpClient, + httpClient as defaultHttpClient, +} from "../apis/http-api-base"; import { components, paths } from "../apis/generated/premint-api-types"; import { ZORA_API_BASE } from "../constants"; +import { NetworkConfig } from "src/apis/chain-constants"; +import { getApiNetworkConfigForChain } from "src/mint/mint-api-client"; type SignaturePostType = paths["/signature"]["post"]; type PremintSignatureRequestBody = @@ -22,36 +27,85 @@ type PremintSignatureGetPathParameters = export type PremintSignatureGetResponse = SignaturePremintGetType["responses"][200]["content"]["application/json"]; +export type PremintCollection = PremintSignatureGetResponse['collection']; + export type BackendChainNames = components["schemas"]["ChainName"]; -const postSignature = async ( - data: PremintSignatureRequestBody, -): Promise => +const postSignature = async ({ + httpClient: { post, retries } = defaultHttpClient, + ...data +}: PremintSignatureRequestBody & { + httpClient?: Pick; +}): Promise => retries(() => post(`${ZORA_API_BASE}premint/signature`, data), ); -const getNextUID = async ( - path: PremintNextUIDGetPathParameters, -): Promise => +const getNextUID = async ({ + chain_name, + collection_address, + httpClient: { retries, get } = defaultHttpClient, +}: PremintNextUIDGetPathParameters & { + httpClient?: Pick; +}): Promise => retries(() => get( - `${ZORA_API_BASE}premint/signature/${path.chain_name}/${path.collection_address}/next_uid`, + `${ZORA_API_BASE}premint/signature/${chain_name}/${collection_address}/next_uid`, ), ); -const getSignature = async ( - path: PremintSignatureGetPathParameters, -): Promise => +const getSignature = async ({ + collection_address, + uid, + chain_name, + httpClient: { retries, get } = defaultHttpClient, +}: PremintSignatureGetPathParameters & { + httpClient?: Pick; +}): Promise => retries(() => get( - `${ZORA_API_BASE}premint/signature/${path.chain_name}/${path.collection_address}/${path.uid}`, + `${ZORA_API_BASE}premint/signature/${chain_name}/${collection_address}/${uid}`, ), ); -export const PremintAPIClient = { - postSignature, - getSignature, - getNextUID, -}; -export { ZORA_API_BASE }; +type OmitChainName = Omit; + +class PremintAPIClient { + httpClient: IHttpClient; + networkConfig: NetworkConfig; + + constructor(chainId: number, httpClient?: IHttpClient) { + this.httpClient = httpClient || defaultHttpClient; + this.networkConfig = getApiNetworkConfigForChain(chainId); + } + postSignature = async ( + data: OmitChainName, + ): Promise => + postSignature({ + ...data, + chain_name: this.networkConfig.zoraBackendChainName, + httpClient: this.httpClient, + }); + + getNextUID = async ( + path: OmitChainName, + ): Promise => + getNextUID({ + ...path, + chain_name: this.networkConfig.zoraBackendChainName, + httpClient: this.httpClient, + }); + + getSignature = async ({ + collection_address, + uid, + }: OmitChainName): Promise => + getSignature({ + collection_address, + uid, + chain_name: this.networkConfig.zoraBackendChainName, + httpClient: this.httpClient, + }); +} + +export { ZORA_API_BASE, PremintAPIClient }; diff --git a/packages/protocol-sdk/src/premint/premint-client.test.ts b/packages/protocol-sdk/src/premint/premint-client.test.ts index 076ed7af0..2c6b592a9 100644 --- a/packages/protocol-sdk/src/premint/premint-client.test.ts +++ b/packages/protocol-sdk/src/premint/premint-client.test.ts @@ -9,7 +9,7 @@ describe("ZoraCreator1155Premint", () => { "can sign on the forked premint contract", async ({ viemClients: { walletClient, publicClient } }) => { const [deployerAccount] = await walletClient.getAddresses(); - const premintClient = createPremintClient({ chain: foundry }); + const premintClient = createPremintClient({ chain: foundry, publicClient }); premintClient.apiClient.getNextUID = vi .fn() @@ -20,7 +20,6 @@ describe("ZoraCreator1155Premint", () => { await premintClient.createPremint({ walletClient, - publicClient, account: deployerAccount!, checkSignature: true, collection: { @@ -36,7 +35,6 @@ describe("ZoraCreator1155Premint", () => { }); expect(premintClient.apiClient.postSignature).toHaveBeenCalledWith({ - chain_name: BackendChainNamesLookup.ZORA_GOERLI, collection: { contractAdmin: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", contractName: "Testing Contract", @@ -71,7 +69,7 @@ describe("ZoraCreator1155Premint", () => { anvilTest( "can validate premint on network", async ({ viemClients: { publicClient } }) => { - const premintClient = createPremintClient({ chain: foundry }); + const premintClient = createPremintClient({ chain: foundry, publicClient }); const premintData = { collection: { @@ -106,7 +104,6 @@ describe("ZoraCreator1155Premint", () => { const signatureValid = await premintClient.isValidSignature({ // @ts-ignore: Fix enum type data: premintData, - publicClient, }); expect(signatureValid.isValid).toBe(true); }, diff --git a/packages/protocol-sdk/src/premint/premint-client.ts b/packages/protocol-sdk/src/premint/premint-client.ts index 790e58a9e..1c024f448 100644 --- a/packages/protocol-sdk/src/premint/premint-client.ts +++ b/packages/protocol-sdk/src/premint/premint-client.ts @@ -1,4 +1,4 @@ -import { decodeEventLog } from "viem"; +import { createPublicClient, decodeEventLog, http } from "viem"; import type { Account, Address, @@ -21,9 +21,10 @@ import type { } from "./premint-api-client"; import { PremintAPIClient } from "./premint-api-client"; import type { DecodeEventLogReturnType } from "viem"; -import { ClientBase } from "../apis/client-base"; import { OPEN_EDITION_MINT_SIZE } from "../constants"; import { REWARD_PER_TOKEN } from "src/apis/chain-constants"; +import { IHttpClient } from "src/apis/http-api-base"; +import { getApiNetworkConfigForChain } from "src/mint/mint-api-client"; type MintArgumentsSettings = { tokenURI: string; @@ -143,16 +144,16 @@ export const encodePremintForAPI = ({ * Preminter API to access ZORA Premint functionality. * Currently only supports V1 premints. */ -class PremintClient extends ClientBase { - apiClient: typeof PremintAPIClient; - - constructor(chain: Chain, apiClient?: typeof PremintAPIClient) { - super(chain); - - if (!apiClient) { - apiClient = PremintAPIClient; - } - this.apiClient = apiClient; +class PremintClient { + readonly apiClient: PremintAPIClient; + readonly publicClient: PublicClient; + readonly chain: Chain; + + constructor(chain: Chain, publicClient?: PublicClient, httpClient?: IHttpClient) { + this.chain = chain; + this.apiClient = new PremintAPIClient(chain.id, httpClient); + this.publicClient = + publicClient || createPublicClient({ chain, transport: http() }); } /** @@ -219,7 +220,6 @@ class PremintClient extends ClientBase { collection: Address; }): Promise { const signatureResponse = await this.apiClient.getSignature({ - chain_name: this.network.zoraBackendChainName, collection_address: collection.toLowerCase(), uid: uid, }); @@ -241,7 +241,6 @@ class PremintClient extends ClientBase { account, checkSignature: false, verifyingContract: collection, - publicClient: this.getPublicClient(), uid: uid, collection: { ...signerData.collection, @@ -270,16 +269,13 @@ class PremintClient extends ClientBase { uid, account, collection, - publicClient, }: { walletClient: WalletClient; - publicClient: PublicClient; uid: number; account?: Account | Address; collection: Address; }) { const signatureResponse = await this.apiClient.getSignature({ - chain_name: this.network.zoraBackendChainName, collection_address: collection.toLowerCase(), uid: uid, }); @@ -298,7 +294,6 @@ class PremintClient extends ClientBase { account, checkSignature: false, verifyingContract: collection, - publicClient: this.getPublicClient(publicClient), uid: uid, collection: signerData.collection, premintConfig: signerData.premint, @@ -313,7 +308,6 @@ class PremintClient extends ClientBase { */ private async signAndSubmitPremint({ walletClient, - publicClient, verifyingContract, premintConfig, uid, @@ -321,7 +315,6 @@ class PremintClient extends ClientBase { checkSignature, collection, }: { - publicClient: PublicClient; uid: number; walletClient: WalletClient; verifyingContract: Address; @@ -347,7 +340,7 @@ class PremintClient extends ClientBase { }); if (checkSignature) { - const [isValidSignature] = await publicClient.readContract({ + const [isValidSignature] = await this.publicClient.readContract({ abi: zoraCreator1155PremintExecutorImplABI, address: this.getExecutorAddress(), functionName: "isValidSignature", @@ -361,7 +354,6 @@ class PremintClient extends ClientBase { const apiData = { collection, premint: encodePremintForAPI(premintConfig), - chain_name: this.network.zoraBackendChainName, signature: signature, }; @@ -394,7 +386,6 @@ class PremintClient extends ClientBase { account, collection, token, - publicClient, walletClient, executionSettings, checkSignature = false, @@ -404,15 +395,12 @@ class PremintClient extends ClientBase { walletClient: WalletClient; collection: PremintSignatureGetResponse["collection"]; token: MintArgumentsSettings; - publicClient?: PublicClient; executionSettings?: { deleted?: boolean; uid?: number; }; }) { - publicClient = this.getPublicClient(publicClient); - - const newContractAddress = await publicClient.readContract({ + const newContractAddress = await this.publicClient.readContract({ address: this.getExecutorAddress(), abi: zoraCreator1155PremintExecutorImplABI, functionName: "getContractAddress", @@ -429,7 +417,6 @@ class PremintClient extends ClientBase { let uid = executionSettings?.uid; if (!uid) { const uidResponse = await this.apiClient.getNextUID({ - chain_name: this.network.zoraBackendChainName, collection_address: newContractAddress.toLowerCase(), }); uid = uidResponse.next_uid; @@ -454,7 +441,6 @@ class PremintClient extends ClientBase { premintConfig, checkSignature, account, - publicClient, walletClient, collection, }); @@ -475,7 +461,6 @@ class PremintClient extends ClientBase { uid: number; }): Promise { return await this.apiClient.getSignature({ - chain_name: this.network.zoraBackendChainName, collection_address: address, uid, }); @@ -489,19 +474,15 @@ class PremintClient extends ClientBase { */ async isValidSignature({ data, - publicClient, }: { data: PremintSignatureGetResponse; - publicClient?: PublicClient; }): Promise<{ isValid: boolean; contractAddress: Address; recoveredSigner: Address; }> { - publicClient = this.getPublicClient(publicClient); - const [isValid, contractAddress, recoveredSigner] = - await publicClient.readContract({ + await this.publicClient.readContract({ abi: zoraCreator1155PremintExecutorImplABI, address: this.getExecutorAddress(), functionName: "isValidSignature", @@ -530,19 +511,21 @@ class PremintClient extends ClientBase { const zoraTokenPath = uid ? `premint-${uid}` : tokenId; + const network = getApiNetworkConfigForChain(this.chain.id); + return { explorer: tokenId ? `https://${this.chain.blockExplorers?.default.url}/token/${address}/instance/${tokenId}` : null, zoraCollect: `https://${ - this.network.isTestnet ? "testnet." : "" + network.isTestnet ? "testnet." : "" }zora.co/collect/${ - this.network.zoraPathChainName + network.zoraPathChainName }:${address}/${zoraTokenPath}`, zoraManage: `https://${ - this.network.isTestnet ? "testnet." : "" + network.isTestnet ? "testnet." : "" }zora.co/collect/${ - this.network.zoraPathChainName + network.zoraPathChainName }:${address}/${zoraTokenPath}`, }; } @@ -608,10 +591,10 @@ class PremintClient extends ClientBase { export function createPremintClient({ chain, - premintAPIClient, + httpClient, + publicClient }: { - chain: Chain; - premintAPIClient?: typeof PremintAPIClient; + chain: Chain, publicClient?: PublicClient, httpClient?: IHttpClient }) { - return new PremintClient(chain, premintAPIClient); + return new PremintClient(chain, publicClient, httpClient); }