Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
kien-ngo committed Oct 20, 2024
1 parent df128bf commit c202eb6
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/silent-eels-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"thirdweb": minor
---

Add new ERC1155 extension: mintAdditionalSupplyToBatch
5 changes: 5 additions & 0 deletions packages/thirdweb/src/exports/extensions/erc1155.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,8 @@ export {
mintToBatch,
type MintToBatchParams,
} from "../../extensions/erc1155/write/mintToBatch.js";

export {
mintAdditionalSupplyToBatch,
type MintAdditionalSupplyToBatchParams,
} from "../../extensions/erc1155/write/mintAdditionalSupplyToBatch.js";
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { describe, expect, it } from "vitest";
import { ANVIL_CHAIN } from "~test/chains.js";
import { TEST_CONTRACT_URI } from "~test/ipfs-uris.js";
import { TEST_CLIENT } from "~test/test-clients.js";
import { TEST_ACCOUNT_C } from "~test/test-wallets.js";
import { getContract } from "../../../contract/contract.js";
import { deployERC1155Contract } from "../../../extensions/prebuilts/deploy-erc1155.js";
import { sendAndConfirmTransaction } from "../../../transaction/actions/send-and-confirm-transaction.js";
import { getNFTs } from "../read/getNFTs.js";
import { mintAdditionalSupplyToBatch } from "./mintAdditionalSupplyToBatch.js";
import { mintToBatch } from "./mintToBatch.js";

const chain = ANVIL_CHAIN;
const client = TEST_CLIENT;
const account = TEST_ACCOUNT_C;

describe("ERC1155 Edition: mintToBatch", () => {
it("should mint multiple tokens in one tx", async () => {
const contract = getContract({
chain,
client,
address: await deployERC1155Contract({
chain,
client,
account,
type: "TokenERC1155",
params: {
name: "edition",
contractURI: TEST_CONTRACT_URI,
},
}),
});

await sendAndConfirmTransaction({
account,
transaction: mintToBatch({
contract,
to: account.address,
nfts: [
{ metadata: { name: "token 0" }, supply: 1n },
{ metadata: { name: "token 1" }, supply: 2n },
{ metadata: { name: "token 2" }, supply: 3n },
],
}),
});

await sendAndConfirmTransaction({
account,
transaction: mintAdditionalSupplyToBatch({
contract,
nfts: [
{ tokenId: 0n, supply: 99n, to: account.address },
{ tokenId: 1n, supply: 98n, to: account.address },
{ tokenId: 2n, supply: 97n, to: account.address },
],
}),
});

const nfts = await getNFTs({ contract });
expect(nfts).toStrictEqual([
{
metadata: { name: "token 0" },
owner: null,
id: 0n,
tokenURI: "ipfs://QmPZ6LpGqMuFbHKTXrNW1NRNLHf1nrxS4dtoFqdZZTKvPX/0",
type: "ERC1155",
supply: 100n,
},
{
metadata: { name: "token 1" },
owner: null,
id: 1n,
tokenURI: "ipfs://QmRFPyc3yEYxR4pQxwyTQWTine51TxWCoD6nzJWR3eX45b/0",
type: "ERC1155",
supply: 100n,
},
{
metadata: { name: "token 2" },
owner: null,
id: 2n,
tokenURI: "ipfs://QmesQiRLHCgqWZM2GFCs7Nb7rr2S72hU1BVQc7xiTyKZtT/0",
type: "ERC1155",
supply: 100n,
},
]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { multicall } from "../../../extensions/common/__generated__/IMulticall/write/multicall.js";
import type { BaseTransactionOptions } from "../../../transaction/types.js";
import { uri } from "../__generated__/IERC1155/read/uri.js";
import { encodeMintTo } from "../__generated__/IMintableERC1155/write/mintTo.js";
import type { MintAdditionalSupplyToParams } from "./mintAdditionalSupplyTo.js";

/**
* @extension ERC1155
*/
export type MintAdditionalSupplyToBatchParams = {
nfts: MintAdditionalSupplyToParams[];
};

/**
* This extension batches multiple `mintAdditionalSupplyToBatch` extensions into one single multicall.
* Keep in mind that there is a limit of how many NFTs you can mint per transaction.
* This limit varies depends on the network that you are transacting on.
*
* You are recommended to experiment with the number to figure out the best number for your chain of choice.
* @extension ERC1155
* @example
* ```ts
* import { mintAdditionalSupplyToBatch } from "thirdweb/extensions/erc1155";
*
* const transaction = mintAdditionalSupplyToBatch({
* contract,
* nfts: [
* { tokenId: 0n, supply: 99n, to: account.address },
* { tokenId: 1n, supply: 98n, to: account.address },
* { tokenId: 2n, supply: 97n, to: account.address },
* ],
* });
* ```
*/
export function mintAdditionalSupplyToBatch(
options: BaseTransactionOptions<MintAdditionalSupplyToBatchParams>,
) {
return multicall({
contract: options.contract,
asyncParams: async () => {
const data = await Promise.all(
options.nfts.map(async (nft) => {
const tokenUri = await uri({
contract: options.contract,
tokenId: nft.tokenId,
});
return encodeMintTo({
to: nft.to,
tokenId: nft.tokenId,
amount: nft.supply,
uri: tokenUri,
});
}),
);
return { data };
},
});
}
39 changes: 15 additions & 24 deletions packages/thirdweb/src/extensions/erc1155/write/mintToBatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,33 +83,24 @@ export function mintToBatch(
return multicall({
contract: options.contract,
asyncParams: async () => {
const uris = await Promise.all(
options.nfts.map((item) => {
if (typeof item.metadata === "string") {
return item.metadata;
}
return upload({
client: options.contract.client,
files: [item.metadata],
const data = await Promise.all(
options.nfts.map(async (nft) => {
const uri =
typeof nft.metadata === "string"
? nft.metadata

Check warning on line 90 in packages/thirdweb/src/extensions/erc1155/write/mintToBatch.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/erc1155/write/mintToBatch.ts#L90

Added line #L90 was not covered by tests
: await upload({
client: options.contract.client,
files: [nft.metadata],
});
return encodeMintTo({
to: options.to,
// maxUint256 is used to indicate that this is a NEW token!
tokenId: maxUint256,
uri,
amount: nft.supply,
});
}),
);

const data = uris.map((uri, index) => {
const item = options.nfts[index];
if (!item) {
// Should not happen
throw new Error("Index mismatch");
}
return encodeMintTo({
to: options.to,
// maxUint256 is used to indicate that this is a NEW token!
tokenId: maxUint256,
uri,
amount: item.supply,
});
});

return { data };
},
overrides: options.overrides,
Expand Down

0 comments on commit c202eb6

Please sign in to comment.