Skip to content

[SDK] Perf improvement for erc-1155-signature-mintable #1824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/moody-points-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@thirdweb-dev/sdk": patch
---

Performance improve for erc-1155-signature-mintable
105 changes: 58 additions & 47 deletions packages/sdk/src/evm/core/classes/erc-1155-signature-mintable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ export class Erc1155SignatureMintable implements DetectableFeature {
): Promise<Transaction<TransactionResultWithId>> => {
const mintRequest = signedPayload.payload;
const signature = signedPayload.signature;
const message = await this.mapPayloadToContractStruct(mintRequest);
const overrides = await this.contractWrapper.getCallOverrides();
const [message, overrides] = await Promise.all([
this.mapPayloadToContractStruct(mintRequest),
this.contractWrapper.getCallOverrides(),
]);
// TODO: Transaction Sequence Pattern
await setErc20Allowance(
this.contractWrapper,
Expand Down Expand Up @@ -136,22 +138,23 @@ export class Erc1155SignatureMintable implements DetectableFeature {
async (
signedPayloads: SignedPayload1155[],
): Promise<Transaction<TransactionResultWithId[]>> => {
const contractPayloads = await Promise.all(
signedPayloads.map(async (s) => {
const message = await this.mapPayloadToContractStruct(s.payload);
const signature = s.signature;
const price = s.payload.price;
if (BigNumber.from(price).gt(0)) {
throw new Error(
"Can only batch free mints. For mints with a price, use regular mint()",
);
}
return {
message,
signature,
};
}),
const contractStructs = await Promise.all(
signedPayloads.map((s) => this.mapPayloadToContractStruct(s.payload)),
);
const contractPayloads = signedPayloads.map((s, index) => {
const message = contractStructs[index];
const signature = s.signature;
const price = s.payload.price;
if (BigNumber.from(price).gt(0)) {
throw new Error(
"Can only batch free mints. For mints with a price, use regular mint()",
);
}
return {
message,
signature,
};
});
const contractEncoder = new ContractEncoder(this.contractWrapper);
const encoded = contractPayloads.map((p) => {
return contractEncoder.encode("mintWithSignature", [
Expand Down Expand Up @@ -276,7 +279,7 @@ export class Erc1155SignatureMintable implements DetectableFeature {
}

/**
* Generate a signature that can be used to mint additionaly supply to an existing NFT.
* Generate a signature that can be used to mint additionally supply to an existing NFT.
*
* @remarks Takes in a payload with the token ID of an existing NFT, and signs it with your private key. The generated signature can then be used to mint additional supply to the NFT using the exact payload and signature generated.
*
Expand All @@ -291,7 +294,7 @@ export class Erc1155SignatureMintable implements DetectableFeature {
* const startTime = new Date();
* const endTime = new Date(Date.now() + 60 * 60 * 24 * 1000);
* const payload = {
* tokenId: 0, // Instead of metadata, we specificy the token ID of the NFT to mint supply to
* tokenId: 0, // Instead of metadata, we specify the token ID of the NFT to mint supply to
* to: {{wallet_address}}, // Who will receive the NFT (or AddressZero for anyone)
* quantity: 2, // the quantity of NFTs to mint
* price: 0.5, // the price per NFT
Expand Down Expand Up @@ -337,7 +340,7 @@ export class Erc1155SignatureMintable implements DetectableFeature {
}

/**
* Genrate a batch of signatures that can be used to mint new NFTs or additionaly supply to existing NFTs dynamically.
* Generate a batch of signatures that can be used to mint new NFTs or additionally supply to existing NFTs dynamically.
*
* @remarks See {@link Erc1155SignatureMintable.generateFromTokenId}
*
Expand All @@ -348,10 +351,10 @@ export class Erc1155SignatureMintable implements DetectableFeature {
public async generateBatchFromTokenIds(
payloadsToSign: PayloadToSign1155WithTokenId[],
): Promise<SignedPayload1155[]> {
await this.roles?.verify(
["minter"],
await this.contractWrapper.getSignerAddress(),
);
const signer = this.contractWrapper.getSigner();
invariant(signer, "No signer available");

await this.roles?.verify(["minter"], await signer.getAddress());

const parsedRequests: FilledSignaturePayload1155WithTokenId[] =
await Promise.all(
Expand All @@ -361,26 +364,34 @@ export class Erc1155SignatureMintable implements DetectableFeature {
);

const metadatas = parsedRequests.map((r) => r.metadata);
const uris = await uploadOrExtractURIs(metadatas, this.storage);

const chainId = await this.contractWrapper.getChainID();
const signer = this.contractWrapper.getSigner();
invariant(signer, "No signer available");
const [uris, chainId, contractInfo] = await Promise.all([
uploadOrExtractURIs(metadatas, this.storage),
this.contractWrapper.getChainID(),
getPrebuiltInfo(
this.contractWrapper.address,
this.contractWrapper.getProvider(),
),
]);

const contractInfo = await getPrebuiltInfo(
this.contractWrapper.address,
this.contractWrapper.getProvider(),
const finalPayloads = await Promise.all(
parsedRequests.map((m, i) =>
Signature1155PayloadOutput.parseAsync({
...m,
uri: uris[i],
}),
),
);
const contractStructs = await Promise.all(
finalPayloads.map((finalPayload) =>
this.mapPayloadToContractStruct(finalPayload),
),
);
const isLegacyContract = contractInfo?.type === "TokenERC1155";

return await Promise.all(
parsedRequests.map(async (m, i) => {
const uri = uris[i];
const finalPayload = await Signature1155PayloadOutput.parseAsync({
...m,
uri,
});
const signature = await this.contractWrapper.signTypedData(
const isLegacyContract = contractInfo?.type === "TokenERC1155";
const signatures = await Promise.all(
contractStructs.map((contractStruct) =>
this.contractWrapper.signTypedData(
signer,
{
name: isLegacyContract ? "TokenERC1155" : "SignatureMintERC1155",
Expand All @@ -389,14 +400,14 @@ export class Erc1155SignatureMintable implements DetectableFeature {
verifyingContract: this.contractWrapper.address,
},
{ MintRequest: MintRequest1155 }, // TYPEHASH
await this.mapPayloadToContractStruct(finalPayload),
);
return {
payload: finalPayload,
signature: signature.toString(),
};
}),
contractStruct,
),
),
);
return signatures.map((signature, index) => ({
payload: finalPayloads[index],
signature: signature.toString(),
}));
}

/** ******************************
Expand Down