Skip to content

Commit 89515e5

Browse files
committed
Update
1 parent 44b2634 commit 89515e5

File tree

4 files changed

+201
-0
lines changed

4 files changed

+201
-0
lines changed

.changeset/six-drinks-joke.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
5+
Add ERC1155 extension: mintToBatch

packages/thirdweb/src/exports/extensions/erc1155.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,8 @@ export {
198198

199199
// Zora 1155 contract
200200
export { nextTokenId } from "../../extensions/erc1155/__generated__/Zora1155/read/nextTokenId.js";
201+
202+
export {
203+
mintToBatch,
204+
type MintToBatchParams,
205+
} from "../../extensions/erc1155/write/mintToBatch.js";
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { describe, expect, it } from "vitest";
2+
import { ANVIL_CHAIN } from "~test/chains.js";
3+
import { TEST_CONTRACT_URI } from "~test/ipfs-uris.js";
4+
import { TEST_CLIENT } from "~test/test-clients.js";
5+
import { TEST_ACCOUNT_C } from "~test/test-wallets.js";
6+
import { getContract } from "../../../contract/contract.js";
7+
import { deployERC1155Contract } from "../../../extensions/prebuilts/deploy-erc1155.js";
8+
import { sendAndConfirmTransaction } from "../../../transaction/actions/send-and-confirm-transaction.js";
9+
import { getNFTs } from "../read/getNFTs.js";
10+
import { mintToBatch } from "./mintToBatch.js";
11+
12+
const chain = ANVIL_CHAIN;
13+
const client = TEST_CLIENT;
14+
const account = TEST_ACCOUNT_C;
15+
16+
describe("ERC1155 Edition: mintToBatch", () => {
17+
it("should mint multiple tokens in one tx", async () => {
18+
const contract = getContract({
19+
chain,
20+
client,
21+
address: await deployERC1155Contract({
22+
chain,
23+
client,
24+
account,
25+
type: "TokenERC1155",
26+
params: {
27+
name: "edition",
28+
contractURI: TEST_CONTRACT_URI,
29+
},
30+
}),
31+
});
32+
33+
await sendAndConfirmTransaction({
34+
account,
35+
transaction: mintToBatch({
36+
contract,
37+
to: account.address,
38+
nfts: [
39+
{ metadata: { name: "token 0" }, supply: 1n },
40+
{ metadata: { name: "token 1" }, supply: 2n },
41+
{ metadata: { name: "token 2" }, supply: 3n },
42+
],
43+
}),
44+
});
45+
46+
const nfts = await getNFTs({ contract });
47+
expect(nfts).toStrictEqual([
48+
{
49+
metadata: { name: "token 0" },
50+
owner: null,
51+
id: 0n,
52+
tokenURI: "ipfs://QmPZ6LpGqMuFbHKTXrNW1NRNLHf1nrxS4dtoFqdZZTKvPX/0",
53+
type: "ERC1155",
54+
supply: 1n,
55+
},
56+
{
57+
metadata: { name: "token 1" },
58+
owner: null,
59+
id: 1n,
60+
tokenURI: "ipfs://QmRFPyc3yEYxR4pQxwyTQWTine51TxWCoD6nzJWR3eX45b/0",
61+
type: "ERC1155",
62+
supply: 2n,
63+
},
64+
{
65+
metadata: { name: "token 2" },
66+
owner: null,
67+
id: 2n,
68+
tokenURI: "ipfs://QmesQiRLHCgqWZM2GFCs7Nb7rr2S72hU1BVQc7xiTyKZtT/0",
69+
type: "ERC1155",
70+
supply: 3n,
71+
},
72+
]);
73+
});
74+
});
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { maxUint256 } from "viem";
2+
import { multicall } from "../../../extensions/common/__generated__/IMulticall/write/multicall.js";
3+
import { upload } from "../../../storage/upload.js";
4+
import type {
5+
BaseTransactionOptions,
6+
WithOverrides,
7+
} from "../../../transaction/types.js";
8+
import type { NFTInput } from "../../../utils/nft/parseNft.js";
9+
import { encodeMintTo } from "../__generated__/IMintableERC1155/write/mintTo.js";
10+
11+
/**
12+
* @extension ERC1155
13+
*/
14+
export type MintToBatchParams = WithOverrides<{
15+
/**
16+
* The wallet that the NFTs will be minted to
17+
*/
18+
to: string;
19+
/**
20+
* An array of NFT metadata & supply to mint
21+
* @example
22+
* ```ts
23+
* const nfts = [
24+
* {
25+
* metadata: { name: "token 0" },
26+
* supply: 1n,
27+
* },
28+
* {
29+
* metadata: { name: "token 1" },
30+
* supply: 10n,
31+
* },
32+
* ]
33+
* ```
34+
*/
35+
nfts: Array<{
36+
supply: bigint;
37+
metadata: NFTInput | string;
38+
}>;
39+
}>;
40+
41+
/**
42+
* This extension batches multiple `mintTo` extensions into one single multicall.
43+
* Keep in mind that there is a limit of how many NFTs you can mint per transaction.
44+
* This limit varies depends on the network that you are transacting on.
45+
*
46+
* You are recommended to experiment with the number to figure out the best number for your chain of choice.
47+
* @param options
48+
* @returns
49+
* @extension ERC1155
50+
* @example
51+
* ```ts
52+
* import { mintBatchTo } from "thirdweb/extension/erc1155";
53+
*
54+
* const transaction = mintToBatch({
55+
* contract: editionContract,
56+
* to: "0x...",
57+
* nfts: [
58+
* {
59+
* metadata: {
60+
* name: "Token #0",
61+
* image: "...",
62+
* attributes: [],
63+
* },
64+
* supply: 100n,
65+
* },
66+
* {
67+
* metadata: {
68+
* name: "Token #1",
69+
* image: "...",
70+
* attributes: [],
71+
* },
72+
* supply: 111n,
73+
* },
74+
* ],
75+
* });
76+
*
77+
* await sendTransaction({ transaction, account });
78+
* ```
79+
*/
80+
export function mintToBatch(
81+
options: BaseTransactionOptions<MintToBatchParams>,
82+
) {
83+
return multicall({
84+
contract: options.contract,
85+
asyncParams: async () => {
86+
const uris = await Promise.all(
87+
options.nfts.map((item) => {
88+
if (typeof item.metadata === "string") {
89+
return item.metadata;
90+
}
91+
return upload({
92+
client: options.contract.client,
93+
files: [item.metadata],
94+
});
95+
}),
96+
);
97+
98+
const data = uris.map((uri, index) => {
99+
const item = options.nfts[index];
100+
if (!item) {
101+
// Should not happen
102+
throw new Error("Index mismatch");
103+
}
104+
return encodeMintTo({
105+
to: options.to,
106+
// maxUint256 is used to indicate that this is a NEW token!
107+
tokenId: maxUint256,
108+
uri,
109+
amount: item.supply,
110+
});
111+
});
112+
113+
return { data };
114+
},
115+
overrides: options.overrides,
116+
});
117+
}

0 commit comments

Comments
 (0)