-
Notifications
You must be signed in to change notification settings - Fork 568
arb-docs #7799
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
+376
−1
Merged
arb-docs #7799
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
224 changes: 224 additions & 0 deletions
224
apps/portal/src/app/contracts/arbitrum-stylus/airdrop-contract/page.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
import { Step, Steps, createMetadata } from "@doc"; | ||
|
||
export const metadata = createMetadata({ | ||
title: "Stylus Airdrop Contracts | thirdweb Documentation", | ||
description: | ||
"Use Stylus Airdrop contracts on Arbitrum for efficient token distribution at scale. WASM-powered smart contracts enable fast, low-cost airdrops to thousands of wallets.", | ||
image: { | ||
title: "Stylus Airdrop Contract", | ||
icon: "contracts", | ||
}, | ||
}); | ||
|
||
# Stylus Airdrop Contract | ||
|
||
|
||
If you need to send tokens to thousands of wallets at once, you can leverage the Stylus Airdrop contracts. | ||
|
||
Learn how to deploy Stylus Airdrop contracts through dashboard or CLI for inexpensive, WASM-powered distribution on [Arbitrum](https://thirdweb.com/arbitrum) chain. | ||
|
||
### Benefits | ||
|
||
- Ink, not gas: Stylus executes WASM thousands of times faster than the EVM, so sending 10 000 NFTs costs a fraction of normal gas. | ||
- Rust Tooling: Cargo tests, Clippy lints, and the full crates ecosystem for your drop logic. | ||
- Interoperability: Rust contracts call Solidity (and vice-versa) with zero wrappers. | ||
- Battle-tested Logic: Template ports the same claim, snapshot & signature pattern used by thirdweb’s Solidity pre-built contracts. | ||
|
||
## Deploy through dashboard | ||
|
||
Deploying a Stylus Airdrop contract is easy through the thirdweb dashboard and ideal when you don't want to modify any code on the contract. | ||
|
||
<Steps> | ||
<Step title="Select Stylus Contract"> | ||
|
||
Navigate to the Stylus Contracts section on Explore and select any Airdrop contract for your project. | ||
</Step> | ||
|
||
<Step title="Deploy Contract"> | ||
Select Arbitrum Sepolia or any other Stylus-supported network, then select Deploy. | ||
</Step> | ||
|
||
<Step title="Upload Recipients"> | ||
You can either upload a CSV file with the recipient addresses and amounts and select `Run Airdrop` | ||
|
||
Or set a claim condition for recipients to claim their tokens on their own. | ||
</Step> | ||
|
||
</Steps> | ||
|
||
## Deploy through CLI | ||
|
||
If you want to modify the contract code or deploy a custom Airdrop contract, you can use the thirdweb CLI. | ||
|
||
<Steps> | ||
<Step title="Create a new Stylus Airdrop project"> | ||
|
||
In your CLI, run the following command to create a new directory with an airdrop template contract. | ||
|
||
```bash | ||
npx thirdweb create-stylus --template airdrop-erc721 | ||
``` | ||
</Step> | ||
|
||
<Step title="Modify contract logic"> | ||
In the `src/lib.rs` file you can modify the contract logic such as adding fees, gating logic, analytics events, and more. | ||
</Step> | ||
|
||
<Step title="Build & Test the Contract"> | ||
|
||
To build your project, run the following command: | ||
|
||
```bash | ||
cargo stylus build | ||
``` | ||
|
||
</Step> | ||
|
||
<Step title="Deploy or Publish Your Contract"> | ||
You can publish and deploy your project to Arbitrum. Publishing stores your contract metadata in thirdweb’s on-chain registry so anyone (including you) can deploy that exact version later with a few clicks. | ||
|
||
To publish your contract, ensure you have your thirdweb secret key from your created project, then run the following command: | ||
|
||
```bash | ||
npx thirdweb publish-stylus -k YOUR_TW_SECRET_KEY | ||
``` | ||
|
||
If you'd prefer to just deploy a single instance of the contract without publishing, run the following command to deploy: | ||
|
||
```bash | ||
npx thirdweb deploy-stylus -k YOUR_TW_SECRET_KEY | ||
``` | ||
|
||
Once the transaction confirms, the CLI will redirect you to the contract management dashboard where you can mint, transfer, view events, or pull ready-made SDK snippets. | ||
</Step> | ||
|
||
</Steps> | ||
|
||
## Interacting with the Contract | ||
|
||
Using the thirdweb SDKs, you can interact with your Stylus Airdrop contract to mint tokens, transfer ownership, and more. | ||
|
||
The following includes three common patterns using thirdweb TypeScript SDK: | ||
|
||
### Owner-executed batch airdrop | ||
|
||
**When to use:** you already have every recipient’s address and want to send everything in a single transaction. | ||
|
||
```javascript | ||
import { createThirdwebClient, getContract, sendTransaction} from "thirdweb"; | ||
import { arbitrumSepolia } from "thirdweb/chains"; | ||
import { airdropERC721 } from "thirdweb/extensions/airdrop"; | ||
import { createWallet, injectedProvider } from "thirdweb/wallets"; | ||
|
||
const client = createThirdwebClient({ clientId }); | ||
|
||
const wallet = createWallet("io.metamask"); // or any wallet id | ||
const account = await wallet.connect({ client }); | ||
|
||
const contract = getContract({ | ||
client, | ||
chain: arbitrumSepolia, | ||
address: "<DEPLOYED_ADDRESS>", | ||
}); | ||
|
||
const contents = [ | ||
{ recipient: "0xAbc…", tokenId: 1n }, | ||
{ recipient: "0x123…", tokenId: 2n }, | ||
]; | ||
|
||
const tx = airdropERC721({ | ||
contract, | ||
tokenAddress: contract.address, | ||
contents, | ||
}); | ||
|
||
await sendTransaction({ transaction: tx, account }); | ||
``` | ||
|
||
(Swap for airdropERC20 or airdropERC1155 helpers as needed.) | ||
|
||
### Claim-based airdrop (Merkle snapshot) | ||
|
||
**When to use:** you know the recipients but want them to claim the tokens at their convenience (gas paid by the claimer). | ||
|
||
1. Generate snapshot off-chain | ||
|
||
```javascript | ||
import { generateMerkleTreeInfoERC721 } from "thirdweb/extensions/airdrop"; | ||
|
||
const snapshot = [ | ||
{ address: "0xAbc…", tokenId: 7n }, | ||
{ address: "0x123…", tokenId: 8n }, | ||
]; | ||
|
||
const { merkleRoot, contents } = await generateMerkleTreeInfoERC721({ snapshot }); | ||
``` | ||
|
||
merkleRoot is a single 32-byte value representing the whole list. | ||
|
||
2. Store root on-chain (_setMerkleRoot(root) in the template). | ||
|
||
```javascript | ||
const tx = setMerkleRoot({ | ||
contract, | ||
root: merkleRoot, | ||
}); | ||
await sendTransaction({ transaction: tx, account }); // executed by admin | ||
``` | ||
|
||
3. Recipient claims: | ||
|
||
```javascript | ||
import { claimERC721, fetchProofsERC721 } from "thirdweb/extensions/airdrop"; | ||
|
||
const proof = await fetchProofsERC721({ | ||
contract, | ||
merkleRoot, | ||
recipient: "0xAbc…", | ||
}); | ||
|
||
const tx = claimERC721({ | ||
contract, | ||
tokenAddress: contract.address, | ||
proof, | ||
}); | ||
|
||
await sendTransaction({ transaction: tx, account }); | ||
``` | ||
|
||
### Signature Based Airdrop (Dynamic Authentication) | ||
|
||
**When to use:** you don’t know the full list ahead of time (e.g., quest rewards). An authorised backend signs a payload per user; the user submits it on-chain. | ||
|
||
1. Generate signed payload server-side: | ||
|
||
```javascript | ||
import { generateAirdropSignatureERC721 } from "thirdweb/extensions/airdrop"; | ||
|
||
const { signature, payload } = await generateAirdropSignatureERC721({ | ||
contract, | ||
signer: account, // ADMIN role or owner | ||
to: "0xRecipient", | ||
tokenId: 42n, | ||
}); | ||
``` | ||
|
||
2. Recipient executes: | ||
|
||
```javascript | ||
import { airdropERC721WithSignature } from "thirdweb/extensions/airdrop"; | ||
|
||
const tx = airdropERC721WithSignature({ | ||
contract, | ||
signature, | ||
payload, | ||
}); | ||
|
||
await sendTransaction({ transaction: tx, account: recipientAccount }); | ||
``` | ||
|
||
### Resources | ||
|
||
- [ERC-721 Airdrop Template](https://github.com/thirdweb-example/stylus-airdrop-erc721-template) | ||
- [TypeScript SDK Documentation > Airdrops](https://portal.thirdweb.com/references/typescript/v5/airdrop/airdropERC721) | ||
|
135 changes: 135 additions & 0 deletions
135
apps/portal/src/app/contracts/arbitrum-stylus/stylus-contract/page.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import { Steps, Step, createMetadata } from "@doc"; | ||
|
||
export const metadata = createMetadata({ | ||
title: "Stylus Contracts | thirdweb Documentation", | ||
description: | ||
"Deploy Stylus contracts on Arbitrum for efficient token distribution at scale. WASM-powered smart contracts enable fast, low-cost airdrops to thousands of wallets.", | ||
image: { | ||
title: "Deploy Stylus Contracts", | ||
icon: "contracts", | ||
}, | ||
}); | ||
|
||
# Deploy Stylus Contracts on Arbitrum | ||
|
||
Arbitrum Stylus brings a second, WebAssembly (WASM) virtual machine to every Arbitrum chain, so you can write contracts in Rust (or C/C++) while staying 100 % interoperable with existing Solidity code. | ||
|
||
Under the hood, Stylus executes WASM thousands of times faster than the EVM, so transactions are metered in a new, much-smaller unit called ink rather than gas — translating to dramatic fee savings for compute- or memory-heavy logic. Learn more about Stylus on the [Arbitrum documentation](https://docs.arbitrum.io/stylus/concepts/how-it-works). | ||
|
||
This tutorial will cover how to create a simple NFT template project with thirdweb CLI and deploy it to the Arbitrum network using Stylus. You can also follow this tutorial to deploy an ERC-20, ERC-1155, or Airdrop contract. | ||
|
||
## Benefits | ||
|
||
- Rust Tooling: Cargo, Clippy, unit tests, Rust crates, and the broader Rust ecosystem are at your disposal. | ||
- Ink-priced execution: Complex math, on-chain SVG generation, even lightweight ML models are suddenly affordable. | ||
- Opt-in re-entrancy protection: The Rust SDK disables re-entrancy by default; you only enable it when you really need it. | ||
- Multi-VM composability: Rust contract can call Solidity contracts (and vice-versa) without wrappers. | ||
|
||
## Prerequisites | ||
|
||
- [Create a project on your thirdweb account](https://thirdweb.com/dashboard) | ||
- Install thirdweb CLI by running `npm install -g thirdweb` | ||
- Install Rust tool chain by running `curl https://sh.rustup.rs -sSf | sh` or visit rust-lang.org | ||
- Install solc by running `npm install -g solc` or visit soliditylang.org | ||
- Install Node version 18 or higher | ||
|
||
## Scaffold an ERC-721 Stylus project | ||
|
||
<Steps> | ||
<Step title="Initialize a new Stylus project"> | ||
In your CLI, create a new directory and run the following command to create a new stylus project: | ||
|
||
```bash | ||
npx thirdweb create-stylus | ||
``` | ||
|
||
Select the ERC-721 template when prompted. This will scaffold a new Stylus project with a basic ERC-721 contract. | ||
</Step> | ||
|
||
<Step title="Set Collection Name & Symbol"> | ||
|
||
Open src/lib.rs and set the collection name and symbol. You may also tweak any other minting logic as well such as supply cap, roles, and fees. | ||
|
||
</Step> | ||
<Step title="Build & test the project"> | ||
|
||
Stylus compiles your Rust to WASM and generates an ABI JSON that thirdweb uses for the dashboard & SDK. | ||
|
||
Run the following command to build your project: | ||
|
||
```bash | ||
cargo stylus build | ||
``` | ||
|
||
You can also run the following command to test your project: | ||
|
||
```bash | ||
cargo test | ||
``` | ||
|
||
</Step> | ||
|
||
<Step title="Deploy or Publish Your Contract"> | ||
|
||
You can publish and deploy your project to Arbitrum. Publishing stores your contract metadata in thirdweb’s on-chain registry so anyone (including you) can deploy that exact version later with a few clicks. | ||
|
||
To publish your contract, ensure you have your thirdweb secret key from your created project, then run the following command: | ||
|
||
```bash | ||
npx thirdweb publish-stylus -k YOUR_TW_SECRET_KEY | ||
``` | ||
|
||
If you'd prefer to just deploy a single instance of the contract without publishing, run the following command to deploy: | ||
|
||
```bash | ||
npx thirdweb deploy-stylus -k YOUR_TW_SECRET_KEY | ||
``` | ||
|
||
Once the transaction confirms, the CLI will redirect you to the contract management dashboard where you can mint, transfer, view events, or pull ready-made SDK snippets. | ||
|
||
</Step> | ||
|
||
<Step title="(Optional) Mint NFTs Programmatically"> | ||
|
||
You can mint NFTs programmatically using the thirdweb SDKs. Use the following code snippet to mint NFTs: | ||
|
||
```javascript | ||
import { createThirdwebClient, getContract, sendTransaction } from "thirdweb"; | ||
import { arbitrumSepolia } from "thirdweb/chains"; | ||
import { mintTo } from "thirdweb/extensions/erc721"; | ||
import { createWallet, injectedProvider } from "thirdweb/wallets"; | ||
|
||
const client = createThirdwebClient({ clientId }); | ||
|
||
const wallet = createWallet("io.metamask"); // or any wallet id | ||
const account = await wallet.connect({ client }); | ||
|
||
// 3 · Wrap the deployed contract | ||
const contract = getContract({ | ||
client, | ||
chain: arbitrumSepolia, | ||
address: "<DEPLOYED_ADDRESS>", | ||
}); | ||
|
||
// 4 · Prepare the mint transaction | ||
const transaction = mintTo({ | ||
contract, | ||
to: "0xRecipient", | ||
nft: { | ||
name: "Stylus NFT #1", | ||
// image, description, attributes, … are optional | ||
}, | ||
}); | ||
|
||
// 5 · Send the transaction | ||
const result = await sendTransaction({ transaction, account }); | ||
console.log("Minted token:", result); | ||
``` | ||
|
||
</Step> | ||
|
||
</Steps> | ||
|
||
## Next Steps | ||
|
||
- Learn more about Arbitrum Stylus through the official docs on architecture, gas/ink, and safety features. [View Arbitrum Documentation.](https://docs.arbitrum.io/stylus/concepts/how-it-works) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Contract security | ||
|
||
All thirdweb pre-built contracts are audited by third-party security firms. You can see the attached audit reports for each contract linked on the contract page on Explore. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.