diff --git a/packages/protocol-sdk/src/premint/premint-client.ts b/packages/protocol-sdk/src/premint/premint-client.ts index 82917aead..845879174 100644 --- a/packages/protocol-sdk/src/premint/premint-client.ts +++ b/packages/protocol-sdk/src/premint/premint-client.ts @@ -386,7 +386,7 @@ class PremintClient extends ClientBase { if (checkSignature) { const { isAuthorized } = await isValidSignature({ chainId: this.chain.id, - contractAddress: verifyingContract, + tokenContract: verifyingContract, originalContractAdmin: collection.contractAdmin as Address, ...premintConfigAndVersion, publicClient: this.getPublicClient(), @@ -544,7 +544,7 @@ class PremintClient extends ClientBase { publicClient = this.getPublicClient(publicClient); const { isAuthorized, recoveredAddress } = await isValidSignature({ - contractAddress: data.collection_address as Address, + tokenContract: data.collection_address as Address, chainId: this.chain.id, originalContractAdmin: data.collection.contractAdmin as Address, premintConfig: convertPremint(data.premint), diff --git a/packages/protocol-sdk/src/premint/preminter.test.ts b/packages/protocol-sdk/src/premint/preminter.test.ts index 1eb8eac1a..1e1245b36 100644 --- a/packages/protocol-sdk/src/premint/preminter.test.ts +++ b/packages/protocol-sdk/src/premint/preminter.test.ts @@ -25,6 +25,7 @@ import { MintArguments, PreminterDomain, recoverCreatorFromCreatorAttribution, + getPremintExecutorAddress, } from "./preminter"; import { AnvilViemClientsTest, @@ -95,7 +96,7 @@ const defaultPremintConfigV2 = ( const ZORA_MINT_FEE = parseEther("0.000777"); -const PREMINTER_ADDRESS = zoraCreator1155PremintExecutorAddress[999]; +const PREMINTER_ADDRESS = getPremintExecutorAddress(); const anvilTest = makeAnvilTest({ forkUrl: forkUrls.zoraSepoli, @@ -147,7 +148,7 @@ describe("ZoraCreator1155Preminter", () => { contractAdmin: creatorAccount, }); - const preminterAddress = zoraCreator1155PremintExecutorAddress[999]; + const preminterAddress = getPremintExecutorAddress(); const contractAddress = await viemClients.publicClient.readContract({ abi: preminterAbi, @@ -191,7 +192,7 @@ describe("ZoraCreator1155Preminter", () => { contractAdmin: creatorAccount, }); - const contractAddress = await viemClients.publicClient.readContract({ + const tokenContract = await viemClients.publicClient.readContract({ abi: preminterAbi, address: PREMINTER_ADDRESS, functionName: "getContractAddress", @@ -201,7 +202,7 @@ describe("ZoraCreator1155Preminter", () => { // sign message containing contract and token creation config and uid const signedMessage = await viemClients.walletClient.signTypedData({ ...premintTypedDataDefinition({ - verifyingContract: contractAddress, + verifyingContract: tokenContract, // we need to sign here for the anvil chain, cause thats where it is run on chainId: foundry.id, premintConfig, @@ -212,7 +213,7 @@ describe("ZoraCreator1155Preminter", () => { // recover and verify address is correct const { recoveredAddress, isAuthorized } = await isValidSignature({ - contractAddress, + tokenContract: tokenContract, chainId: viemClients.publicClient.chain!.id, originalContractAdmin: contractConfig.contractAdmin, premintConfig, @@ -251,7 +252,7 @@ describe("ZoraCreator1155Preminter", () => { contractAdmin: creatorAccount, }); - const contractAddress = await viemClients.publicClient.readContract({ + const tokenContract = await viemClients.publicClient.readContract({ abi: preminterAbi, address: PREMINTER_ADDRESS, functionName: "getContractAddress", @@ -261,7 +262,7 @@ describe("ZoraCreator1155Preminter", () => { // sign message containing contract and token creation config and uid const signedMessage = await viemClients.walletClient.signTypedData({ ...premintTypedDataDefinition({ - verifyingContract: contractAddress, + verifyingContract: tokenContract, // we need to sign here for the anvil chain, cause thats where it is run on chainId: foundry.id, premintConfig, @@ -272,7 +273,7 @@ describe("ZoraCreator1155Preminter", () => { // recover and verify address is correct const { recoveredAddress, isAuthorized } = await isValidSignature({ - contractAddress, + tokenContract: tokenContract, chainId: viemClients.publicClient.chain!.id, originalContractAdmin: contractConfig.contractAdmin, premintConfig, @@ -580,7 +581,7 @@ describe("ZoraCreator1155Preminter", () => { const recoveredSigner = await recoverCreatorFromCreatorAttribution({ creatorAttribution: creatorAttributionEvent.args, chainId: signingChainId, - contractAddress + tokenContract: contractAddress }) expect(creatorFromEvent).toBe(creatorAccount); diff --git a/packages/protocol-sdk/src/premint/preminter.ts b/packages/protocol-sdk/src/premint/preminter.ts index a12a3b66e..050d5bede 100644 --- a/packages/protocol-sdk/src/premint/preminter.ts +++ b/packages/protocol-sdk/src/premint/preminter.ts @@ -110,6 +110,8 @@ type PremintConfigWithVersion = { export type PremintConfigAndVersion = PremintConfigWithVersion<"1"> | PremintConfigWithVersion<"2">; +export const getPremintExecutorAddress = () => zoraCreator1155PremintExecutorImplAddress[999]; + /** * Creates a typed data definition for a premint config. Works for all versions of the premint config by specifying the premintConfigVersion. * @@ -164,7 +166,7 @@ export type IsValidSignatureReturn = { * create premints on the given contract. Works for all versions of the premint config by specifying the premintConfigVersion. * * @param params validationProperties - * @param params.contractAddress the address of the 1155 contract + * @param params.tokenContract the address of the 1155 contract * @param params.originalContractAdmin the original contractAdmin on the ContractCreationConfig for the premint; this is usually the original creator of the premint * @param params.signature signature to validate * @param params.chainId the chain id of the current chain @@ -174,21 +176,21 @@ export type IsValidSignatureReturn = { * @returns */ export async function isValidSignature({ - contractAddress, + tokenContract, originalContractAdmin, signature, chainId, publicClient, ...premintConfigAndVersion }: { - contractAddress: Address; + tokenContract: Address; originalContractAdmin: Address; signature: Hex; chainId: number; publicClient: PublicClient; } & PremintConfigAndVersion): Promise { const typedData = premintTypedDataDefinition({ - verifyingContract: contractAddress, + verifyingContract: tokenContract, chainId, ...premintConfigAndVersion }); @@ -198,7 +200,7 @@ export async function isValidSignature({ signature, publicClient, premintConfigContractAdmin: originalContractAdmin, - contractAddress, + tokenContract: tokenContract, }); } @@ -210,7 +212,7 @@ export async function isValidSignature({ * @param params.signature signature to validate * @param params.publicClient public rpc read-only client * @param params.premintConfigContractAdmin the original contractAdmin on the ContractCreationConfig for the premint; this is usually the original creator of the premint - * @param params.contractAddress the address of the 1155 contract + * @param params.tokenContract the address of the 1155 contract * @returns */ export async function recoverAndValidateSignature({ @@ -218,9 +220,9 @@ export async function recoverAndValidateSignature({ signature, publicClient, premintConfigContractAdmin, - contractAddress, + tokenContract, }: { - contractAddress: Address; + tokenContract: Address; premintConfigContractAdmin: Address; typedData: TypedDataDefinition; signature: Hex; @@ -242,13 +244,13 @@ export async function recoverAndValidateSignature({ } // premint executor is same address on all chains - const premintExecutorAddress = zoraCreator1155PremintExecutorImplAddress[999]; + const premintExecutorAddress = getPremintExecutorAddress(); const isAuthorized = await publicClient.readContract({ abi: preminterAbi, address: premintExecutorAddress, functionName: "isAuthorizedToCreatePremint", - args: [recoveredAddress, premintConfigContractAdmin, contractAddress], + args: [recoveredAddress, premintConfigContractAdmin, tokenContract], }); return { @@ -297,11 +299,13 @@ export type CreatorAttributionEventParams = GetEventArgs { @@ -310,7 +314,7 @@ export const recoverCreatorFromCreatorAttribution = async ({ creatorAttribution: domain: { chainId, name: domainName, - verifyingContract: contractAddress, + verifyingContract: tokenContract, version, }, types: { @@ -339,3 +343,17 @@ export const recoverCreatorFromCreatorAttribution = async ({ creatorAttribution: signature: signature!, }); } + +/** + * Checks if the 1155 contract at that address supports the given version of the premint config. + */ +export const supportsPremintVersion = async (version: PremintConfigVersion, tokenContract: Address, publicClient: PublicClient) => { + const supportedPremintSignatureVersions = await publicClient.readContract({ + abi: preminterAbi, + address: getPremintExecutorAddress(), + functionName: "supportedPremintSignatureVersions", + args: [tokenContract] + }); + + return supportedPremintSignatureVersions.includes(version); +} \ No newline at end of file