Skip to content

Commit

Permalink
added tsdoc comments
Browse files Browse the repository at this point in the history
  • Loading branch information
oveddan committed Nov 22, 2023
1 parent b1b76b3 commit ec28c3c
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 43 deletions.
15 changes: 2 additions & 13 deletions packages/protocol-sdk/src/premint/preminter.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
keccak256,
Hex,
concat,
recoverAddress,
hashDomain,
Address,
zeroAddress,
} from "viem";
Expand Down Expand Up @@ -579,21 +574,15 @@ describe("ZoraCreator1155Preminter", () => {

const creatorAttributionEvent = topics[0]!;

const { creator: creatorFromEvent, domainName, signature, structHash, version } =
const { creator: creatorFromEvent } =
creatorAttributionEvent.args;

const recoveredSigner = await recoverCreatorFromCreatorAttribution({
creatorAttribution: {
domainName: domainName!,
signature: signature!,
structHash: structHash!,
version: version!
},
creatorAttribution: creatorAttributionEvent.args,
chainId: signingChainId,
contractAddress
})

expect(domainName).toBe(PreminterDomain);
expect(creatorFromEvent).toBe(creatorAccount);
expect(recoveredSigner).toBe(creatorFromEvent);
},
Expand Down
101 changes: 71 additions & 30 deletions packages/protocol-sdk/src/premint/preminter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Address } from "abitype";
import { Address, ExtractAbiEvent } from "abitype";
import { ExtractAbiFunction, AbiParametersToPrimitiveTypes } from "abitype";
import {
zoraCreator1155PremintExecutorImplABI as preminterAbi,
zoraCreator1155ImplABI,
zoraCreator1155PremintExecutorImplAddress,
} from "@zoralabs/protocol-deployments";
import {
Expand All @@ -14,6 +15,7 @@ import {
keccak256,
concat,
recoverAddress,
GetEventArgs,
} from "viem";

type PremintV1Inputs = ExtractAbiFunction<
Expand Down Expand Up @@ -108,8 +110,15 @@ type PremintConfigWithVersion<T extends PremintConfigVersion> = {

export type PremintConfigAndVersion = PremintConfigWithVersion<"1"> | PremintConfigWithVersion<"2">;

// Convenience method to create the structured typed data
// needed to sign for a premint contract and token
/**
* Creates a typed data definition for a premint config. Works for all versions of the premint config by specifying the premintConfigVersion.
*
* @param params.verifyingContract the address of the 1155 contract
* @param params.chainId the chain id the premint is signed for
* @param params.premintConfigVersion the version of the premint config
* @param params.premintConfig the premint config
* @returns
*/
export const premintTypedDataDefinition = ({
verifyingContract,
chainId,
Expand All @@ -119,26 +128,23 @@ export const premintTypedDataDefinition = ({
verifyingContract: Address;
chainId: number;
} & PremintConfigAndVersion): TypedDataDefinition => {
const domain = {
chainId,
name: PreminterDomain,
version,
verifyingContract: verifyingContract,
};

if (version === PremintConfigVersion.V1)
return {
domain: {
chainId,
name: PreminterDomain,
version: PremintConfigVersion.V1,
verifyingContract: verifyingContract,
},
domain,
types: v1Types,
message: premintConfig,
primaryType: "CreatorAttribution",
} satisfies TypedDataDefinition<typeof v1Types, "CreatorAttribution">;
if (version === PremintConfigVersion.V2) {
return {
domain: {
chainId,
name: PreminterDomain,
version: PremintConfigVersion.V2,
verifyingContract: verifyingContract,
},
domain,
types: v2Types,
message: premintConfig,
primaryType: "CreatorAttribution",
Expand All @@ -153,6 +159,20 @@ export type IsValidSignatureReturn = {
recoveredAddress?: Address;
};

/**
* Checks if the provided signature is valid for the provided premint config. Is valid means that the signature is valid, and that the recovered signer is authorized to
* 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.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
* @param params.publicClient public rpc read-only client
* @param params.premintConfigVersion the version of the premint config
* @param params.premintConfig the premint config
* @returns
*/
export async function isValidSignature({
contractAddress,
originalContractAdmin,
Expand All @@ -177,24 +197,33 @@ export async function isValidSignature({
typedData,
signature,
publicClient,
originalContractAdmin,
premintConfigContractAdmin: originalContractAdmin,
contractAddress,
chainId,
});
}

/**
* Recovers the address from a typed data signature and then checks if the recovered address is authorized to create a premint
*
* @param params validationProperties
* @param params.typedData typed data definition for premint config
* @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
* @returns
*/
export async function recoverAndValidateSignature({
typedData,
signature,
publicClient,
originalContractAdmin,
premintConfigContractAdmin,
contractAddress,
}: {
contractAddress: Address;
originalContractAdmin: Address;
premintConfigContractAdmin: Address;
typedData: TypedDataDefinition;
signature: Hex;
chainId: number;
publicClient: PublicClient;
}): Promise<IsValidSignatureReturn> {
let recoveredAddress: Address;
Expand All @@ -219,7 +248,7 @@ export async function recoverAndValidateSignature({
abi: preminterAbi,
address: premintExecutorAddress,
functionName: "isAuthorizedToCreatePremint",
args: [recoveredAddress, originalContractAdmin, contractAddress],
args: [recoveredAddress, premintConfigContractAdmin, contractAddress],
});

return {
Expand All @@ -228,8 +257,13 @@ export async function recoverAndValidateSignature({
};
}

// Takes a premint config v1 and migrates it to
// version 2, adding the createReferral field

/**
* Converts a premint config from v1 to v2
*
* @param premintConfig premint config to convert
* @param createReferral address that referred the creator, that will receive create referral rewards for the created token
*/
export function migratePremintConfigToV2({
premintConfig,
createReferral = zeroAddress,
Expand All @@ -253,13 +287,20 @@ export function migratePremintConfigToV2({
},
};
}

export type CreatorAttributionEventParams = GetEventArgs<typeof zoraCreator1155ImplABI, 'CreatorAttribution', { EnableUnion: false }>;


/**
* Recovers the address from a CreatorAttribution event emitted from a ZoraCreator1155 contract
* Useful for verifying that the creator of a token is the one who signed a premint for its creation.
*
* @param creatorAttribution parameters from the CreatorAttribution event
* @returns the address of the signer
*/
export const recoverCreatorFromCreatorAttribution = async ({ creatorAttribution: {version, domainName, structHash, signature }, chainId, contractAddress}: {
creatorAttribution: {
version: string
domainName: string
structHash: Hex,
signature: Hex
},
creatorAttribution: CreatorAttributionEventParams,
contractAddress: Address,
chainId: number
}) => {
Expand Down Expand Up @@ -295,6 +336,6 @@ export const recoverCreatorFromCreatorAttribution = async ({ creatorAttribution:

return await recoverAddress({
hash: hashedTypedData,
signature: signature,
signature: signature!,
});
}

0 comments on commit ec28c3c

Please sign in to comment.