Compare commits

..
Author SHA1 Message Date
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>GitHub Action
ddfdfc5a02 Version Packages (#2856)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <[email protected]>
2024-04-25 15:32:29 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
dbdafa2b01 chore(chains): update chains (#2852)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-25 15:05:38 -07:00
77c2a8ae0c Update code snippet for ERC20 getBalance; fix typos (#2857)
Signed-off-by: Jonas Daniels <[email protected]>
Co-authored-by: Kien Ngo <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-25 14:27:01 -07:00
5c1f4db356 Fix: Use 127.0.0.1 on anvil rpc (#2860)
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-25 14:26:42 -07:00
YashandGitHub 5b83353237 Export airdrop extensions (#2861) 2024-04-25 21:19:22 +00:00
56c139c5a2 feat: Add account abstraction options to useConnect (#2853)
Signed-off-by: Jonas Daniels <[email protected]>
Co-authored-by: Manan Tank <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-25 21:06:41 +00:00
Jonas DanielsandGitHub 03d8d6c15b feat(TransactionButton): add gasless prop (#2859) 2024-04-25 20:10:21 +00:00
gregandGitHub f12f9bbdcf Cleanup getUniswapV3Pool docs and internal naming (#2855) 2024-04-25 19:59:17 +00:00
FirekeeperandGitHub 82ee42d667 Unity 4.12.4 (#2858) 2024-04-25 19:50:05 +00:00
FirekeeperandGitHub 81c297faeb Unity 4.12.3 (#2854) 2024-04-25 07:44:08 +00:00
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>GitHub Action
20fb0d2300 Version Packages (#2847)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <[email protected]>
2024-04-24 16:48:07 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
637c510f59 chore(chains): update chains (#2838)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-24 16:02:15 -07:00
YashandGitHub 2ae9a13b01 feat: add new airdrop extension (#2841) 2024-04-24 22:24:15 +00:00
Manan TankandGitHub 8d91e55eac Add missing lang for JSDoc code examples (#2851) 2024-04-24 21:24:30 +00:00
Manan TankandGitHub aa0b8c4465 Fix All Wallets UI in Connect (#2850) 2024-04-24 20:37:25 +00:00
Jonas DanielsandGitHub 41be954bd0 feat: Add celo chains to known op stack chains (#2848) 2024-04-24 11:55:40 -07:00
e8e3368fde Add extension: isERC20 (#2846)
Signed-off-by: Jonas Daniels <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-24 10:06:03 -07:00
135 changed files with 6936 additions and 238 deletions
+14
View File
@@ -1,5 +1,19 @@
# @thirdweb-dev/auth
## 4.1.69
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.5.11
## 4.1.68
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.5.10
## 4.1.67
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "4.1.67",
"version": "4.1.69",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
+12
View File
@@ -1,5 +1,17 @@
# @thirdweb-dev/chains
## 0.1.101
### Patch Changes
- [#2852](https://github.com/thirdweb-dev/js/pull/2852) [`dbdafa2`](https://github.com/thirdweb-dev/js/commit/dbdafa2b01148b13d05fd75803926d9d37396668) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
## 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
+1 -1
View File
@@ -24,7 +24,7 @@ export default {
"nativeCurrency": {
"name": "SMR",
"symbol": "SMR",
"decimals": 6
"decimals": 18
},
"networkId": 1073,
"rpc": [
+7 -1
View File
@@ -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"
],
+6
View File
@@ -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": {
+1 -1
View File
@@ -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,
+45
View File
@@ -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;
+30
View File
@@ -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;
+30
View File
@@ -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;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 46109,
"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": "qr0224t1tp Testnet",
"nativeCurrency": {
"name": "qr0224t1tp Testnet Token",
"symbol": "CRH",
"decimals": 18
},
"networkId": 46109,
"redFlags": [],
"rpc": [
"https://46109.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/qr0224t1tp/testnet/rpc"
],
"shortName": "qr0224t1tp Testnet",
"slug": "qr0224t1tp-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -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;
+3 -2
View File
@@ -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",
+30
View File
@@ -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;
+45
View File
@@ -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;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.99",
"version": "0.1.101",
"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
+20
View File
@@ -1,5 +1,25 @@
# thirdweb
## 0.13.77
### Patch Changes
- Updated dependencies [[`dbdafa2`](https://github.com/thirdweb-dev/js/commit/dbdafa2b01148b13d05fd75803926d9d37396668)]:
- @thirdweb-dev/chains@0.1.101
- @thirdweb-dev/sdk@4.0.71
- @thirdweb-dev/wallets@2.5.11
- @thirdweb-dev/auth@4.1.69
## 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
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/cli",
"main": "dist/cli/index.js",
"version": "0.13.75",
"version": "0.13.77",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
+20
View File
@@ -1,5 +1,25 @@
# @thirdweb-dev/react-core
## 4.6.10
### Patch Changes
- Updated dependencies [[`dbdafa2`](https://github.com/thirdweb-dev/js/commit/dbdafa2b01148b13d05fd75803926d9d37396668)]:
- @thirdweb-dev/chains@0.1.101
- @thirdweb-dev/sdk@4.0.71
- @thirdweb-dev/wallets@2.5.11
- @thirdweb-dev/auth@4.1.69
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "4.6.8",
"version": "4.6.10",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -1,5 +1,9 @@
# @thirdweb-dev/react-native-compat
## 0.7.42
## 0.7.41
## 0.7.40
## 0.7.39
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/react-native-compat",
"description": "Shims for Thirdweb in React Native Projects",
"version": "0.7.40",
"version": "0.7.42",
"author": "thirdweb eng <[email protected]>",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native-compat",
"license": "Apache-2.0",
+20
View File
@@ -1,5 +1,25 @@
# @thirdweb-dev/react-native
## 0.7.42
### Patch Changes
- Updated dependencies [[`dbdafa2`](https://github.com/thirdweb-dev/js/commit/dbdafa2b01148b13d05fd75803926d9d37396668)]:
- @thirdweb-dev/chains@0.1.101
- @thirdweb-dev/sdk@4.0.71
- @thirdweb-dev/react-core@4.6.10
- @thirdweb-dev/wallets@2.5.11
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-native",
"version": "0.7.40",
"version": "0.7.42",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
+20
View File
@@ -1,5 +1,25 @@
# @thirdweb-dev/react
## 4.6.10
### Patch Changes
- Updated dependencies [[`dbdafa2`](https://github.com/thirdweb-dev/js/commit/dbdafa2b01148b13d05fd75803926d9d37396668)]:
- @thirdweb-dev/chains@0.1.101
- @thirdweb-dev/sdk@4.0.71
- @thirdweb-dev/react-core@4.6.10
- @thirdweb-dev/wallets@2.5.11
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "4.6.8",
"version": "4.6.10",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
Binary file not shown.
+18
View File
@@ -1,5 +1,23 @@
# @thirdweb-dev/sdk
## 4.0.71
### Patch Changes
- Updated dependencies [[`03d8d6c`](https://github.com/thirdweb-dev/js/commit/03d8d6c15b02fb6889680484daf40f6189ad6359), [`5b83353`](https://github.com/thirdweb-dev/js/commit/5b833532372dd6e96dd0aeda7a4b190e9f280d4f), [`77c2a8a`](https://github.com/thirdweb-dev/js/commit/77c2a8ae0cdb49091bd961b60ef5c316ccd6e119), [`dbdafa2`](https://github.com/thirdweb-dev/js/commit/dbdafa2b01148b13d05fd75803926d9d37396668), [`56c139c`](https://github.com/thirdweb-dev/js/commit/56c139c5a2c1e702e038a8948fefd647b3695823)]:
- thirdweb@5.13.0
- @thirdweb-dev/chains@0.1.101
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/sdk",
"version": "4.0.69",
"version": "4.0.71",
"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.
@@ -1,5 +1,29 @@
# @thirdweb-dev/unity-js-bridge
## 0.6.20
### Patch Changes
- [#2858](https://github.com/thirdweb-dev/js/pull/2858) [`82ee42d`](https://github.com/thirdweb-dev/js/commit/82ee42d667219b5a2aa323278af1e9981076b339) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - Unity 4.12.4
- [#2854](https://github.com/thirdweb-dev/js/pull/2854) [`81c297f`](https://github.com/thirdweb-dev/js/commit/81c297faeb698503cf5e2716d604c9f0c18ad668) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - Unity 4.12.3
- Updated dependencies [[`dbdafa2`](https://github.com/thirdweb-dev/js/commit/dbdafa2b01148b13d05fd75803926d9d37396668)]:
- @thirdweb-dev/chains@0.1.101
- @thirdweb-dev/sdk@4.0.71
- @thirdweb-dev/wallets@2.5.11
- @thirdweb-dev/auth@4.1.69
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/unity-js-bridge",
"version": "0.6.18",
"version": "0.6.20",
"main": "dist/thirdweb-unity-bridge.js",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
"license": "Apache-2.0",
@@ -171,7 +171,7 @@ class ThirdwebBridge implements TWBridge {
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
(globalThis as any).X_SDK_PLATFORM = "unity";
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
(globalThis as any).X_SDK_VERSION = "4.12.2";
(globalThis as any).X_SDK_VERSION = "4.12.4";
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
(globalThis as any).X_SDK_OS = browser?.os ?? "unknown";
}
+16
View File
@@ -1,5 +1,21 @@
# @thirdweb-dev/wallets
## 2.5.11
### Patch Changes
- Updated dependencies [[`dbdafa2`](https://github.com/thirdweb-dev/js/commit/dbdafa2b01148b13d05fd75803926d9d37396668)]:
- @thirdweb-dev/chains@0.1.101
- @thirdweb-dev/sdk@4.0.71
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/wallets",
"version": "2.5.9",
"version": "2.5.11",
"main": "dist/thirdweb-dev-wallets.cjs.js",
"module": "dist/thirdweb-dev-wallets.esm.js",
"browser": {
+1 -1
View File
@@ -39,7 +39,7 @@ export const SERVICE_DEFINITIONS = {
},
embeddedWallets: {
name: "embeddedWallets",
title: "Embedded Wallets",
title: "In-App Wallets",
description: "E-mail and social login wallets for easy web3 onboarding",
// all actions allowed
actions: [],
+31
View File
@@ -1,5 +1,36 @@
# thirdweb
## 5.13.0
### Minor Changes
- [#2853](https://github.com/thirdweb-dev/js/pull/2853) [`56c139c`](https://github.com/thirdweb-dev/js/commit/56c139c5a2c1e702e038a8948fefd647b3695823) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add account abstraction options to `useConnect` and handle smart wallet autoconnection outside of UI components
### Patch Changes
- [#2859](https://github.com/thirdweb-dev/js/pull/2859) [`03d8d6c`](https://github.com/thirdweb-dev/js/commit/03d8d6c15b02fb6889680484daf40f6189ad6359) Thanks [@jnsdls](https://github.com/jnsdls)! - add `gasless` prop to `<TransactionButton />`
- [#2861](https://github.com/thirdweb-dev/js/pull/2861) [`5b83353`](https://github.com/thirdweb-dev/js/commit/5b833532372dd6e96dd0aeda7a4b190e9f280d4f) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Export airdrop extensions
- [#2857](https://github.com/thirdweb-dev/js/pull/2857) [`77c2a8a`](https://github.com/thirdweb-dev/js/commit/77c2a8ae0cdb49091bd961b60ef5c316ccd6e119) Thanks [@kien-ngo](https://github.com/kien-ngo)! - Docs: update incorrect code snippets, fix typos
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "thirdweb",
"version": "5.11.0",
"version": "5.13.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": [] }
]
+2 -2
View File
@@ -31,7 +31,7 @@ export const viemAdapter = {
* ```ts
* import { viemAdapter } from "thirdweb/adapters";
*
* const contract = viemmAdapter.contract.fromViem({
* const contract = viemAdapter.contract.fromViem({
* viemContract: viemContract,
* chain: ethereum,
* client,
@@ -246,7 +246,7 @@ function fromViemWalletClient(options: {
const viemAccount = options.walletClient.account;
if (!viemAccount) {
throw new Error(
"Account not found in walletClient, please pass it explicitely.",
"Account not found in walletClient, please pass it explicitly.",
);
}
return {
@@ -3,7 +3,7 @@ import { defineChain } from "../utils.js";
export const anvil = /* @__PURE__ */ defineChain({
id: 31337,
name: "Anvil",
rpc: "http://localhost:8545",
rpc: "http://127.0.0.1:8545",
testnet: true,
nativeCurrency: {
name: "Anvil Ether",
@@ -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 };
@@ -27,7 +27,7 @@ export type WatchContractEventsOptions<
* ### Listen to all events for a contract
* ```ts
* import { watchContractEvents } from "thirdweb";
* const unwatch = watchEvents({
* const unwatch = watchContractEvents({
* contract: myContract,
* onEvents: (events) => {
* // do something with the events
@@ -41,7 +41,7 @@ export type WatchContractEventsOptions<
* const myEvent = prepareEvent({
* event: "event MyEvent(uint256 myArg)",
* });
* const events = await watchEvents({
* const events = await watchContractEvents({
* contract: myContract,
* events: [myEvent],
* onEvents: (events) => {
@@ -0,0 +1,82 @@
/**
* READ
*/
export {
isClaimed,
type IsClaimedParams,
} from "../../extensions/airdrop/__generated__/Airdrop/read/isClaimed.js";
export {
tokenConditionId,
type TokenConditionIdParams,
} from "../../extensions/airdrop/__generated__/Airdrop/read/tokenConditionId.js";
export {
tokenMerkleRoot,
type TokenMerkleRootParams,
} from "../../extensions/airdrop/__generated__/Airdrop/read/tokenMerkleRoot.js";
/**
* Write
*/
export {
airdropERC20,
type AirdropERC20Params,
} from "../../extensions/airdrop/__generated__/Airdrop/write/airdropERC20.js";
export {
airdropERC721,
type AirdropERC721Params,
} from "../../extensions/airdrop/__generated__/Airdrop/write/airdropERC721.js";
export {
airdropERC1155,
type AirdropERC1155Params,
} from "../../extensions/airdrop/__generated__/Airdrop/write/airdropERC1155.js";
export {
airdropNativeToken,
type AirdropNativeTokenParams,
} from "../../extensions/airdrop/__generated__/Airdrop/write/airdropNativeToken.js";
export {
setMerkleRoot,
type SetMerkleRootParams,
} from "../../extensions/airdrop/__generated__/Airdrop/write/setMerkleRoot.js";
export {
airdropERC20WithSignature,
generateAirdropSignatureERC20,
type GenerateAirdropERC20SignatureOptions,
} from "../../extensions/airdrop/write/airdropERC20WithSignature.js";
export {
airdropERC721WithSignature,
generateAirdropSignatureERC721,
type GenerateAirdropERC721SignatureOptions,
} from "../../extensions/airdrop/write/airdropERC721WithSignature.js";
export {
airdropERC1155WithSignature,
generateAirdropSignatureERC1155,
type GenerateAirdropERC1155SignatureOptions,
} from "../../extensions/airdrop/write/airdropERC1155WithSignature.js";
export {
claimERC20,
type ClaimERC20Params,
} from "../../extensions/airdrop/write/claimERC20.js";
export {
claimERC721,
type ClaimERC721Params,
} from "../../extensions/airdrop/write/claimERC721.js";
export {
claimERC1155,
type ClaimERC1155Params,
} from "../../extensions/airdrop/write/claimERC1155.js";
export {
generateMerkleTreeInfoERC20,
type GenerateMerkleTreeInfoERC20Params,
} from "../../extensions/airdrop/write/merkleInfoERC20.js";
export {
generateMerkleTreeInfoERC721,
type GenerateMerkleTreeInfoERC721Params,
} from "../../extensions/airdrop/write/merkleInfoERC721.js";
export {
generateMerkleTreeInfoERC1155,
type GenerateMerkleTreeInfoERC1155Params,
} from "../../extensions/airdrop/write/merkleInfoERC1155.js";
export {
saveSnapshot,
type SaveSnapshotParams,
} from "../../extensions/airdrop/write/saveSnapshot.js";
@@ -1,4 +1,5 @@
// read
export { isERC20 } from "../../extensions/erc20/read/isERC20.js";
export {
getBalance,
type GetBalanceParams,
@@ -61,7 +61,7 @@ export {
} from "../../extensions/uniswap/__generated__/IUniswapV3Factory/write/setOwner.js";
export {
getUniswapV3Pools as getUniswapV3Pool,
type GetUniswapV3PoolsParams as GetUniswapV3PoolParams,
type GetUniswapV3PoolsResult as GetUniswapV3PoolResult,
getUniswapV3Pool,
type GetUniswapV3PoolParams,
type GetUniswapV3PoolResult,
} from "../../extensions/uniswap/read/getUniswapV3Pools.js";
+2
View File
@@ -54,6 +54,8 @@ export {
useIsAutoConnecting,
} from "../react/core/hooks/wallets/wallet-hooks.js";
export type { ConnectManagerOptions } from "../wallets/manager/index.js";
// contract related
export { useReadContract } from "../react/core/hooks/contract/useReadContract.js";
export {
@@ -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)",
});
}
@@ -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)",
});
}
@@ -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)",
});
}
@@ -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)",
});
}
@@ -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)",
});
}
@@ -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,
});
}
@@ -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: [],
});
}
@@ -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: [],
});
}
@@ -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],
});
}
@@ -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: [],
});
}
@@ -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],
});
}
@@ -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],
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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,
});
}
@@ -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 GenerateAirdropERC1155SignatureOptions = {
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: GenerateAirdropERC1155SignatureOptions,
) {
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 GenerateAirdropERC20SignatureOptions = {
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: GenerateAirdropERC20SignatureOptions,
) {
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 GenerateAirdropERC721SignatureOptions = {
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: GenerateAirdropERC721SignatureOptions,
) {
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 GenerateMerkleTreeInfoERC1155Params = {
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<GenerateMerkleTreeInfoERC1155Params>,
) {
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 GenerateMerkleTreeInfoERC20Params = {
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<GenerateMerkleTreeInfoERC20Params>,
) {
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 GenerateMerkleTreeInfoERC721Params = {
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<GenerateMerkleTreeInfoERC721Params>,
) {
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;
},
});
}
@@ -17,7 +17,7 @@ export type ResolveNameOptions = {
};
/**
* Resolves the primary name for a specificed address.
* Resolves the primary name for a specified address.
* @param options - The options for resolving an ENS address.
* @example
* ```ts
@@ -18,7 +18,7 @@ const MAGIC_VALUE = "0x1626ba7e";
* @param options.signature - The signature to check.
* @extension ERC1271
* @example
* ```
* ```ts
* import { checkContractWalletSignature } from "thirdweb/extensions/erc1271";
* const isValid = await checkContractWalletSignature({
* contract: myContract,
@@ -30,9 +30,9 @@ export type GetBalanceResult = {
* @extension ERC20
* @example
* ```ts
* import { balanceOf } from "thirdweb/extensions/erc20";
* import { getBalance } from "thirdweb/extensions/erc20";
*
* const balance = await balanceOf({ contract, address: "0x..." });
* const balance = await getBalance({ contract, address: "0x..." });
* ```
*/
export async function getBalance(
@@ -0,0 +1,20 @@
import type { BaseTransactionOptions } from "../../../transaction/types.js";
import { supportsInterface } from "../../erc165/__generated__/IERC165/read/supportsInterface.js";
/**
* Check if a contract supports the ERC20 interface.
* @param options - The transaction options.
* @returns A boolean indicating whether the contract supports the ERC20 interface.
* @extension ERC20
* @example
* ```ts
* import { isERC20 } from "thirdweb/extensions/erc20";
* const result = await isERC20({ contract });
* ```
*/
export function isERC20(options: BaseTransactionOptions) {
return supportsInterface({
contract: options.contract,
interfaceId: "0x36372b07",
});
}

Some files were not shown because too many files have changed in this diff Show More