In this example, we use packs to create loot boxes that can contain any amount of:
- ERC-721 NFTs
- ERC-1155 NFTs
- ERC-20 tokens
We can open these loot boxes to reveal the tokens inside!
- Pack contract: To create openable loot boxes that contain NFTs from our Edition and Token contracts.
- Edition contract: To create NFTs with multiple copies and bundle them into the packs.
- Token contract: To create our own token that we can bundle into the packs.
- React SDK: to enable users to connect their wallets with the useMetamask hook, and access hooks such as usePack to interact with the Pack contract.
- thirdweb TypeScript SDK: To write scripts that create and deploy our pack contract, and bundle the tokens into the packs.
To create your own version of this template, you can use the following steps:
Use our CLI to create a copy of this repo on your local machine:
npx create-tw-app --example packs
This example project uses a Token, Edition, and Pack contract.
You can deploy all of these contracts via the thirdweb dashboard
This project also includes a deployPack script that you can use to deploy the pack contract and a bundleTokens script that you can use to bundle the tokens (from your NFT/Token contracts) into the packs.
Replace the example contract addresses with your contract addresses in the pages, scripts, and components of this project.
You can use find and replace to change these contract addresses. Our example contract addresses are:
- Pack:
0x0Aee160411473f63be2DfF2865E81A1D59636C97
- Token:
0x270d0f9DA22332F33159337E3DE244113a1C863C
- Edition:
0xb4A48c837aB7D0e5C85eA2b0D9Aa11537340Fa17
Below, you'll find the core features of this example explained!
You can use the thirdweb dashboard to deploy a pack contract.
In this example project, we have written a script to deploy the pack contract via the SDK in deployPack.ts.
const packAddress = await sdk.deployer.deployPack({
name: "Treasure Chests",
primary_sale_recipient: "0xb371d1C5629C70ACd726B20a045D197c256E1054",
});
Inside the bundleTokens script, we can bundle NFTs and Tokens into the packs.
We bundle 500 units worth of tokens to create 100 packs with 5 rewards each.
const packNfts = await pack.create({
// ... our tokens and NFTs here
// ...
rewardsPerPack: 5,
});
We wrap our application in the ThirdwebProvider
in the _app.tsx so that we can use all of the React SDK's hooks:
<ThirdwebProvider desiredChainId={activeChainId}>
<Component {...pageProps} />
</ThirdwebProvider>
Now in the index.tsx file, we can use the useMetamask hook to connect to the user's wallet:
const address = useAddress();
const connectWithMetamask = useMetamask();
const disconnectWallet = useDisconnect();
We use the usePack hook to connect to the pack contract using it's contract address:
const pack = usePack("0x0Aee160411473f63be2DfF2865E81A1D59636C97");
Since each pack is an ERC-1155 NFT itself, we can use the useOwnedNFTs hook to view the packs (and quantity) that the user owns:
const { data: nfts, isLoading } = useOwnedNFTs(pack, address);
We use the nfts
array to display the packs that the user owns on the UI.
To open a pack, we simply pass the tokenId of the pack and the quantity to open to the open
function:
const openedRewards = await pack?.open(0, 1); // 0 = tokenId, 1 = quantity
We then use the values returned in this openedRewards
object to display the tokens that the user opened.
Since the openedRewards
object returns the contractAddress
and tokenId
, we use the useNFT or the
useMetadata hook (for ERC-20 tokens) to get the metadata of the tokens that were opened:
// For ERC-1155 / ERC-721 tokens:
const edition = useEdition(reward.contractAddress);
const { data } = useNFT(edition, reward.tokenId);
// For ERC-20 tokens:
const token = useToken(reward.contractAddress);
const { data } = useMetadata(token);
Then we again map
over the rewards arrays contained in the openedRewards
object and display the rewards that the user opened on the UI.
For any questions, suggestions, join our discord at https://discord.gg/thirdweb.