Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20fb0d2300 | ||
|
|
637c510f59 | ||
|
|
2ae9a13b01 | ||
|
|
8d91e55eac | ||
|
|
aa0b8c4465 | ||
|
|
41be954bd0 | ||
|
|
e8e3368fde | ||
|
|
e1cd07c3e0 | ||
|
|
8683449abb | ||
|
|
cfff7e838a | ||
|
|
948f155e7c | ||
|
|
d7e6671c0a | ||
|
|
560d8adafa | ||
|
|
3be61ddc52 | ||
|
|
a0e26a8c4f |
+50
-40
@@ -1,9 +1,5 @@
|
||||
# Contributing to thirdweb
|
||||
|
||||
You can find a full video tutorial on how to contribute to thirdweb below:
|
||||
|
||||
https://www.youtube.com/watch?v=TXsQ3qok3B0
|
||||
|
||||
## Getting Started
|
||||
|
||||
To get started, read the [How this repo works](#how-this-repo-works) section below to learn about the structure of this repo.
|
||||
@@ -12,23 +8,19 @@ From there, you can take a look at our [Good First Issues](https://github.com/th
|
||||
|
||||
If you have any questions about the issue, feel free to ask on our [Discord server](https://discord.gg/thirdweb) in the `#contributors` channel; where you'll be able to get help from our team and other contributors.
|
||||
|
||||
<br/>
|
||||
<br />
|
||||
|
||||
## How this repo works
|
||||
|
||||
[@thirdweb-dev/js](https://github.com/thirdweb-dev/js) is a monorepo, meaning it contains many projects within it.
|
||||
We use [Turborepo](https://turbo.build/repo/docs) to manage the repository, and help speed up the [CI/CD](https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment) pipeline to ship to production faster 🚢. Turborepo is a project dependency, and doesn't need to be installed separately.
|
||||
|
||||
We use [Turborepo](https://turborepo.org/docs/getting-started) to manage the monorepo, and help speed up the [CI/CD](https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment) pipeline to ship to production faster 🚢.
|
||||
We use [pnpm](https://pnpm.io) for package management across the repo. `pnpm` is similar to `npm` or `yarn` but with more efficient disk space usage.
|
||||
|
||||
You can see a quick outline of each of the projects within this repo below, each living within the [/packages](/packages) directory:
|
||||
**With the v5 SDK, we've consolidated everything into a single project at [/packages/thirdweb](./packages/thirdweb). You can still find the legacy packages at [/legacy_packages](./legacy_packages).**
|
||||
|
||||
| Package | Description | Latest Version |
|
||||
| ------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [/sdk](./legacy_packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/react](./legacy_packages/react) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/auth](./legacy_packages/auth) | Best in class wallet authentication for Node backends | <a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/storage](./legacy_packages/storage) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/cli](./legacy_packages/cli) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
This single package provides a performant & lightweight SDK to interact with any EVM chain across Node, React, and React Native. Learn more about how to use the thirdweb SDK in our [documentation](https://portal.thirdweb.com/typescript/v5).
|
||||
|
||||
<br />
|
||||
|
||||
## How to contribute
|
||||
|
||||
@@ -36,7 +28,7 @@ Let's explore how you can set up the repo on your local machine and start contri
|
||||
|
||||
This section requires some existing knowledge of [Git](https://git-scm.com/), [Node.js](https://nodejs.org/en/) and [pnpm](https://pnpm.io/).
|
||||
|
||||
<br/>
|
||||
<br />
|
||||
|
||||
### Getting the repo
|
||||
|
||||
@@ -50,26 +42,50 @@ To begin:
|
||||
|
||||
3. Create a new branch on your fork to start working on your changes:
|
||||
|
||||
```
|
||||
git checkout -b MY_BRANCH_NAME
|
||||
```bash
|
||||
git checkout -b <YOUR BRANCH NAME>
|
||||
```
|
||||
|
||||
4. Install the dependencies:
|
||||
```
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
If you are on windows, use the `--ignore-scripts` flag
|
||||
```
|
||||
```bash
|
||||
pnpm install --ignore-scripts
|
||||
```
|
||||
|
||||
Now you have got the repo on your local machine, and you're ready to start making your changes!
|
||||
Now you have the repo on your local machine, and you're ready to start making your changes!
|
||||
|
||||
<br/>
|
||||
|
||||
### Test Your Changes
|
||||
|
||||
We use [yalc](https://github.com/wclr/yalc) to test changes locally.
|
||||
#### Writing Unit Tests
|
||||
|
||||
Try to include unit test coverage with your changes where appropriate. We use `vitest` for testing, look for files with the `.test.ts` extension for examples of how to structure your unit tests.
|
||||
|
||||
To run your tests, run the following from the package directory (most likely /packages/thirdweb):
|
||||
|
||||
```bash
|
||||
pnpm test:dev <YOUR TEST FILE PATH>
|
||||
```
|
||||
|
||||
> Specifying your test file path is optional, but will save time by only running specific tests each time. Before opening your PR, run `pnpm test` from the monorepo root (without specifying your test file) to ensure your changes didn't break any existing tests.
|
||||
|
||||
#### Linting
|
||||
|
||||
We use a linter to maintain best practices across projects. Once your changes are complete (or periodically while making changes), run the linter with the following command from the repo root:
|
||||
|
||||
```bash
|
||||
pnpm lint
|
||||
```
|
||||
|
||||
If there are errors, try running `pnpm fix` to auto-fix any basic errors. Other linter errors, like missing documentation, will need to be fixed manually. See existing files for examples of inline documentation.
|
||||
|
||||
#### Creating a Local Test Project
|
||||
|
||||
You can use [yalc](https://github.com/wclr/yalc) to test changes on a local project.
|
||||
|
||||
Install the yalc CLI globally:
|
||||
|
||||
@@ -77,40 +93,35 @@ Install the yalc CLI globally:
|
||||
pnpm add yalc -g
|
||||
```
|
||||
|
||||
First, create a test project where you can experiment with your changes:
|
||||
First, create a test project where you can experiment with your changes. This can be any node project that uses your changes.
|
||||
|
||||
You can create a basic starter project with the `sdk` and `react` packages installed using the CLI:
|
||||
|
||||
Push your local version to your `yalc` store with:
|
||||
|
||||
```bash
|
||||
npx thirdweb create --app
|
||||
pnpm build && pnpm push
|
||||
```
|
||||
|
||||
Use `yalc` to link your local changes in the monorepo to the test project, by running the following command from your test repo:
|
||||
Link your local changes in the monorepo to the test project by running the following command from your test repo:
|
||||
|
||||
```bash
|
||||
yalc add @thirdweb-dev/react # Link the react package
|
||||
yalc add @thirdweb-dev/sdk # Link the sdk package
|
||||
# etc...
|
||||
yalc add thirdweb
|
||||
```
|
||||
|
||||
From the monorepo, run the following command to publish your local changes to the test project:
|
||||
Now, each time you make a change to the monorepo, you can run `pnpm push` from the monorepo then `yalc update thirdweb` from your test project to publish your latest changes to the test project.
|
||||
|
||||
```bash
|
||||
pnpm push
|
||||
```
|
||||
If your changes modify dependencies, you may need to reinstall dependencies on your test project with `pnpm install`
|
||||
|
||||
Now, each time you make a change to the monorepo, you can run `pnpm push` to publish your changes to the test project.
|
||||
To make sure your latest changes are used, in your test project you may need to:
|
||||
|
||||
In your test project, you need to:
|
||||
|
||||
1. Delete the dependencies cache. If you're using Next.js, that is the `.next` directory, and if you're using CRA, that is the `node_modules/.cache` directory.
|
||||
1. Delete the dependencies cache. If you're using Next.js, that's the `.next` directory, and if you're using CRA, that's the `node_modules/.cache` directory.
|
||||
2. Restart the development server.
|
||||
|
||||
#### Testing from npm
|
||||
|
||||
You can also test your changes by publishing a dev package to npm and adding your package as you normally do in your projects.
|
||||
|
||||
Once you have your PR up you can add a comment with the text: `/release-pr`. This will trigger a GitHub action that will publish a dev version to npm.
|
||||
**Once you have your PR up** you can add a comment with the text: `/release-pr`. This will trigger a GitHub action that will publish a dev version to npm.
|
||||
|
||||
You can see the action progress in GitHub's `Actions` tab, look for the workflow: `release-pr`.
|
||||
|
||||
@@ -154,9 +165,8 @@ git commit -am "My commit message"
|
||||
3. Push your changes to the SDK:
|
||||
|
||||
```
|
||||
git push origin MY_BRANCH_NAME
|
||||
git push origin <YOUR BRANCH NAME>
|
||||
```
|
||||
|
||||
4. Create a [pull request](https://www.atlassian.com/git/tutorials/making-a-pull-request) to the `main` branch of the official (not your fork) SDK repo.
|
||||
|
||||
It's helpful to tag PRs with `[SDK]`, `[REACT]`, `[AUTH]`, (the name of the package you're modifying) to indicate the package that you are engaging with.
|
||||
|
||||
Vendored
+3
@@ -8,5 +8,8 @@
|
||||
"typescript.preferences.importModuleSpecifier": "relative",
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "biomejs.biome"
|
||||
},
|
||||
"[markdown]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 4.1.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@2.5.10
|
||||
|
||||
## 4.1.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@2.5.9
|
||||
|
||||
## 4.1.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "4.1.66",
|
||||
"version": "4.1.68",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.100
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2838](https://github.com/thirdweb-dev/js/pull/2838) [`637c510`](https://github.com/thirdweb-dev/js/commit/637c510f59c2504bd29cedbdf4bda694719681dc) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
|
||||
|
||||
## 0.1.99
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -24,7 +24,7 @@ export default {
|
||||
"nativeCurrency": {
|
||||
"name": "SMR",
|
||||
"symbol": "SMR",
|
||||
"decimals": 6
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 1073,
|
||||
"rpc": [
|
||||
|
||||
@@ -2,7 +2,13 @@ import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "IOTA EVM",
|
||||
"chainId": 1075,
|
||||
"explorers": [],
|
||||
"explorers": [
|
||||
{
|
||||
"name": "explorer",
|
||||
"url": "https://explorer.evm.testnet.iotaledger.net",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"faucets": [
|
||||
"https://evm-toolkit.evm.testnet.iotaledger.net"
|
||||
],
|
||||
|
||||
@@ -4,6 +4,12 @@ export default {
|
||||
"chainId": 1221,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmeC4mKGbBpwmLfFxUSsareWkSWJomevUmex8ajjxo1zHx",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://www.cyclenetwork.io/",
|
||||
"name": "Cycle Network Testnet",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -6,22 +6,10 @@ export default {
|
||||
{
|
||||
"name": "BOASCAN",
|
||||
"url": "https://boascan.io",
|
||||
"standard": "EIP3091",
|
||||
"icon": {
|
||||
"url": "ipfs://QmW3CT4SHmso5dRJdsjR8GL1qmt79HkdAebCn2uNaWXFYh",
|
||||
"width": 256,
|
||||
"height": 257,
|
||||
"format": "png"
|
||||
}
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmW3CT4SHmso5dRJdsjR8GL1qmt79HkdAebCn2uNaWXFYh",
|
||||
"width": 256,
|
||||
"height": 257,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://docs.bosagora.org",
|
||||
"name": "BOSagora Mainnet",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -31,7 +31,7 @@ export default {
|
||||
"networkId": 224433,
|
||||
"rpc": [
|
||||
"https://224433.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://holeskyrpc1.conet.network"
|
||||
"https://rpc.conet.network"
|
||||
],
|
||||
"shortName": "conet-holesky",
|
||||
"slip44": 2147708081,
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "ETH",
|
||||
"chainId": 27483,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Nanon Sepolia Rollup Testnet Explorer",
|
||||
"url": "https://sepolia-explorer.nanon.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://bafybeiduib2fygrwziqpy4yuqr6vvnd6elhahpigbcowcipjjhk6c3qiny",
|
||||
"width": 400,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://www.nanon.network",
|
||||
"name": "Nanon Sepolia",
|
||||
"nativeCurrency": {
|
||||
"name": "Sepolia Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 27483,
|
||||
"parent": {
|
||||
"type": "L2",
|
||||
"chain": "eip155-11155111",
|
||||
"bridges": [
|
||||
{
|
||||
"url": "https://sepolia-bridge.nanon.network"
|
||||
}
|
||||
]
|
||||
},
|
||||
"rpc": [
|
||||
"https://27483.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://sepolia-rpc.nanon.network"
|
||||
],
|
||||
"shortName": "Nanon-Testnet",
|
||||
"slip44": 1,
|
||||
"slug": "nanon-sepolia",
|
||||
"testnet": true,
|
||||
"title": "Nanon Sepolia Rollup Testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 30406,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "MUGEN Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "MUGEN Testnet Token",
|
||||
"symbol": "MGN",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 30406,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://30406.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/mugen/testnet/rpc"
|
||||
],
|
||||
"shortName": "MUGEN Testnet",
|
||||
"slug": "mugen-testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 38904,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QaUser1490 Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "QaUser1490 Testnet Token",
|
||||
"symbol": "PNK",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 38904,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://38904.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QaUser1490 Testnet",
|
||||
"slug": "qauser1490-testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -6,22 +6,10 @@ export default {
|
||||
{
|
||||
"name": "MEVerse Chain Testnet Explorer",
|
||||
"url": "https://testnet.meversescan.io",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmPuQ6gaCfUtNdRuaEDbdhot2m2KCy2ZHCJUvZXJAtdeyJ",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
}
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmPuQ6gaCfUtNdRuaEDbdhot2m2KCy2ZHCJUvZXJAtdeyJ",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://www.meverse.sg",
|
||||
"name": "MEVerse Chain Testnet",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 65174,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QaUser9821 Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "QaUser9821 Testnet Token",
|
||||
"symbol": "HKL",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 65174,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://65174.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QaUser9821 Testnet",
|
||||
"slug": "qauser9821-testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -10,12 +10,6 @@ export default {
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmYbskrGpidbMwsJekTeLrr8Z6GA9q4Uxh7piS1F9BdWWv",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://compverse.io",
|
||||
"name": "Compverse Mainnet",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -6,22 +6,10 @@ export default {
|
||||
{
|
||||
"name": "MEVerse Chain Explorer",
|
||||
"url": "https://www.meversescan.io",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmPuQ6gaCfUtNdRuaEDbdhot2m2KCy2ZHCJUvZXJAtdeyJ",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
}
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmPuQ6gaCfUtNdRuaEDbdhot2m2KCy2ZHCJUvZXJAtdeyJ",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://www.meverse.sg",
|
||||
"name": "MEVerse Chain Mainnet",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -16,12 +16,6 @@ export default {
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmVhezQHkqSZ5Tvtsw18giA1yBjV1URSsBQ7HenUh6p6oC",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://octa.space",
|
||||
"name": "OctaSpace",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -5,7 +5,7 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "explorer",
|
||||
"url": "https://iota-evm.blockscout.com",
|
||||
"url": "https://explorer.evm.iota.org",
|
||||
"standard": "EIP3091",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreibky2sy6qhi6arktayvologkrgu5kudpgdxfkx4uosbvmstz7v4di",
|
||||
@@ -32,7 +32,8 @@ export default {
|
||||
"networkId": 8822,
|
||||
"rpc": [
|
||||
"https://8822.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://json-rpc.evm.iotaledger.net"
|
||||
"https://json-rpc.evm.iotaledger.net",
|
||||
"https://ws.json-rpc.evm.iotaledger.net"
|
||||
],
|
||||
"shortName": "iotaevm",
|
||||
"slug": "iota-evm",
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 88795,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QaUser8230 Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "QaUser8230 Testnet Token",
|
||||
"symbol": "GRB",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 88795,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://88795.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QaUser8230 Testnet",
|
||||
"slug": "qauser8230-testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -6,22 +6,10 @@ export default {
|
||||
{
|
||||
"name": "Pepe Explorer",
|
||||
"url": "https://explorer.pepenetwork.io",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmPX3uipdwd195z1MJff7uj8hpZdSuVvM5z47eiz2o7Gz5",
|
||||
"width": 960,
|
||||
"height": 944,
|
||||
"format": "png"
|
||||
}
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmPX3uipdwd195z1MJff7uj8hpZdSuVvM5z47eiz2o7Gz5",
|
||||
"width": 960,
|
||||
"height": 944,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://pepenetwork.io",
|
||||
"name": "PepeNetwork Mainnet",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "treasure",
|
||||
"chainId": 978657,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Treasurescan",
|
||||
"url": "https://testnet.treasurescan.io/",
|
||||
"standard": "EIP3091",
|
||||
"icon": {
|
||||
"url": "ipfs://QmbzZk23owb7grDEbEJLuxgUAqQVcHmdjsEkkCD7E9C5R9/Treasure_Primary_Icon%20-%20Karel%20Vuong.png",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"faucets": [
|
||||
"https://portal.treasure.lol/faucet"
|
||||
],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmQYRpJAMyPt1DKz1iAuseX3puBZYmdGgFeaZCFDPhixXp",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://portal.treasure.lol",
|
||||
"name": "Treasure Ruby",
|
||||
"nativeCurrency": {
|
||||
"name": "Testnet MAGIC",
|
||||
"symbol": "MAGIC",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 978657,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://978657.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-testnet.treasure.lol/http",
|
||||
"wss://rpc-testnet.treasure.lol/ws"
|
||||
],
|
||||
"shortName": "MAGIC",
|
||||
"slug": "treasure-ruby",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -10,12 +10,6 @@ export default {
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmZTWoZ3LvivSinaJ4aSwqU8pCXw8oSZNnUCh4wwXxtAoQ",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://larissa.network",
|
||||
"name": "Larissa Chain",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.99",
|
||||
"version": "0.1.100",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"exports": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,24 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.13.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469), [`637c510`](https://github.com/thirdweb-dev/js/commit/637c510f59c2504bd29cedbdf4bda694719681dc)]:
|
||||
- @thirdweb-dev/sdk@4.0.70
|
||||
- @thirdweb-dev/chains@0.1.100
|
||||
- @thirdweb-dev/wallets@2.5.10
|
||||
- @thirdweb-dev/auth@4.1.68
|
||||
|
||||
## 0.13.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@4.0.69
|
||||
- @thirdweb-dev/wallets@2.5.9
|
||||
- @thirdweb-dev/auth@4.1.67
|
||||
|
||||
## 0.13.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/cli",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.13.74",
|
||||
"version": "0.13.76",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 4.6.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469), [`637c510`](https://github.com/thirdweb-dev/js/commit/637c510f59c2504bd29cedbdf4bda694719681dc)]:
|
||||
- @thirdweb-dev/sdk@4.0.70
|
||||
- @thirdweb-dev/chains@0.1.100
|
||||
- @thirdweb-dev/wallets@2.5.10
|
||||
- @thirdweb-dev/auth@4.1.68
|
||||
|
||||
## 4.6.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@4.0.69
|
||||
- @thirdweb-dev/wallets@2.5.9
|
||||
- @thirdweb-dev/auth@4.1.67
|
||||
|
||||
## 4.6.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "4.6.7",
|
||||
"version": "4.6.9",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,9 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.7.41
|
||||
|
||||
## 0.7.40
|
||||
|
||||
## 0.7.39
|
||||
|
||||
## 0.7.38
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.7.39",
|
||||
"version": "0.7.41",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native-compat",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.7.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469), [`637c510`](https://github.com/thirdweb-dev/js/commit/637c510f59c2504bd29cedbdf4bda694719681dc)]:
|
||||
- @thirdweb-dev/sdk@4.0.70
|
||||
- @thirdweb-dev/chains@0.1.100
|
||||
- @thirdweb-dev/react-core@4.6.9
|
||||
- @thirdweb-dev/wallets@2.5.10
|
||||
|
||||
## 0.7.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@4.0.69
|
||||
- @thirdweb-dev/react-core@4.6.8
|
||||
- @thirdweb-dev/wallets@2.5.9
|
||||
|
||||
## 0.7.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.7.39",
|
||||
"version": "0.7.41",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,26 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 4.6.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469), [`637c510`](https://github.com/thirdweb-dev/js/commit/637c510f59c2504bd29cedbdf4bda694719681dc)]:
|
||||
- @thirdweb-dev/sdk@4.0.70
|
||||
- @thirdweb-dev/chains@0.1.100
|
||||
- @thirdweb-dev/react-core@4.6.9
|
||||
- @thirdweb-dev/wallets@2.5.10
|
||||
|
||||
## 4.6.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2679](https://github.com/thirdweb-dev/js/pull/2679) [`560d8ad`](https://github.com/thirdweb-dev/js/commit/560d8adafa011dc48e48e73d7eb6a36170d38cef) Thanks [@ElasticBottle](https://github.com/ElasticBottle)! - Fix In-App wallet country selector styles on windows
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@4.0.69
|
||||
- @thirdweb-dev/react-core@4.6.8
|
||||
- @thirdweb-dev/wallets@2.5.9
|
||||
|
||||
## 4.6.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "4.6.7",
|
||||
"version": "4.6.9",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -12,3 +12,4 @@ export const StyledH2 = /* @__PURE__ */ styled.h2;
|
||||
export const StyledP = /* @__PURE__ */ styled.p;
|
||||
export const StyledUl = /* @__PURE__ */ styled.ul;
|
||||
export const StyledSelect = /* @__PURE__ */ styled.select;
|
||||
export const StyledOption = /* @__PURE__ */ styled.option;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useQuery } from "@tanstack/react-query";
|
||||
import React, { useRef } from "react";
|
||||
import { fontSize, spacing } from "../../../design-system";
|
||||
import { useCustomTheme } from "../../../design-system/CustomThemeProvider";
|
||||
import { StyledSelect } from "../../../design-system/elements";
|
||||
import { StyledOption, StyledSelect } from "../../../design-system/elements";
|
||||
|
||||
export function CountrySelector({
|
||||
countryCode,
|
||||
@@ -52,12 +52,12 @@ export function CountrySelector({
|
||||
</option>
|
||||
{supportedCountriesForSms.map((country) => {
|
||||
return (
|
||||
<option
|
||||
<Option
|
||||
key={country.countryIsoCode}
|
||||
value={`${country.countryIsoCode} +${country.phoneNumberCode}`}
|
||||
>
|
||||
{country.countryName} +{country.phoneNumberCode}{" "}
|
||||
</option>
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
@@ -65,7 +65,20 @@ export function CountrySelector({
|
||||
);
|
||||
}
|
||||
|
||||
export const Select = /* @__PURE__ */ StyledSelect(() => {
|
||||
|
||||
const Option = /* @__PURE__ */ StyledOption(() => {
|
||||
const theme = useCustomTheme();
|
||||
return {
|
||||
color: theme.colors.primaryText,
|
||||
background: theme.colors.modalBg,
|
||||
transition: "background 0.3s ease",
|
||||
"&:hover": {
|
||||
background: theme.colors.walletSelectorButtonHoverBg,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const Select = /* @__PURE__ */ StyledSelect(() => {
|
||||
const theme = useCustomTheme();
|
||||
return {
|
||||
fontSize: fontSize.sm,
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,22 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 4.0.70
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2848](https://github.com/thirdweb-dev/js/pull/2848) [`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469) Thanks [@jnsdls](https://github.com/jnsdls)! - add `celo` chains to known `op stack` chains
|
||||
|
||||
- Updated dependencies [[`2ae9a13`](https://github.com/thirdweb-dev/js/commit/2ae9a13b01e7a436536b3d412690150f9f960c72), [`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469), [`637c510`](https://github.com/thirdweb-dev/js/commit/637c510f59c2504bd29cedbdf4bda694719681dc), [`e8e3368`](https://github.com/thirdweb-dev/js/commit/e8e3368fdef1aa9aaefe6243486395b666b47137), [`aa0b8c4`](https://github.com/thirdweb-dev/js/commit/aa0b8c44650b9d0f45f6dff66ebbceb64cfd7be3)]:
|
||||
- thirdweb@5.12.0
|
||||
- @thirdweb-dev/chains@0.1.100
|
||||
|
||||
## 4.0.69
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`560d8ad`](https://github.com/thirdweb-dev/js/commit/560d8adafa011dc48e48e73d7eb6a36170d38cef), [`d7e6671`](https://github.com/thirdweb-dev/js/commit/d7e6671c0a34cc8a3523f397a45d754617c9fbb0), [`948f155`](https://github.com/thirdweb-dev/js/commit/948f155e7c2406cc5a172a6c5abe18ba8da89e2a), [`3be61dd`](https://github.com/thirdweb-dev/js/commit/3be61ddc52cef168cda0bee13e93a926dedf479a), [`cfff7e8`](https://github.com/thirdweb-dev/js/commit/cfff7e838af1c464c9b5fbb547153eaae41e2c66)]:
|
||||
- thirdweb@5.11.0
|
||||
|
||||
## 4.0.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "4.0.68",
|
||||
"version": "4.0.70",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -11,6 +11,8 @@ import {
|
||||
BaseSepoliaTestnet,
|
||||
Zora,
|
||||
ZoraSepoliaTestnet,
|
||||
Celo,
|
||||
CeloAlfajoresTestnet,
|
||||
} from "@thirdweb-dev/chains";
|
||||
|
||||
type FeeData = {
|
||||
@@ -134,7 +136,9 @@ function isOpStackChain(chainId: number) {
|
||||
chainId === Base.chainId ||
|
||||
chainId === BaseSepoliaTestnet.chainId ||
|
||||
chainId === Zora.chainId ||
|
||||
chainId === ZoraSepoliaTestnet.chainId
|
||||
chainId === ZoraSepoliaTestnet.chainId ||
|
||||
chainId === Celo.chainId ||
|
||||
chainId === CeloAlfajoresTestnet.chainId
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,24 @@
|
||||
# @thirdweb-dev/unity-js-bridge
|
||||
|
||||
## 0.6.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469), [`637c510`](https://github.com/thirdweb-dev/js/commit/637c510f59c2504bd29cedbdf4bda694719681dc)]:
|
||||
- @thirdweb-dev/sdk@4.0.70
|
||||
- @thirdweb-dev/chains@0.1.100
|
||||
- @thirdweb-dev/wallets@2.5.10
|
||||
- @thirdweb-dev/auth@4.1.68
|
||||
|
||||
## 0.6.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@4.0.69
|
||||
- @thirdweb-dev/wallets@2.5.9
|
||||
- @thirdweb-dev/auth@4.1.67
|
||||
|
||||
## 0.6.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/unity-js-bridge",
|
||||
"version": "0.6.17",
|
||||
"version": "0.6.19",
|
||||
"main": "dist/thirdweb-unity-bridge.js",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @thirdweb-dev/wallets
|
||||
|
||||
## 2.5.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469), [`637c510`](https://github.com/thirdweb-dev/js/commit/637c510f59c2504bd29cedbdf4bda694719681dc)]:
|
||||
- @thirdweb-dev/sdk@4.0.70
|
||||
- @thirdweb-dev/chains@0.1.100
|
||||
|
||||
## 2.5.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@4.0.69
|
||||
|
||||
## 2.5.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/wallets",
|
||||
"version": "2.5.8",
|
||||
"version": "2.5.10",
|
||||
"main": "dist/thirdweb-dev-wallets.cjs.js",
|
||||
"module": "dist/thirdweb-dev-wallets.esm.js",
|
||||
"browser": {
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,146 @@
|
||||
# thirdweb
|
||||
|
||||
## 5.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2841](https://github.com/thirdweb-dev/js/pull/2841) [`2ae9a13`](https://github.com/thirdweb-dev/js/commit/2ae9a13b01e7a436536b3d412690150f9f960c72) Thanks [@kumaryash90](https://github.com/kumaryash90)! - SDK V5 extension for new Airdrop contract.
|
||||
|
||||
- [#2846](https://github.com/thirdweb-dev/js/pull/2846) [`e8e3368`](https://github.com/thirdweb-dev/js/commit/e8e3368fdef1aa9aaefe6243486395b666b47137) Thanks [@kien-ngo](https://github.com/kien-ngo)! - Add isERC20 extension
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2848](https://github.com/thirdweb-dev/js/pull/2848) [`41be954`](https://github.com/thirdweb-dev/js/commit/41be954bd0a92d49767d62a6fa02f1ee0effb469) Thanks [@jnsdls](https://github.com/jnsdls)! - add `celo` chains to known `op stack` chains
|
||||
|
||||
- [#2850](https://github.com/thirdweb-dev/js/pull/2850) [`aa0b8c4`](https://github.com/thirdweb-dev/js/commit/aa0b8c44650b9d0f45f6dff66ebbceb64cfd7be3) Thanks [@MananTank](https://github.com/MananTank)! - Fix "All wallets" UI in Connect
|
||||
|
||||
- Remove duplicated entry for "inApp"
|
||||
- Remove wallets specified by developer
|
||||
|
||||
## 5.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2679](https://github.com/thirdweb-dev/js/pull/2679) [`560d8ad`](https://github.com/thirdweb-dev/js/commit/560d8adafa011dc48e48e73d7eb6a36170d38cef) Thanks [@ElasticBottle](https://github.com/ElasticBottle)! - Add support for connecting in-app wallet using phone number
|
||||
|
||||
## Usage in TypeScript
|
||||
|
||||
```ts
|
||||
import { createThirdwebClient, createWallet } from "thirdweb";
|
||||
import { preAuthenticate } from "thirdweb/wallets/in-app";
|
||||
|
||||
const client = createThirdwebClient({ clientId: "..." });
|
||||
|
||||
const phoneNumber = '+123456789';
|
||||
|
||||
// Send OTP to given phone number
|
||||
async function sendOTP() {
|
||||
await preAuthenticate({
|
||||
strategy: "phone",
|
||||
phoneNumber,
|
||||
client,
|
||||
});
|
||||
}
|
||||
|
||||
async function connect() {
|
||||
// create a in-app wallet instance
|
||||
const wallet = createWallet('inApp');
|
||||
// if the OTP is correct, the wallet will be connected else an error will be thrown
|
||||
const account = await wallet.connect({
|
||||
client,
|
||||
strategy: "phone";
|
||||
phoneNumber,
|
||||
verificationCode: '...' // Pass the OTP entered by the user
|
||||
});
|
||||
|
||||
console.log('connected to', account);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage in React
|
||||
|
||||
```tsx
|
||||
import { createThirdwebClient } from "thirdweb";
|
||||
import { preAuthenticate } from "thirdweb/wallets/in-app";
|
||||
import { useConnect } from "thirdweb/react";
|
||||
|
||||
const client = createThirdwebClient({ clientId: "..." });
|
||||
|
||||
function Component() {
|
||||
const { connect } = useConnect();
|
||||
const [phoneNumber, setPhoneNumber] = useState(''); // get phone number from user
|
||||
const [otp, setOtp] = useState(''); // get OTP from user
|
||||
|
||||
// Send OTP to given phone number
|
||||
async function sendOTP() {
|
||||
await preAuthenticate({
|
||||
strategy: "phone",
|
||||
phoneNumber,
|
||||
client,
|
||||
});
|
||||
}
|
||||
|
||||
async function connect() {
|
||||
// create a in-app wallet instance
|
||||
const wallet = createWallet('inApp');
|
||||
// if the OTP is correct, the wallet will be connected else an error will be thrown
|
||||
await wallet.connect({
|
||||
client,
|
||||
strategy: "phone";
|
||||
phoneNumber,
|
||||
verificationCode: otp
|
||||
});
|
||||
|
||||
// set the wallet as active
|
||||
connect(wallet)
|
||||
}
|
||||
|
||||
// render UI to get OTP and phone number from user
|
||||
return <div> ... </div>
|
||||
}
|
||||
```
|
||||
|
||||
- [#2818](https://github.com/thirdweb-dev/js/pull/2818) [`948f155`](https://github.com/thirdweb-dev/js/commit/948f155e7c2406cc5a172a6c5abe18ba8da89e2a) Thanks [@jnsdls](https://github.com/jnsdls)! - **Gasless transactions in Typescript**
|
||||
|
||||
```ts
|
||||
import { sendTransaction } from "thirdweb";
|
||||
|
||||
const result = sendTransaction({
|
||||
transaction,
|
||||
account,
|
||||
gasless: {
|
||||
provider: "engine",
|
||||
relayerUrl: "https://...",
|
||||
relayerForwarderAddress: "0x...",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
**Gasless transactions in React**
|
||||
|
||||
```jsx
|
||||
import { useSendTransaction } from "thirdweb/react";
|
||||
|
||||
const { mutate } = useSendTransaction({
|
||||
gasless: {
|
||||
provider: "engine",
|
||||
relayerUrl: "https://...",
|
||||
relayerForwarderAddress: "0x...",
|
||||
},
|
||||
});
|
||||
|
||||
// Call mutate with the transaction object
|
||||
mutate(transaction);
|
||||
```
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2842](https://github.com/thirdweb-dev/js/pull/2842) [`d7e6671`](https://github.com/thirdweb-dev/js/commit/d7e6671c0a34cc8a3523f397a45d754617c9fbb0) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - fix: handle signature minting with price and currency
|
||||
|
||||
- [#2839](https://github.com/thirdweb-dev/js/pull/2839) [`3be61dd`](https://github.com/thirdweb-dev/js/commit/3be61ddc52cef168cda0bee13e93a926dedf479a) Thanks [@MananTank](https://github.com/MananTank)! - Enable Buy Modal by default with useSendTransaction hook
|
||||
|
||||
- [#2768](https://github.com/thirdweb-dev/js/pull/2768) [`cfff7e8`](https://github.com/thirdweb-dev/js/commit/cfff7e838af1c464c9b5fbb547153eaae41e2c66) Thanks [@MananTank](https://github.com/MananTank)! - Fix custom chain not being used
|
||||
|
||||
## 5.10.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"version": "5.10.1",
|
||||
"version": "5.12.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/thirdweb-dev/js.git#main"
|
||||
|
||||
@@ -0,0 +1,408 @@
|
||||
[
|
||||
"function tokenConditionId(address tokenAddress) view returns (uint256)",
|
||||
"function tokenMerkleRoot(address tokenAddress) view returns (bytes32)",
|
||||
{ "type": "constructor", "inputs": [], "stateMutability": "nonpayable" },
|
||||
{
|
||||
"type": "function",
|
||||
"name": "airdropERC1155",
|
||||
"inputs": [
|
||||
{ "name": "_tokenAddress", "type": "address", "internalType": "address" },
|
||||
{
|
||||
"name": "_contents",
|
||||
"type": "tuple[]",
|
||||
"internalType": "struct Airdrop.AirdropContentERC1155[]",
|
||||
"components": [
|
||||
{ "name": "recipient", "type": "address", "internalType": "address" },
|
||||
{ "name": "tokenId", "type": "uint256", "internalType": "uint256" },
|
||||
{ "name": "amount", "type": "uint256", "internalType": "uint256" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "airdropERC1155WithSignature",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "req",
|
||||
"type": "tuple",
|
||||
"internalType": "struct Airdrop.AirdropRequestERC1155",
|
||||
"components": [
|
||||
{ "name": "uid", "type": "bytes32", "internalType": "bytes32" },
|
||||
{
|
||||
"name": "tokenAddress",
|
||||
"type": "address",
|
||||
"internalType": "address"
|
||||
},
|
||||
{
|
||||
"name": "expirationTimestamp",
|
||||
"type": "uint256",
|
||||
"internalType": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "contents",
|
||||
"type": "tuple[]",
|
||||
"internalType": "struct Airdrop.AirdropContentERC1155[]",
|
||||
"components": [
|
||||
{
|
||||
"name": "recipient",
|
||||
"type": "address",
|
||||
"internalType": "address"
|
||||
},
|
||||
{
|
||||
"name": "tokenId",
|
||||
"type": "uint256",
|
||||
"internalType": "uint256"
|
||||
},
|
||||
{ "name": "amount", "type": "uint256", "internalType": "uint256" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{ "name": "signature", "type": "bytes", "internalType": "bytes" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "airdropERC20",
|
||||
"inputs": [
|
||||
{ "name": "_tokenAddress", "type": "address", "internalType": "address" },
|
||||
{
|
||||
"name": "_contents",
|
||||
"type": "tuple[]",
|
||||
"internalType": "struct Airdrop.AirdropContentERC20[]",
|
||||
"components": [
|
||||
{ "name": "recipient", "type": "address", "internalType": "address" },
|
||||
{ "name": "amount", "type": "uint256", "internalType": "uint256" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "airdropERC20WithSignature",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "req",
|
||||
"type": "tuple",
|
||||
"internalType": "struct Airdrop.AirdropRequestERC20",
|
||||
"components": [
|
||||
{ "name": "uid", "type": "bytes32", "internalType": "bytes32" },
|
||||
{
|
||||
"name": "tokenAddress",
|
||||
"type": "address",
|
||||
"internalType": "address"
|
||||
},
|
||||
{
|
||||
"name": "expirationTimestamp",
|
||||
"type": "uint256",
|
||||
"internalType": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "contents",
|
||||
"type": "tuple[]",
|
||||
"internalType": "struct Airdrop.AirdropContentERC20[]",
|
||||
"components": [
|
||||
{
|
||||
"name": "recipient",
|
||||
"type": "address",
|
||||
"internalType": "address"
|
||||
},
|
||||
{ "name": "amount", "type": "uint256", "internalType": "uint256" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{ "name": "signature", "type": "bytes", "internalType": "bytes" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "airdropERC721",
|
||||
"inputs": [
|
||||
{ "name": "_tokenAddress", "type": "address", "internalType": "address" },
|
||||
{
|
||||
"name": "_contents",
|
||||
"type": "tuple[]",
|
||||
"internalType": "struct Airdrop.AirdropContentERC721[]",
|
||||
"components": [
|
||||
{ "name": "recipient", "type": "address", "internalType": "address" },
|
||||
{ "name": "tokenId", "type": "uint256", "internalType": "uint256" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "airdropERC721WithSignature",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "req",
|
||||
"type": "tuple",
|
||||
"internalType": "struct Airdrop.AirdropRequestERC721",
|
||||
"components": [
|
||||
{ "name": "uid", "type": "bytes32", "internalType": "bytes32" },
|
||||
{
|
||||
"name": "tokenAddress",
|
||||
"type": "address",
|
||||
"internalType": "address"
|
||||
},
|
||||
{
|
||||
"name": "expirationTimestamp",
|
||||
"type": "uint256",
|
||||
"internalType": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "contents",
|
||||
"type": "tuple[]",
|
||||
"internalType": "struct Airdrop.AirdropContentERC721[]",
|
||||
"components": [
|
||||
{
|
||||
"name": "recipient",
|
||||
"type": "address",
|
||||
"internalType": "address"
|
||||
},
|
||||
{
|
||||
"name": "tokenId",
|
||||
"type": "uint256",
|
||||
"internalType": "uint256"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{ "name": "signature", "type": "bytes", "internalType": "bytes" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "airdropNativeToken",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_contents",
|
||||
"type": "tuple[]",
|
||||
"internalType": "struct Airdrop.AirdropContentERC20[]",
|
||||
"components": [
|
||||
{ "name": "recipient", "type": "address", "internalType": "address" },
|
||||
{ "name": "amount", "type": "uint256", "internalType": "uint256" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "payable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "claimERC1155",
|
||||
"inputs": [
|
||||
{ "name": "_token", "type": "address", "internalType": "address" },
|
||||
{ "name": "_receiver", "type": "address", "internalType": "address" },
|
||||
{ "name": "_tokenId", "type": "uint256", "internalType": "uint256" },
|
||||
{ "name": "_quantity", "type": "uint256", "internalType": "uint256" },
|
||||
{ "name": "_proofs", "type": "bytes32[]", "internalType": "bytes32[]" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "claimERC20",
|
||||
"inputs": [
|
||||
{ "name": "_token", "type": "address", "internalType": "address" },
|
||||
{ "name": "_receiver", "type": "address", "internalType": "address" },
|
||||
{ "name": "_quantity", "type": "uint256", "internalType": "uint256" },
|
||||
{ "name": "_proofs", "type": "bytes32[]", "internalType": "bytes32[]" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "claimERC721",
|
||||
"inputs": [
|
||||
{ "name": "_token", "type": "address", "internalType": "address" },
|
||||
{ "name": "_receiver", "type": "address", "internalType": "address" },
|
||||
{ "name": "_tokenId", "type": "uint256", "internalType": "uint256" },
|
||||
{ "name": "_proofs", "type": "bytes32[]", "internalType": "bytes32[]" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "eip712Domain",
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{ "name": "fields", "type": "bytes1", "internalType": "bytes1" },
|
||||
{ "name": "name", "type": "string", "internalType": "string" },
|
||||
{ "name": "version", "type": "string", "internalType": "string" },
|
||||
{ "name": "chainId", "type": "uint256", "internalType": "uint256" },
|
||||
{
|
||||
"name": "verifyingContract",
|
||||
"type": "address",
|
||||
"internalType": "address"
|
||||
},
|
||||
{ "name": "salt", "type": "bytes32", "internalType": "bytes32" },
|
||||
{ "name": "extensions", "type": "uint256[]", "internalType": "uint256[]" }
|
||||
],
|
||||
"stateMutability": "view"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "initialize",
|
||||
"inputs": [
|
||||
{ "name": "_defaultAdmin", "type": "address", "internalType": "address" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "isClaimed",
|
||||
"inputs": [
|
||||
{ "name": "_receiver", "type": "address", "internalType": "address" },
|
||||
{ "name": "_token", "type": "address", "internalType": "address" },
|
||||
{ "name": "_tokenId", "type": "uint256", "internalType": "uint256" }
|
||||
],
|
||||
"outputs": [{ "name": "", "type": "bool", "internalType": "bool" }],
|
||||
"stateMutability": "view"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "owner",
|
||||
"inputs": [],
|
||||
"outputs": [{ "name": "", "type": "address", "internalType": "address" }],
|
||||
"stateMutability": "view"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "setMerkleRoot",
|
||||
"inputs": [
|
||||
{ "name": "_token", "type": "address", "internalType": "address" },
|
||||
{
|
||||
"name": "_tokenMerkleRoot",
|
||||
"type": "bytes32",
|
||||
"internalType": "bytes32"
|
||||
},
|
||||
{ "name": "_resetClaimStatus", "type": "bool", "internalType": "bool" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"name": "setOwner",
|
||||
"inputs": [
|
||||
{ "name": "_newOwner", "type": "address", "internalType": "address" }
|
||||
],
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable"
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"name": "Airdrop",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "token",
|
||||
"type": "address",
|
||||
"indexed": false,
|
||||
"internalType": "address"
|
||||
}
|
||||
],
|
||||
"anonymous": false
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"name": "AirdropClaimed",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "token",
|
||||
"type": "address",
|
||||
"indexed": false,
|
||||
"internalType": "address"
|
||||
},
|
||||
{
|
||||
"name": "receiver",
|
||||
"type": "address",
|
||||
"indexed": false,
|
||||
"internalType": "address"
|
||||
}
|
||||
],
|
||||
"anonymous": false
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"name": "AirdropWithSignature",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "token",
|
||||
"type": "address",
|
||||
"indexed": false,
|
||||
"internalType": "address"
|
||||
}
|
||||
],
|
||||
"anonymous": false
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"name": "Initialized",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "version",
|
||||
"type": "uint8",
|
||||
"indexed": false,
|
||||
"internalType": "uint8"
|
||||
}
|
||||
],
|
||||
"anonymous": false
|
||||
},
|
||||
{
|
||||
"type": "event",
|
||||
"name": "OwnerUpdated",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "prevOwner",
|
||||
"type": "address",
|
||||
"indexed": true,
|
||||
"internalType": "address"
|
||||
},
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address",
|
||||
"indexed": true,
|
||||
"internalType": "address"
|
||||
}
|
||||
],
|
||||
"anonymous": false
|
||||
},
|
||||
{ "type": "error", "name": "AirdropAlreadyClaimed", "inputs": [] },
|
||||
{ "type": "error", "name": "AirdropInvalidProof", "inputs": [] },
|
||||
{ "type": "error", "name": "AirdropNoMerkleRoot", "inputs": [] },
|
||||
{ "type": "error", "name": "AirdropRequestAlreadyProcessed", "inputs": [] },
|
||||
{
|
||||
"type": "error",
|
||||
"name": "AirdropRequestExpired",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "expirationTimestamp",
|
||||
"type": "uint256",
|
||||
"internalType": "uint256"
|
||||
}
|
||||
]
|
||||
},
|
||||
{ "type": "error", "name": "AirdropRequestInvalidSigner", "inputs": [] },
|
||||
{ "type": "error", "name": "AirdropValueMismatch", "inputs": [] },
|
||||
{ "type": "error", "name": "OwnableUnauthorized", "inputs": [] }
|
||||
]
|
||||
@@ -15,6 +15,8 @@ const opChains = [
|
||||
zoraSepolia.id,
|
||||
34443, // mode
|
||||
919, // mode testnet
|
||||
42220, // celo
|
||||
44787, // celo testnet
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,9 +18,11 @@ export async function getOrDeployInfraForPublishedContract(
|
||||
args: ClientAndChainAndAccount & {
|
||||
contractId: string;
|
||||
constructorParams: unknown[];
|
||||
publisher?: string;
|
||||
},
|
||||
) {
|
||||
const { chain, client, account, contractId, constructorParams } = args;
|
||||
const { chain, client, account, contractId, constructorParams, publisher } =
|
||||
args;
|
||||
let [cloneFactoryContract, implementationContract] = await Promise.all([
|
||||
getDeployedCloneFactoryContract({
|
||||
chain,
|
||||
@@ -31,6 +33,7 @@ export async function getOrDeployInfraForPublishedContract(
|
||||
client,
|
||||
contractId,
|
||||
constructorParams,
|
||||
publisher,
|
||||
}),
|
||||
]);
|
||||
|
||||
@@ -47,6 +50,7 @@ export async function getOrDeployInfraForPublishedContract(
|
||||
account,
|
||||
contractId,
|
||||
constructorParams,
|
||||
publisher,
|
||||
});
|
||||
}
|
||||
return { cloneFactoryContract, implementationContract };
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// read
|
||||
export { isERC20 } from "../../extensions/erc20/read/isERC20.js";
|
||||
export {
|
||||
getBalance,
|
||||
type GetBalanceParams,
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { prepareEvent } from "../../../../../event/prepare-event.js";
|
||||
|
||||
/**
|
||||
* Creates an event object for the Airdrop event.
|
||||
* @returns The prepared event object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getContractEvents } from "thirdweb";
|
||||
* import { airdropEvent } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const events = await getContractEvents({
|
||||
* contract,
|
||||
* events: [
|
||||
* airdropEvent()
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function airdropEvent() {
|
||||
return prepareEvent({
|
||||
signature: "event Airdrop(address token)",
|
||||
});
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { prepareEvent } from "../../../../../event/prepare-event.js";
|
||||
|
||||
/**
|
||||
* Creates an event object for the AirdropClaimed event.
|
||||
* @returns The prepared event object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getContractEvents } from "thirdweb";
|
||||
* import { airdropClaimedEvent } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const events = await getContractEvents({
|
||||
* contract,
|
||||
* events: [
|
||||
* airdropClaimedEvent()
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function airdropClaimedEvent() {
|
||||
return prepareEvent({
|
||||
signature: "event AirdropClaimed(address token, address receiver)",
|
||||
});
|
||||
}
|
||||
Generated
+24
@@ -0,0 +1,24 @@
|
||||
import { prepareEvent } from "../../../../../event/prepare-event.js";
|
||||
|
||||
/**
|
||||
* Creates an event object for the AirdropWithSignature event.
|
||||
* @returns The prepared event object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getContractEvents } from "thirdweb";
|
||||
* import { airdropWithSignatureEvent } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const events = await getContractEvents({
|
||||
* contract,
|
||||
* events: [
|
||||
* airdropWithSignatureEvent()
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function airdropWithSignatureEvent() {
|
||||
return prepareEvent({
|
||||
signature: "event AirdropWithSignature(address token)",
|
||||
});
|
||||
}
|
||||
Generated
+24
@@ -0,0 +1,24 @@
|
||||
import { prepareEvent } from "../../../../../event/prepare-event.js";
|
||||
|
||||
/**
|
||||
* Creates an event object for the ContractURIUpdated event.
|
||||
* @returns The prepared event object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getContractEvents } from "thirdweb";
|
||||
* import { contractURIUpdatedEvent } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const events = await getContractEvents({
|
||||
* contract,
|
||||
* events: [
|
||||
* contractURIUpdatedEvent()
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function contractURIUpdatedEvent() {
|
||||
return prepareEvent({
|
||||
signature: "event ContractURIUpdated(string prevURI, string newURI)",
|
||||
});
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { prepareEvent } from "../../../../../event/prepare-event.js";
|
||||
|
||||
/**
|
||||
* Creates an event object for the Initialized event.
|
||||
* @returns The prepared event object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getContractEvents } from "thirdweb";
|
||||
* import { initializedEvent } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const events = await getContractEvents({
|
||||
* contract,
|
||||
* events: [
|
||||
* initializedEvent()
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function initializedEvent() {
|
||||
return prepareEvent({
|
||||
signature: "event Initialized(uint8 version)",
|
||||
});
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import { prepareEvent } from "../../../../../event/prepare-event.js";
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
|
||||
/**
|
||||
* Represents the filters for the "OwnerUpdated" event.
|
||||
*/
|
||||
export type OwnerUpdatedEventFilters = Partial<{
|
||||
prevOwner: AbiParameterToPrimitiveType<{
|
||||
name: "prevOwner";
|
||||
type: "address";
|
||||
indexed: true;
|
||||
internalType: "address";
|
||||
}>;
|
||||
newOwner: AbiParameterToPrimitiveType<{
|
||||
name: "newOwner";
|
||||
type: "address";
|
||||
indexed: true;
|
||||
internalType: "address";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Creates an event object for the OwnerUpdated event.
|
||||
* @param filters - Optional filters to apply to the event.
|
||||
* @returns The prepared event object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getContractEvents } from "thirdweb";
|
||||
* import { ownerUpdatedEvent } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const events = await getContractEvents({
|
||||
* contract,
|
||||
* events: [
|
||||
* ownerUpdatedEvent({
|
||||
* prevOwner: ...,
|
||||
* newOwner: ...,
|
||||
* })
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function ownerUpdatedEvent(filters: OwnerUpdatedEventFilters = {}) {
|
||||
return prepareEvent({
|
||||
signature:
|
||||
"event OwnerUpdated(address indexed prevOwner, address indexed newOwner)",
|
||||
filters,
|
||||
});
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { readContract } from "../../../../../transaction/read-contract.js";
|
||||
import type { BaseTransactionOptions } from "../../../../../transaction/types.js";
|
||||
|
||||
import { decodeAbiParameters } from "viem";
|
||||
import type { Hex } from "../../../../../utils/encoding/hex.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
export const FN_SELECTOR = "0xe8a3d485" as const;
|
||||
const FN_INPUTS = [] as const;
|
||||
const FN_OUTPUTS = [
|
||||
{
|
||||
type: "string",
|
||||
},
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `contractURI` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `contractURI` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isContractURISupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isContractURISupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isContractURISupported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the result of the contractURI function call.
|
||||
* @param result - The hexadecimal result to decode.
|
||||
* @returns The decoded result as per the FN_OUTPUTS definition.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { decodeContractURIResult } from "thirdweb/extensions/airdrop";
|
||||
* const result = decodeContractURIResult("...");
|
||||
* ```
|
||||
*/
|
||||
export function decodeContractURIResult(result: Hex) {
|
||||
return decodeAbiParameters(FN_OUTPUTS, result)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "contractURI" function on the contract.
|
||||
* @param options - The options for the contractURI function.
|
||||
* @returns The parsed result of the function call.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { contractURI } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const result = await contractURI();
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export async function contractURI(options: BaseTransactionOptions) {
|
||||
return readContract({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: [],
|
||||
});
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
import { readContract } from "../../../../../transaction/read-contract.js";
|
||||
import type { BaseTransactionOptions } from "../../../../../transaction/types.js";
|
||||
|
||||
import { decodeAbiParameters } from "viem";
|
||||
import type { Hex } from "../../../../../utils/encoding/hex.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
export const FN_SELECTOR = "0x84b0196e" as const;
|
||||
const FN_INPUTS = [] as const;
|
||||
const FN_OUTPUTS = [
|
||||
{
|
||||
name: "fields",
|
||||
type: "bytes1",
|
||||
internalType: "bytes1",
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
type: "string",
|
||||
internalType: "string",
|
||||
},
|
||||
{
|
||||
name: "version",
|
||||
type: "string",
|
||||
internalType: "string",
|
||||
},
|
||||
{
|
||||
name: "chainId",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "verifyingContract",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "salt",
|
||||
type: "bytes32",
|
||||
internalType: "bytes32",
|
||||
},
|
||||
{
|
||||
name: "extensions",
|
||||
type: "uint256[]",
|
||||
internalType: "uint256[]",
|
||||
},
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `eip712Domain` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `eip712Domain` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isEip712DomainSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isEip712DomainSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isEip712DomainSupported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the result of the eip712Domain function call.
|
||||
* @param result - The hexadecimal result to decode.
|
||||
* @returns The decoded result as per the FN_OUTPUTS definition.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { decodeEip712DomainResult } from "thirdweb/extensions/airdrop";
|
||||
* const result = decodeEip712DomainResult("...");
|
||||
* ```
|
||||
*/
|
||||
export function decodeEip712DomainResult(result: Hex) {
|
||||
return decodeAbiParameters(FN_OUTPUTS, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "eip712Domain" function on the contract.
|
||||
* @param options - The options for the eip712Domain function.
|
||||
* @returns The parsed result of the function call.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { eip712Domain } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const result = await eip712Domain();
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export async function eip712Domain(options: BaseTransactionOptions) {
|
||||
return readContract({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: [],
|
||||
});
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import { readContract } from "../../../../../transaction/read-contract.js";
|
||||
import type { BaseTransactionOptions } from "../../../../../transaction/types.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { decodeAbiParameters } from "viem";
|
||||
import type { Hex } from "../../../../../utils/encoding/hex.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "isClaimed" function.
|
||||
*/
|
||||
export type IsClaimedParams = {
|
||||
receiver: AbiParameterToPrimitiveType<{
|
||||
name: "_receiver";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
token: AbiParameterToPrimitiveType<{
|
||||
name: "_token";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
tokenId: AbiParameterToPrimitiveType<{
|
||||
name: "_tokenId";
|
||||
type: "uint256";
|
||||
internalType: "uint256";
|
||||
}>;
|
||||
};
|
||||
|
||||
export const FN_SELECTOR = "0xd12acf73" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_receiver",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_token",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_tokenId",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [
|
||||
{
|
||||
name: "",
|
||||
type: "bool",
|
||||
internalType: "bool",
|
||||
},
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `isClaimed` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `isClaimed` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isIsClaimedSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isIsClaimedSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isIsClaimedSupported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "isClaimed" function.
|
||||
* @param options - The options for the isClaimed function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeIsClaimedParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeIsClaimedParams({
|
||||
* receiver: ...,
|
||||
* token: ...,
|
||||
* tokenId: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeIsClaimedParams(options: IsClaimedParams) {
|
||||
return encodeAbiParameters(FN_INPUTS, [
|
||||
options.receiver,
|
||||
options.token,
|
||||
options.tokenId,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "isClaimed" function into a Hex string with its parameters.
|
||||
* @param options - The options for the isClaimed function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeIsClaimed } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeIsClaimed({
|
||||
* receiver: ...,
|
||||
* token: ...,
|
||||
* tokenId: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeIsClaimed(options: IsClaimedParams) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeIsClaimedParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the result of the isClaimed function call.
|
||||
* @param result - The hexadecimal result to decode.
|
||||
* @returns The decoded result as per the FN_OUTPUTS definition.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { decodeIsClaimedResult } from "thirdweb/extensions/airdrop";
|
||||
* const result = decodeIsClaimedResult("...");
|
||||
* ```
|
||||
*/
|
||||
export function decodeIsClaimedResult(result: Hex) {
|
||||
return decodeAbiParameters(FN_OUTPUTS, result)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "isClaimed" function on the contract.
|
||||
* @param options - The options for the isClaimed function.
|
||||
* @returns The parsed result of the function call.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isClaimed } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const result = await isClaimed({
|
||||
* receiver: ...,
|
||||
* token: ...,
|
||||
* tokenId: ...,
|
||||
* });
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export async function isClaimed(
|
||||
options: BaseTransactionOptions<IsClaimedParams>,
|
||||
) {
|
||||
return readContract({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: [options.receiver, options.token, options.tokenId],
|
||||
});
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
import { readContract } from "../../../../../transaction/read-contract.js";
|
||||
import type { BaseTransactionOptions } from "../../../../../transaction/types.js";
|
||||
|
||||
import { decodeAbiParameters } from "viem";
|
||||
import type { Hex } from "../../../../../utils/encoding/hex.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
export const FN_SELECTOR = "0x8da5cb5b" as const;
|
||||
const FN_INPUTS = [] as const;
|
||||
const FN_OUTPUTS = [
|
||||
{
|
||||
name: "",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `owner` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `owner` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isOwnerSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isOwnerSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isOwnerSupported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the result of the owner function call.
|
||||
* @param result - The hexadecimal result to decode.
|
||||
* @returns The decoded result as per the FN_OUTPUTS definition.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { decodeOwnerResult } from "thirdweb/extensions/airdrop";
|
||||
* const result = decodeOwnerResult("...");
|
||||
* ```
|
||||
*/
|
||||
export function decodeOwnerResult(result: Hex) {
|
||||
return decodeAbiParameters(FN_OUTPUTS, result)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "owner" function on the contract.
|
||||
* @param options - The options for the owner function.
|
||||
* @returns The parsed result of the function call.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { owner } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const result = await owner();
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export async function owner(options: BaseTransactionOptions) {
|
||||
return readContract({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: [],
|
||||
});
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import { readContract } from "../../../../../transaction/read-contract.js";
|
||||
import type { BaseTransactionOptions } from "../../../../../transaction/types.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { decodeAbiParameters } from "viem";
|
||||
import type { Hex } from "../../../../../utils/encoding/hex.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "tokenConditionId" function.
|
||||
*/
|
||||
export type TokenConditionIdParams = {
|
||||
tokenAddress: AbiParameterToPrimitiveType<{
|
||||
type: "address";
|
||||
name: "tokenAddress";
|
||||
}>;
|
||||
};
|
||||
|
||||
export const FN_SELECTOR = "0x3dc28d49" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
type: "address",
|
||||
name: "tokenAddress",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [
|
||||
{
|
||||
type: "uint256",
|
||||
},
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `tokenConditionId` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `tokenConditionId` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isTokenConditionIdSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isTokenConditionIdSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isTokenConditionIdSupported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "tokenConditionId" function.
|
||||
* @param options - The options for the tokenConditionId function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeTokenConditionIdParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeTokenConditionIdParams({
|
||||
* tokenAddress: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeTokenConditionIdParams(options: TokenConditionIdParams) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.tokenAddress]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "tokenConditionId" function into a Hex string with its parameters.
|
||||
* @param options - The options for the tokenConditionId function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeTokenConditionId } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeTokenConditionId({
|
||||
* tokenAddress: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeTokenConditionId(options: TokenConditionIdParams) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeTokenConditionIdParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the result of the tokenConditionId function call.
|
||||
* @param result - The hexadecimal result to decode.
|
||||
* @returns The decoded result as per the FN_OUTPUTS definition.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { decodeTokenConditionIdResult } from "thirdweb/extensions/airdrop";
|
||||
* const result = decodeTokenConditionIdResult("...");
|
||||
* ```
|
||||
*/
|
||||
export function decodeTokenConditionIdResult(result: Hex) {
|
||||
return decodeAbiParameters(FN_OUTPUTS, result)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "tokenConditionId" function on the contract.
|
||||
* @param options - The options for the tokenConditionId function.
|
||||
* @returns The parsed result of the function call.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { tokenConditionId } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const result = await tokenConditionId({
|
||||
* tokenAddress: ...,
|
||||
* });
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export async function tokenConditionId(
|
||||
options: BaseTransactionOptions<TokenConditionIdParams>,
|
||||
) {
|
||||
return readContract({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: [options.tokenAddress],
|
||||
});
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import { readContract } from "../../../../../transaction/read-contract.js";
|
||||
import type { BaseTransactionOptions } from "../../../../../transaction/types.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { decodeAbiParameters } from "viem";
|
||||
import type { Hex } from "../../../../../utils/encoding/hex.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "tokenMerkleRoot" function.
|
||||
*/
|
||||
export type TokenMerkleRootParams = {
|
||||
tokenAddress: AbiParameterToPrimitiveType<{
|
||||
type: "address";
|
||||
name: "tokenAddress";
|
||||
}>;
|
||||
};
|
||||
|
||||
export const FN_SELECTOR = "0x95f5c120" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
type: "address",
|
||||
name: "tokenAddress",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [
|
||||
{
|
||||
type: "bytes32",
|
||||
},
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `tokenMerkleRoot` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `tokenMerkleRoot` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isTokenMerkleRootSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isTokenMerkleRootSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isTokenMerkleRootSupported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "tokenMerkleRoot" function.
|
||||
* @param options - The options for the tokenMerkleRoot function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeTokenMerkleRootParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeTokenMerkleRootParams({
|
||||
* tokenAddress: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeTokenMerkleRootParams(options: TokenMerkleRootParams) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.tokenAddress]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "tokenMerkleRoot" function into a Hex string with its parameters.
|
||||
* @param options - The options for the tokenMerkleRoot function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeTokenMerkleRoot } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeTokenMerkleRoot({
|
||||
* tokenAddress: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeTokenMerkleRoot(options: TokenMerkleRootParams) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeTokenMerkleRootParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the result of the tokenMerkleRoot function call.
|
||||
* @param result - The hexadecimal result to decode.
|
||||
* @returns The decoded result as per the FN_OUTPUTS definition.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { decodeTokenMerkleRootResult } from "thirdweb/extensions/airdrop";
|
||||
* const result = decodeTokenMerkleRootResult("...");
|
||||
* ```
|
||||
*/
|
||||
export function decodeTokenMerkleRootResult(result: Hex) {
|
||||
return decodeAbiParameters(FN_OUTPUTS, result)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "tokenMerkleRoot" function on the contract.
|
||||
* @param options - The options for the tokenMerkleRoot function.
|
||||
* @returns The parsed result of the function call.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { tokenMerkleRoot } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const result = await tokenMerkleRoot({
|
||||
* tokenAddress: ...,
|
||||
* });
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export async function tokenMerkleRoot(
|
||||
options: BaseTransactionOptions<TokenMerkleRootParams>,
|
||||
) {
|
||||
return readContract({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: [options.tokenAddress],
|
||||
});
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "airdropERC1155" function.
|
||||
*/
|
||||
export type AirdropERC1155Params = WithOverrides<{
|
||||
tokenAddress: AbiParameterToPrimitiveType<{
|
||||
name: "_tokenAddress";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
contents: AbiParameterToPrimitiveType<{
|
||||
name: "_contents";
|
||||
type: "tuple[]";
|
||||
internalType: "struct Airdrop.AirdropContentERC1155[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "tokenId"; type: "uint256"; internalType: "uint256" },
|
||||
{ name: "amount"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0x2d89e38b" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_tokenAddress",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_contents",
|
||||
type: "tuple[]",
|
||||
internalType: "struct Airdrop.AirdropContentERC1155[]",
|
||||
components: [
|
||||
{
|
||||
name: "recipient",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "tokenId",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "amount",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `airdropERC1155` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `airdropERC1155` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isAirdropERC1155Supported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isAirdropERC1155Supported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isAirdropERC1155Supported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "airdropERC1155" function.
|
||||
* @param options - The options for the airdropERC1155 function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC1155Params } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC1155Params({
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC1155Params(options: AirdropERC1155Params) {
|
||||
return encodeAbiParameters(FN_INPUTS, [
|
||||
options.tokenAddress,
|
||||
options.contents,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "airdropERC1155" function into a Hex string with its parameters.
|
||||
* @param options - The options for the airdropERC1155 function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC1155 } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC1155({
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC1155(options: AirdropERC1155Params) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeAirdropERC1155Params(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "airdropERC1155" function on the contract.
|
||||
* @param options - The options for the "airdropERC1155" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC1155 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = airdropERC1155({
|
||||
* contract,
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function airdropERC1155(
|
||||
options: BaseTransactionOptions<
|
||||
| AirdropERC1155Params
|
||||
| {
|
||||
asyncParams: () => Promise<AirdropERC1155Params>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.tokenAddress, resolvedOptions.contents] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
Generated
+204
@@ -0,0 +1,204 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "airdropERC1155WithSignature" function.
|
||||
*/
|
||||
export type AirdropERC1155WithSignatureParams = WithOverrides<{
|
||||
req: AbiParameterToPrimitiveType<{
|
||||
name: "req";
|
||||
type: "tuple";
|
||||
internalType: "struct Airdrop.AirdropRequestERC1155";
|
||||
components: [
|
||||
{ name: "uid"; type: "bytes32"; internalType: "bytes32" },
|
||||
{ name: "tokenAddress"; type: "address"; internalType: "address" },
|
||||
{ name: "expirationTimestamp"; type: "uint256"; internalType: "uint256" },
|
||||
{
|
||||
name: "contents";
|
||||
type: "tuple[]";
|
||||
internalType: "struct Airdrop.AirdropContentERC1155[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "tokenId"; type: "uint256"; internalType: "uint256" },
|
||||
{ name: "amount"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
},
|
||||
];
|
||||
}>;
|
||||
signature: AbiParameterToPrimitiveType<{
|
||||
name: "signature";
|
||||
type: "bytes";
|
||||
internalType: "bytes";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0xd0d4afd6" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "req",
|
||||
type: "tuple",
|
||||
internalType: "struct Airdrop.AirdropRequestERC1155",
|
||||
components: [
|
||||
{
|
||||
name: "uid",
|
||||
type: "bytes32",
|
||||
internalType: "bytes32",
|
||||
},
|
||||
{
|
||||
name: "tokenAddress",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "expirationTimestamp",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "contents",
|
||||
type: "tuple[]",
|
||||
internalType: "struct Airdrop.AirdropContentERC1155[]",
|
||||
components: [
|
||||
{
|
||||
name: "recipient",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "tokenId",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "amount",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "signature",
|
||||
type: "bytes",
|
||||
internalType: "bytes",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `airdropERC1155WithSignature` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `airdropERC1155WithSignature` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isAirdropERC1155WithSignatureSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isAirdropERC1155WithSignatureSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isAirdropERC1155WithSignatureSupported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "airdropERC1155WithSignature" function.
|
||||
* @param options - The options for the airdropERC1155WithSignature function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC1155WithSignatureParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC1155WithSignatureParams({
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC1155WithSignatureParams(
|
||||
options: AirdropERC1155WithSignatureParams,
|
||||
) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.req, options.signature]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "airdropERC1155WithSignature" function into a Hex string with its parameters.
|
||||
* @param options - The options for the airdropERC1155WithSignature function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC1155WithSignature } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC1155WithSignature({
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC1155WithSignature(
|
||||
options: AirdropERC1155WithSignatureParams,
|
||||
) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeAirdropERC1155WithSignatureParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "airdropERC1155WithSignature" function on the contract.
|
||||
* @param options - The options for the "airdropERC1155WithSignature" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC1155WithSignature } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = airdropERC1155WithSignature({
|
||||
* contract,
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function airdropERC1155WithSignature(
|
||||
options: BaseTransactionOptions<
|
||||
| AirdropERC1155WithSignatureParams
|
||||
| {
|
||||
asyncParams: () => Promise<AirdropERC1155WithSignatureParams>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.req, resolvedOptions.signature] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "airdropERC20" function.
|
||||
*/
|
||||
export type AirdropERC20Params = WithOverrides<{
|
||||
tokenAddress: AbiParameterToPrimitiveType<{
|
||||
name: "_tokenAddress";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
contents: AbiParameterToPrimitiveType<{
|
||||
name: "_contents";
|
||||
type: "tuple[]";
|
||||
internalType: "struct Airdrop.AirdropContentERC20[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "amount"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0x56b0b449" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_tokenAddress",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_contents",
|
||||
type: "tuple[]",
|
||||
internalType: "struct Airdrop.AirdropContentERC20[]",
|
||||
components: [
|
||||
{
|
||||
name: "recipient",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "amount",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `airdropERC20` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `airdropERC20` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isAirdropERC20Supported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isAirdropERC20Supported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isAirdropERC20Supported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "airdropERC20" function.
|
||||
* @param options - The options for the airdropERC20 function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC20Params } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC20Params({
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC20Params(options: AirdropERC20Params) {
|
||||
return encodeAbiParameters(FN_INPUTS, [
|
||||
options.tokenAddress,
|
||||
options.contents,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "airdropERC20" function into a Hex string with its parameters.
|
||||
* @param options - The options for the airdropERC20 function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC20 } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC20({
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC20(options: AirdropERC20Params) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeAirdropERC20Params(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "airdropERC20" function on the contract.
|
||||
* @param options - The options for the "airdropERC20" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC20 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = airdropERC20({
|
||||
* contract,
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function airdropERC20(
|
||||
options: BaseTransactionOptions<
|
||||
| AirdropERC20Params
|
||||
| {
|
||||
asyncParams: () => Promise<AirdropERC20Params>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.tokenAddress, resolvedOptions.contents] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
Generated
+198
@@ -0,0 +1,198 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "airdropERC20WithSignature" function.
|
||||
*/
|
||||
export type AirdropERC20WithSignatureParams = WithOverrides<{
|
||||
req: AbiParameterToPrimitiveType<{
|
||||
name: "req";
|
||||
type: "tuple";
|
||||
internalType: "struct Airdrop.AirdropRequestERC20";
|
||||
components: [
|
||||
{ name: "uid"; type: "bytes32"; internalType: "bytes32" },
|
||||
{ name: "tokenAddress"; type: "address"; internalType: "address" },
|
||||
{ name: "expirationTimestamp"; type: "uint256"; internalType: "uint256" },
|
||||
{
|
||||
name: "contents";
|
||||
type: "tuple[]";
|
||||
internalType: "struct Airdrop.AirdropContentERC20[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "amount"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
},
|
||||
];
|
||||
}>;
|
||||
signature: AbiParameterToPrimitiveType<{
|
||||
name: "signature";
|
||||
type: "bytes";
|
||||
internalType: "bytes";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0xaaba07f6" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "req",
|
||||
type: "tuple",
|
||||
internalType: "struct Airdrop.AirdropRequestERC20",
|
||||
components: [
|
||||
{
|
||||
name: "uid",
|
||||
type: "bytes32",
|
||||
internalType: "bytes32",
|
||||
},
|
||||
{
|
||||
name: "tokenAddress",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "expirationTimestamp",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "contents",
|
||||
type: "tuple[]",
|
||||
internalType: "struct Airdrop.AirdropContentERC20[]",
|
||||
components: [
|
||||
{
|
||||
name: "recipient",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "amount",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "signature",
|
||||
type: "bytes",
|
||||
internalType: "bytes",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `airdropERC20WithSignature` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `airdropERC20WithSignature` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isAirdropERC20WithSignatureSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isAirdropERC20WithSignatureSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isAirdropERC20WithSignatureSupported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "airdropERC20WithSignature" function.
|
||||
* @param options - The options for the airdropERC20WithSignature function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC20WithSignatureParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC20WithSignatureParams({
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC20WithSignatureParams(
|
||||
options: AirdropERC20WithSignatureParams,
|
||||
) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.req, options.signature]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "airdropERC20WithSignature" function into a Hex string with its parameters.
|
||||
* @param options - The options for the airdropERC20WithSignature function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC20WithSignature } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC20WithSignature({
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC20WithSignature(
|
||||
options: AirdropERC20WithSignatureParams,
|
||||
) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeAirdropERC20WithSignatureParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "airdropERC20WithSignature" function on the contract.
|
||||
* @param options - The options for the "airdropERC20WithSignature" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC20WithSignature } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = airdropERC20WithSignature({
|
||||
* contract,
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function airdropERC20WithSignature(
|
||||
options: BaseTransactionOptions<
|
||||
| AirdropERC20WithSignatureParams
|
||||
| {
|
||||
asyncParams: () => Promise<AirdropERC20WithSignatureParams>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.req, resolvedOptions.signature] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "airdropERC721" function.
|
||||
*/
|
||||
export type AirdropERC721Params = WithOverrides<{
|
||||
tokenAddress: AbiParameterToPrimitiveType<{
|
||||
name: "_tokenAddress";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
contents: AbiParameterToPrimitiveType<{
|
||||
name: "_contents";
|
||||
type: "tuple[]";
|
||||
internalType: "struct Airdrop.AirdropContentERC721[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "tokenId"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0x6d582ebe" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_tokenAddress",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_contents",
|
||||
type: "tuple[]",
|
||||
internalType: "struct Airdrop.AirdropContentERC721[]",
|
||||
components: [
|
||||
{
|
||||
name: "recipient",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "tokenId",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `airdropERC721` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `airdropERC721` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isAirdropERC721Supported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isAirdropERC721Supported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isAirdropERC721Supported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "airdropERC721" function.
|
||||
* @param options - The options for the airdropERC721 function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC721Params } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC721Params({
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC721Params(options: AirdropERC721Params) {
|
||||
return encodeAbiParameters(FN_INPUTS, [
|
||||
options.tokenAddress,
|
||||
options.contents,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "airdropERC721" function into a Hex string with its parameters.
|
||||
* @param options - The options for the airdropERC721 function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC721 } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC721({
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC721(options: AirdropERC721Params) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeAirdropERC721Params(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "airdropERC721" function on the contract.
|
||||
* @param options - The options for the "airdropERC721" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC721 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = airdropERC721({
|
||||
* contract,
|
||||
* tokenAddress: ...,
|
||||
* contents: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function airdropERC721(
|
||||
options: BaseTransactionOptions<
|
||||
| AirdropERC721Params
|
||||
| {
|
||||
asyncParams: () => Promise<AirdropERC721Params>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.tokenAddress, resolvedOptions.contents] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
Generated
+198
@@ -0,0 +1,198 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "airdropERC721WithSignature" function.
|
||||
*/
|
||||
export type AirdropERC721WithSignatureParams = WithOverrides<{
|
||||
req: AbiParameterToPrimitiveType<{
|
||||
name: "req";
|
||||
type: "tuple";
|
||||
internalType: "struct Airdrop.AirdropRequestERC721";
|
||||
components: [
|
||||
{ name: "uid"; type: "bytes32"; internalType: "bytes32" },
|
||||
{ name: "tokenAddress"; type: "address"; internalType: "address" },
|
||||
{ name: "expirationTimestamp"; type: "uint256"; internalType: "uint256" },
|
||||
{
|
||||
name: "contents";
|
||||
type: "tuple[]";
|
||||
internalType: "struct Airdrop.AirdropContentERC721[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "tokenId"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
},
|
||||
];
|
||||
}>;
|
||||
signature: AbiParameterToPrimitiveType<{
|
||||
name: "signature";
|
||||
type: "bytes";
|
||||
internalType: "bytes";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0xb654a6f3" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "req",
|
||||
type: "tuple",
|
||||
internalType: "struct Airdrop.AirdropRequestERC721",
|
||||
components: [
|
||||
{
|
||||
name: "uid",
|
||||
type: "bytes32",
|
||||
internalType: "bytes32",
|
||||
},
|
||||
{
|
||||
name: "tokenAddress",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "expirationTimestamp",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "contents",
|
||||
type: "tuple[]",
|
||||
internalType: "struct Airdrop.AirdropContentERC721[]",
|
||||
components: [
|
||||
{
|
||||
name: "recipient",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "tokenId",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "signature",
|
||||
type: "bytes",
|
||||
internalType: "bytes",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `airdropERC721WithSignature` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `airdropERC721WithSignature` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isAirdropERC721WithSignatureSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isAirdropERC721WithSignatureSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isAirdropERC721WithSignatureSupported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "airdropERC721WithSignature" function.
|
||||
* @param options - The options for the airdropERC721WithSignature function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC721WithSignatureParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC721WithSignatureParams({
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC721WithSignatureParams(
|
||||
options: AirdropERC721WithSignatureParams,
|
||||
) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.req, options.signature]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "airdropERC721WithSignature" function into a Hex string with its parameters.
|
||||
* @param options - The options for the airdropERC721WithSignature function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropERC721WithSignature } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropERC721WithSignature({
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropERC721WithSignature(
|
||||
options: AirdropERC721WithSignatureParams,
|
||||
) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeAirdropERC721WithSignatureParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "airdropERC721WithSignature" function on the contract.
|
||||
* @param options - The options for the "airdropERC721WithSignature" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC721WithSignature } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = airdropERC721WithSignature({
|
||||
* contract,
|
||||
* req: ...,
|
||||
* signature: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function airdropERC721WithSignature(
|
||||
options: BaseTransactionOptions<
|
||||
| AirdropERC721WithSignatureParams
|
||||
| {
|
||||
asyncParams: () => Promise<AirdropERC721WithSignatureParams>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.req, resolvedOptions.signature] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
Generated
+151
@@ -0,0 +1,151 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "airdropNativeToken" function.
|
||||
*/
|
||||
export type AirdropNativeTokenParams = WithOverrides<{
|
||||
contents: AbiParameterToPrimitiveType<{
|
||||
name: "_contents";
|
||||
type: "tuple[]";
|
||||
internalType: "struct Airdrop.AirdropContentERC20[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "amount"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0x0d5818f7" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_contents",
|
||||
type: "tuple[]",
|
||||
internalType: "struct Airdrop.AirdropContentERC20[]",
|
||||
components: [
|
||||
{
|
||||
name: "recipient",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "amount",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `airdropNativeToken` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `airdropNativeToken` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isAirdropNativeTokenSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isAirdropNativeTokenSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isAirdropNativeTokenSupported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "airdropNativeToken" function.
|
||||
* @param options - The options for the airdropNativeToken function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropNativeTokenParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropNativeTokenParams({
|
||||
* contents: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropNativeTokenParams(
|
||||
options: AirdropNativeTokenParams,
|
||||
) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.contents]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "airdropNativeToken" function into a Hex string with its parameters.
|
||||
* @param options - The options for the airdropNativeToken function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeAirdropNativeToken } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeAirdropNativeToken({
|
||||
* contents: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeAirdropNativeToken(options: AirdropNativeTokenParams) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeAirdropNativeTokenParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "airdropNativeToken" function on the contract.
|
||||
* @param options - The options for the "airdropNativeToken" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropNativeToken } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = airdropNativeToken({
|
||||
* contract,
|
||||
* contents: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function airdropNativeToken(
|
||||
options: BaseTransactionOptions<
|
||||
| AirdropNativeTokenParams
|
||||
| {
|
||||
asyncParams: () => Promise<AirdropNativeTokenParams>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.contents] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "claimERC1155" function.
|
||||
*/
|
||||
export type ClaimERC1155Params = WithOverrides<{
|
||||
token: AbiParameterToPrimitiveType<{
|
||||
name: "_token";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
receiver: AbiParameterToPrimitiveType<{
|
||||
name: "_receiver";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
tokenId: AbiParameterToPrimitiveType<{
|
||||
name: "_tokenId";
|
||||
type: "uint256";
|
||||
internalType: "uint256";
|
||||
}>;
|
||||
quantity: AbiParameterToPrimitiveType<{
|
||||
name: "_quantity";
|
||||
type: "uint256";
|
||||
internalType: "uint256";
|
||||
}>;
|
||||
proofs: AbiParameterToPrimitiveType<{
|
||||
name: "_proofs";
|
||||
type: "bytes32[]";
|
||||
internalType: "bytes32[]";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0xc6fa26ab" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_token",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_receiver",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_tokenId",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_quantity",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_proofs",
|
||||
type: "bytes32[]",
|
||||
internalType: "bytes32[]",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `claimERC1155` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `claimERC1155` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isClaimERC1155Supported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isClaimERC1155Supported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isClaimERC1155Supported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "claimERC1155" function.
|
||||
* @param options - The options for the claimERC1155 function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeClaimERC1155Params } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeClaimERC1155Params({
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* tokenId: ...,
|
||||
* quantity: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeClaimERC1155Params(options: ClaimERC1155Params) {
|
||||
return encodeAbiParameters(FN_INPUTS, [
|
||||
options.token,
|
||||
options.receiver,
|
||||
options.tokenId,
|
||||
options.quantity,
|
||||
options.proofs,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "claimERC1155" function into a Hex string with its parameters.
|
||||
* @param options - The options for the claimERC1155 function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeClaimERC1155 } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeClaimERC1155({
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* tokenId: ...,
|
||||
* quantity: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeClaimERC1155(options: ClaimERC1155Params) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeClaimERC1155Params(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "claimERC1155" function on the contract.
|
||||
* @param options - The options for the "claimERC1155" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { claimERC1155 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = claimERC1155({
|
||||
* contract,
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* tokenId: ...,
|
||||
* quantity: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function claimERC1155(
|
||||
options: BaseTransactionOptions<
|
||||
| ClaimERC1155Params
|
||||
| {
|
||||
asyncParams: () => Promise<ClaimERC1155Params>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [
|
||||
resolvedOptions.token,
|
||||
resolvedOptions.receiver,
|
||||
resolvedOptions.tokenId,
|
||||
resolvedOptions.quantity,
|
||||
resolvedOptions.proofs,
|
||||
] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "claimERC20" function.
|
||||
*/
|
||||
export type ClaimERC20Params = WithOverrides<{
|
||||
token: AbiParameterToPrimitiveType<{
|
||||
name: "_token";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
receiver: AbiParameterToPrimitiveType<{
|
||||
name: "_receiver";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
quantity: AbiParameterToPrimitiveType<{
|
||||
name: "_quantity";
|
||||
type: "uint256";
|
||||
internalType: "uint256";
|
||||
}>;
|
||||
proofs: AbiParameterToPrimitiveType<{
|
||||
name: "_proofs";
|
||||
type: "bytes32[]";
|
||||
internalType: "bytes32[]";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0xecf3d3d4" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_token",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_receiver",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_quantity",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_proofs",
|
||||
type: "bytes32[]",
|
||||
internalType: "bytes32[]",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `claimERC20` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `claimERC20` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isClaimERC20Supported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isClaimERC20Supported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isClaimERC20Supported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "claimERC20" function.
|
||||
* @param options - The options for the claimERC20 function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeClaimERC20Params } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeClaimERC20Params({
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* quantity: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeClaimERC20Params(options: ClaimERC20Params) {
|
||||
return encodeAbiParameters(FN_INPUTS, [
|
||||
options.token,
|
||||
options.receiver,
|
||||
options.quantity,
|
||||
options.proofs,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "claimERC20" function into a Hex string with its parameters.
|
||||
* @param options - The options for the claimERC20 function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeClaimERC20 } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeClaimERC20({
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* quantity: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeClaimERC20(options: ClaimERC20Params) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeClaimERC20Params(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "claimERC20" function on the contract.
|
||||
* @param options - The options for the "claimERC20" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { claimERC20 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = claimERC20({
|
||||
* contract,
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* quantity: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function claimERC20(
|
||||
options: BaseTransactionOptions<
|
||||
| ClaimERC20Params
|
||||
| {
|
||||
asyncParams: () => Promise<ClaimERC20Params>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [
|
||||
resolvedOptions.token,
|
||||
resolvedOptions.receiver,
|
||||
resolvedOptions.quantity,
|
||||
resolvedOptions.proofs,
|
||||
] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "claimERC721" function.
|
||||
*/
|
||||
export type ClaimERC721Params = WithOverrides<{
|
||||
token: AbiParameterToPrimitiveType<{
|
||||
name: "_token";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
receiver: AbiParameterToPrimitiveType<{
|
||||
name: "_receiver";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
tokenId: AbiParameterToPrimitiveType<{
|
||||
name: "_tokenId";
|
||||
type: "uint256";
|
||||
internalType: "uint256";
|
||||
}>;
|
||||
proofs: AbiParameterToPrimitiveType<{
|
||||
name: "_proofs";
|
||||
type: "bytes32[]";
|
||||
internalType: "bytes32[]";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0x1290be10" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_token",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_receiver",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_tokenId",
|
||||
type: "uint256",
|
||||
internalType: "uint256",
|
||||
},
|
||||
{
|
||||
name: "_proofs",
|
||||
type: "bytes32[]",
|
||||
internalType: "bytes32[]",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `claimERC721` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `claimERC721` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isClaimERC721Supported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isClaimERC721Supported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isClaimERC721Supported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "claimERC721" function.
|
||||
* @param options - The options for the claimERC721 function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeClaimERC721Params } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeClaimERC721Params({
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* tokenId: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeClaimERC721Params(options: ClaimERC721Params) {
|
||||
return encodeAbiParameters(FN_INPUTS, [
|
||||
options.token,
|
||||
options.receiver,
|
||||
options.tokenId,
|
||||
options.proofs,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "claimERC721" function into a Hex string with its parameters.
|
||||
* @param options - The options for the claimERC721 function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeClaimERC721 } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeClaimERC721({
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* tokenId: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeClaimERC721(options: ClaimERC721Params) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeClaimERC721Params(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "claimERC721" function on the contract.
|
||||
* @param options - The options for the "claimERC721" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { claimERC721 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = claimERC721({
|
||||
* contract,
|
||||
* token: ...,
|
||||
* receiver: ...,
|
||||
* tokenId: ...,
|
||||
* proofs: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function claimERC721(
|
||||
options: BaseTransactionOptions<
|
||||
| ClaimERC721Params
|
||||
| {
|
||||
asyncParams: () => Promise<ClaimERC721Params>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [
|
||||
resolvedOptions.token,
|
||||
resolvedOptions.receiver,
|
||||
resolvedOptions.tokenId,
|
||||
resolvedOptions.proofs,
|
||||
] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "initialize" function.
|
||||
*/
|
||||
export type InitializeParams = WithOverrides<{
|
||||
defaultAdmin: AbiParameterToPrimitiveType<{
|
||||
name: "_defaultAdmin";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0xc4d66de8" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_defaultAdmin",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `initialize` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `initialize` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isInitializeSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isInitializeSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isInitializeSupported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "initialize" function.
|
||||
* @param options - The options for the initialize function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeInitializeParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeInitializeParams({
|
||||
* defaultAdmin: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeInitializeParams(options: InitializeParams) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.defaultAdmin]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "initialize" function into a Hex string with its parameters.
|
||||
* @param options - The options for the initialize function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeInitialize } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeInitialize({
|
||||
* defaultAdmin: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeInitialize(options: InitializeParams) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeInitializeParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "initialize" function on the contract.
|
||||
* @param options - The options for the "initialize" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { initialize } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = initialize({
|
||||
* contract,
|
||||
* defaultAdmin: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function initialize(
|
||||
options: BaseTransactionOptions<
|
||||
| InitializeParams
|
||||
| {
|
||||
asyncParams: () => Promise<InitializeParams>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.defaultAdmin] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "setContractURI" function.
|
||||
*/
|
||||
export type SetContractURIParams = WithOverrides<{
|
||||
uri: AbiParameterToPrimitiveType<{ type: "string"; name: "_uri" }>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0x938e3d7b" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
type: "string",
|
||||
name: "_uri",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `setContractURI` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `setContractURI` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isSetContractURISupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isSetContractURISupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isSetContractURISupported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "setContractURI" function.
|
||||
* @param options - The options for the setContractURI function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeSetContractURIParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeSetContractURIParams({
|
||||
* uri: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeSetContractURIParams(options: SetContractURIParams) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.uri]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "setContractURI" function into a Hex string with its parameters.
|
||||
* @param options - The options for the setContractURI function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeSetContractURI } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeSetContractURI({
|
||||
* uri: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeSetContractURI(options: SetContractURIParams) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeSetContractURIParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "setContractURI" function on the contract.
|
||||
* @param options - The options for the "setContractURI" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { setContractURI } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = setContractURI({
|
||||
* contract,
|
||||
* uri: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function setContractURI(
|
||||
options: BaseTransactionOptions<
|
||||
| SetContractURIParams
|
||||
| {
|
||||
asyncParams: () => Promise<SetContractURIParams>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.uri] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "setMerkleRoot" function.
|
||||
*/
|
||||
export type SetMerkleRootParams = WithOverrides<{
|
||||
token: AbiParameterToPrimitiveType<{
|
||||
name: "_token";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
tokenMerkleRoot: AbiParameterToPrimitiveType<{
|
||||
name: "_tokenMerkleRoot";
|
||||
type: "bytes32";
|
||||
internalType: "bytes32";
|
||||
}>;
|
||||
resetClaimStatus: AbiParameterToPrimitiveType<{
|
||||
name: "_resetClaimStatus";
|
||||
type: "bool";
|
||||
internalType: "bool";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0x8259a87b" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_token",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
{
|
||||
name: "_tokenMerkleRoot",
|
||||
type: "bytes32",
|
||||
internalType: "bytes32",
|
||||
},
|
||||
{
|
||||
name: "_resetClaimStatus",
|
||||
type: "bool",
|
||||
internalType: "bool",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `setMerkleRoot` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `setMerkleRoot` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isSetMerkleRootSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isSetMerkleRootSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isSetMerkleRootSupported(
|
||||
contract: ThirdwebContract<any>,
|
||||
) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "setMerkleRoot" function.
|
||||
* @param options - The options for the setMerkleRoot function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeSetMerkleRootParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeSetMerkleRootParams({
|
||||
* token: ...,
|
||||
* tokenMerkleRoot: ...,
|
||||
* resetClaimStatus: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeSetMerkleRootParams(options: SetMerkleRootParams) {
|
||||
return encodeAbiParameters(FN_INPUTS, [
|
||||
options.token,
|
||||
options.tokenMerkleRoot,
|
||||
options.resetClaimStatus,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "setMerkleRoot" function into a Hex string with its parameters.
|
||||
* @param options - The options for the setMerkleRoot function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeSetMerkleRoot } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeSetMerkleRoot({
|
||||
* token: ...,
|
||||
* tokenMerkleRoot: ...,
|
||||
* resetClaimStatus: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeSetMerkleRoot(options: SetMerkleRootParams) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeSetMerkleRootParams(options).slice(
|
||||
2,
|
||||
)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "setMerkleRoot" function on the contract.
|
||||
* @param options - The options for the "setMerkleRoot" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { setMerkleRoot } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = setMerkleRoot({
|
||||
* contract,
|
||||
* token: ...,
|
||||
* tokenMerkleRoot: ...,
|
||||
* resetClaimStatus: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function setMerkleRoot(
|
||||
options: BaseTransactionOptions<
|
||||
| SetMerkleRootParams
|
||||
| {
|
||||
asyncParams: () => Promise<SetMerkleRootParams>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [
|
||||
resolvedOptions.token,
|
||||
resolvedOptions.tokenMerkleRoot,
|
||||
resolvedOptions.resetClaimStatus,
|
||||
] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
import type { AbiParameterToPrimitiveType } from "abitype";
|
||||
import type {
|
||||
BaseTransactionOptions,
|
||||
WithOverrides,
|
||||
} from "../../../../../transaction/types.js";
|
||||
import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js";
|
||||
import { encodeAbiParameters } from "../../../../../utils/abi/encodeAbiParameters.js";
|
||||
import { once } from "../../../../../utils/promise/once.js";
|
||||
import type { ThirdwebContract } from "../../../../../contract/contract.js";
|
||||
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
||||
|
||||
/**
|
||||
* Represents the parameters for the "setOwner" function.
|
||||
*/
|
||||
export type SetOwnerParams = WithOverrides<{
|
||||
newOwner: AbiParameterToPrimitiveType<{
|
||||
name: "_newOwner";
|
||||
type: "address";
|
||||
internalType: "address";
|
||||
}>;
|
||||
}>;
|
||||
|
||||
export const FN_SELECTOR = "0x13af4035" as const;
|
||||
const FN_INPUTS = [
|
||||
{
|
||||
name: "_newOwner",
|
||||
type: "address",
|
||||
internalType: "address",
|
||||
},
|
||||
] as const;
|
||||
const FN_OUTPUTS = [] as const;
|
||||
|
||||
/**
|
||||
* Checks if the `setOwner` method is supported by the given contract.
|
||||
* @param contract The ThirdwebContract.
|
||||
* @returns A promise that resolves to a boolean indicating if the `setOwner` method is supported.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { isSetOwnerSupported } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const supported = await isSetOwnerSupported(contract);
|
||||
* ```
|
||||
*/
|
||||
export async function isSetOwnerSupported(contract: ThirdwebContract<any>) {
|
||||
return detectMethod({
|
||||
contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the parameters for the "setOwner" function.
|
||||
* @param options - The options for the setOwner function.
|
||||
* @returns The encoded ABI parameters.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeSetOwnerParams } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeSetOwnerParams({
|
||||
* newOwner: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeSetOwnerParams(options: SetOwnerParams) {
|
||||
return encodeAbiParameters(FN_INPUTS, [options.newOwner]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the "setOwner" function into a Hex string with its parameters.
|
||||
* @param options - The options for the setOwner function.
|
||||
* @returns The encoded hexadecimal string.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { encodeSetOwner } "thirdweb/extensions/airdrop";
|
||||
* const result = encodeSetOwner({
|
||||
* newOwner: ...,
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function encodeSetOwner(options: SetOwnerParams) {
|
||||
// we do a "manual" concat here to avoid the overhead of the "concatHex" function
|
||||
// we can do this because we know the specific formats of the values
|
||||
return (FN_SELECTOR +
|
||||
encodeSetOwnerParams(options).slice(2)) as `${typeof FN_SELECTOR}${string}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the "setOwner" function on the contract.
|
||||
* @param options - The options for the "setOwner" function.
|
||||
* @returns A prepared transaction object.
|
||||
* @extension AIRDROP
|
||||
* @example
|
||||
* ```ts
|
||||
* import { setOwner } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const transaction = setOwner({
|
||||
* contract,
|
||||
* newOwner: ...,
|
||||
* });
|
||||
*
|
||||
* // Send the transaction
|
||||
* ...
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export function setOwner(
|
||||
options: BaseTransactionOptions<
|
||||
| SetOwnerParams
|
||||
| {
|
||||
asyncParams: () => Promise<SetOwnerParams>;
|
||||
}
|
||||
>,
|
||||
) {
|
||||
const asyncOptions = once(async () => {
|
||||
return "asyncParams" in options ? await options.asyncParams() : options;
|
||||
});
|
||||
|
||||
return prepareContractCall({
|
||||
contract: options.contract,
|
||||
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
||||
params: async () => {
|
||||
const resolvedOptions = await asyncOptions();
|
||||
return [resolvedOptions.newOwner] as const;
|
||||
},
|
||||
value: async () => (await asyncOptions()).overrides?.value,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
|
||||
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
|
||||
import {
|
||||
TEST_ACCOUNT_A,
|
||||
TEST_ACCOUNT_B,
|
||||
TEST_ACCOUNT_C,
|
||||
TEST_ACCOUNT_D,
|
||||
} from "../../../../test/src/test-wallets.js";
|
||||
import {
|
||||
type ThirdwebContract,
|
||||
getContract,
|
||||
} from "../../../contract/contract.js";
|
||||
import {
|
||||
balanceOf,
|
||||
setApprovalForAll,
|
||||
} from "../../../exports/extensions/erc1155.js";
|
||||
import { sendTransaction } from "../../../transaction/actions/send-transaction.js";
|
||||
import { mintTo } from "../../erc1155/write/mintTo.js";
|
||||
import { deployERC1155Contract } from "../../prebuilts/deploy-erc1155.js";
|
||||
import { deployPublishedContract } from "../../prebuilts/deploy-published.js";
|
||||
import {
|
||||
airdropERC1155WithSignature,
|
||||
generateAirdropSignatureERC1155,
|
||||
} from "./airdropERC1155WithSignature.js";
|
||||
|
||||
// skip this test suite if there is no secret key available to test with
|
||||
// TODO: remove reliance on secret key during unit tests entirely
|
||||
describe.runIf(process.env.TW_SECRET_KEY)(
|
||||
"generateAirdropSignatureERC11551155",
|
||||
() => {
|
||||
let airdropContract: ThirdwebContract;
|
||||
let erc1155TokenContract: ThirdwebContract;
|
||||
|
||||
beforeAll(async () => {
|
||||
airdropContract = getContract({
|
||||
address: await deployPublishedContract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
contractId: "Airdrop",
|
||||
contractParams: [TEST_ACCOUNT_A.address],
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
erc1155TokenContract = getContract({
|
||||
address: await deployERC1155Contract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
params: {
|
||||
name: "Test",
|
||||
symbol: "TST",
|
||||
},
|
||||
type: "TokenERC1155",
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
const mintTransactions = [
|
||||
mintTo({
|
||||
contract: erc1155TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
supply: 100000n,
|
||||
nft: {
|
||||
name: "Test 0",
|
||||
},
|
||||
}),
|
||||
mintTo({
|
||||
contract: erc1155TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
supply: 100000n,
|
||||
nft: {
|
||||
name: "Test 1",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
for (const tx of mintTransactions) {
|
||||
await sendTransaction({
|
||||
transaction: tx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}
|
||||
|
||||
const approvalTx = setApprovalForAll({
|
||||
contract: erc1155TokenContract,
|
||||
operator: airdropContract.address,
|
||||
approved: true,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: approvalTx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
it("should send airdrop of ERC1155 tokens with signature", async () => {
|
||||
const contents = [
|
||||
{ recipient: TEST_ACCOUNT_B.address, tokenId: 0n, amount: 10n },
|
||||
{ recipient: TEST_ACCOUNT_C.address, tokenId: 0n, amount: 12n },
|
||||
{ recipient: TEST_ACCOUNT_D.address, tokenId: 1n, amount: 5n },
|
||||
];
|
||||
const { req, signature } = await generateAirdropSignatureERC1155({
|
||||
airdropRequest: {
|
||||
tokenAddress: erc1155TokenContract.address,
|
||||
contents,
|
||||
},
|
||||
account: TEST_ACCOUNT_A,
|
||||
contract: airdropContract,
|
||||
});
|
||||
|
||||
const transaction = airdropERC1155WithSignature({
|
||||
contract: airdropContract,
|
||||
req,
|
||||
signature,
|
||||
});
|
||||
const { transactionHash } = await sendTransaction({
|
||||
transaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const balanceB = await balanceOf({
|
||||
contract: erc1155TokenContract,
|
||||
owner: TEST_ACCOUNT_B.address,
|
||||
tokenId: 0n,
|
||||
});
|
||||
|
||||
const balanceC = await balanceOf({
|
||||
contract: erc1155TokenContract,
|
||||
owner: TEST_ACCOUNT_C.address,
|
||||
tokenId: 0n,
|
||||
});
|
||||
|
||||
const balanceD = await balanceOf({
|
||||
contract: erc1155TokenContract,
|
||||
owner: TEST_ACCOUNT_D.address,
|
||||
tokenId: 1n,
|
||||
});
|
||||
|
||||
expect(balanceB).to.equal(10n);
|
||||
expect(balanceC).to.equal(12n);
|
||||
expect(balanceD).to.equal(5n);
|
||||
|
||||
expect(transactionHash.length).toBe(66);
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,143 @@
|
||||
import type { AbiParameterToPrimitiveType, Address } from "abitype";
|
||||
import type { ThirdwebContract } from "../../../contract/contract.js";
|
||||
import { dateToSeconds, tenYearsFromNow } from "../../../utils/date.js";
|
||||
import type { Hex } from "../../../utils/encoding/hex.js";
|
||||
import { randomBytes32 } from "../../../utils/uuid.js";
|
||||
import type { Account } from "../../../wallets/interfaces/wallet.js";
|
||||
import { airdropERC1155WithSignature as generatedAirdropERC1155WithSignature } from "../__generated__/Airdrop/write/airdropERC1155WithSignature.js";
|
||||
|
||||
/**
|
||||
* Airdrops ERC1155 tokens to a list of recipients, with the request signed by admin
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC1155WithSignature, generateAirdropSignatureERC1155 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const { req, signature } = await generateAirdropSignatureERC1155(...)
|
||||
*
|
||||
* const transaction = airdropERC1155WithSignature({
|
||||
* contract,
|
||||
* req,
|
||||
* signature,
|
||||
* });
|
||||
* await sendTransaction({ transaction, account });
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the transaction result.
|
||||
*/
|
||||
export const airdropERC1155WithSignature = generatedAirdropERC1155WithSignature;
|
||||
|
||||
export type GenerateAirdropSignatureOptions = {
|
||||
account: Account;
|
||||
contract: ThirdwebContract;
|
||||
airdropRequest: GenerateReqInput;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates the req and signature for sending ERC1155 airdrop.
|
||||
* @param options - The options for the airdrop.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC1155WithSignature, generateAirdropSignatureERC1155 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* // list of recipients, tokenIds and amounts to airdrop for each recipient
|
||||
* const contents = [
|
||||
* { recipient: "0x...", tokenId: 0, amount: 10n },
|
||||
* { recipient: "0x...", tokenId: 0, amount: 15n },
|
||||
* { recipient: "0x...", tokenId: 0, amount: 20n },
|
||||
* ];
|
||||
*
|
||||
* const { req, signature } = await generateAirdropSignatureERC1155({
|
||||
* account,
|
||||
* contract,
|
||||
* airdropRequest: {
|
||||
* tokenAddress: "0x...", // address of the ERC1155 token to airdrop
|
||||
* contents
|
||||
* },
|
||||
* });
|
||||
*
|
||||
* const transaction = airdropERC1155WithSignature({
|
||||
* contract,
|
||||
* req,
|
||||
* signature,
|
||||
* });
|
||||
* await sendTransaction({ transaction, account });
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the req and signature.
|
||||
*/
|
||||
export async function generateAirdropSignatureERC1155(
|
||||
options: GenerateAirdropSignatureOptions,
|
||||
) {
|
||||
const { airdropRequest, account, contract } = options;
|
||||
const tokenAddress = airdropRequest.tokenAddress;
|
||||
const contents = airdropRequest.contents;
|
||||
const uid = airdropRequest.uid || (await randomBytes32());
|
||||
const endTime = airdropRequest.expirationTimestamp || tenYearsFromNow();
|
||||
|
||||
const req: ReqType = {
|
||||
uid,
|
||||
tokenAddress,
|
||||
expirationTimestamp: dateToSeconds(endTime),
|
||||
contents,
|
||||
};
|
||||
|
||||
const signature = await account.signTypedData({
|
||||
domain: {
|
||||
name: "Airdrop",
|
||||
version: "1",
|
||||
chainId: contract.chain.id,
|
||||
verifyingContract: contract.address as Hex,
|
||||
},
|
||||
types: { AirdropRequestERC1155, AirdropContentERC1155 },
|
||||
primaryType: "AirdropRequestERC1155",
|
||||
message: req,
|
||||
});
|
||||
return { req, signature };
|
||||
}
|
||||
|
||||
type ContentType = AbiParameterToPrimitiveType<{
|
||||
type: "tuple[]";
|
||||
name: "contents";
|
||||
components: typeof AirdropContentERC1155;
|
||||
}>;
|
||||
|
||||
type ReqType = AbiParameterToPrimitiveType<{
|
||||
type: "tuple";
|
||||
name: "req";
|
||||
components: [
|
||||
{ name: "uid"; type: "bytes32"; internalType: "bytes32" },
|
||||
{ name: "tokenAddress"; type: "address"; internalType: "address" },
|
||||
{ name: "expirationTimestamp"; type: "uint256"; internalType: "uint256" },
|
||||
{
|
||||
name: "contents";
|
||||
type: "tuple[]";
|
||||
internalType: "struct Airdrop.AirdropContentERC1155[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "tokenId"; type: "uint256"; internalType: "uint256" },
|
||||
{ name: "amount"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
},
|
||||
];
|
||||
}>;
|
||||
|
||||
type GenerateReqInput = {
|
||||
uid?: Hex;
|
||||
tokenAddress: Address;
|
||||
expirationTimestamp?: Date;
|
||||
contents: ContentType;
|
||||
};
|
||||
|
||||
export const AirdropContentERC1155 = [
|
||||
{ name: "recipient", type: "address" },
|
||||
{ name: "tokenId", type: "uint256" },
|
||||
{ name: "amount", type: "uint256" },
|
||||
] as const;
|
||||
|
||||
export const AirdropRequestERC1155 = [
|
||||
{ name: "uid", type: "bytes32" },
|
||||
{ name: "tokenAddress", type: "address" },
|
||||
{ name: "expirationTimestamp", type: "uint256" },
|
||||
{ name: "contents", type: "AirdropContentERC1155[]" },
|
||||
] as const;
|
||||
@@ -0,0 +1,144 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
|
||||
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
|
||||
import {
|
||||
TEST_ACCOUNT_A,
|
||||
TEST_ACCOUNT_B,
|
||||
TEST_ACCOUNT_C,
|
||||
TEST_ACCOUNT_D,
|
||||
} from "../../../../test/src/test-wallets.js";
|
||||
import {
|
||||
type ThirdwebContract,
|
||||
getContract,
|
||||
} from "../../../contract/contract.js";
|
||||
import { sendTransaction } from "../../../transaction/actions/send-transaction.js";
|
||||
import { getBalance } from "../../erc20/read/getBalance.js";
|
||||
import { approve } from "../../erc20/write/approve.js";
|
||||
import { mintTo } from "../../erc20/write/mintTo.js";
|
||||
import { deployERC20Contract } from "../../prebuilts/deploy-erc20.js";
|
||||
import { deployPublishedContract } from "../../prebuilts/deploy-published.js";
|
||||
import {
|
||||
airdropERC20WithSignature,
|
||||
generateAirdropSignatureERC20,
|
||||
} from "./airdropERC20WithSignature.js";
|
||||
|
||||
// skip this test suite if there is no secret key available to test with
|
||||
// TODO: remove reliance on secret key during unit tests entirely
|
||||
describe.runIf(process.env.TW_SECRET_KEY)(
|
||||
"generateAirdropSignatureERC2020",
|
||||
() => {
|
||||
let airdropContract: ThirdwebContract;
|
||||
let erc20TokenContract: ThirdwebContract;
|
||||
|
||||
beforeAll(async () => {
|
||||
airdropContract = getContract({
|
||||
address: await deployPublishedContract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
contractId: "Airdrop",
|
||||
contractParams: [TEST_ACCOUNT_A.address],
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
erc20TokenContract = getContract({
|
||||
address: await deployERC20Contract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
params: {
|
||||
name: "TestToken",
|
||||
symbol: "TSTT",
|
||||
},
|
||||
type: "TokenERC20",
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
const mintTx = mintTo({
|
||||
contract: erc20TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
amountWei: 1000n,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: mintTx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const approvalTx = await approve({
|
||||
contract: erc20TokenContract,
|
||||
spender: airdropContract.address,
|
||||
amountWei: 1000n,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: approvalTx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
it("should send airdrop of ERC20 tokens with signature", async () => {
|
||||
const contents = [
|
||||
{ recipient: TEST_ACCOUNT_B.address, amount: 10n },
|
||||
{ recipient: TEST_ACCOUNT_C.address, amount: 15n },
|
||||
{ recipient: TEST_ACCOUNT_D.address, amount: 20n },
|
||||
];
|
||||
const { req, signature } = await generateAirdropSignatureERC20({
|
||||
airdropRequest: {
|
||||
tokenAddress: erc20TokenContract.address,
|
||||
contents,
|
||||
},
|
||||
account: TEST_ACCOUNT_A,
|
||||
contract: airdropContract,
|
||||
});
|
||||
|
||||
const transaction = airdropERC20WithSignature({
|
||||
contract: airdropContract,
|
||||
req,
|
||||
signature,
|
||||
});
|
||||
const { transactionHash } = await sendTransaction({
|
||||
transaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const balanceB = (
|
||||
await getBalance({
|
||||
contract: erc20TokenContract,
|
||||
address: TEST_ACCOUNT_B.address,
|
||||
})
|
||||
).value;
|
||||
|
||||
const balanceC = (
|
||||
await getBalance({
|
||||
contract: erc20TokenContract,
|
||||
address: TEST_ACCOUNT_C.address,
|
||||
})
|
||||
).value;
|
||||
|
||||
const balanceD = (
|
||||
await getBalance({
|
||||
contract: erc20TokenContract,
|
||||
address: TEST_ACCOUNT_D.address,
|
||||
})
|
||||
).value;
|
||||
|
||||
// admin balance
|
||||
const balanceA = (
|
||||
await getBalance({
|
||||
contract: erc20TokenContract,
|
||||
address: TEST_ACCOUNT_A.address,
|
||||
})
|
||||
).value;
|
||||
|
||||
expect(balanceB).to.equal(10n);
|
||||
expect(balanceC).to.equal(15n);
|
||||
expect(balanceD).to.equal(20n);
|
||||
|
||||
expect(balanceA).to.equal(1000n - balanceB - balanceC - balanceD);
|
||||
|
||||
expect(transactionHash.length).toBe(66);
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,141 @@
|
||||
import type { AbiParameterToPrimitiveType, Address } from "abitype";
|
||||
import type { ThirdwebContract } from "../../../contract/contract.js";
|
||||
import { dateToSeconds, tenYearsFromNow } from "../../../utils/date.js";
|
||||
import type { Hex } from "../../../utils/encoding/hex.js";
|
||||
import { randomBytes32 } from "../../../utils/uuid.js";
|
||||
import type { Account } from "../../../wallets/interfaces/wallet.js";
|
||||
import { airdropERC20WithSignature as generatedAirdropERC20WithSignature } from "../__generated__/Airdrop/write/airdropERC20WithSignature.js";
|
||||
|
||||
/**
|
||||
* Airdrops ERC20 tokens to a list of recipients, with the request signed by admin
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC20WithSignature, generateAirdropSignatureERC20 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const { req, signature } = await generateAirdropSignatureERC20(...)
|
||||
*
|
||||
* const transaction = airdropERC20WithSignature({
|
||||
* contract,
|
||||
* req,
|
||||
* signature,
|
||||
* });
|
||||
* await sendTransaction({ transaction, account });
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the transaction result.
|
||||
*/
|
||||
export const airdropERC20WithSignature = generatedAirdropERC20WithSignature;
|
||||
|
||||
export type GenerateAirdropSignatureOptions = {
|
||||
account: Account;
|
||||
contract: ThirdwebContract;
|
||||
airdropRequest: GenerateReqInput;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates the req and signature for sending ERC20 airdrop.
|
||||
* @param options - The options for the airdrop.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC20WithSignature, generateAirdropSignatureERC20 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* // list of recipients and amounts to airdrop for each recipient
|
||||
* const contents = [
|
||||
* { recipient: "0x...", amount: 10n }, // amount in wei
|
||||
* { recipient: "0x...", amount: 15n }, // amount in wei
|
||||
* { recipient: "0x...", amount: 20n }, // amount in wei
|
||||
* ];
|
||||
*
|
||||
* const { req, signature } = await generateAirdropSignatureERC20({
|
||||
* account,
|
||||
* contract,
|
||||
* airdropRequest: {
|
||||
* tokenAddress: "0x...", // address of the ERC20 token to airdrop
|
||||
* contents
|
||||
* },
|
||||
* });
|
||||
*
|
||||
* const transaction = airdropERC20WithSignature({
|
||||
* contract,
|
||||
* req,
|
||||
* signature,
|
||||
* });
|
||||
* await sendTransaction({ transaction, account });
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the req and signature.
|
||||
*/
|
||||
export async function generateAirdropSignatureERC20(
|
||||
options: GenerateAirdropSignatureOptions,
|
||||
) {
|
||||
const { airdropRequest, account, contract } = options;
|
||||
const tokenAddress = airdropRequest.tokenAddress;
|
||||
const contents = airdropRequest.contents;
|
||||
const uid = airdropRequest.uid || (await randomBytes32());
|
||||
|
||||
const endTime = airdropRequest.expirationTimestamp || tenYearsFromNow();
|
||||
|
||||
const req: ReqType = {
|
||||
uid,
|
||||
tokenAddress,
|
||||
expirationTimestamp: dateToSeconds(endTime),
|
||||
contents,
|
||||
};
|
||||
|
||||
const signature = await account.signTypedData({
|
||||
domain: {
|
||||
name: "Airdrop",
|
||||
version: "1",
|
||||
chainId: contract.chain.id,
|
||||
verifyingContract: contract.address as Hex,
|
||||
},
|
||||
types: { AirdropRequestERC20, AirdropContentERC20 },
|
||||
primaryType: "AirdropRequestERC20",
|
||||
message: req,
|
||||
});
|
||||
return { req, signature };
|
||||
}
|
||||
|
||||
type ContentType = AbiParameterToPrimitiveType<{
|
||||
type: "tuple[]";
|
||||
name: "contents";
|
||||
components: typeof AirdropContentERC20;
|
||||
}>;
|
||||
|
||||
type ReqType = AbiParameterToPrimitiveType<{
|
||||
type: "tuple";
|
||||
name: "req";
|
||||
components: [
|
||||
{ name: "uid"; type: "bytes32"; internalType: "bytes32" },
|
||||
{ name: "tokenAddress"; type: "address"; internalType: "address" },
|
||||
{ name: "expirationTimestamp"; type: "uint256"; internalType: "uint256" },
|
||||
{
|
||||
name: "contents";
|
||||
type: "tuple[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "amount"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
},
|
||||
];
|
||||
}>;
|
||||
|
||||
type GenerateReqInput = {
|
||||
uid?: Hex;
|
||||
tokenAddress: Address;
|
||||
expirationTimestamp?: Date;
|
||||
contents: ContentType;
|
||||
};
|
||||
|
||||
export const AirdropContentERC20 = [
|
||||
{ name: "recipient", type: "address" },
|
||||
{ name: "amount", type: "uint256" },
|
||||
] as const;
|
||||
|
||||
export const AirdropRequestERC20 = [
|
||||
{ name: "uid", type: "bytes32" },
|
||||
{ name: "tokenAddress", type: "address" },
|
||||
{ name: "expirationTimestamp", type: "uint256" },
|
||||
{ name: "contents", type: "AirdropContentERC20[]" },
|
||||
] as const;
|
||||
@@ -0,0 +1,159 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
|
||||
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
|
||||
import {
|
||||
TEST_ACCOUNT_A,
|
||||
TEST_ACCOUNT_B,
|
||||
TEST_ACCOUNT_C,
|
||||
TEST_ACCOUNT_D,
|
||||
} from "../../../../test/src/test-wallets.js";
|
||||
import {
|
||||
type ThirdwebContract,
|
||||
getContract,
|
||||
} from "../../../contract/contract.js";
|
||||
import {
|
||||
ownerOf,
|
||||
setApprovalForAll,
|
||||
} from "../../../exports/extensions/erc721.js";
|
||||
import { sendTransaction } from "../../../transaction/actions/send-transaction.js";
|
||||
import { mintTo } from "../../erc721/write/mintTo.js";
|
||||
import { deployERC721Contract } from "../../prebuilts/deploy-erc721.js";
|
||||
import { deployPublishedContract } from "../../prebuilts/deploy-published.js";
|
||||
import {
|
||||
airdropERC721WithSignature,
|
||||
generateAirdropSignatureERC721,
|
||||
} from "./airdropERC721WithSignature.js";
|
||||
|
||||
// skip this test suite if there is no secret key available to test with
|
||||
// TODO: remove reliance on secret key during unit tests entirely
|
||||
describe.runIf(process.env.TW_SECRET_KEY)(
|
||||
"generateAirdropSignatureERC721721",
|
||||
() => {
|
||||
let airdropContract: ThirdwebContract;
|
||||
let erc721TokenContract: ThirdwebContract;
|
||||
|
||||
beforeAll(async () => {
|
||||
airdropContract = getContract({
|
||||
address: await deployPublishedContract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
contractId: "Airdrop",
|
||||
contractParams: [TEST_ACCOUNT_A.address],
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
erc721TokenContract = getContract({
|
||||
address: await deployERC721Contract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
params: {
|
||||
name: "Test",
|
||||
symbol: "TST",
|
||||
},
|
||||
type: "TokenERC721",
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
const mintTransactions = [
|
||||
mintTo({
|
||||
contract: erc721TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
nft: {
|
||||
name: "Test 0",
|
||||
},
|
||||
}),
|
||||
mintTo({
|
||||
contract: erc721TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
nft: {
|
||||
name: "Test 1",
|
||||
},
|
||||
}),
|
||||
mintTo({
|
||||
contract: erc721TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
nft: {
|
||||
name: "Test 2",
|
||||
},
|
||||
}),
|
||||
mintTo({
|
||||
contract: erc721TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
nft: {
|
||||
name: "Test 3",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
for (const tx of mintTransactions) {
|
||||
await sendTransaction({
|
||||
transaction: tx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}
|
||||
|
||||
const approvalTx = setApprovalForAll({
|
||||
contract: erc721TokenContract,
|
||||
operator: airdropContract.address,
|
||||
approved: true,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: approvalTx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
it("should send airdrop of ERC721 tokens with signature", async () => {
|
||||
const contents = [
|
||||
{ recipient: TEST_ACCOUNT_B.address, tokenId: 0n },
|
||||
{ recipient: TEST_ACCOUNT_C.address, tokenId: 1n },
|
||||
{ recipient: TEST_ACCOUNT_D.address, tokenId: 2n },
|
||||
];
|
||||
const { req, signature } = await generateAirdropSignatureERC721({
|
||||
airdropRequest: {
|
||||
tokenAddress: erc721TokenContract.address,
|
||||
contents,
|
||||
},
|
||||
account: TEST_ACCOUNT_A,
|
||||
contract: airdropContract,
|
||||
});
|
||||
|
||||
const transaction = airdropERC721WithSignature({
|
||||
contract: airdropContract,
|
||||
req,
|
||||
signature,
|
||||
});
|
||||
const { transactionHash } = await sendTransaction({
|
||||
transaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const ownerZero = await ownerOf({
|
||||
contract: erc721TokenContract,
|
||||
tokenId: 0n,
|
||||
});
|
||||
|
||||
const ownerOne = await ownerOf({
|
||||
contract: erc721TokenContract,
|
||||
tokenId: 1n,
|
||||
});
|
||||
|
||||
const ownerTwo = await ownerOf({
|
||||
contract: erc721TokenContract,
|
||||
tokenId: 2n,
|
||||
});
|
||||
|
||||
expect(ownerZero).to.equal(TEST_ACCOUNT_B.address);
|
||||
expect(ownerOne).to.equal(TEST_ACCOUNT_C.address);
|
||||
expect(ownerTwo).to.equal(TEST_ACCOUNT_D.address);
|
||||
|
||||
expect(transactionHash.length).toBe(66);
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,140 @@
|
||||
import type { AbiParameterToPrimitiveType, Address } from "abitype";
|
||||
import type { ThirdwebContract } from "../../../contract/contract.js";
|
||||
import { dateToSeconds, tenYearsFromNow } from "../../../utils/date.js";
|
||||
import type { Hex } from "../../../utils/encoding/hex.js";
|
||||
import { randomBytes32 } from "../../../utils/uuid.js";
|
||||
import type { Account } from "../../../wallets/interfaces/wallet.js";
|
||||
import { airdropERC721WithSignature as generatedAirdropERC721WithSignature } from "../__generated__/Airdrop/write/airdropERC721WithSignature.js";
|
||||
|
||||
/**
|
||||
* Airdrops ERC721 tokens to a list of recipients, with the request signed by admin
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC721WithSignature, generateAirdropSignatureERC721 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const { req, signature } = await generateAirdropSignatureERC721(...)
|
||||
*
|
||||
* const transaction = airdropERC721WithSignature({
|
||||
* contract,
|
||||
* req,
|
||||
* signature,
|
||||
* });
|
||||
* await sendTransaction({ transaction, account });
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the transaction result.
|
||||
*/
|
||||
export const airdropERC721WithSignature = generatedAirdropERC721WithSignature;
|
||||
|
||||
export type GenerateAirdropSignatureOptions = {
|
||||
account: Account;
|
||||
contract: ThirdwebContract;
|
||||
airdropRequest: GenerateReqInput;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates the req and signature for sending ERC721 airdrop.
|
||||
* @param options - The options for the airdrop.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { airdropERC721WithSignature, generateAirdropSignatureERC721 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* // list of recipients and tokenIds to airdrop for each recipient
|
||||
* const contents = [
|
||||
* { recipient: "0x...", tokenId: 0 },
|
||||
* { recipient: "0x...", tokenId: 1 },
|
||||
* { recipient: "0x...", tokenId: 2 },
|
||||
* ];
|
||||
*
|
||||
* const { req, signature } = await generateAirdropSignatureERC721({
|
||||
* account,
|
||||
* contract,
|
||||
* airdropRequest: {
|
||||
* tokenAddress: "0x...", // address of the ERC721 token to airdrop
|
||||
* contents
|
||||
* },
|
||||
* });
|
||||
*
|
||||
* const transaction = airdropERC721WithSignature({
|
||||
* contract,
|
||||
* req,
|
||||
* signature,
|
||||
* });
|
||||
* await sendTransaction({ transaction, account });
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the req and signature.
|
||||
*/
|
||||
export async function generateAirdropSignatureERC721(
|
||||
options: GenerateAirdropSignatureOptions,
|
||||
) {
|
||||
const { airdropRequest, account, contract } = options;
|
||||
const tokenAddress = airdropRequest.tokenAddress;
|
||||
const contents = airdropRequest.contents;
|
||||
const uid = airdropRequest.uid || (await randomBytes32());
|
||||
const endTime = airdropRequest.expirationTimestamp || tenYearsFromNow();
|
||||
|
||||
const req: ReqType = {
|
||||
uid,
|
||||
tokenAddress,
|
||||
expirationTimestamp: dateToSeconds(endTime),
|
||||
contents,
|
||||
};
|
||||
|
||||
const signature = await account.signTypedData({
|
||||
domain: {
|
||||
name: "Airdrop",
|
||||
version: "1",
|
||||
chainId: contract.chain.id,
|
||||
verifyingContract: contract.address as Hex,
|
||||
},
|
||||
types: { AirdropRequestERC721, AirdropContentERC721 },
|
||||
primaryType: "AirdropRequestERC721",
|
||||
message: req,
|
||||
});
|
||||
return { req, signature };
|
||||
}
|
||||
|
||||
type ContentType = AbiParameterToPrimitiveType<{
|
||||
type: "tuple[]";
|
||||
name: "contents";
|
||||
components: typeof AirdropContentERC721;
|
||||
}>;
|
||||
|
||||
type ReqType = AbiParameterToPrimitiveType<{
|
||||
type: "tuple";
|
||||
name: "req";
|
||||
components: [
|
||||
{ name: "uid"; type: "bytes32"; internalType: "bytes32" },
|
||||
{ name: "tokenAddress"; type: "address"; internalType: "address" },
|
||||
{ name: "expirationTimestamp"; type: "uint256"; internalType: "uint256" },
|
||||
{
|
||||
name: "contents";
|
||||
type: "tuple[]";
|
||||
components: [
|
||||
{ name: "recipient"; type: "address"; internalType: "address" },
|
||||
{ name: "tokenId"; type: "uint256"; internalType: "uint256" },
|
||||
];
|
||||
},
|
||||
];
|
||||
}>;
|
||||
|
||||
type GenerateReqInput = {
|
||||
uid?: Hex;
|
||||
tokenAddress: Address;
|
||||
expirationTimestamp?: Date;
|
||||
contents: ContentType;
|
||||
};
|
||||
|
||||
export const AirdropContentERC721 = [
|
||||
{ name: "recipient", type: "address" },
|
||||
{ name: "tokenId", type: "uint256" },
|
||||
] as const;
|
||||
|
||||
export const AirdropRequestERC721 = [
|
||||
{ name: "uid", type: "bytes32" },
|
||||
{ name: "tokenAddress", type: "address" },
|
||||
{ name: "expirationTimestamp", type: "uint256" },
|
||||
{ name: "contents", type: "AirdropContentERC721[]" },
|
||||
] as const;
|
||||
@@ -0,0 +1,152 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
|
||||
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
|
||||
import {
|
||||
TEST_ACCOUNT_A,
|
||||
TEST_ACCOUNT_B,
|
||||
TEST_ACCOUNT_C,
|
||||
TEST_ACCOUNT_D,
|
||||
} from "../../../../test/src/test-wallets.js";
|
||||
import {
|
||||
type ThirdwebContract,
|
||||
getContract,
|
||||
} from "../../../contract/contract.js";
|
||||
import {
|
||||
balanceOf,
|
||||
setApprovalForAll,
|
||||
} from "../../../exports/extensions/erc1155.js";
|
||||
import { sendTransaction } from "../../../transaction/actions/send-transaction.js";
|
||||
import { mintTo } from "../../erc1155/write/mintTo.js";
|
||||
import { deployERC1155Contract } from "../../prebuilts/deploy-erc1155.js";
|
||||
import { deployPublishedContract } from "../../prebuilts/deploy-published.js";
|
||||
import { setMerkleRoot } from "../__generated__/Airdrop/write/setMerkleRoot.js";
|
||||
import { claimERC1155 } from "./claimERC1155.js";
|
||||
import { generateMerkleTreeInfoERC1155 } from "./merkleInfoERC1155.js";
|
||||
import { saveSnapshot } from "./saveSnapshot.js";
|
||||
|
||||
// skip this test suite if there is no secret key available to test with
|
||||
// TODO: remove reliance on secret key during unit tests entirely
|
||||
describe.runIf(process.env.TW_SECRET_KEY)("claimERC1155", () => {
|
||||
let airdropContract: ThirdwebContract;
|
||||
let erc1155TokenContract: ThirdwebContract;
|
||||
|
||||
beforeAll(async () => {
|
||||
airdropContract = getContract({
|
||||
address: await deployPublishedContract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
contractId: "Airdrop",
|
||||
publisher: "0xFD78F7E2dF2B8c3D5bff0413c96f3237500898B3",
|
||||
contractParams: [TEST_ACCOUNT_A.address, ""],
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
erc1155TokenContract = getContract({
|
||||
address: await deployERC1155Contract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
params: {
|
||||
name: "Test",
|
||||
symbol: "TST",
|
||||
},
|
||||
type: "TokenERC1155",
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
const mintTransactions = [
|
||||
mintTo({
|
||||
contract: erc1155TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
supply: 100000n,
|
||||
nft: {
|
||||
name: "Test 0",
|
||||
},
|
||||
}),
|
||||
mintTo({
|
||||
contract: erc1155TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
supply: 100000n,
|
||||
nft: {
|
||||
name: "Test 1",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
for (const tx of mintTransactions) {
|
||||
await sendTransaction({
|
||||
transaction: tx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}
|
||||
|
||||
const approvalTx = setApprovalForAll({
|
||||
contract: erc1155TokenContract,
|
||||
operator: airdropContract.address,
|
||||
approved: true,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: approvalTx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
it("should send ERC1155 tokens to allowlisted claimer", async () => {
|
||||
const snapshot = [
|
||||
{ recipient: TEST_ACCOUNT_B.address, tokenId: 0, amount: 10 },
|
||||
{ recipient: TEST_ACCOUNT_C.address, tokenId: 0, amount: 12 },
|
||||
{ recipient: TEST_ACCOUNT_D.address, tokenId: 1, amount: 5 },
|
||||
];
|
||||
|
||||
const { merkleRoot, snapshotUri } = await generateMerkleTreeInfoERC1155({
|
||||
snapshot,
|
||||
tokenAddress: erc1155TokenContract.address,
|
||||
contract: airdropContract,
|
||||
});
|
||||
const saveSnapshotTransaction = saveSnapshot({
|
||||
merkleRoot,
|
||||
snapshotUri,
|
||||
contract: airdropContract,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: saveSnapshotTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const setMerkleRootTransaction = setMerkleRoot({
|
||||
token: erc1155TokenContract.address,
|
||||
tokenMerkleRoot: merkleRoot as `0x${string}`,
|
||||
resetClaimStatus: true,
|
||||
contract: airdropContract,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: setMerkleRootTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const claimTransaction = claimERC1155({
|
||||
tokenAddress: erc1155TokenContract.address,
|
||||
recipient: TEST_ACCOUNT_B.address,
|
||||
contract: airdropContract,
|
||||
});
|
||||
const { transactionHash } = await sendTransaction({
|
||||
transaction: claimTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const balanceB = await balanceOf({
|
||||
contract: erc1155TokenContract,
|
||||
owner: TEST_ACCOUNT_B.address,
|
||||
tokenId: 0n,
|
||||
});
|
||||
|
||||
expect(balanceB).to.equal(10n);
|
||||
|
||||
expect(transactionHash.length).toBe(66);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,66 @@
|
||||
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
||||
import type { Address } from "../../../utils/address.js";
|
||||
import { fetchProofsERC1155 } from "../../../utils/extensions/airdrop/fetch-proofs-erc1155.js";
|
||||
import { tokenMerkleRoot } from "../__generated__/Airdrop/read/tokenMerkleRoot.js";
|
||||
import { claimERC1155 as generatedClaimERC1155 } from "../__generated__/Airdrop/write/claimERC1155.js";
|
||||
|
||||
export type ClaimERC1155Params = {
|
||||
tokenAddress: string;
|
||||
recipient: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Claim airdrop of ERC1155 tokens for allowlisted addresses. (Pull based airdrop)
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { claimERC1155 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const tokenAddress = "0x..." // Address of airdropped tokens to claim
|
||||
* const recipient = "0x..." // Address of the allowlisted recipient
|
||||
*
|
||||
* const claimTransaction = claimERC1155({
|
||||
* contract,
|
||||
* tokenAddress,
|
||||
* recipient
|
||||
* });
|
||||
*
|
||||
* await sendTransaction({ claimTransaction, account });
|
||||
*
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the transaction result.
|
||||
*/
|
||||
export function claimERC1155(
|
||||
options: BaseTransactionOptions<ClaimERC1155Params>,
|
||||
) {
|
||||
return generatedClaimERC1155({
|
||||
contract: options.contract,
|
||||
asyncParams: async () => {
|
||||
const merkleRoot = await tokenMerkleRoot({
|
||||
contract: options.contract,
|
||||
tokenAddress: options.tokenAddress,
|
||||
});
|
||||
|
||||
const tokenAddress = options.tokenAddress;
|
||||
|
||||
const merkleProof = await fetchProofsERC1155({
|
||||
contract: options.contract,
|
||||
recipient: options.recipient,
|
||||
merkleRoot,
|
||||
});
|
||||
|
||||
if (!merkleProof) {
|
||||
throw new Error("Proof not found for recipient address");
|
||||
}
|
||||
|
||||
return {
|
||||
token: tokenAddress as Address,
|
||||
receiver: merkleProof.recipient as Address,
|
||||
tokenId: merkleProof.tokenId,
|
||||
quantity: merkleProof.quantity,
|
||||
proofs: merkleProof.proof,
|
||||
} as const;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
|
||||
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
|
||||
import {
|
||||
TEST_ACCOUNT_A,
|
||||
TEST_ACCOUNT_B,
|
||||
TEST_ACCOUNT_C,
|
||||
TEST_ACCOUNT_D,
|
||||
} from "../../../../test/src/test-wallets.js";
|
||||
import {
|
||||
type ThirdwebContract,
|
||||
getContract,
|
||||
} from "../../../contract/contract.js";
|
||||
import { sendTransaction } from "../../../transaction/actions/send-transaction.js";
|
||||
import { getBalance } from "../../erc20/read/getBalance.js";
|
||||
import { approve } from "../../erc20/write/approve.js";
|
||||
import { mintTo } from "../../erc20/write/mintTo.js";
|
||||
import { deployERC20Contract } from "../../prebuilts/deploy-erc20.js";
|
||||
import { deployPublishedContract } from "../../prebuilts/deploy-published.js";
|
||||
import { setMerkleRoot } from "../__generated__/Airdrop/write/setMerkleRoot.js";
|
||||
import { claimERC20 } from "./claimERC20.js";
|
||||
import { generateMerkleTreeInfoERC20 } from "./merkleInfoERC20.js";
|
||||
import { saveSnapshot } from "./saveSnapshot.js";
|
||||
|
||||
// skip this test suite if there is no secret key available to test with
|
||||
// TODO: remove reliance on secret key during unit tests entirely
|
||||
describe.runIf(process.env.TW_SECRET_KEY)("claimERC20", () => {
|
||||
let airdropContract: ThirdwebContract;
|
||||
let erc20TokenContract: ThirdwebContract;
|
||||
|
||||
beforeAll(async () => {
|
||||
airdropContract = getContract({
|
||||
address: await deployPublishedContract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
contractId: "Airdrop",
|
||||
publisher: "0xFD78F7E2dF2B8c3D5bff0413c96f3237500898B3",
|
||||
contractParams: [TEST_ACCOUNT_A.address, ""],
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
erc20TokenContract = getContract({
|
||||
address: await deployERC20Contract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
params: {
|
||||
name: "TestToken",
|
||||
symbol: "TSTT",
|
||||
},
|
||||
type: "TokenERC20",
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
const mintTx = mintTo({
|
||||
contract: erc20TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
amount: 1000,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: mintTx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const approvalTx = await approve({
|
||||
contract: erc20TokenContract,
|
||||
spender: airdropContract.address,
|
||||
amount: 1000,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: approvalTx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
it("should send ERC20 tokens to allowlisted claimer", async () => {
|
||||
const snapshot = [
|
||||
{ recipient: TEST_ACCOUNT_B.address, amount: 10 },
|
||||
{ recipient: TEST_ACCOUNT_C.address, amount: 15 },
|
||||
{ recipient: TEST_ACCOUNT_D.address, amount: 20 },
|
||||
];
|
||||
const { merkleRoot, snapshotUri } = await generateMerkleTreeInfoERC20({
|
||||
snapshot,
|
||||
tokenAddress: erc20TokenContract.address,
|
||||
contract: airdropContract,
|
||||
});
|
||||
|
||||
const saveSnapshotTransaction = saveSnapshot({
|
||||
merkleRoot,
|
||||
snapshotUri,
|
||||
contract: airdropContract,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: saveSnapshotTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const setMerkleRootTransaction = setMerkleRoot({
|
||||
token: erc20TokenContract.address,
|
||||
tokenMerkleRoot: merkleRoot as `0x${string}`,
|
||||
resetClaimStatus: true,
|
||||
contract: airdropContract,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: setMerkleRootTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const claimTransaction = claimERC20({
|
||||
tokenAddress: erc20TokenContract.address,
|
||||
recipient: TEST_ACCOUNT_B.address,
|
||||
contract: airdropContract,
|
||||
});
|
||||
const { transactionHash } = await sendTransaction({
|
||||
transaction: claimTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const balanceB = (
|
||||
await getBalance({
|
||||
contract: erc20TokenContract,
|
||||
address: TEST_ACCOUNT_B.address,
|
||||
})
|
||||
).value;
|
||||
|
||||
expect(balanceB).to.equal(10n * 10n ** 18n);
|
||||
|
||||
expect(transactionHash.length).toBe(66);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,88 @@
|
||||
import {
|
||||
ADDRESS_ZERO,
|
||||
isNativeTokenAddress,
|
||||
} from "../../../constants/addresses.js";
|
||||
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
||||
import type { Address } from "../../../utils/address.js";
|
||||
import { fetchProofsrERC20 } from "../../../utils/extensions/airdrop/fetch-proofs-erc20.js";
|
||||
import { tokenMerkleRoot } from "../__generated__/Airdrop/read/tokenMerkleRoot.js";
|
||||
import { claimERC20 as generatedClaimERC20 } from "../__generated__/Airdrop/write/claimERC20.js";
|
||||
|
||||
export type ClaimERC20Params = {
|
||||
tokenAddress: string;
|
||||
recipient: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Claim airdrop of ERC20 tokens for allowlisted addresses. (Pull based airdrop)
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { claimERC20 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const tokenAddress = "0x..." // Address of airdropped tokens to claim
|
||||
* const recipient = "0x..." // Address of the allowlisted recipient
|
||||
*
|
||||
* const claimTransaction = claimERC20({
|
||||
* contract,
|
||||
* tokenAddress,
|
||||
* recipient
|
||||
* });
|
||||
*
|
||||
* await sendTransaction({ claimTransaction, account });
|
||||
*
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the transaction result.
|
||||
*/
|
||||
export function claimERC20(options: BaseTransactionOptions<ClaimERC20Params>) {
|
||||
return generatedClaimERC20({
|
||||
contract: options.contract,
|
||||
asyncParams: async () => {
|
||||
const merkleRoot = await tokenMerkleRoot({
|
||||
contract: options.contract,
|
||||
tokenAddress: options.tokenAddress,
|
||||
});
|
||||
|
||||
const tokenAddress = options.tokenAddress;
|
||||
const tokenDecimals = await (async () => {
|
||||
if (
|
||||
isNativeTokenAddress(tokenAddress) ||
|
||||
tokenAddress === ADDRESS_ZERO
|
||||
) {
|
||||
throw new Error(
|
||||
"Token address can't be zero address or native token",
|
||||
);
|
||||
}
|
||||
const [{ getContract }, { decimals: getDecimals }] = await Promise.all([
|
||||
import("../../../contract/contract.js"),
|
||||
import("../../erc20/read/decimals.js"),
|
||||
]);
|
||||
const tokenContract = getContract({
|
||||
address: tokenAddress,
|
||||
chain: options.contract.chain,
|
||||
client: options.contract.client,
|
||||
});
|
||||
return await getDecimals({ contract: tokenContract });
|
||||
})();
|
||||
|
||||
const merkleProof = await fetchProofsrERC20({
|
||||
contract: options.contract,
|
||||
recipient: options.recipient,
|
||||
merkleRoot,
|
||||
tokenDecimals,
|
||||
});
|
||||
|
||||
if (!merkleProof) {
|
||||
throw new Error("Proof not found for recipient address");
|
||||
}
|
||||
|
||||
return {
|
||||
token: tokenAddress as Address,
|
||||
receiver: merkleProof.recipient as Address,
|
||||
quantity: merkleProof.quantity,
|
||||
proofs: merkleProof.proof,
|
||||
} as const;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
|
||||
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
|
||||
import {
|
||||
TEST_ACCOUNT_A,
|
||||
TEST_ACCOUNT_B,
|
||||
TEST_ACCOUNT_C,
|
||||
TEST_ACCOUNT_D,
|
||||
} from "../../../../test/src/test-wallets.js";
|
||||
import {
|
||||
type ThirdwebContract,
|
||||
getContract,
|
||||
} from "../../../contract/contract.js";
|
||||
import {
|
||||
ownerOf,
|
||||
setApprovalForAll,
|
||||
} from "../../../exports/extensions/erc721.js";
|
||||
import { sendTransaction } from "../../../transaction/actions/send-transaction.js";
|
||||
import { mintTo } from "../../erc721/write/mintTo.js";
|
||||
import { deployERC721Contract } from "../../prebuilts/deploy-erc721.js";
|
||||
import { deployPublishedContract } from "../../prebuilts/deploy-published.js";
|
||||
import { setMerkleRoot } from "../__generated__/Airdrop/write/setMerkleRoot.js";
|
||||
import { claimERC721 } from "./claimERC721.js";
|
||||
import { generateMerkleTreeInfoERC721 } from "./merkleInfoERC721.js";
|
||||
import { saveSnapshot } from "./saveSnapshot.js";
|
||||
|
||||
// skip this test suite if there is no secret key available to test with
|
||||
// TODO: remove reliance on secret key during unit tests entirely
|
||||
describe.runIf(process.env.TW_SECRET_KEY)("claimERC721", () => {
|
||||
let airdropContract: ThirdwebContract;
|
||||
let erc721TokenContract: ThirdwebContract;
|
||||
|
||||
beforeAll(async () => {
|
||||
airdropContract = getContract({
|
||||
address: await deployPublishedContract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
contractId: "Airdrop",
|
||||
publisher: "0xFD78F7E2dF2B8c3D5bff0413c96f3237500898B3",
|
||||
contractParams: [TEST_ACCOUNT_A.address, ""],
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
erc721TokenContract = getContract({
|
||||
address: await deployERC721Contract({
|
||||
account: TEST_ACCOUNT_A,
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
params: {
|
||||
name: "Test",
|
||||
symbol: "TST",
|
||||
},
|
||||
type: "TokenERC721",
|
||||
}),
|
||||
chain: ANVIL_CHAIN,
|
||||
client: TEST_CLIENT,
|
||||
});
|
||||
|
||||
const mintTransactions = [
|
||||
mintTo({
|
||||
contract: erc721TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
nft: {
|
||||
name: "Test 0",
|
||||
},
|
||||
}),
|
||||
mintTo({
|
||||
contract: erc721TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
nft: {
|
||||
name: "Test 1",
|
||||
},
|
||||
}),
|
||||
mintTo({
|
||||
contract: erc721TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
nft: {
|
||||
name: "Test 2",
|
||||
},
|
||||
}),
|
||||
mintTo({
|
||||
contract: erc721TokenContract,
|
||||
to: TEST_ACCOUNT_A.address,
|
||||
nft: {
|
||||
name: "Test 3",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
for (const tx of mintTransactions) {
|
||||
await sendTransaction({
|
||||
transaction: tx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}
|
||||
|
||||
const approvalTx = setApprovalForAll({
|
||||
contract: erc721TokenContract,
|
||||
operator: airdropContract.address,
|
||||
approved: true,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: approvalTx,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
it("should send ERC721 tokens to allowlisted claimer", async () => {
|
||||
const snapshot = [
|
||||
{ recipient: TEST_ACCOUNT_B.address, tokenId: 0 },
|
||||
{ recipient: TEST_ACCOUNT_C.address, tokenId: 1 },
|
||||
{ recipient: TEST_ACCOUNT_D.address, tokenId: 2 },
|
||||
];
|
||||
|
||||
const { merkleRoot, snapshotUri } = await generateMerkleTreeInfoERC721({
|
||||
snapshot,
|
||||
tokenAddress: erc721TokenContract.address,
|
||||
contract: airdropContract,
|
||||
});
|
||||
const saveSnapshotTransaction = saveSnapshot({
|
||||
merkleRoot,
|
||||
snapshotUri,
|
||||
contract: airdropContract,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: saveSnapshotTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const setMerkleRootTransaction = setMerkleRoot({
|
||||
token: erc721TokenContract.address,
|
||||
tokenMerkleRoot: merkleRoot as `0x${string}`,
|
||||
resetClaimStatus: true,
|
||||
contract: airdropContract,
|
||||
});
|
||||
await sendTransaction({
|
||||
transaction: setMerkleRootTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const claimTransaction = claimERC721({
|
||||
tokenAddress: erc721TokenContract.address,
|
||||
recipient: TEST_ACCOUNT_B.address,
|
||||
contract: airdropContract,
|
||||
});
|
||||
const { transactionHash } = await sendTransaction({
|
||||
transaction: claimTransaction,
|
||||
account: TEST_ACCOUNT_A,
|
||||
});
|
||||
|
||||
const ownerZero = await ownerOf({
|
||||
contract: erc721TokenContract,
|
||||
tokenId: 0n,
|
||||
});
|
||||
|
||||
expect(ownerZero).to.equal(TEST_ACCOUNT_B.address);
|
||||
|
||||
expect(transactionHash.length).toBe(66);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,65 @@
|
||||
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
||||
import type { Address } from "../../../utils/address.js";
|
||||
import { fetchProofsERC721 } from "../../../utils/extensions/airdrop/fetch-proofs-erc721.js";
|
||||
import { tokenMerkleRoot } from "../__generated__/Airdrop/read/tokenMerkleRoot.js";
|
||||
import { claimERC721 as generatedClaimERC721 } from "../__generated__/Airdrop/write/claimERC721.js";
|
||||
|
||||
export type ClaimERC721Params = {
|
||||
tokenAddress: string;
|
||||
recipient: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Claim airdrop of ERC721 tokens for allowlisted addresses. (Pull based airdrop)
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { claimERC721 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* const tokenAddress = "0x..." // Address of airdropped tokens to claim
|
||||
* const recipient = "0x..." // Address of the allowlisted recipient
|
||||
*
|
||||
* const claimTransaction = claimERC721({
|
||||
* contract,
|
||||
* tokenAddress,
|
||||
* recipient
|
||||
* });
|
||||
*
|
||||
* await sendTransaction({ claimTransaction, account });
|
||||
*
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the transaction result.
|
||||
*/
|
||||
export function claimERC721(
|
||||
options: BaseTransactionOptions<ClaimERC721Params>,
|
||||
) {
|
||||
return generatedClaimERC721({
|
||||
contract: options.contract,
|
||||
asyncParams: async () => {
|
||||
const merkleRoot = await tokenMerkleRoot({
|
||||
contract: options.contract,
|
||||
tokenAddress: options.tokenAddress,
|
||||
});
|
||||
|
||||
const tokenAddress = options.tokenAddress;
|
||||
|
||||
const merkleProof = await fetchProofsERC721({
|
||||
contract: options.contract,
|
||||
recipient: options.recipient,
|
||||
merkleRoot,
|
||||
});
|
||||
|
||||
if (!merkleProof) {
|
||||
throw new Error("Proof not found for recipient address");
|
||||
}
|
||||
|
||||
return {
|
||||
token: tokenAddress as Address,
|
||||
receiver: merkleProof.recipient as Address,
|
||||
tokenId: merkleProof.tokenId,
|
||||
proofs: merkleProof.proof,
|
||||
} as const;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
||||
import { processSnapshotERC1155 } from "../../../utils/extensions/airdrop/process-snapshot-erc1155.js";
|
||||
import type { SnapshotEntryERC1155 } from "../../../utils/extensions/airdrop/types.js";
|
||||
|
||||
export type GenerateMerkleTreeInfoParams = {
|
||||
snapshot: SnapshotEntryERC1155[];
|
||||
tokenAddress: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate merkle tree for a given snapshot.
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { generateMerkleTreeInfoERC1155 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* // snapshot / allowlist of airdrop recipients and amounts
|
||||
* const snapshot = [
|
||||
* { recipient: "0x...", tokenId: 0, amount: 10 },
|
||||
* { recipient: "0x...", tokenId: 1, amount: 12 },
|
||||
* { recipient: "0x...", tokenId: 2, amount: 15 },
|
||||
* ];
|
||||
*
|
||||
* const tokenAddress = "0x..." // Address of ERC1155 airdrop token
|
||||
*
|
||||
* const { merkleRoot, snapshotUri } = await generateMerkleTreeInfoERC1155({
|
||||
* contract,
|
||||
* tokenAddress,
|
||||
* snapshot
|
||||
* });
|
||||
*
|
||||
* // Optional next steps {See: saveSnapshot and setMerkleRoot functions}
|
||||
* // - Save snapshot on-chain (on the airdrop contract uri)
|
||||
* // - Set merkle root on the contract to enable claiming
|
||||
*
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the merkle-root and snapshot-uri.
|
||||
*/
|
||||
export async function generateMerkleTreeInfoERC1155(
|
||||
options: BaseTransactionOptions<GenerateMerkleTreeInfoParams>,
|
||||
) {
|
||||
const { snapshot, contract } = options;
|
||||
|
||||
// generate merkle tree from snapshot
|
||||
const { shardedMerkleInfo, uri } = await processSnapshotERC1155({
|
||||
snapshot,
|
||||
client: contract.client,
|
||||
});
|
||||
return {
|
||||
merkleRoot: shardedMerkleInfo.merkleRoot,
|
||||
snapshotUri: uri,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import {
|
||||
ADDRESS_ZERO,
|
||||
isNativeTokenAddress,
|
||||
} from "../../../constants/addresses.js";
|
||||
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
||||
import { processSnapshotERC20 } from "../../../utils/extensions/airdrop/process-snapshot-erc20.js";
|
||||
import type { SnapshotEntryERC20 } from "../../../utils/extensions/airdrop/types.js";
|
||||
|
||||
export type GenerateMerkleTreeInfoParams = {
|
||||
snapshot: SnapshotEntryERC20[];
|
||||
tokenAddress: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate merkle tree for a given snapshot.
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { generateMerkleTreeInfoERC20 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* // snapshot / allowlist of airdrop recipients and amounts
|
||||
* const snapshot = [
|
||||
* { recipient: "0x...", amount: 10 },
|
||||
* { recipient: "0x...", amount: 15 },
|
||||
* { recipient: "0x...", amount: 20 },
|
||||
* ];
|
||||
*
|
||||
* const tokenAddress = "0x..." // Address of ERC20 airdrop token
|
||||
*
|
||||
* const { merkleRoot, snapshotUri } = await generateMerkleTreeInfoERC20({
|
||||
* contract,
|
||||
* tokenAddress,
|
||||
* snapshot
|
||||
* });
|
||||
*
|
||||
* // Optional next steps {See: saveSnapshot and setMerkleRoot functions}
|
||||
* // - Save snapshot on-chain (on the airdrop contract uri)
|
||||
* // - Set merkle root on the contract to enable claiming
|
||||
*
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the merkle-root and snapshot-uri.
|
||||
*/
|
||||
export async function generateMerkleTreeInfoERC20(
|
||||
options: BaseTransactionOptions<GenerateMerkleTreeInfoParams>,
|
||||
) {
|
||||
const { snapshot, contract } = options;
|
||||
|
||||
// get token decimals
|
||||
const tokenAddress = options.tokenAddress;
|
||||
const tokenDecimals = await (async () => {
|
||||
if (isNativeTokenAddress(tokenAddress) || tokenAddress === ADDRESS_ZERO) {
|
||||
throw new Error("Token address can't be zero address or native token");
|
||||
}
|
||||
const [{ getContract }, { decimals: getDecimals }] = await Promise.all([
|
||||
import("../../../contract/contract.js"),
|
||||
import("../../erc20/read/decimals.js"),
|
||||
]);
|
||||
const tokenContract = getContract({
|
||||
address: tokenAddress,
|
||||
chain: contract.chain,
|
||||
client: contract.client,
|
||||
});
|
||||
return await getDecimals({ contract: tokenContract });
|
||||
})();
|
||||
|
||||
// generate merkle tree from snapshot
|
||||
const { shardedMerkleInfo, uri } = await processSnapshotERC20({
|
||||
snapshot,
|
||||
client: contract.client,
|
||||
tokenDecimals,
|
||||
});
|
||||
return {
|
||||
merkleRoot: shardedMerkleInfo.merkleRoot,
|
||||
snapshotUri: uri,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
||||
import { processSnapshotERC721 } from "../../../utils/extensions/airdrop/process-snapshot-erc721.js";
|
||||
import type { SnapshotEntryERC721 } from "../../../utils/extensions/airdrop/types.js";
|
||||
|
||||
export type GenerateMerkleTreeInfoParams = {
|
||||
snapshot: SnapshotEntryERC721[];
|
||||
tokenAddress: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate merkle tree for a given snapshot.
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { generateMerkleTreeInfoERC721 } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* // snapshot / allowlist of airdrop recipients and amounts
|
||||
* const snapshot = [
|
||||
* { recipient: "0x...", tokenId: 0 },
|
||||
* { recipient: "0x...", tokenId: 1 },
|
||||
* { recipient: "0x...", tokenId: 2 },
|
||||
* ];
|
||||
*
|
||||
* const tokenAddress = "0x..." // Address of ERC721 airdrop token
|
||||
*
|
||||
* const { merkleRoot, snapshotUri } = await generateMerkleTreeInfoERC721({
|
||||
* contract,
|
||||
* tokenAddress,
|
||||
* snapshot
|
||||
* });
|
||||
*
|
||||
* // Optional next steps {See: saveSnapshot and setMerkleRoot functions}
|
||||
* // - Save snapshot on-chain (on the airdrop contract uri)
|
||||
* // - Set merkle root on the contract to enable claiming
|
||||
*
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the merkle-root and snapshot-uri.
|
||||
*/
|
||||
export async function generateMerkleTreeInfoERC721(
|
||||
options: BaseTransactionOptions<GenerateMerkleTreeInfoParams>,
|
||||
) {
|
||||
const { snapshot, contract } = options;
|
||||
|
||||
// generate merkle tree from snapshot
|
||||
const { shardedMerkleInfo, uri } = await processSnapshotERC721({
|
||||
snapshot,
|
||||
client: contract.client,
|
||||
});
|
||||
return {
|
||||
merkleRoot: shardedMerkleInfo.merkleRoot,
|
||||
snapshotUri: uri,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { upload } from "../../../storage/upload.js";
|
||||
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
||||
import { setContractURI } from "../__generated__/Airdrop/write/setContractURI.js";
|
||||
|
||||
export type SaveSnapshotParams = {
|
||||
merkleRoot: string;
|
||||
snapshotUri: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate merkle tree for a given snapshot and save the info on-chain.
|
||||
* @param options - The transaction options.
|
||||
* @example
|
||||
* ```ts
|
||||
*
|
||||
* // This is ERC20 example. Should import and use other ERC variants as needed
|
||||
*
|
||||
* import { generateMerkleTreeInfoERC20, saveSnapshot, setMerkleRoot } from "thirdweb/extensions/airdrop";
|
||||
*
|
||||
* // snapshot / allowlist of airdrop recipients and amounts
|
||||
* const snapshot = [
|
||||
* { recipient: "0x...", amount: 10 },
|
||||
* { recipient: "0x...", amount: 15 },
|
||||
* { recipient: "0x...", amount: 20 },
|
||||
* ];
|
||||
*
|
||||
* const tokenAddress = "0x..." // Address of airdrop token
|
||||
*
|
||||
* const { merkleRoot, snapshotUri } = await generateMerkleTreeInfoERC20({
|
||||
* contract,
|
||||
* tokenAddress,
|
||||
* snapshot
|
||||
* });
|
||||
*
|
||||
* const saveSnapshotTransaction = saveSnapshot({
|
||||
* contract,
|
||||
* merkleRoot,
|
||||
* snapshotUri,
|
||||
* });
|
||||
* await sendTransaction({ saveSnapshotTransaction, account });
|
||||
*
|
||||
* const setMerkleRootTransaction = setMerkleRoot({
|
||||
* contract,
|
||||
* token,
|
||||
* tokenMerkleRoot: merkleRoot as `0x${string}`,
|
||||
* resetClaimStatus: false // toggle as needed
|
||||
* signature,
|
||||
* });
|
||||
* await sendTransaction({ setMerkleRootTransaction, account });
|
||||
*
|
||||
* ```
|
||||
* @extension Airdrop
|
||||
* @returns A promise that resolves to the transaction result.
|
||||
*/
|
||||
export function saveSnapshot(
|
||||
options: BaseTransactionOptions<SaveSnapshotParams>,
|
||||
) {
|
||||
return setContractURI({
|
||||
contract: options.contract,
|
||||
asyncParams: async () => {
|
||||
const merkleInfos: Record<string, string> = {};
|
||||
// need to upload merkle tree info to the contract metadata
|
||||
|
||||
const [{ getContractMetadata }, { contractURI }] = await Promise.all([
|
||||
import("../../common/read/getContractMetadata.js"),
|
||||
import(
|
||||
"../../common/__generated__/IContractMetadata/read/contractURI.js"
|
||||
),
|
||||
]);
|
||||
const metadata = await getContractMetadata({
|
||||
contract: options.contract,
|
||||
});
|
||||
const contractUri = await contractURI({
|
||||
contract: options.contract,
|
||||
});
|
||||
|
||||
merkleInfos[options.merkleRoot] = options.snapshotUri;
|
||||
|
||||
// keep the old merkle roots from other tokenIds
|
||||
for (const key of Object.keys(metadata.merkle || {})) {
|
||||
merkleInfos[key] = metadata.merkle[key];
|
||||
}
|
||||
const mergedMetadata = {
|
||||
...metadata,
|
||||
merkle: merkleInfos,
|
||||
};
|
||||
const uri = await upload({
|
||||
client: options.contract.client,
|
||||
files: [mergedMetadata],
|
||||
});
|
||||
|
||||
if (uri === contractUri) {
|
||||
throw new Error("Merkle tree info already saved");
|
||||
}
|
||||
|
||||
return {
|
||||
uri,
|
||||
} as const;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export type SetClaimConditionsParams = {
|
||||
* ```ts
|
||||
* import { setClaimConditions } from "thirdweb/extensions/erc1155";
|
||||
*
|
||||
* const tx = await setClaimConditions({
|
||||
* const tx = setClaimConditions({
|
||||
* contract,
|
||||
* tokenId: 0n,
|
||||
* phases: [
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
import type { AbiParameterToPrimitiveType, Address } from "abitype";
|
||||
import { maxUint256 } from "viem";
|
||||
import { NATIVE_TOKEN_ADDRESS } from "../../../constants/addresses.js";
|
||||
import {
|
||||
NATIVE_TOKEN_ADDRESS,
|
||||
isNativeTokenAddress,
|
||||
} from "../../../constants/addresses.js";
|
||||
import type { ThirdwebContract } from "../../../contract/contract.js";
|
||||
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
||||
import { toBigInt } from "../../../utils/bigint.js";
|
||||
import { dateToSeconds, tenYearsFromNow } from "../../../utils/date.js";
|
||||
import type { Hex } from "../../../utils/encoding/hex.js";
|
||||
import type { NFTInput } from "../../../utils/nft/parseNft.js";
|
||||
import { randomBytes32 } from "../../../utils/uuid.js";
|
||||
import type { Account } from "../../../wallets/interfaces/wallet.js";
|
||||
import { mintWithSignature as generatedMintWithSignature } from "../__generated__/ISignatureMintERC1155/write/mintWithSignature.js";
|
||||
import {
|
||||
type MintWithSignatureParams,
|
||||
mintWithSignature as generatedMintWithSignature,
|
||||
} from "../__generated__/ISignatureMintERC1155/write/mintWithSignature.js";
|
||||
|
||||
/**
|
||||
* Mints a new ERC1155 token with the given minter signature
|
||||
@@ -29,7 +36,19 @@ import { mintWithSignature as generatedMintWithSignature } from "../__generated_
|
||||
* @extension ERC1155
|
||||
* @returns A promise that resolves to the transaction result.
|
||||
*/
|
||||
export const mintWithSignature = generatedMintWithSignature;
|
||||
export function mintWithSignature(
|
||||
options: BaseTransactionOptions<MintWithSignatureParams>,
|
||||
) {
|
||||
const value = isNativeTokenAddress(options.payload.currency)
|
||||
? options.payload.pricePerToken * options.payload.quantity
|
||||
: 0n;
|
||||
return generatedMintWithSignature({
|
||||
...options,
|
||||
overrides: {
|
||||
value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export type GenerateMintSignatureOptions = {
|
||||
account: Account;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user