Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
603e24f1e2 | ||
|
|
c9027fced0 | ||
|
|
ac8fa0b345 | ||
|
|
81a32b4dd2 | ||
|
|
bd0bb4fed7 | ||
|
|
b616dca7eb | ||
|
|
59434aac4f | ||
|
|
cef16471f4 | ||
|
|
0db0cc7564 | ||
|
|
229a47413e | ||
|
|
b75bcef55b | ||
|
|
2545a440dc | ||
|
|
0b4b6a5b4e | ||
|
|
b3d57949bd | ||
|
|
1cf1f866d5 | ||
|
|
602d8cbcfa | ||
|
|
33a78e68d1 | ||
|
|
235eb0460a | ||
|
|
3bb846adf0 | ||
|
|
b5648aee83 | ||
|
|
1b8f812fb8 | ||
|
|
1547d76cce | ||
|
|
7c78d1c6e8 | ||
|
|
058e4357c7 | ||
|
|
3a0e904fc2 |
@@ -1,5 +1,19 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 3.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b616dca7`](https://github.com/thirdweb-dev/js/commit/b616dca7eb861cd1d2adba3f3d1fe9c3b50f259e), [`2545a440`](https://github.com/thirdweb-dev/js/commit/2545a440dc272690cacbc23023f7b0a68f390c6e), [`229a4741`](https://github.com/thirdweb-dev/js/commit/229a47413e422952ad946b8c09af32cc1fcdc7f0)]:
|
||||
- @thirdweb-dev/wallets@0.2.15
|
||||
|
||||
## 3.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
|
||||
- @thirdweb-dev/wallets@0.2.14
|
||||
|
||||
## 3.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "3.0.12",
|
||||
"version": "3.0.14",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#870](https://github.com/thirdweb-dev/js/pull/870) [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains
|
||||
|
||||
## 0.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "ShimmerEVM Testnet",
|
||||
"title": "ShimmerEVM Testnet",
|
||||
"chain": "ShimmerEVM",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreibky2sy6qhi6arktayvologkrgu5kudpgdxfkx4uosbvmstz7v4di",
|
||||
"width": 720,
|
||||
"height": 720,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://shimmerevm-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://json-rpc.evm.testnet.shimmer.network"
|
||||
],
|
||||
"faucets": [
|
||||
"https://evm-toolkit.evm.testnet.shimmer.network",
|
||||
"https://evm-faucet.testnet.shimmer.network"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "SMR",
|
||||
"symbol": "SMR",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://shimmer.network",
|
||||
"shortName": "shimmerevm-testnet",
|
||||
"chainId": 1071,
|
||||
"networkId": 1071,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "explorer",
|
||||
"url": "https://explorer.evm.testnet.shimmer.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "shimmerevm-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,47 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Defi Oracle Meta Mainnet",
|
||||
"chain": "dfiometa",
|
||||
"icon": {
|
||||
"url": "ipfs://QmYrMRnjQJcNkYq9AvZ2FQ9kzYj9szzP4YDmyNA1ybd8xE",
|
||||
"width": 1000,
|
||||
"height": 1043,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://defi-oracle-meta.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.public-0138.defi-oracle.io",
|
||||
"wss://rpc.public-0138.defi-oracle.io"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://defi-oracle.io/",
|
||||
"shortName": "dfio-meta-main",
|
||||
"chainId": 138,
|
||||
"networkId": 1,
|
||||
"slip44": 60,
|
||||
"ens": {
|
||||
"registry": "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Quorum Explorer",
|
||||
"url": "https://public-0138.defi-oracle.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "defi-oracle-meta"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Neutrinos TestNet",
|
||||
"chain": "NEUTR",
|
||||
"rpc": [
|
||||
"https://neutrinos-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet-rpc.neutrinoschain.com"
|
||||
],
|
||||
"faucets": [
|
||||
"https://neutrinoschain.com/faucet"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Neutrinos",
|
||||
"symbol": "NEUTR",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.neutrinoschain.com",
|
||||
"shortName": "NEUTR",
|
||||
"chainId": 197,
|
||||
"networkId": 197,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://testnet.neutrinoschain.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "neutrinos-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -5,10 +5,10 @@ export default {
|
||||
"shortName": "Camelark",
|
||||
"chain": "ETHW",
|
||||
"icon": {
|
||||
"url": "ipfs://QmbXDcCWHh8jExE1tAUkUKzXyTb8srpC75ogZq1QYkMMRW",
|
||||
"url": "ipfs://QmeJerrsURFNt2LL7DE7TxeunjrQXiuezdfHyqmsbwX3MZ",
|
||||
"width": 128,
|
||||
"height": 128,
|
||||
"format": "svg"
|
||||
"format": "png"
|
||||
},
|
||||
"networkId": 20001,
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Defi Oracle Meta Testnet",
|
||||
"chain": "dfiometatest",
|
||||
"icon": {
|
||||
"url": "ipfs://QmYrMRnjQJcNkYq9AvZ2FQ9kzYj9szzP4YDmyNA1ybd8xE",
|
||||
"width": 1000,
|
||||
"height": 1043,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://defi-oracle-meta-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.public-2138.defi-oracle.io",
|
||||
"wss://rpc.public-2138.defi-oracle.io"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "testEther",
|
||||
"symbol": "tETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://defi-oracle.io/",
|
||||
"shortName": "dfio-meta-test",
|
||||
"chainId": 2138,
|
||||
"networkId": 21,
|
||||
"slip44": 60,
|
||||
"ens": {
|
||||
"registry": "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Quorum Explorer",
|
||||
"url": "https://public-2138.defi-oracle.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "defi-oracle-meta-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Taf ECO Chain Mainnet",
|
||||
"chain": "Taf ECO Chain",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreigpxhu7glccsislhjqpl5fnsfmj2io4cy33blhky642uiuyojossy",
|
||||
"width": 400,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://taf-eco-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet.tafchain.com/v1"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Taf ECO Chain Mainnet",
|
||||
"symbol": "TAFECO",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.tafchain.com",
|
||||
"shortName": "TAFECO",
|
||||
"chainId": 224168,
|
||||
"networkId": 224168,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Taf ECO Chain Mainnet",
|
||||
"url": "https://ecoscan.tafchain.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "taf-eco-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,50 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "WEMIX Kanvas Sepolia",
|
||||
"title": "WEMIX Kanvas Testnet Sepolia",
|
||||
"chainId": 2357,
|
||||
"shortName": "kanvas-aqua",
|
||||
"chain": "ETH",
|
||||
"networkId": 2357,
|
||||
"nativeCurrency": {
|
||||
"name": "Sepolia Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"rpc": [
|
||||
"https://wemix-kanvas-sepolia.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://api.aqua.wemixkanvas.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"infoURL": "https://wemixkanvas.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmVcVxsHsVg5BMii3EJ1MUSnLBZkQicpjmXjSmW66bCEUF",
|
||||
"width": 320,
|
||||
"height": 320,
|
||||
"format": "svg"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://blockscout.aqua.wemixkanvas.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmVcVxsHsVg5BMii3EJ1MUSnLBZkQicpjmXjSmW66bCEUF",
|
||||
"width": 320,
|
||||
"height": 320,
|
||||
"format": "svg"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"parent": {
|
||||
"type": "L2",
|
||||
"chain": "eip155-11155111",
|
||||
"bridges": [
|
||||
{
|
||||
"url": "https://wemixkanvas.io/bridge"
|
||||
}
|
||||
]
|
||||
},
|
||||
"testnet": true,
|
||||
"slug": "wemix-kanvas-sepolia"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Acria IntelliChain",
|
||||
"chain": "AIC",
|
||||
"rpc": [
|
||||
"https://acria-intellichain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://aic.acria.ai"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "ACRIA",
|
||||
"symbol": "ACRIA",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://acria.ai",
|
||||
"shortName": "aic",
|
||||
"chainId": 47,
|
||||
"networkId": 47,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Acria IntelliChain-Explorer",
|
||||
"url": "https://explorer.acria.ai",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "acria-intellichain"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,28 +0,0 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Canto Testnet",
|
||||
"chain": "Canto Tesnet",
|
||||
"rpc": [
|
||||
"https://canto-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://eth.plexnode.wtf/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Canto",
|
||||
"symbol": "CANTO",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://canto.io",
|
||||
"shortName": "tcanto",
|
||||
"chainId": 740,
|
||||
"networkId": 740,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Canto Tesnet Explorer (Neobase)",
|
||||
"url": "https://testnet-explorer.canto.neobase.one",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "canto-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Canto Tesnet",
|
||||
"chain": "Canto",
|
||||
"rpc": [
|
||||
"https://canto-tesnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet-archive.plexnode.wtf"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Testnet Canto",
|
||||
"symbol": "CANTO",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://canto.io",
|
||||
"shortName": "TestnetCanto",
|
||||
"chainId": 7701,
|
||||
"networkId": 7701,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Canto Testnet EVM Explorer (Blockscout)",
|
||||
"url": "https://testnet.tuber.build",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "canto-tesnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "BeOne Chain Mainnet",
|
||||
"chain": "BOC",
|
||||
"icon": {
|
||||
"url": "ipfs://QmbVLQnaMDu86bPyKgCvTGhFBeYwjr15hQnrCcsp1EkAGL",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://beone-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://dataseed1.beonechain.com",
|
||||
"https://dataseed2.beonechain.com",
|
||||
"https://dataseed-us1.beonechain.com",
|
||||
"https://dataseed-us2.beonechain.com",
|
||||
"https://dataseed-uk1.beonechain.com",
|
||||
"https://dataseed-uk2.beonechain.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "BeOne Chain Mainnet",
|
||||
"symbol": "BOC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://beonechain.com",
|
||||
"shortName": "BOC",
|
||||
"chainId": 818,
|
||||
"networkId": 818,
|
||||
"slip44": 8181,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "BeOne Chain Mainnet",
|
||||
"url": "https://beonescan.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "beone-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "DecentraBone Layer1 Testnet",
|
||||
"chain": "DBONE",
|
||||
"rpc": [
|
||||
"https://decentrabone-layer1-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://layer1test.decentrabone.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "DecentraBone",
|
||||
"symbol": "DBONE",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://decentrabone.com",
|
||||
"shortName": "DBONE",
|
||||
"chainId": 910,
|
||||
"networkId": 910,
|
||||
"testnet": true,
|
||||
"slug": "decentrabone-layer1-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.10",
|
||||
"version": "0.1.11",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"browser": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,39 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.10.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#877](https://github.com/thirdweb-dev/js/pull/877) [`cef16471`](https://github.com/thirdweb-dev/js/commit/cef16471f4493d7c2c1897a81ffebf84a743716e) Thanks [@iketw](https://github.com/iketw)! - [CLI] Update min ruby version supported to 2.7.6 for React Native templates
|
||||
|
||||
- Updated dependencies [[`ac8fa0b3`](https://github.com/thirdweb-dev/js/commit/ac8fa0b34545a2bc0b489a0551d476a9f560e851), [`b75bcef5`](https://github.com/thirdweb-dev/js/commit/b75bcef55bfdedc260b5b62bb4aff10a7d5c47b6), [`c9027fce`](https://github.com/thirdweb-dev/js/commit/c9027fced0fffbf757bf0080bc4a49f5464df647)]:
|
||||
- @thirdweb-dev/sdk@3.10.10
|
||||
|
||||
## 0.10.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
|
||||
- @thirdweb-dev/sdk@3.10.9
|
||||
|
||||
## 0.10.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#867](https://github.com/thirdweb-dev/js/pull/867) [`3bb846ad`](https://github.com/thirdweb-dev/js/commit/3bb846adf0484e8b7dc7dfeba9f9c0ee26f4ef35) Thanks [@adam-maj](https://github.com/adam-maj)! - Generate auto detects smart contracts in project
|
||||
|
||||
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
|
||||
- @thirdweb-dev/sdk@3.10.8
|
||||
- @thirdweb-dev/chains@0.1.11
|
||||
|
||||
## 0.10.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#857](https://github.com/thirdweb-dev/js/pull/857) [`3a0e904f`](https://github.com/thirdweb-dev/js/commit/3a0e904fc2bae5134ba3bf65ba666c3360e4fced) Thanks [@adam-maj](https://github.com/adam-maj)! - Add skip intro flag to generate command and fix ABI cache regex
|
||||
|
||||
- [#860](https://github.com/thirdweb-dev/js/pull/860) [`058e4357`](https://github.com/thirdweb-dev/js/commit/058e4357c783911a6cab6b38c6eebbb3277dfe93) Thanks [@iketw](https://github.com/iketw)! - [CLI] Only checks ruby version and attempts to run pod install if the platform is macOS
|
||||
|
||||
## 0.10.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -63,7 +63,7 @@ Deploying published contracts give deployers access to automatic SDKs to integra
|
||||
npx thirdweb@latest detect
|
||||
```
|
||||
|
||||
As you're developing your contracts, you may want to implement [Extensions](https://portal.thirdweb.com/contractkit) to unlock functionality on the SDKs (ie. nft minting with automatic upload to IPFS) and the dashboard (ie. generated UI to manage permissions). This command will show what extensions were detected on your contract, unlocking the corresponding functionality on the SDKs and dashboard.
|
||||
As you're developing your contracts, you may want to implement [Extensions](https://portal.thirdweb.com/solidity/extensions) to unlock functionality on the SDKs (ie. nft minting with automatic upload to IPFS) and the dashboard (ie. generated UI to manage permissions). This command will show what extensions were detected on your contract, unlocking the corresponding functionality on the SDKs and dashboard.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export const CREATE_MESSAGES = {
|
||||
} as const;
|
||||
|
||||
export const GENERATE_MESSAGES = {
|
||||
deployerAddress: "What is your deployer wallet address?",
|
||||
chains: "What chains are you using in your project?",
|
||||
};
|
||||
|
||||
export const ERROR_MESSAGES = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.10.7",
|
||||
"version": "0.10.11",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -34,6 +34,7 @@
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
"@thirdweb-dev/storage": "workspace:*",
|
||||
"async-retry": "^1.3.3",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { logger } from "../core/helpers/logger";
|
||||
import { existsSync, readdirSync, statSync } from "fs";
|
||||
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
|
||||
import { basename, join } from "path";
|
||||
|
||||
export function findFiles(
|
||||
@@ -38,3 +38,38 @@ export function findFiles(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function findMatches(
|
||||
startPath: string,
|
||||
filter: RegExp,
|
||||
results: string[],
|
||||
) {
|
||||
if (!existsSync(startPath)) {
|
||||
console.log("no dir ", startPath);
|
||||
return;
|
||||
}
|
||||
|
||||
const files = readdirSync(startPath);
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const filename = join(startPath, files[i]);
|
||||
const stat = statSync(filename);
|
||||
|
||||
if (stat.isDirectory() && basename(filename) === "node_modules") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stat.isDirectory() && filename.startsWith(".")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
findMatches(filename, filter, results);
|
||||
} else {
|
||||
const fileContents = readFileSync(filename, "utf-8");
|
||||
const matches = fileContents.match(filter);
|
||||
if (matches) {
|
||||
results.push(...matches);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { runCommand } from "./run-command";
|
||||
import chalk from "chalk";
|
||||
|
||||
export const SUPPORTED_RUBY_VERSION = "2.7.5";
|
||||
export const SUPPORTED_RUBY_VERSION = "2.7.6";
|
||||
|
||||
/**
|
||||
* Checks if the current ruby version is supported by the project.
|
||||
|
||||
@@ -62,6 +62,24 @@ export async function createApp({
|
||||
}
|
||||
}
|
||||
|
||||
const isReactNative =
|
||||
template?.includes("react-native") || framework === "react-native";
|
||||
function isReactNativeCLI() {
|
||||
return (
|
||||
isReactNative &&
|
||||
(language === "typescript" || (template && !template.includes("expo")))
|
||||
);
|
||||
}
|
||||
|
||||
function isMacOS() {
|
||||
return process.platform === "darwin";
|
||||
}
|
||||
|
||||
if (isReactNativeCLI() && isMacOS()) {
|
||||
// fail early if the user doesn't have the right version of Ruby installed on macOS
|
||||
await checkRubyVersion();
|
||||
}
|
||||
|
||||
const root = path.resolve(appPath);
|
||||
|
||||
if (!(await isWriteable(path.dirname(root)))) {
|
||||
@@ -98,20 +116,6 @@ export async function createApp({
|
||||
);
|
||||
}
|
||||
|
||||
const isReactNative =
|
||||
template?.includes("react-native") || framework === "react-native";
|
||||
function isReactNativeCLI() {
|
||||
return (
|
||||
isReactNative &&
|
||||
(language === "typescript" || (template && !template.includes("expo")))
|
||||
);
|
||||
}
|
||||
|
||||
if (isReactNativeCLI()) {
|
||||
// fail early if the user doesn't have the right version of Ruby installed
|
||||
await checkRubyVersion();
|
||||
}
|
||||
|
||||
if (template) {
|
||||
/**
|
||||
* If a template repository is provided, clone it.
|
||||
@@ -199,7 +203,7 @@ export async function createApp({
|
||||
console.log();
|
||||
}
|
||||
|
||||
if (isReactNativeCLI()) {
|
||||
if (isReactNativeCLI() && isMacOS()) {
|
||||
await podInstall(root, isOnline);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { runCommand } from "./run-command";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
/**
|
||||
* Checks if the current ruby version is supported by the project.
|
||||
*
|
||||
* @returns A Promise that resolves once the ruby version is checked. True if it changed, false otherwise.
|
||||
*/
|
||||
export function setRubyVersion(root: string): Promise<boolean> {
|
||||
/**
|
||||
* Return a Promise that resolves once the installation is finished.
|
||||
*/
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
await runCommand("ruby", ["-v"], false, (dataBfr) => {
|
||||
const data = String(dataBfr);
|
||||
const systemVersion = data.split(" ")[1];
|
||||
|
||||
let rubyVersionFile = path.join(root, ".ruby-version");
|
||||
let rubyProjectVersionString = "";
|
||||
|
||||
try {
|
||||
rubyProjectVersionString = String(fs.readFileSync(rubyVersionFile));
|
||||
} catch (error) {
|
||||
rubyVersionFile = path.join(root, "_ruby-version");
|
||||
rubyProjectVersionString = String(fs.readFileSync(rubyVersionFile));
|
||||
}
|
||||
|
||||
try {
|
||||
if (systemVersion.includes(rubyProjectVersionString)) {
|
||||
// same version, no need to update
|
||||
resolve(false);
|
||||
} else {
|
||||
const systemVersionWithoutPatch = systemVersion.split("p")[0];
|
||||
fs.writeFileSync(rubyVersionFile, systemVersionWithoutPatch);
|
||||
resolve(true);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(
|
||||
"Failed to update ruby version. Please, set your ruby version to a minimum of 2.6 and try again.",
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3,54 +3,101 @@ import {
|
||||
DeployedContract,
|
||||
fetchContractMetadataFromAddress,
|
||||
getChainProvider,
|
||||
ThirdwebSDK,
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { spinner, info } from "../core/helpers/logger";
|
||||
import { allChains } from "@thirdweb-dev/chains";
|
||||
import fs from "fs";
|
||||
import prompts from "prompts";
|
||||
|
||||
type GenerateOptions = {
|
||||
path: string;
|
||||
deployer?: string;
|
||||
};
|
||||
import { findMatches } from "../common/file-helper";
|
||||
import ora from "ora";
|
||||
import { GenerateOptions, ThirdwebConfig } from "./types";
|
||||
import { CHAIN_OPTIONS, getContractsForAddresses } from "./utils";
|
||||
|
||||
export async function generate(options: GenerateOptions) {
|
||||
let projectPath: string = options.path?.replace(/\/$/, "") || ".";
|
||||
|
||||
let contracts: DeployedContract[] = [];
|
||||
|
||||
// Find all addresses in this project
|
||||
let addresses: string[] = [];
|
||||
findMatches(projectPath, /(0x[a-fA-F0-9]{40})/g, addresses);
|
||||
|
||||
// We check if there's a thirdweb.json config file present
|
||||
if (fs.existsSync(`${projectPath}/thirdweb.json`)) {
|
||||
// First we check if there's a thirdweb.json config file present
|
||||
const thirdwebConfig = JSON.parse(
|
||||
// Read the current thirdweb config file
|
||||
const thirdwebConfig: ThirdwebConfig = JSON.parse(
|
||||
fs.readFileSync(`${projectPath}/thirdweb.json`, "utf-8"),
|
||||
);
|
||||
contracts = thirdwebConfig.contracts as DeployedContract[];
|
||||
} else {
|
||||
// Otherwise, we get contracts by deployer address (and generate a thirdweb.json)
|
||||
let deployerAddress: string;
|
||||
if (options.deployer) {
|
||||
deployerAddress = options.deployer;
|
||||
} else {
|
||||
const res = await prompts({
|
||||
type: "text",
|
||||
name: "deployer",
|
||||
message: GENERATE_MESSAGES.deployerAddress,
|
||||
});
|
||||
|
||||
deployerAddress = res.deployer.trim();
|
||||
}
|
||||
|
||||
const sdk = new ThirdwebSDK("polygon");
|
||||
contracts = await sdk.multiChainRegistry.getContractAddresses(
|
||||
deployerAddress,
|
||||
// Check if there are any addresses in the project that aren't yet in the config
|
||||
const configAddresses = thirdwebConfig.contracts.map((contract) =>
|
||||
contract.address.toLowerCase(),
|
||||
);
|
||||
const newAddresses = addresses.filter(
|
||||
(address) => !configAddresses.includes(address.toLowerCase()),
|
||||
);
|
||||
|
||||
// Initialize contracts to the contracts in thirdweb.json file
|
||||
contracts = [...thirdwebConfig.contracts];
|
||||
|
||||
// If we have new contracts that aren't yet stored in config
|
||||
// get full contract objects
|
||||
if (newAddresses.length) {
|
||||
const chainIds = thirdwebConfig.chainIds;
|
||||
await getContractsForAddresses(newAddresses, chainIds, contracts);
|
||||
|
||||
if (contracts.length > thirdwebConfig.contracts.length) {
|
||||
fs.writeFileSync(
|
||||
`${projectPath}/thirdweb.json`,
|
||||
JSON.stringify({ chainIds, contracts }, undefined, 2),
|
||||
);
|
||||
|
||||
const numberOfNewContracts =
|
||||
contracts.length - thirdwebConfig.contracts.length;
|
||||
info(
|
||||
`Updated thirdweb.json with ${numberOfNewContracts} new contract${
|
||||
numberOfNewContracts === 1 ? "" : "s"
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If there is no configuration file present, we need to generate one...
|
||||
|
||||
// First we ask the user what chains are used in their project
|
||||
const res = await prompts({
|
||||
type: "autocompleteMultiselect",
|
||||
name: "chains",
|
||||
message: GENERATE_MESSAGES.chains,
|
||||
choices: CHAIN_OPTIONS,
|
||||
});
|
||||
|
||||
const chainIds: number[] = res.chains.map(
|
||||
(index: number) => allChains[index].chainId,
|
||||
);
|
||||
|
||||
// Then we check for the chainId of each address
|
||||
await getContractsForAddresses(addresses, chainIds, contracts);
|
||||
|
||||
// Create a thirdweb.json file with the specific contracts and chain ids
|
||||
fs.writeFileSync(
|
||||
`${projectPath}/thirdweb.json`,
|
||||
JSON.stringify({ contracts }, undefined, 2),
|
||||
JSON.stringify({ chainIds, contracts }, undefined, 2),
|
||||
);
|
||||
|
||||
info(
|
||||
`Created a thirdweb.json file with configuration for ${
|
||||
contracts.length
|
||||
} contract${
|
||||
contracts.length === 1 ? "" : "s"
|
||||
} detected in your project.\n\n - You can also update this configuration manually by editing the file.\n`,
|
||||
);
|
||||
}
|
||||
|
||||
// Attempt to download the ABI for the contract
|
||||
// Attempt to download the ABI for each contract
|
||||
const abiSpinner = spinner(
|
||||
`Downloading ABIs for contracts configured in 'thirdweb.json'`,
|
||||
);
|
||||
const storage = new ThirdwebStorage();
|
||||
const metadata: {
|
||||
address: string;
|
||||
@@ -97,7 +144,7 @@ export async function generate(options: GenerateOptions) {
|
||||
}
|
||||
|
||||
const file = fs.readFileSync(filePath, "utf-8");
|
||||
const abiRegex = /GENERATED_ABI = \{.*\}/s;
|
||||
const abiRegex = /GENERATED_ABI = \{.*\};\n\n/s;
|
||||
const contractAbis = metadata.reduce((acc, contract) => {
|
||||
acc[contract.address] = contract.metadata.abi;
|
||||
return acc;
|
||||
@@ -105,8 +152,9 @@ export async function generate(options: GenerateOptions) {
|
||||
const updatedAbis = JSON.stringify(contractAbis, null, 2);
|
||||
const updatedFile = file.replace(
|
||||
abiRegex,
|
||||
`GENERATED_ABI = ${updatedAbis}`,
|
||||
`GENERATED_ABI = ${updatedAbis};\n\n`,
|
||||
);
|
||||
|
||||
fs.writeFileSync(filePath, updatedFile);
|
||||
});
|
||||
|
||||
@@ -128,6 +176,12 @@ export async function generate(options: GenerateOptions) {
|
||||
fs.writeFileSync(typeFilePath, updatedFile);
|
||||
}
|
||||
|
||||
abiSpinner.succeed(
|
||||
`Downloaded and cached ABIs for ${contracts.length} smart contract${
|
||||
contracts.length === 1 ? "" : "s"
|
||||
}`,
|
||||
);
|
||||
|
||||
// Add generate command to postinstall
|
||||
const packageJsonPath = `${projectPath}/package.json`;
|
||||
if (!fs.existsSync(packageJsonPath)) {
|
||||
@@ -141,8 +195,8 @@ export async function generate(options: GenerateOptions) {
|
||||
|
||||
const postinstall = packageJson.scripts?.postinstall
|
||||
? packageJson.scripts.postinstall +
|
||||
` && npx thirdweb generate --skip-update-check`
|
||||
: `npx thirdweb generate --skip-update-check`;
|
||||
` && export THIRDWEB_CLI_SKIP_INTRO=true && npx thirdweb generate --skip-update-check`
|
||||
: `export THIRDWEB_CLI_SKIP_INTRO=true && npx thirdweb generate --skip-update-check`;
|
||||
|
||||
fs.writeFileSync(
|
||||
packageJsonPath,
|
||||
@@ -158,4 +212,8 @@ export async function generate(options: GenerateOptions) {
|
||||
2,
|
||||
),
|
||||
);
|
||||
|
||||
ora(
|
||||
"Added 'npx thirdweb generate' to postinstall in package.json.\n\n - This is necessary to use 'thirdweb generate' in production.\n",
|
||||
).info();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { DeployedContract } from "@thirdweb-dev/sdk";
|
||||
|
||||
export type ThirdwebConfig = {
|
||||
chainIds: number[];
|
||||
contracts: DeployedContract[];
|
||||
};
|
||||
|
||||
export type GenerateOptions = {
|
||||
path: string;
|
||||
deployer?: string;
|
||||
};
|
||||
|
||||
export type ContractChainPrompt = {
|
||||
address: string;
|
||||
chains: {
|
||||
slug: string;
|
||||
chainId: number;
|
||||
}[];
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
import { DeployedContract, getChainProvider } from "@thirdweb-dev/sdk";
|
||||
import prompts from "prompts";
|
||||
import { ContractChainPrompt } from "./types";
|
||||
import { allChains } from "@thirdweb-dev/chains";
|
||||
|
||||
export const CHAIN_OPTIONS = allChains.map((chain) => ({ title: chain.slug }));
|
||||
|
||||
export async function getContractsForAddresses(
|
||||
addresses: string[],
|
||||
chainIds: number[],
|
||||
contracts: DeployedContract[],
|
||||
) {
|
||||
let contractChainPrompts: ContractChainPrompt[] = [];
|
||||
|
||||
await Promise.all(
|
||||
addresses.map(async (address) => {
|
||||
// Check which chainIds of the provided chains have a contract at this address
|
||||
let chainIdsWithContract: number[] = [];
|
||||
|
||||
await Promise.all(
|
||||
chainIds.map(async (chainId) => {
|
||||
// Handles cacheing of provider by chain
|
||||
const provider = getChainProvider(chainId, {});
|
||||
|
||||
try {
|
||||
const code = await provider.getCode(address);
|
||||
|
||||
if (!code || code === "0x") {
|
||||
return;
|
||||
}
|
||||
|
||||
chainIdsWithContract.push(chainId);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
// If no chainId has this contract, we assume it's an EOA and move on
|
||||
if (!chainIdsWithContract.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If only one chain has this contract address, add it to our contracts list
|
||||
if (chainIdsWithContract.length === 1) {
|
||||
contracts.push({
|
||||
address,
|
||||
chainId: chainIdsWithContract[0],
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, add our contract to the list of contracts
|
||||
// where we need to prompt the user to select the chain
|
||||
contractChainPrompts.push({
|
||||
address,
|
||||
chains: chainIdsWithContract.map((chainId) => ({
|
||||
slug: allChains[chainId].slug,
|
||||
chainId,
|
||||
})),
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// TODO: Long term, smart contracts in the generated-abis cache should be cached by
|
||||
// both smart contract and chain id because people may want to use the same contract address
|
||||
// on different chains
|
||||
|
||||
// For all addresses that have smart contracts deployed on multiple selected chains
|
||||
// allow the user to specify which chain they want to use for their smart contract
|
||||
for (const prompt of contractChainPrompts) {
|
||||
const res = await prompts({
|
||||
type: "select",
|
||||
name: "chainId",
|
||||
message: `What chain is smart contract '${prompt.address}' on?`,
|
||||
choices: prompt.chains.map((chain) => ({
|
||||
title: chain.slug,
|
||||
value: chain.chainId,
|
||||
})),
|
||||
});
|
||||
|
||||
contracts.push({
|
||||
address: prompt.address,
|
||||
chainId: res.chainId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/contracts-js
|
||||
|
||||
## 1.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#756](https://github.com/thirdweb-dev/js/pull/756) [`b75bcef5`](https://github.com/thirdweb-dev/js/commit/b75bcef55bfdedc260b5b62bb4aff10a7d5c47b6) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Any EVM deploy flow with Create2 factory
|
||||
|
||||
## 1.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/contracts-js",
|
||||
"version": "1.3.2",
|
||||
"version": "1.3.3",
|
||||
"main": "dist/thirdweb-dev-contracts-js.cjs.js",
|
||||
"module": "dist/thirdweb-dev-contracts-js.esm.js",
|
||||
"browser": {
|
||||
@@ -10,7 +10,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/contracts-js",
|
||||
"dependencies": {
|
||||
"@thirdweb-dev/contracts": "3.4.4"
|
||||
"@thirdweb-dev/contracts": "3.4.6-1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 3.11.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#876](https://github.com/thirdweb-dev/js/pull/876) [`0db0cc75`](https://github.com/thirdweb-dev/js/commit/0db0cc756436dba8f9df0cf8678b87c009acc283) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Fix useContractEvents cache not storing individual events
|
||||
|
||||
- Updated dependencies [[`ac8fa0b3`](https://github.com/thirdweb-dev/js/commit/ac8fa0b34545a2bc0b489a0551d476a9f560e851), [`b616dca7`](https://github.com/thirdweb-dev/js/commit/b616dca7eb861cd1d2adba3f3d1fe9c3b50f259e), [`2545a440`](https://github.com/thirdweb-dev/js/commit/2545a440dc272690cacbc23023f7b0a68f390c6e), [`b75bcef5`](https://github.com/thirdweb-dev/js/commit/b75bcef55bfdedc260b5b62bb4aff10a7d5c47b6), [`229a4741`](https://github.com/thirdweb-dev/js/commit/229a47413e422952ad946b8c09af32cc1fcdc7f0), [`c9027fce`](https://github.com/thirdweb-dev/js/commit/c9027fced0fffbf757bf0080bc4a49f5464df647)]:
|
||||
- @thirdweb-dev/sdk@3.10.10
|
||||
- @thirdweb-dev/wallets@0.2.15
|
||||
|
||||
## 3.11.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
|
||||
- @thirdweb-dev/sdk@3.10.9
|
||||
|
||||
## 3.11.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#870](https://github.com/thirdweb-dev/js/pull/870) [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d) Thanks [@jnsdls](https://github.com/jnsdls)! - fix crash during SSR when "window" is undefined
|
||||
|
||||
- [#862](https://github.com/thirdweb-dev/js/pull/862) [`b5648aee`](https://github.com/thirdweb-dev/js/commit/b5648aee83b299d07a8eed7773bd32bcceef9657) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Make tokenId optional one useNFTBalance
|
||||
|
||||
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
|
||||
- @thirdweb-dev/sdk@3.10.8
|
||||
- @thirdweb-dev/wallets@0.2.14
|
||||
- @thirdweb-dev/chains@0.1.11
|
||||
|
||||
## 3.11.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "3.11.4",
|
||||
"version": "3.11.7",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -61,12 +61,12 @@ export function useNetwork(): [NetworkMetadata, SwitchNetwork | undefined] {
|
||||
const supportedChains = useSupportedChains();
|
||||
const wallet = useWallet();
|
||||
|
||||
const isMetamaskInstalled = assertWindowEthereum(window)
|
||||
? window.ethereum.isMetaMask
|
||||
const isMetamaskInstalled = assertWindowEthereum(globalThis.window)
|
||||
? globalThis.window.ethereum.isMetaMask
|
||||
: false;
|
||||
|
||||
const isCoinbaseInstalled = assertWindowEthereum(window)
|
||||
? window.ethereum.isCoinbaseWallet
|
||||
const isCoinbaseInstalled = assertWindowEthereum(globalThis.window)
|
||||
? globalThis.window.ethereum.isCoinbaseWallet
|
||||
: false;
|
||||
|
||||
// switch not supported if connected to a mobile wallet
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {
|
||||
AbstractBrowserWallet,
|
||||
AbstractClientWallet,
|
||||
Chain,
|
||||
DAppMetaData,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
@@ -15,16 +15,16 @@ export type WalletOptions = {
|
||||
dappMetadata?: DAppMetaData;
|
||||
} & ExtraCoreWalletOptions;
|
||||
|
||||
export type WalletInstance = InstanceType<typeof AbstractBrowserWallet>;
|
||||
export type WalletInstance = InstanceType<typeof AbstractClientWallet>;
|
||||
|
||||
export type WalletClass<I extends WalletInstance = WalletInstance> = {
|
||||
id: string;
|
||||
new (options: WalletOptions): I;
|
||||
meta: (typeof AbstractBrowserWallet)["meta"];
|
||||
meta: (typeof AbstractClientWallet)["meta"];
|
||||
};
|
||||
|
||||
export type Wallet<I extends WalletInstance = WalletInstance> = {
|
||||
id: string;
|
||||
meta: (typeof AbstractBrowserWallet)["meta"];
|
||||
meta: (typeof AbstractClientWallet)["meta"];
|
||||
create: (options: WalletOptions) => I;
|
||||
};
|
||||
|
||||
@@ -427,11 +427,11 @@ export function useContractEvents(
|
||||
() =>
|
||||
createCacheKeyWithNetwork(
|
||||
eventName
|
||||
? cacheKeys.contract.events.getAllEvents(contractAddress)
|
||||
: cacheKeys.contract.events.getEvents(
|
||||
? cacheKeys.contract.events.getEvents(
|
||||
contractAddress,
|
||||
eventName as string,
|
||||
),
|
||||
)
|
||||
: cacheKeys.contract.events.getAllEvents(contractAddress),
|
||||
activeChainId,
|
||||
),
|
||||
[activeChainId, contractAddress, eventName],
|
||||
|
||||
@@ -275,7 +275,7 @@ export function useOwnedNFTs<TContract extends NFTContract>(
|
||||
export function useNFTBalance(
|
||||
contract: RequiredParam<NFTContract>,
|
||||
ownerWalletAddress: RequiredParam<WalletAddress>,
|
||||
tokenId: RequiredParam<BigNumberish>,
|
||||
tokenId?: RequiredParam<BigNumberish>,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
const { erc721, erc1155 } = getErcs(contract);
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.2.7
|
||||
|
||||
## 0.2.6
|
||||
|
||||
## 0.2.5
|
||||
|
||||
## 0.2.4
|
||||
|
||||
## 0.2.3
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.2.4",
|
||||
"version": "0.2.7",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.2.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ac8fa0b3`](https://github.com/thirdweb-dev/js/commit/ac8fa0b34545a2bc0b489a0551d476a9f560e851), [`b616dca7`](https://github.com/thirdweb-dev/js/commit/b616dca7eb861cd1d2adba3f3d1fe9c3b50f259e), [`2545a440`](https://github.com/thirdweb-dev/js/commit/2545a440dc272690cacbc23023f7b0a68f390c6e), [`b75bcef5`](https://github.com/thirdweb-dev/js/commit/b75bcef55bfdedc260b5b62bb4aff10a7d5c47b6), [`229a4741`](https://github.com/thirdweb-dev/js/commit/229a47413e422952ad946b8c09af32cc1fcdc7f0), [`c9027fce`](https://github.com/thirdweb-dev/js/commit/c9027fced0fffbf757bf0080bc4a49f5464df647), [`0db0cc75`](https://github.com/thirdweb-dev/js/commit/0db0cc756436dba8f9df0cf8678b87c009acc283)]:
|
||||
- @thirdweb-dev/sdk@3.10.10
|
||||
- @thirdweb-dev/wallets@0.2.15
|
||||
- @thirdweb-dev/react-core@3.11.7
|
||||
|
||||
## 0.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
|
||||
- @thirdweb-dev/sdk@3.10.9
|
||||
- @thirdweb-dev/react-core@3.11.6
|
||||
|
||||
## 0.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d), [`b5648aee`](https://github.com/thirdweb-dev/js/commit/b5648aee83b299d07a8eed7773bd32bcceef9657), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
|
||||
- @thirdweb-dev/sdk@3.10.8
|
||||
- @thirdweb-dev/react-core@3.11.5
|
||||
- @thirdweb-dev/wallets@0.2.14
|
||||
- @thirdweb-dev/chains@0.1.11
|
||||
|
||||
## 0.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.2.4",
|
||||
"version": "0.2.7",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -4,7 +4,7 @@ import type {
|
||||
CoinbaseWalletConnectorOptions,
|
||||
} from "../connectors/coinbase-wallet";
|
||||
import {
|
||||
AbstractBrowserWallet,
|
||||
AbstractClientWallet,
|
||||
TWConnector,
|
||||
WagmiAdapter,
|
||||
WalletOptions,
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
|
||||
type CoinbaseWalletOptions = Omit<WalletOptions<CoinbaseWalletConnectorOptions>,"walletStorage">;
|
||||
|
||||
export class CoinbaseWallet extends AbstractBrowserWallet<CoinbaseWalletConnectorOptions> {
|
||||
export class CoinbaseWallet extends AbstractClientWallet<CoinbaseWalletConnectorOptions> {
|
||||
static meta = {
|
||||
id: "coinbase",
|
||||
name: "Coinbase Wallet",
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.11.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#859](https://github.com/thirdweb-dev/js/pull/859) [`229a4741`](https://github.com/thirdweb-dev/js/commit/229a47413e422952ad946b8c09af32cc1fcdc7f0) Thanks [@MananTank](https://github.com/MananTank)! - Fix Error when connecting to Safe in Vite
|
||||
|
||||
- [#879](https://github.com/thirdweb-dev/js/pull/879) [`59434aac`](https://github.com/thirdweb-dev/js/commit/59434aac4f1ca6d16a212c5379cf29fd346baf26) Thanks [@MananTank](https://github.com/MananTank)! - [react] add style prop on ConnectWallet and Web3Button
|
||||
|
||||
- Updated dependencies [[`ac8fa0b3`](https://github.com/thirdweb-dev/js/commit/ac8fa0b34545a2bc0b489a0551d476a9f560e851), [`b616dca7`](https://github.com/thirdweb-dev/js/commit/b616dca7eb861cd1d2adba3f3d1fe9c3b50f259e), [`2545a440`](https://github.com/thirdweb-dev/js/commit/2545a440dc272690cacbc23023f7b0a68f390c6e), [`b75bcef5`](https://github.com/thirdweb-dev/js/commit/b75bcef55bfdedc260b5b62bb4aff10a7d5c47b6), [`229a4741`](https://github.com/thirdweb-dev/js/commit/229a47413e422952ad946b8c09af32cc1fcdc7f0), [`c9027fce`](https://github.com/thirdweb-dev/js/commit/c9027fced0fffbf757bf0080bc4a49f5464df647), [`0db0cc75`](https://github.com/thirdweb-dev/js/commit/0db0cc756436dba8f9df0cf8678b87c009acc283)]:
|
||||
- @thirdweb-dev/sdk@3.10.10
|
||||
- @thirdweb-dev/wallets@0.2.15
|
||||
- @thirdweb-dev/react-core@3.11.7
|
||||
|
||||
## 3.11.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
|
||||
- @thirdweb-dev/sdk@3.10.9
|
||||
- @thirdweb-dev/react-core@3.11.6
|
||||
|
||||
## 3.11.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d), [`b5648aee`](https://github.com/thirdweb-dev/js/commit/b5648aee83b299d07a8eed7773bd32bcceef9657), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
|
||||
- @thirdweb-dev/sdk@3.10.8
|
||||
- @thirdweb-dev/react-core@3.11.5
|
||||
- @thirdweb-dev/wallets@0.2.14
|
||||
- @thirdweb-dev/chains@0.1.11
|
||||
|
||||
## 3.11.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -143,7 +143,7 @@ Each [extension](https://portal.thirdweb.com/extensions) you implement in your s
|
||||
|
||||
These hooks make it easy to interact with your smart contracts by implementing the complex logic for you under the hood.
|
||||
|
||||
For example, if your smart contract implements [ERC721Supply](https://portal.thirdweb.com/contractkit/interfaces/erc721supply#unlocked-features), you unlock the ability to [view all NFTs](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721supply#get-all-minted-nfts) on that contract using the SDK; which fetches all of your NFT metadata and the current owner of each NFT in parallel. In the React SDK, that is available using `useNFTs`:
|
||||
For example, if your smart contract implements [ERC721Supply](https://portal.thirdweb.com/solidity/extensions/erc721supply), you unlock the ability to [view all NFTs](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721supply#get-all-minted-nfts) on that contract using the SDK; which fetches all of your NFT metadata and the current owner of each NFT in parallel. In the React SDK, that is available using `useNFTs`:
|
||||
|
||||
```jsx
|
||||
import { useContract, useNFTs } from "@thirdweb-dev/react";
|
||||
@@ -154,7 +154,7 @@ export default function Home() {
|
||||
}
|
||||
```
|
||||
|
||||
If we want to mint an NFT and our contract implements [ERC721Mintable](https://portal.thirdweb.com/contractkit/interfaces/erc721mintable#unlocked-features), we can use the [`useMintNFT`](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721mintable) hook to mint an NFT from the connected wallet; handling all of the logic of uploading and pinning the metadata to IPFS for us behind the scenes.
|
||||
If we want to mint an NFT and our contract implements [ERC721Mintable](https://portal.thirdweb.com/solidity/extensions/erc721mintable), we can use the [`useMintNFT`](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721mintable) hook to mint an NFT from the connected wallet; handling all of the logic of uploading and pinning the metadata to IPFS for us behind the scenes.
|
||||
|
||||
```jsx
|
||||
import { useContract, useNFTs, useMintNFT } from "@thirdweb-dev/react";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.11.4",
|
||||
"version": "3.11.7",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -11,6 +11,7 @@ export const ChainIcon: React.FC<{
|
||||
chain?: Chain;
|
||||
size: string;
|
||||
active?: boolean;
|
||||
className?: string;
|
||||
}> = (props) => {
|
||||
const url = props.chain?.icon?.url;
|
||||
const src = url ? resolveIpfsUri(url) : defaultChainIcon;
|
||||
@@ -34,6 +35,7 @@ export const ChainIcon: React.FC<{
|
||||
alt=""
|
||||
width={props.size}
|
||||
height={props.size}
|
||||
className={props.className}
|
||||
/>
|
||||
{props.active && <ActiveDot />}
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ export const Img: React.FC<{
|
||||
src: string;
|
||||
alt?: string;
|
||||
loading?: "eager" | "lazy";
|
||||
className?: string;
|
||||
}> = (props) => {
|
||||
return (
|
||||
<img
|
||||
@@ -19,6 +20,7 @@ export const Img: React.FC<{
|
||||
height: props.height + "px",
|
||||
width: props.width + "px",
|
||||
}}
|
||||
className={props.className}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -22,6 +22,8 @@ import invariant from "tiny-invariant";
|
||||
|
||||
type ActionFn = (contract: SmartContract) => any;
|
||||
|
||||
const TW_WEB3BUTTON = "tw-web3button";
|
||||
|
||||
interface Web3ButtonProps<TActionFn extends ActionFn> {
|
||||
className?: string;
|
||||
contractAddress: `0x${string}` | `${string}.eth` | string;
|
||||
@@ -40,6 +42,7 @@ interface Web3ButtonProps<TActionFn extends ActionFn> {
|
||||
action: TActionFn;
|
||||
type?: "button" | "submit" | "reset";
|
||||
theme?: "dark" | "light";
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,6 +78,7 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
className,
|
||||
type,
|
||||
theme,
|
||||
style,
|
||||
}: PropsWithChildren<Web3ButtonProps<TAction>>) => {
|
||||
const address = useAddress();
|
||||
const sdkChainId = useSDKChainId();
|
||||
@@ -121,7 +125,13 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
);
|
||||
|
||||
if (!address) {
|
||||
return <ConnectWallet theme={theme} />;
|
||||
return (
|
||||
<ConnectWallet
|
||||
style={style}
|
||||
theme={theme}
|
||||
className={`${className || ""} ${TW_WEB3BUTTON}--connect-wallet`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// let onClick = () => actionMutation.mutate();
|
||||
@@ -152,9 +162,11 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
<Button
|
||||
variant="inverted"
|
||||
type={type}
|
||||
className={className}
|
||||
className={`${className || ""} ${TW_WEB3BUTTON}--switch-network`}
|
||||
onClick={handleSwitchChain}
|
||||
style={btnStyle}
|
||||
style={{ ...btnStyle, ...style }}
|
||||
data-is-loading={confirmStatus === "waiting"}
|
||||
data-theme={theme}
|
||||
>
|
||||
{confirmStatus === "waiting" ? (
|
||||
<Spinner size="sm" color={"inverted"} />
|
||||
@@ -195,10 +207,11 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
<Button
|
||||
variant="inverted"
|
||||
type={type}
|
||||
className={className}
|
||||
className={`${className || ""} ${TW_WEB3BUTTON}`}
|
||||
disabled
|
||||
onClick={handleSwitchChain}
|
||||
style={btnStyle}
|
||||
style={{ ...btnStyle, ...style }}
|
||||
data-is-loading
|
||||
data-theme={theme}
|
||||
>
|
||||
<Spinner size="md" color={"inverted"} />
|
||||
</Button>
|
||||
@@ -211,10 +224,12 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
<Button
|
||||
variant="inverted"
|
||||
type={type}
|
||||
className={className}
|
||||
className={`${className || ""} ${TW_WEB3BUTTON}`}
|
||||
onClick={() => actionMutation.mutate()}
|
||||
disabled={isDisabled}
|
||||
style={btnStyle}
|
||||
style={{ ...btnStyle, ...style }}
|
||||
data-is-loading="false"
|
||||
data-theme={theme}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
|
||||
@@ -36,8 +36,11 @@ type ConnectWalletProps = {
|
||||
loginOptions?: LoginOptions;
|
||||
loginOptional?: boolean;
|
||||
};
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
const TW_CONNECT_WALLET = "tw-connect-wallet";
|
||||
|
||||
/**
|
||||
* A component that allows the user to connect their wallet.
|
||||
*
|
||||
@@ -98,7 +101,13 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
|
||||
|
||||
{/* Sign In Button */}
|
||||
{requiresSignIn && (
|
||||
<Button variant="inverted" onClick={signIn}>
|
||||
<Button
|
||||
variant="inverted"
|
||||
onClick={signIn}
|
||||
data-theme={theme}
|
||||
className={`${TW_CONNECT_WALLET}--sign-in`}
|
||||
style={props.style}
|
||||
>
|
||||
<Flex
|
||||
alignItems="center"
|
||||
gap="sm"
|
||||
@@ -120,11 +129,14 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
|
||||
// connect wallet button
|
||||
<AnimatedButton
|
||||
disabled={isLoading}
|
||||
className={props.className}
|
||||
className={`${props.className || ""} ${TW_CONNECT_WALLET}`}
|
||||
data-theme={theme}
|
||||
data-is-loading={isLoading}
|
||||
variant="inverted"
|
||||
type="button"
|
||||
style={{
|
||||
minWidth: "140px",
|
||||
...props.style,
|
||||
}}
|
||||
aria-label={
|
||||
connectionStatus === "connecting" ? "Connecting" : btnTitle
|
||||
@@ -139,6 +151,8 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
|
||||
) : (
|
||||
<ConnectedWalletDetails
|
||||
dropdownPosition={props.dropdownPosition}
|
||||
theme={theme}
|
||||
style={props.style}
|
||||
onDisconnect={() => {
|
||||
if (authConfig?.authUrl) {
|
||||
logout();
|
||||
|
||||
@@ -44,9 +44,13 @@ export type DropDownPosition = {
|
||||
align: "start" | "center" | "end";
|
||||
};
|
||||
|
||||
const TW_CONNECTED_WALLET = "tw-connected-wallet";
|
||||
|
||||
export const ConnectedWalletDetails: React.FC<{
|
||||
dropdownPosition?: DropDownPosition;
|
||||
onDisconnect: () => void;
|
||||
theme: "dark" | "light";
|
||||
style?: React.CSSProperties;
|
||||
}> = (props) => {
|
||||
const disconnect = useDisconnect();
|
||||
const chains = useSupportedChains();
|
||||
@@ -101,12 +105,21 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
}, [personalWallet]);
|
||||
|
||||
const trigger = (
|
||||
<WalletInfoButton type="button">
|
||||
<ChainIcon chain={chain} size={iconSize.lg} />
|
||||
<WalletInfoButton
|
||||
type="button"
|
||||
className={TW_CONNECTED_WALLET}
|
||||
data-theme={props.theme}
|
||||
style={props.style}
|
||||
>
|
||||
<ChainIcon
|
||||
chain={chain}
|
||||
size={iconSize.lg}
|
||||
className={`${TW_CONNECTED_WALLET}__network-icon`}
|
||||
/>
|
||||
|
||||
<ColFlex>
|
||||
{!balanceQuery.isLoading ? (
|
||||
<WalletBalance>
|
||||
<WalletBalance className={`${TW_CONNECTED_WALLET}__balance`}>
|
||||
{balanceQuery.data?.displayValue.slice(0, 5)}{" "}
|
||||
{balanceQuery.data?.symbol}
|
||||
</WalletBalance>
|
||||
@@ -114,10 +127,17 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
<Skeleton height={fontSize.sm} width="82px" />
|
||||
)}
|
||||
<Spacer y="xs" />
|
||||
<WalletAddress>{shortenString(address || "")}</WalletAddress>
|
||||
<WalletAddress className={`${TW_CONNECTED_WALLET}__address`}>
|
||||
{shortenString(address || "")}
|
||||
</WalletAddress>
|
||||
</ColFlex>
|
||||
|
||||
<Img width={iconSize.lg} height={iconSize.lg} src={activeWalletIconURL} />
|
||||
<Img
|
||||
width={iconSize.lg}
|
||||
height={iconSize.lg}
|
||||
src={activeWalletIconURL}
|
||||
className={`${TW_CONNECTED_WALLET}__wallet-icon`}
|
||||
/>
|
||||
</WalletInfoButton>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 3.10.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#882](https://github.com/thirdweb-dev/js/pull/882) [`ac8fa0b3`](https://github.com/thirdweb-dev/js/commit/ac8fa0b34545a2bc0b489a0551d476a9f560e851) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix resolving proxy implementation addreses with leading 0s
|
||||
|
||||
- [#756](https://github.com/thirdweb-dev/js/pull/756) [`b75bcef5`](https://github.com/thirdweb-dev/js/commit/b75bcef55bfdedc260b5b62bb4aff10a7d5c47b6) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Any EVM deploy flow with Create2 factory
|
||||
|
||||
- [#878](https://github.com/thirdweb-dev/js/pull/878) [`c9027fce`](https://github.com/thirdweb-dev/js/commit/c9027fced0fffbf757bf0080bc4a49f5464df647) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Util function for any-evm deployment status
|
||||
|
||||
- Updated dependencies [[`b75bcef5`](https://github.com/thirdweb-dev/js/commit/b75bcef55bfdedc260b5b62bb4aff10a7d5c47b6)]:
|
||||
- @thirdweb-dev/contracts-js@1.3.3
|
||||
|
||||
## 3.10.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#864](https://github.com/thirdweb-dev/js/pull/864) [`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5) Thanks [@ciaranightingale](https://github.com/ciaranightingale)! - Remove necessity for LazyMint to detect any of the claim extensions
|
||||
|
||||
- [#869](https://github.com/thirdweb-dev/js/pull/869) [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe) Thanks [@adam-maj](https://github.com/adam-maj)! - Add .prepare() syntax to tiered-drop
|
||||
|
||||
## 3.10.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#861](https://github.com/thirdweb-dev/js/pull/861) [`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152) Thanks [@adam-maj](https://github.com/adam-maj)! - Add option to pass timestamps for dates
|
||||
|
||||
- [#863](https://github.com/thirdweb-dev/js/pull/863) [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310) Thanks [@ciaranightingale](https://github.com/ciaranightingale)! - Update Solidity SDK detected extension portal links
|
||||
|
||||
- Updated dependencies [[`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
|
||||
- @thirdweb-dev/chains@0.1.11
|
||||
|
||||
## 3.10.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "3.10.7",
|
||||
"version": "3.10.10",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,771 @@
|
||||
import invariant from "tiny-invariant";
|
||||
import { BigNumber, BytesLike, ethers, providers, Signer } from "ethers";
|
||||
import { bytecode as WETHBytecode } from "./WETH9";
|
||||
import {
|
||||
DeploymentInfo,
|
||||
KeylessDeploymentInfo,
|
||||
KeylessTransaction,
|
||||
} from "../types/any-evm/deploy-data";
|
||||
import {
|
||||
CloneFactory,
|
||||
EOAForwarder,
|
||||
Forwarder,
|
||||
INFRA_CONTRACTS_MAP,
|
||||
NativeTokenWrapper,
|
||||
} from "./infra-data";
|
||||
import { ThirdwebSDK } from "../core/sdk";
|
||||
import { InfraContractType } from "../core";
|
||||
import {
|
||||
extractConstructorParamsFromAbi,
|
||||
fetchPreDeployMetadata,
|
||||
} from "./feature-detection";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { getNativeTokenByChainId } from "../constants";
|
||||
import { PreDeployMetadataFetched } from "../schema";
|
||||
import { toWei } from "./currency";
|
||||
import { DeployOptions } from "../types";
|
||||
|
||||
//
|
||||
// =============================
|
||||
// ======== CONSTANTS ==========
|
||||
// =============================
|
||||
//
|
||||
|
||||
const THIRDWEB_DEPLOYER = "0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024";
|
||||
|
||||
export const CREATE2_FACTORY_BYTECODE =
|
||||
"0x604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3";
|
||||
export const SIGNATURE = {
|
||||
v: 27,
|
||||
r: "0x2222222222222222222222222222222222222222222222222222222222222222",
|
||||
s: "0x2222222222222222222222222222222222222222222222222222222222222222",
|
||||
};
|
||||
export const COMMON_FACTORY = "0x4e59b44847b379578588920cA78FbF26c0B4956C"; // for pre-eip-155 supporting chains
|
||||
export const DEPLOYER_BYTECODE =
|
||||
"0x60806040526040516107f33803806107f383398101604081905261002291610359565b805160005b818110156100c157828181518110610041576100416104c9565b6020026020010151600001516001600160a01b03163b600014156100af576100ad838281518110610074576100746104c9565b602002602001015160200151848381518110610092576100926104c9565b6020026020010151604001516100c960201b6100091760201c565b505b806100b9816104df565b915050610027565b505050610557565b606061011183836040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061011860201b60201c565b9392505050565b6060610127848460008561012f565b949350505050565b6060824710156101955760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084015b60405180910390fd5b6001600160a01b0385163b6101ec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161018c565b600080866001600160a01b031685876040516102089190610508565b60006040518083038185875af1925050503d8060008114610245576040519150601f19603f3d011682016040523d82523d6000602084013e61024a565b606091505b50909250905061025b828286610266565b979650505050505050565b60608315610275575081610111565b8251156102855782518084602001fd5b8160405162461bcd60e51b815260040161018c9190610524565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156102d7576102d761029f565b60405290565b604051601f8201601f191681016001600160401b03811182821017156103055761030561029f565b604052919050565b80516001600160a01b038116811461032457600080fd5b919050565b60005b8381101561034457818101518382015260200161032c565b83811115610353576000848401525b50505050565b6000602080838503121561036c57600080fd5b82516001600160401b038082111561038357600080fd5b818501915085601f83011261039757600080fd5b8151818111156103a9576103a961029f565b8060051b6103b88582016102dd565b91825283810185019185810190898411156103d257600080fd5b86860192505b838310156104bc578251858111156103f05760008081fd5b86016060601f19828d0381018213156104095760008081fd5b6104116102b5565b61041c8b850161030d565b8152604061042b81860161030d565b828d01529284015192898411156104425760008081fd5b83850194508e603f86011261045957600093508384fd5b8b85015193508984111561046f5761046f61029f565b61047f8c84601f870116016102dd565b92508383528e818587010111156104965760008081fd5b6104a5848d8501838801610329565b8101919091528452505091860191908601906103d8565b9998505050505050505050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561050157634e487b7160e01b600052601160045260246000fd5b5060010190565b6000825161051a818460208701610329565b9190910192915050565b6020815260008251806020840152610543816040850160208701610329565b601f01601f19169190910160400192915050565b61028d806105666000396000f3fe6080604052600080fd5b606061004b83836040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610052565b9392505050565b60606100618484600085610069565b949350505050565b6060824710156100cf5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084015b60405180910390fd5b6001600160a01b0385163b6101265760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016100c6565b600080866001600160a01b031685876040516101429190610208565b60006040518083038185875af1925050503d806000811461017f576040519150601f19603f3d011682016040523d82523d6000602084013e610184565b606091505b509150915061019482828661019f565b979650505050505050565b606083156101ae57508161004b565b8251156101be5782518084602001fd5b8160405162461bcd60e51b81526004016100c69190610224565b60005b838110156101f35781810151838201526020016101db565b83811115610202576000848401525b50505050565b6000825161021a8184602087016101d8565b9190910192915050565b60208152600082518060208401526102438160408501602087016101d8565b601f01601f1916919091016040019291505056fea26469706673582212200b524eb8ceaafe6c603273ee859fddbc2d6f1b7860c3d853dcf6f129f9d9371364736f6c634300080c0033";
|
||||
export const DEPLOYER_ABI = [
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
components: [
|
||||
{
|
||||
internalType: "address",
|
||||
name: "predictedAddress",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "address",
|
||||
name: "to",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "bytes",
|
||||
name: "data",
|
||||
type: "bytes",
|
||||
},
|
||||
],
|
||||
internalType: "struct IDeployer.Transaction[]",
|
||||
name: "transactions",
|
||||
type: "tuple[]",
|
||||
},
|
||||
],
|
||||
stateMutability: "payable",
|
||||
type: "constructor",
|
||||
},
|
||||
];
|
||||
|
||||
//
|
||||
// ==================================
|
||||
// ======== View Functions ==========
|
||||
// ==================================
|
||||
//
|
||||
|
||||
/**
|
||||
* Check if a contract exists at the given address
|
||||
*
|
||||
* @internal
|
||||
* @param address
|
||||
* @param provider
|
||||
*/
|
||||
export async function isContractDeployed(
|
||||
address: string,
|
||||
provider: providers.Provider,
|
||||
): Promise<boolean> {
|
||||
const code = await provider.getCode(address);
|
||||
|
||||
return code !== "0x";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a chain enforces EIP-155 transactions
|
||||
* Ref: https://eips.ethereum.org/EIPS/eip-155
|
||||
*
|
||||
* @internal
|
||||
* @param provider
|
||||
*/
|
||||
export async function isEIP155Enforced(
|
||||
provider: providers.Provider,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
// TODO: Find a better way to check this.
|
||||
|
||||
// Send a random transaction of legacy type (pre-eip-155).
|
||||
// It will fail. Parse the error message to check whether eip-155 is enforced.
|
||||
await provider.sendTransaction(
|
||||
"0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",
|
||||
);
|
||||
} catch (e: any) {
|
||||
if (
|
||||
e.toString().toLowerCase().includes("eip-155") ||
|
||||
e.message?.toString().toLowerCase().includes("eip-155") ||
|
||||
e.data?.message?.toString().toLowerCase().includes("eip-155")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CREATE2 Factory address for a network
|
||||
* Source code of the factory:
|
||||
* https://github.com/Arachnid/deterministic-deployment-proxy/blob/master/source/deterministic-deployment-proxy.yul
|
||||
*
|
||||
* @internal
|
||||
* @param provider
|
||||
*/
|
||||
export async function getCreate2FactoryAddress(
|
||||
provider: providers.Provider,
|
||||
): Promise<string> {
|
||||
const commonFactoryExists = await isContractDeployed(
|
||||
COMMON_FACTORY,
|
||||
provider,
|
||||
);
|
||||
if (commonFactoryExists) {
|
||||
return COMMON_FACTORY;
|
||||
}
|
||||
|
||||
const enforceEip155 = await isEIP155Enforced(provider);
|
||||
const chainId = enforceEip155 ? (await provider.getNetwork()).chainId : 0;
|
||||
const deploymentInfo = getCreate2FactoryDeploymentInfo(chainId);
|
||||
|
||||
return deploymentInfo.deployment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate salt for deployment with Create2
|
||||
* Note: Salt component is generated by appending `tw` (thirdweb) to the bytecode
|
||||
*
|
||||
* @internal
|
||||
* @param bytecode: Creation bytecode of the contract to deploy
|
||||
*/
|
||||
export function getSaltHash(bytecode: string): string {
|
||||
const bytecodeHash = ethers.utils.id(bytecode);
|
||||
const salt = `tw.${bytecodeHash}`;
|
||||
const saltHash = ethers.utils.id(salt);
|
||||
|
||||
return saltHash;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Construct init-bytecode, packed with salthash.
|
||||
* This hex data is intended to be sent to the CREATE2 factory address
|
||||
*
|
||||
* @internal
|
||||
* @param bytecode: Creation bytecode of the contract to deploy
|
||||
* @param encodedArgs: Abi-encoded constructor params
|
||||
*/
|
||||
export function getInitBytecodeWithSalt(
|
||||
bytecode: string,
|
||||
encodedArgs: BytesLike,
|
||||
): string {
|
||||
const saltHash = getSaltHash(bytecode);
|
||||
|
||||
const initBytecodeWithSalt = ethers.utils.solidityPack(
|
||||
["bytes32", "bytes", "bytes"],
|
||||
[saltHash, bytecode, encodedArgs],
|
||||
);
|
||||
|
||||
return initBytecodeWithSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Pre-compute a contract's deployment address for a CREATE2 deployment.
|
||||
*
|
||||
* @public
|
||||
* @param bytecode: Creation bytecode of the contract to deploy
|
||||
* @param encodedArgs: Abi-encoded constructor params
|
||||
* @param create2FactoryAddress
|
||||
*/
|
||||
export function computeDeploymentAddress(
|
||||
bytecode: string,
|
||||
encodedArgs: BytesLike,
|
||||
create2FactoryAddress: string,
|
||||
): string {
|
||||
const saltHash = getSaltHash(bytecode);
|
||||
|
||||
// 1. create init bytecode hash with contract's bytecode and encoded args
|
||||
const initBytecode = ethers.utils.solidityPack(
|
||||
["bytes", "bytes"],
|
||||
[bytecode, encodedArgs],
|
||||
);
|
||||
|
||||
// 2. abi-encode pack the deployer address, salt, and bytecode hash
|
||||
const deployInfoPacked = ethers.utils.solidityPack(
|
||||
["bytes1", "address", "bytes32", "bytes32"],
|
||||
[
|
||||
"0xff",
|
||||
create2FactoryAddress,
|
||||
saltHash,
|
||||
ethers.utils.solidityKeccak256(["bytes"], [initBytecode]),
|
||||
],
|
||||
);
|
||||
|
||||
// 3. hash the packed deploy info
|
||||
const hashedDeployInfo = ethers.utils.solidityKeccak256(
|
||||
["bytes"],
|
||||
[deployInfoPacked],
|
||||
);
|
||||
|
||||
// 4. return last 20 bytes (40 characters) of the hash -- this is the predicted address
|
||||
return `0x${hashedDeployInfo.slice(26)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
* @param provider
|
||||
* @param storage
|
||||
* @param create2Factory
|
||||
*/
|
||||
export async function computeEOAForwarderAddress(
|
||||
provider: providers.Provider,
|
||||
storage: ThirdwebStorage,
|
||||
create2Factory?: string,
|
||||
): Promise<string> {
|
||||
if (!create2Factory) {
|
||||
create2Factory = await getCreate2FactoryAddress(provider);
|
||||
}
|
||||
return await computeAddressInfra(
|
||||
EOAForwarder.contractType,
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
* @param provider
|
||||
* @param storage
|
||||
* @param create2Factory
|
||||
*/
|
||||
export async function computeForwarderAddress(
|
||||
provider: providers.Provider,
|
||||
storage: ThirdwebStorage,
|
||||
create2Factory?: string,
|
||||
): Promise<string> {
|
||||
if (!create2Factory) {
|
||||
create2Factory = await getCreate2FactoryAddress(provider);
|
||||
}
|
||||
return await computeAddressInfra(
|
||||
Forwarder.contractType,
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
* @param provider
|
||||
* @param storage
|
||||
* @param create2Factory
|
||||
*/
|
||||
export async function computeCloneFactoryAddress(
|
||||
provider: providers.Provider,
|
||||
storage: ThirdwebStorage,
|
||||
create2Factory?: string,
|
||||
): Promise<string> {
|
||||
if (!create2Factory) {
|
||||
create2Factory = await getCreate2FactoryAddress(provider);
|
||||
}
|
||||
return await computeAddressInfra(
|
||||
CloneFactory.contractType,
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
* @param provider
|
||||
* @param storage
|
||||
* @param create2Factory
|
||||
*/
|
||||
export async function computeNativeTokenAddress(
|
||||
provider: providers.Provider,
|
||||
storage: ThirdwebStorage,
|
||||
create2Factory?: string,
|
||||
): Promise<string> {
|
||||
if (!create2Factory) {
|
||||
create2Factory = await getCreate2FactoryAddress(provider);
|
||||
}
|
||||
return await computeAddressInfra(
|
||||
NativeTokenWrapper.contractType,
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// ==============================================
|
||||
// ======== Create / Send Transactions ==========
|
||||
// ==============================================
|
||||
//
|
||||
|
||||
/**
|
||||
* Generate a transaction to be sent with a keyless signer.
|
||||
*
|
||||
* @public
|
||||
* @param transaction: Unsigned transaction object
|
||||
* @param signature: Signature bytes
|
||||
*/
|
||||
export function getKeylessTxn(
|
||||
transaction: ethers.UnsignedTransaction,
|
||||
signature: string,
|
||||
): KeylessTransaction {
|
||||
// 1. Create serialized txn string
|
||||
const digest = ethers.utils.arrayify(
|
||||
ethers.utils.keccak256(ethers.utils.serializeTransaction(transaction)),
|
||||
);
|
||||
|
||||
// 2. Determine signer address from custom signature + txn
|
||||
const signer = ethers.utils.recoverAddress(digest, signature);
|
||||
|
||||
// 3. Create the signed serialized txn string.
|
||||
// To be sent directly to the chain using a provider.
|
||||
const signedSerializedTx = ethers.utils.serializeTransaction(
|
||||
transaction,
|
||||
signature,
|
||||
);
|
||||
|
||||
return {
|
||||
signer: signer,
|
||||
transaction: signedSerializedTx,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploy Nick's Create2 factory on a given network.
|
||||
* Deployment is keyless. Signer is needed to fund the keyless signer address.
|
||||
* Ref: https://github.com/Arachnid/deterministic-deployment-proxy
|
||||
*
|
||||
* @public
|
||||
* @param signer
|
||||
*/
|
||||
export async function deployCreate2Factory(
|
||||
signer: Signer,
|
||||
options?: DeployOptions,
|
||||
): Promise<string> {
|
||||
invariant(signer.provider, "No provider");
|
||||
const commonFactoryExists = await isContractDeployed(
|
||||
COMMON_FACTORY,
|
||||
signer.provider,
|
||||
);
|
||||
if (commonFactoryExists) {
|
||||
return COMMON_FACTORY;
|
||||
}
|
||||
|
||||
const enforceEip155 = await isEIP155Enforced(signer.provider);
|
||||
const networkId = (await signer.provider.getNetwork()).chainId;
|
||||
const chainId = enforceEip155 ? networkId : 0;
|
||||
console.debug(`ChainId ${networkId} enforces EIP155: ${enforceEip155}`);
|
||||
const deploymentInfo = getCreate2FactoryDeploymentInfo(chainId);
|
||||
|
||||
const factoryExists = await isContractDeployed(
|
||||
deploymentInfo.deployment,
|
||||
signer.provider,
|
||||
);
|
||||
|
||||
// deploy community factory if not already deployed
|
||||
if (!factoryExists) {
|
||||
// send balance to the keyless signer
|
||||
if (
|
||||
(await signer.provider.getBalance(deploymentInfo.signer)).lt(
|
||||
toWei("0.01"),
|
||||
)
|
||||
) {
|
||||
await signer.sendTransaction({
|
||||
to: deploymentInfo.signer,
|
||||
value: toWei("0.01"),
|
||||
});
|
||||
}
|
||||
|
||||
// deploy
|
||||
try {
|
||||
console.debug(
|
||||
`deploying CREATE2 factory at: ${deploymentInfo.deployment}`,
|
||||
);
|
||||
|
||||
options?.notifier?.("deploying", "create2Factory");
|
||||
await signer.provider.sendTransaction(deploymentInfo.transaction);
|
||||
options?.notifier?.("deployed", "create2Factory");
|
||||
} catch (err) {
|
||||
throw new Error(`Couldn't deploy CREATE2 factory: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
return deploymentInfo.deployment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploy a contract at a deterministic address, using Create2 method
|
||||
* Address depends on the Create2 factory address.
|
||||
*
|
||||
* @public
|
||||
*
|
||||
* @param singer
|
||||
* @param bytecode
|
||||
* @param encodedArgs
|
||||
* @param create2FactoryAddress
|
||||
*/
|
||||
export async function deployContractDeterministic(
|
||||
signer: Signer,
|
||||
bytecode: string,
|
||||
encodedArgs: BytesLike,
|
||||
create2FactoryAddress: string,
|
||||
options?: DeployOptions,
|
||||
predictedAddress?: string,
|
||||
gasLimit: number = 7000000,
|
||||
) {
|
||||
// Check if the implementation contract is already deployed
|
||||
const code = predictedAddress
|
||||
? await signer.provider?.getCode(predictedAddress)
|
||||
: "0x";
|
||||
|
||||
if (code === "0x") {
|
||||
console.debug(
|
||||
`deploying contract via create2 factory at: ${predictedAddress}`,
|
||||
);
|
||||
const initBytecodeWithSalt = getInitBytecodeWithSalt(bytecode, encodedArgs);
|
||||
|
||||
let tx: ethers.PopulatedTransaction = {
|
||||
to: create2FactoryAddress,
|
||||
data: initBytecodeWithSalt,
|
||||
};
|
||||
|
||||
try {
|
||||
await signer.estimateGas(tx);
|
||||
} catch (e) {
|
||||
console.debug("error estimating gas while deploying prebuilt: ", e);
|
||||
tx.gasLimit = BigNumber.from(gasLimit);
|
||||
}
|
||||
options?.notifier?.("deploying", "implementation");
|
||||
await (await signer.sendTransaction(tx)).wait();
|
||||
options?.notifier?.("deployed", "implementation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns txn data for keyless deploys as well as signer deploys.
|
||||
* Also provides a list of infra contracts to deploy.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param metadataUri
|
||||
* @param storage
|
||||
* @param provider
|
||||
* @param create2Factory
|
||||
*/
|
||||
export async function getDeploymentInfo(
|
||||
metadataUri: string,
|
||||
storage: ThirdwebStorage,
|
||||
provider: providers.Provider,
|
||||
create2Factory?: string,
|
||||
): Promise<DeploymentInfo> {
|
||||
const compilerMetadata = await fetchPreDeployMetadata(metadataUri, storage);
|
||||
if (!create2Factory) {
|
||||
create2Factory = await getCreate2FactoryAddress(provider);
|
||||
}
|
||||
|
||||
// 1. Get abi-encoded args and list of infra contracts required based on constructor params
|
||||
const { encodedArgs, infraContracts } =
|
||||
await encodeConstructorParamsForImplementation(
|
||||
compilerMetadata,
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
|
||||
// 2. Compute the CREATE2 address
|
||||
const predictedAddress = computeDeploymentAddress(
|
||||
compilerMetadata.bytecode,
|
||||
encodedArgs,
|
||||
create2Factory,
|
||||
);
|
||||
|
||||
// 3. Add TWStatelessFactory and Forwarder to the list of infra contracts --
|
||||
// these must be deployed regardless of constructor params of implementation contract
|
||||
infraContracts.push(CloneFactory.contractType);
|
||||
infraContracts.push(Forwarder.contractType);
|
||||
|
||||
return {
|
||||
bytecode: compilerMetadata.bytecode,
|
||||
encodedArgs: encodedArgs,
|
||||
predictedAddress: predictedAddress,
|
||||
infraContractsToDeploy: infraContracts,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploy Infra contracts with a signer.
|
||||
* The serialized txn data and addresses are precomputed for infra contracts.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param signer: Signer of infra deployment txns
|
||||
* @param provider
|
||||
* @param storage
|
||||
* @param create2Factory
|
||||
* @param contractTypes: List of infra contracts to deploy
|
||||
*/
|
||||
export async function deployInfraWithSigner(
|
||||
signer: Signer,
|
||||
provider: providers.Provider,
|
||||
storage: ThirdwebStorage,
|
||||
create2Factory: string,
|
||||
contractTypes: InfraContractType[],
|
||||
options?: DeployOptions,
|
||||
) {
|
||||
const txns = [];
|
||||
|
||||
for (let contractType of contractTypes as InfraContractType[]) {
|
||||
const infraContractAddress = await computeAddressInfra(
|
||||
contractType,
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
|
||||
if (contractType === NativeTokenWrapper.contractType) {
|
||||
const code = await provider.getCode(infraContractAddress);
|
||||
if (code === "0x") {
|
||||
const initCode = getInitBytecodeWithSalt(WETHBytecode, []);
|
||||
|
||||
txns.push({
|
||||
predictedAddress: infraContractAddress,
|
||||
to: create2Factory,
|
||||
data: initCode,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const uri = await fetchPublishedContractURI(
|
||||
INFRA_CONTRACTS_MAP[contractType].name,
|
||||
);
|
||||
const infraContractMetadata = await fetchPreDeployMetadata(uri, storage);
|
||||
const code = await provider.getCode(infraContractAddress);
|
||||
|
||||
if (code === "0x") {
|
||||
const encodedArgs = (
|
||||
await encodeConstructorParamsForImplementation(
|
||||
infraContractMetadata,
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
)
|
||||
).encodedArgs;
|
||||
// get init bytecode
|
||||
const initBytecodeWithSalt = getInitBytecodeWithSalt(
|
||||
infraContractMetadata.bytecode,
|
||||
encodedArgs,
|
||||
);
|
||||
|
||||
txns.push({
|
||||
predictedAddress: infraContractAddress,
|
||||
to: create2Factory,
|
||||
data: initBytecodeWithSalt,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Call/deploy the throaway-deployer only if there are any contracts to deploy
|
||||
if (txns.length > 0) {
|
||||
txns.forEach((tx) =>
|
||||
console.debug(`deploying infra contract at: ${tx.predictedAddress}`),
|
||||
);
|
||||
options?.notifier?.("deploying", "infra");
|
||||
// Using the deployer contract, send the deploy transactions to common factory with a signer
|
||||
const deployer = new ethers.ContractFactory(DEPLOYER_ABI, DEPLOYER_BYTECODE)
|
||||
.connect(signer)
|
||||
.deploy(txns);
|
||||
await (await deployer).deployed();
|
||||
|
||||
options?.notifier?.("deployed", "infra");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ==============================================
|
||||
// ======== Other helper functions ==============
|
||||
// ==============================================
|
||||
//
|
||||
|
||||
/**
|
||||
*
|
||||
* @public
|
||||
* @param transaction: Unsigned transaction object
|
||||
* @param signature: Signature bytes
|
||||
*/
|
||||
export function getCreate2FactoryDeploymentInfo(
|
||||
chainId: number,
|
||||
): KeylessDeploymentInfo {
|
||||
const signature = ethers.utils.joinSignature(SIGNATURE);
|
||||
const deploymentTransaction = getKeylessTxn(
|
||||
{
|
||||
gasPrice: 100 * 10 ** 9,
|
||||
gasLimit: 100000,
|
||||
nonce: 0,
|
||||
data: CREATE2_FACTORY_BYTECODE,
|
||||
chainId: chainId,
|
||||
},
|
||||
signature,
|
||||
);
|
||||
const create2FactoryAddress = ethers.utils.getContractAddress({
|
||||
from: deploymentTransaction.signer,
|
||||
nonce: 0,
|
||||
});
|
||||
|
||||
return {
|
||||
...deploymentTransaction,
|
||||
deployment: create2FactoryAddress,
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchPublishedContractURI(
|
||||
contractName: string,
|
||||
): Promise<string> {
|
||||
// fetch the publish URI from the ContractPublisher contract
|
||||
const publishedContract = await new ThirdwebSDK("polygon")
|
||||
.getPublisher()
|
||||
.getVersion(THIRDWEB_DEPLOYER, contractName);
|
||||
if (!publishedContract) {
|
||||
throw new Error(
|
||||
`No published contract found for ${contractName} at version by '${THIRDWEB_DEPLOYER}'`,
|
||||
);
|
||||
}
|
||||
return publishedContract?.metadataUri;
|
||||
}
|
||||
|
||||
export async function computeAddressInfra(
|
||||
contractType: InfraContractType,
|
||||
provider: providers.Provider,
|
||||
storage: ThirdwebStorage,
|
||||
create2Factory: string,
|
||||
): Promise<string> {
|
||||
const contract = INFRA_CONTRACTS_MAP[contractType];
|
||||
|
||||
if (contract.contractType === NativeTokenWrapper.contractType) {
|
||||
const address = computeDeploymentAddress(WETHBytecode, [], create2Factory);
|
||||
|
||||
return address;
|
||||
} else {
|
||||
let uri = await fetchPublishedContractURI(contract.name);
|
||||
|
||||
const metadata = await fetchPreDeployMetadata(uri, storage);
|
||||
const encodedArgs = (
|
||||
await encodeConstructorParamsForImplementation(
|
||||
metadata,
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
)
|
||||
).encodedArgs;
|
||||
const address = computeDeploymentAddress(
|
||||
metadata.bytecode,
|
||||
encodedArgs,
|
||||
create2Factory,
|
||||
);
|
||||
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Determine constructor params required by an implementation contract.
|
||||
* Return abi-encoded params.
|
||||
*/
|
||||
async function encodeConstructorParamsForImplementation(
|
||||
compilerMetadata: PreDeployMetadataFetched,
|
||||
provider: providers.Provider,
|
||||
storage: ThirdwebStorage,
|
||||
create2Factory: string,
|
||||
) {
|
||||
const chainId = (await provider.getNetwork()).chainId;
|
||||
const infraContracts: InfraContractType[] = [];
|
||||
const constructorParams = extractConstructorParamsFromAbi(
|
||||
compilerMetadata.abi,
|
||||
);
|
||||
|
||||
const constructorParamTypes = constructorParams.map((p) => p.type);
|
||||
const constructorParamValues = await Promise.all(
|
||||
constructorParams.map(async (p) => {
|
||||
if (p.name && p.name.includes("nativeTokenWrapper")) {
|
||||
let nativeTokenWrapperAddress =
|
||||
getNativeTokenByChainId(chainId).wrapped.address;
|
||||
|
||||
if (nativeTokenWrapperAddress === ethers.constants.AddressZero) {
|
||||
nativeTokenWrapperAddress = await computeNativeTokenAddress(
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
infraContracts.push(NativeTokenWrapper.contractType);
|
||||
}
|
||||
|
||||
return nativeTokenWrapperAddress;
|
||||
} else if (p.name && p.name.includes("trustedForwarder")) {
|
||||
if (
|
||||
compilerMetadata.analytics?.contract_name &&
|
||||
compilerMetadata.analytics.contract_name === "Pack"
|
||||
) {
|
||||
infraContracts.push(EOAForwarder.contractType);
|
||||
const eoaForwarderAddress = await computeEOAForwarderAddress(
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
return eoaForwarderAddress;
|
||||
}
|
||||
infraContracts.push(Forwarder.contractType);
|
||||
const forwarderAddress = await computeForwarderAddress(
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
);
|
||||
return forwarderAddress;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
const encodedArgs = ethers.utils.defaultAbiCoder.encode(
|
||||
constructorParamTypes,
|
||||
constructorParamValues,
|
||||
);
|
||||
return { encodedArgs, infraContracts };
|
||||
}
|
||||
@@ -18,8 +18,11 @@ import {
|
||||
PrebuiltContractType,
|
||||
DeploySchemaForPrebuiltContractType,
|
||||
} from "../core";
|
||||
import { BigNumber, Signer } from "ethers";
|
||||
import { BigNumber, providers, Signer } from "ethers";
|
||||
import { z } from "zod";
|
||||
import { SUPPORTED_CHAIN_IDS } from "../constants";
|
||||
import { computeForwarderAddress } from "./any-evm-utils";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -36,13 +39,25 @@ export async function getDeployArguments<
|
||||
metadata: z.input<DeploySchemaForPrebuiltContractType<TContractType>>,
|
||||
contractURI: string,
|
||||
signer: Signer,
|
||||
storage: ThirdwebStorage,
|
||||
): Promise<any[]> {
|
||||
const chainId = await signer.getChainId();
|
||||
const signerAddress = await signer.getAddress();
|
||||
let trustedForwarders =
|
||||
contractType === PackInitializer.contractType
|
||||
? []
|
||||
: getDefaultTrustedForwarders(chainId);
|
||||
const chainEnum = SUPPORTED_CHAIN_IDS.find((c) => c === chainId);
|
||||
let trustedForwarders;
|
||||
if (!chainEnum) {
|
||||
const forwarder = await computeForwarderAddress(
|
||||
signer.provider as providers.Provider,
|
||||
storage,
|
||||
);
|
||||
trustedForwarders = [forwarder];
|
||||
} else {
|
||||
trustedForwarders =
|
||||
contractType === PackInitializer.contractType
|
||||
? []
|
||||
: getDefaultTrustedForwarders(chainId);
|
||||
}
|
||||
|
||||
// override default forwarders if custom ones are passed in
|
||||
if (metadata.trusted_forwarders && metadata.trusted_forwarders.length > 0) {
|
||||
trustedForwarders = metadata.trusted_forwarders;
|
||||
|
||||
@@ -26,6 +26,7 @@ import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import bs58 from "bs58";
|
||||
import { BaseContract, BigNumber, ethers } from "ethers";
|
||||
import { z } from "zod";
|
||||
import { isAddress } from "ethers/lib/utils";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -316,7 +317,13 @@ export async function resolveContractUriFromAddress(
|
||||
address: string,
|
||||
provider: ethers.providers.Provider,
|
||||
): Promise<string | undefined> {
|
||||
const bytecode = await provider.getCode(address);
|
||||
let bytecode;
|
||||
try {
|
||||
bytecode = await provider.getCode(address);
|
||||
} catch (e) {
|
||||
throw new Error(`Failed to get bytecode for address ${address}: ${e}`);
|
||||
}
|
||||
|
||||
if (bytecode === "0x") {
|
||||
const chain = await provider.getNetwork();
|
||||
throw new Error(
|
||||
@@ -345,8 +352,11 @@ export async function resolveContractUriFromAddress(
|
||||
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
|
||||
),
|
||||
);
|
||||
const implementationAddress = ethers.utils.hexStripZeros(proxyStorage);
|
||||
if (implementationAddress !== "0x") {
|
||||
const implementationAddress = `0x${proxyStorage.slice(-40)}`;
|
||||
if (
|
||||
isAddress(implementationAddress) &&
|
||||
implementationAddress !== ethers.constants.AddressZero
|
||||
) {
|
||||
return await resolveContractUriFromAddress(
|
||||
implementationAddress,
|
||||
provider,
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
export const CloneFactory = {
|
||||
name: "TWCloneFactory" as const,
|
||||
contractType: "cloneFactory" as const,
|
||||
};
|
||||
|
||||
export const NativeTokenWrapper = {
|
||||
name: "WETH9" as const,
|
||||
contractType: "nativeTokenWrapper" as const,
|
||||
};
|
||||
|
||||
export const Forwarder = {
|
||||
name: "Forwarder" as const,
|
||||
contractType: "forwarder" as const,
|
||||
};
|
||||
|
||||
export const EOAForwarder = {
|
||||
name: "ForwarderEOAOnly" as const,
|
||||
contractType: "eoaForwarder" as const,
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const INFRA_CONTRACTS_MAP = {
|
||||
[NativeTokenWrapper.contractType]: NativeTokenWrapper,
|
||||
[Forwarder.contractType]: Forwarder,
|
||||
[EOAForwarder.contractType]: EOAForwarder,
|
||||
[CloneFactory.contractType]: CloneFactory,
|
||||
} as const;
|
||||
@@ -17,7 +17,7 @@ export const FEATURE_EDITION_BURNABLE = {
|
||||
namespace: "edition.burn",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155burnable",
|
||||
contracts: "IBurnableERC1155",
|
||||
contracts: "erc1155burnable",
|
||||
},
|
||||
abis: [Erc1155Abi, IBurnableERC1155Abi],
|
||||
features: {},
|
||||
@@ -28,9 +28,9 @@ export const FEATURE_EDITION_CLAIM_CONDITIONS_V1 = {
|
||||
namespace: "edition.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155claimable",
|
||||
contracts: "DropSinglePhase1155",
|
||||
contracts: "erc1155dropsinglephase",
|
||||
},
|
||||
abis: [Erc1155Abi, ILazyMintAbi, IDropSinglePhase1155_V1],
|
||||
abis: [Erc1155Abi, IDropSinglePhase1155_V1],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -39,9 +39,9 @@ export const FEATURE_EDITION_CLAIM_CONDITIONS_V2 = {
|
||||
namespace: "edition.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155claimable",
|
||||
contracts: "DropSinglePhase1155",
|
||||
contracts: "erc1155claimconditions",
|
||||
},
|
||||
abis: [Erc1155Abi, ILazyMintAbi, IDropSinglePhase1155],
|
||||
abis: [Erc1155Abi, IDropSinglePhase1155],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -50,9 +50,9 @@ export const FEATURE_EDITION_CLAIM_PHASES_V2 = {
|
||||
namespace: "edition.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155claimable",
|
||||
contracts: "Drop1155",
|
||||
contracts: "erc1155claimphases",
|
||||
},
|
||||
abis: [Erc1155Abi, ILazyMintAbi, IDropMultiPhase1155],
|
||||
abis: [Erc1155Abi, IDropMultiPhase1155],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -61,7 +61,7 @@ export const FEATURE_EDITION_CLAIM_PHASES_V1 = {
|
||||
namespace: "edition.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155claimable",
|
||||
contracts: "Drop1155",
|
||||
contracts: "erc1155claimphases",
|
||||
},
|
||||
abis: [DropERC1155_V2Abi],
|
||||
features: {},
|
||||
@@ -72,9 +72,9 @@ export const FEATURE_EDITION_CLAIM_CUSTOM = {
|
||||
namespace: "edition.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155claimable",
|
||||
contracts: "IClaimableERC1155",
|
||||
contracts: "erc1155claimcustom",
|
||||
},
|
||||
abis: [Erc1155Abi, ILazyMintAbi, IClaimableERC1155],
|
||||
abis: [Erc1155Abi, IClaimableERC1155],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -83,7 +83,7 @@ export const FEATURE_EDITION_REVEALABLE = {
|
||||
namespace: "edition.drop.revealer",
|
||||
docLinks: {
|
||||
sdk: "sdk.drop.delayedreveal",
|
||||
contracts: "DelayedReveal",
|
||||
contracts: "erc1155revealable",
|
||||
},
|
||||
abis: [Erc1155Abi, ILazyMintAbi, DelayedRevealAbi],
|
||||
features: {},
|
||||
@@ -94,17 +94,11 @@ export const FEATURE_EDITION_LAZY_MINTABLE_V2 = {
|
||||
namespace: "edition.drop",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155droppable",
|
||||
contracts: "LazyMint",
|
||||
contracts: "lazymint",
|
||||
},
|
||||
abis: [Erc1155Abi, ILazyMintAbi],
|
||||
features: {
|
||||
[FEATURE_EDITION_REVEALABLE.name]: FEATURE_EDITION_REVEALABLE,
|
||||
[FEATURE_EDITION_CLAIM_CUSTOM.name]: FEATURE_EDITION_CLAIM_CUSTOM,
|
||||
[FEATURE_EDITION_CLAIM_CONDITIONS_V1.name]:
|
||||
FEATURE_EDITION_CLAIM_CONDITIONS_V1,
|
||||
[FEATURE_EDITION_CLAIM_CONDITIONS_V2.name]:
|
||||
FEATURE_EDITION_CLAIM_CONDITIONS_V2,
|
||||
[FEATURE_EDITION_CLAIM_PHASES_V2.name]: FEATURE_EDITION_CLAIM_PHASES_V2,
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -113,7 +107,7 @@ export const FEATURE_EDITION_LAZY_MINTABLE_V1 = {
|
||||
namespace: "edition.drop",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155droppable",
|
||||
contracts: "LazyMint",
|
||||
contracts: "lazymint",
|
||||
},
|
||||
abis: [DropERC1155_V2Abi],
|
||||
features: {
|
||||
@@ -126,7 +120,7 @@ export const FEATURE_EDITION_SIGNATURE_MINTABLE = {
|
||||
namespace: "edition.signature",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155signaturemintable",
|
||||
contracts: "ISignatureMintERC1155",
|
||||
contracts: "erc1155signaturemint",
|
||||
},
|
||||
abis: [Erc1155Abi, ISignatureMintERC1155Abi],
|
||||
features: {},
|
||||
@@ -137,7 +131,7 @@ export const FEATURE_EDITION_BATCH_TRASNFERABLE = {
|
||||
namespace: "",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155",
|
||||
contracts: "IMulticall",
|
||||
contracts: "multicall",
|
||||
},
|
||||
abis: [Erc1155Abi, MulticallAbi],
|
||||
features: {},
|
||||
@@ -148,7 +142,7 @@ export const FEATURE_EDITION_BATCH_MINTABLE = {
|
||||
namespace: "edition.mint.batch",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155batchmintable",
|
||||
contracts: "IMulticall",
|
||||
contracts: "erc1155batchmintable",
|
||||
},
|
||||
abis: [Erc1155Abi, IMintableERC1155Abi, MulticallAbi],
|
||||
features: {},
|
||||
@@ -159,7 +153,7 @@ export const FEATURE_EDITION_MINTABLE = {
|
||||
namespace: "edition.mint",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155mintable",
|
||||
contracts: "IMintableERC1155",
|
||||
contracts: "erc1155mintable",
|
||||
},
|
||||
abis: [Erc1155Abi, IMintableERC1155Abi],
|
||||
features: {
|
||||
@@ -172,7 +166,7 @@ export const FEATURE_EDITION_ENUMERABLE = {
|
||||
namespace: "edition.query",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155",
|
||||
contracts: "IERC1155",
|
||||
contracts: "erc1155enumerable",
|
||||
},
|
||||
abis: [Erc1155Abi, Erc1155EnumerableAbi],
|
||||
features: {},
|
||||
@@ -183,7 +177,7 @@ export const FEATURE_EDITION = {
|
||||
namespace: "edition",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc1155enumerable",
|
||||
contracts: "IERC1155Enumerable",
|
||||
contracts: "erc1155",
|
||||
},
|
||||
abis: [Erc1155Abi],
|
||||
features: {
|
||||
@@ -195,5 +189,11 @@ export const FEATURE_EDITION = {
|
||||
[FEATURE_EDITION_REVEALABLE.name]: FEATURE_EDITION_REVEALABLE,
|
||||
[FEATURE_EDITION_SIGNATURE_MINTABLE.name]:
|
||||
FEATURE_EDITION_SIGNATURE_MINTABLE,
|
||||
[FEATURE_EDITION_CLAIM_CUSTOM.name]: FEATURE_EDITION_CLAIM_CUSTOM,
|
||||
[FEATURE_EDITION_CLAIM_CONDITIONS_V1.name]:
|
||||
FEATURE_EDITION_CLAIM_CONDITIONS_V1,
|
||||
[FEATURE_EDITION_CLAIM_CONDITIONS_V2.name]:
|
||||
FEATURE_EDITION_CLAIM_CONDITIONS_V2,
|
||||
[FEATURE_EDITION_CLAIM_PHASES_V2.name]: FEATURE_EDITION_CLAIM_PHASES_V2,
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -14,7 +14,7 @@ export const FEATURE_TOKEN_CLAIM_CONDITIONS_V1 = {
|
||||
namespace: "token.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20dclaimable",
|
||||
contracts: "DropSinglePhase_V1",
|
||||
contracts: "erc20claimconditions",
|
||||
},
|
||||
abis: [ERC20Abi, IDropSinglePhaseV1],
|
||||
features: {},
|
||||
@@ -25,7 +25,7 @@ export const FEATURE_TOKEN_CLAIM_CONDITIONS_V2 = {
|
||||
namespace: "token.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20dclaimable",
|
||||
contracts: "DropSinglePhase",
|
||||
contracts: "erc20claimconditions",
|
||||
},
|
||||
abis: [ERC20Abi, IDropSinglePhase],
|
||||
features: {},
|
||||
@@ -36,7 +36,7 @@ export const FEATURE_TOKEN_CLAIM_PHASES_V2 = {
|
||||
namespace: "token.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20dclaimable",
|
||||
contracts: "Drop",
|
||||
contracts: "erc20claimphases",
|
||||
},
|
||||
abis: [ERC20Abi, IDrop],
|
||||
features: {},
|
||||
@@ -47,7 +47,7 @@ export const FEATURE_TOKEN_CLAIM_PHASES_V1 = {
|
||||
namespace: "token.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20dclaimable",
|
||||
contracts: "Drop",
|
||||
contracts: "erc20claimphases",
|
||||
},
|
||||
abis: [DropERC20_V2Abi],
|
||||
features: {},
|
||||
@@ -58,7 +58,7 @@ export const FEATURE_TOKEN_BURNABLE = {
|
||||
namespace: "token.burn",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20burnable",
|
||||
contracts: "IBurnableERC20",
|
||||
contracts: "erc20burnable",
|
||||
},
|
||||
abis: [ERC20Abi, IBurnableERC20Abi],
|
||||
features: {},
|
||||
@@ -69,7 +69,7 @@ export const FEATURE_TOKEN_SIGNATURE_MINTABLE = {
|
||||
namespace: "token.signature",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20signaturemintable",
|
||||
contracts: "ISignatureMintERC20",
|
||||
contracts: "erc20signaturemint",
|
||||
},
|
||||
abis: [ERC20Abi, ISignatureMintERC20Abi],
|
||||
features: {},
|
||||
@@ -80,7 +80,7 @@ export const FEATURE_TOKEN_BATCH_MINTABLE = {
|
||||
namespace: "token.mint.batch",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20batchmintable",
|
||||
contracts: "IMulticall",
|
||||
contracts: "erc20batchmintable",
|
||||
},
|
||||
abis: [ERC20Abi, IMintableERC20Abi, MulticallAbi],
|
||||
features: {},
|
||||
@@ -91,7 +91,7 @@ export const FEATURE_TOKEN_MINTABLE = {
|
||||
namespace: "token.mint",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20mintable",
|
||||
contracts: "IMintableERC20",
|
||||
contracts: "erc20mintable",
|
||||
},
|
||||
abis: [ERC20Abi, IMintableERC20Abi],
|
||||
features: {
|
||||
@@ -104,7 +104,7 @@ export const FEATURE_TOKEN_PERMIT = {
|
||||
namespace: "token.permit",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20permit",
|
||||
contracts: "IERC20Permit",
|
||||
contracts: "erc20permit",
|
||||
},
|
||||
abis: [ERC20Abi, IERC20PermitAbi],
|
||||
features: {},
|
||||
@@ -115,7 +115,7 @@ export const FEATURE_TOKEN = {
|
||||
namespace: "token",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc20",
|
||||
contracts: "IERC20",
|
||||
contracts: "erc20",
|
||||
},
|
||||
abis: [ERC20Abi],
|
||||
features: {
|
||||
|
||||
@@ -20,7 +20,7 @@ export const FEATURE_NFT_BURNABLE = {
|
||||
namespace: "nft.burn",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721burnable",
|
||||
contracts: "IBurnableERC721",
|
||||
contracts: "erc721burnable",
|
||||
},
|
||||
abis: [Erc721Abi, IBurnableERC721Abi],
|
||||
features: {},
|
||||
@@ -31,7 +31,7 @@ export const FEATURE_NFT_REVEALABLE = {
|
||||
namespace: "nft.drop.revealer",
|
||||
docLinks: {
|
||||
sdk: "sdk.delayedreveal",
|
||||
contracts: "DelayedReveal",
|
||||
contracts: "erc721revealable",
|
||||
},
|
||||
abis: [Erc721Abi, ILazyMintAbi, DelayedRevealAbi],
|
||||
features: {},
|
||||
@@ -42,7 +42,8 @@ export const FEATURE_NFT_TIERED_DROP = {
|
||||
namespace: "nft.tieredDrop",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721tiereddrop",
|
||||
contracts: "TieredDrop",
|
||||
//TODO
|
||||
contracts: "",
|
||||
},
|
||||
abis: [Erc721Abi, TieredDropAbi],
|
||||
features: {},
|
||||
@@ -53,9 +54,9 @@ export const FEATURE_NFT_CLAIM_CONDITIONS_V1 = {
|
||||
namespace: "nft.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721claimable",
|
||||
contracts: "DropSinglePhase_V1",
|
||||
contracts: "erc721claimconditions",
|
||||
},
|
||||
abis: [Erc721Abi, ILazyMintAbi, IDropSinglePhaseV1],
|
||||
abis: [Erc721Abi, IDropSinglePhaseV1],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -64,9 +65,9 @@ export const FEATURE_NFT_CLAIM_CONDITIONS_V2 = {
|
||||
namespace: "nft.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721claimable",
|
||||
contracts: "DropSinglePhase",
|
||||
contracts: "erc721claimconditions",
|
||||
},
|
||||
abis: [Erc721Abi, ILazyMintAbi, IDropSinglePhase],
|
||||
abis: [Erc721Abi, IDropSinglePhase],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -75,7 +76,7 @@ export const FEATURE_NFT_CLAIM_PHASES_V1 = {
|
||||
namespace: "nft.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721claimable",
|
||||
contracts: "Drop",
|
||||
contracts: "erc721claimphases",
|
||||
},
|
||||
abis: [DropERC721_V3Abi],
|
||||
features: {},
|
||||
@@ -86,9 +87,9 @@ export const FEATURE_NFT_CLAIM_PHASES_V2 = {
|
||||
namespace: "nft.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721claimable",
|
||||
contracts: "Drop",
|
||||
contracts: "erc721claimphases",
|
||||
},
|
||||
abis: [Erc721Abi, ILazyMintAbi, IDrop],
|
||||
abis: [Erc721Abi, IDrop],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -97,9 +98,9 @@ export const FEATURE_NFT_CLAIM_CUSTOM = {
|
||||
namespace: "nft.drop.claim",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721claimable",
|
||||
contracts: "IClaimableERC721",
|
||||
contracts: "erc721claimcustom",
|
||||
},
|
||||
abis: [Erc721Abi, ILazyMintAbi, IClaimableERC721],
|
||||
abis: [Erc721Abi, IClaimableERC721],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
@@ -108,16 +109,11 @@ export const FEATURE_NFT_LAZY_MINTABLE = {
|
||||
namespace: "nft.drop",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721lazymintable",
|
||||
contracts: "LazyMint",
|
||||
contracts: "lazymint",
|
||||
},
|
||||
abis: [Erc721Abi, ILazyMintAbi],
|
||||
features: {
|
||||
[FEATURE_NFT_REVEALABLE.name]: FEATURE_NFT_REVEALABLE,
|
||||
[FEATURE_NFT_CLAIM_CUSTOM.name]: FEATURE_NFT_CLAIM_CUSTOM,
|
||||
[FEATURE_NFT_CLAIM_CONDITIONS_V1.name]: FEATURE_NFT_CLAIM_CONDITIONS_V1,
|
||||
[FEATURE_NFT_CLAIM_CONDITIONS_V2.name]: FEATURE_NFT_CLAIM_CONDITIONS_V2,
|
||||
[FEATURE_NFT_CLAIM_PHASES_V1.name]: FEATURE_NFT_CLAIM_PHASES_V1,
|
||||
[FEATURE_NFT_CLAIM_PHASES_V2.name]: FEATURE_NFT_CLAIM_PHASES_V2,
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -126,7 +122,7 @@ export const FEATURE_NFT_BATCH_MINTABLE = {
|
||||
namespace: "nft.mint.batch",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721batchmintable",
|
||||
contracts: "IMulticall",
|
||||
contracts: "erc721batchmintable",
|
||||
},
|
||||
abis: [Erc721Abi, IMintableERC721Abi, MulticallAbi],
|
||||
features: {},
|
||||
@@ -137,7 +133,7 @@ export const FEATURE_NFT_MINTABLE = {
|
||||
namespace: "nft.mint",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721mintable",
|
||||
contracts: "IMintableERC721",
|
||||
contracts: "erc721mintable",
|
||||
},
|
||||
abis: [Erc721Abi, IMintableERC721Abi],
|
||||
features: {
|
||||
@@ -150,7 +146,7 @@ export const FEATURE_NFT_SIGNATURE_MINTABLE_V2 = {
|
||||
namespace: "nft.signature",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721signaturemint",
|
||||
contracts: "ISignatureMintERC721",
|
||||
contracts: "erc721signaturemint",
|
||||
},
|
||||
abis: [Erc721Abi, SignatureMintERC721Abi],
|
||||
features: {},
|
||||
@@ -161,7 +157,7 @@ export const FEATURE_NFT_SIGNATURE_MINTABLE_V1 = {
|
||||
namespace: "nft.signature",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721signaturemint",
|
||||
contracts: "ISignatureMintERC721",
|
||||
contracts: "erc721signaturemint",
|
||||
},
|
||||
abis: [SignatureMintERC721_V1Abi],
|
||||
features: {},
|
||||
@@ -172,7 +168,7 @@ export const FEATURE_NFT_ENUMERABLE = {
|
||||
namespace: "nft.query.owned",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721enumerable",
|
||||
contracts: "IERC721Enumerable",
|
||||
contracts: "erc721enumerable",
|
||||
},
|
||||
abis: [Erc721Abi, Erc721EnumerableAbi],
|
||||
features: {},
|
||||
@@ -183,7 +179,7 @@ export const FEATURE_NFT_SUPPLY = {
|
||||
namespace: "nft.query",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721supply",
|
||||
contracts: "IERC721Supply",
|
||||
contracts: "erc721supply",
|
||||
},
|
||||
abis: [Erc721Abi, Erc721SupplyAbi],
|
||||
features: {
|
||||
@@ -196,7 +192,7 @@ export const FEATURE_NFT = {
|
||||
namespace: "nft",
|
||||
docLinks: {
|
||||
sdk: "sdk.erc721",
|
||||
contracts: "IERC721",
|
||||
contracts: "erc721",
|
||||
},
|
||||
abis: [Erc721Abi],
|
||||
features: {
|
||||
@@ -207,5 +203,10 @@ export const FEATURE_NFT = {
|
||||
[FEATURE_NFT_SIGNATURE_MINTABLE_V1.name]: FEATURE_NFT_SIGNATURE_MINTABLE_V1,
|
||||
[FEATURE_NFT_SIGNATURE_MINTABLE_V2.name]: FEATURE_NFT_SIGNATURE_MINTABLE_V2,
|
||||
[FEATURE_NFT_TIERED_DROP.name]: FEATURE_NFT_TIERED_DROP,
|
||||
[FEATURE_NFT_CLAIM_CUSTOM.name]: FEATURE_NFT_CLAIM_CUSTOM,
|
||||
[FEATURE_NFT_CLAIM_CONDITIONS_V1.name]: FEATURE_NFT_CLAIM_CONDITIONS_V1,
|
||||
[FEATURE_NFT_CLAIM_CONDITIONS_V2.name]: FEATURE_NFT_CLAIM_CONDITIONS_V2,
|
||||
[FEATURE_NFT_CLAIM_PHASES_V1.name]: FEATURE_NFT_CLAIM_PHASES_V1,
|
||||
[FEATURE_NFT_CLAIM_PHASES_V2.name]: FEATURE_NFT_CLAIM_PHASES_V2,
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -107,7 +107,7 @@ export const FEATURE_ROYALTY = {
|
||||
namespace: "royalty",
|
||||
docLinks: {
|
||||
sdk: "sdk.contractroyalty",
|
||||
contracts: "Royalty",
|
||||
contracts: "royalty",
|
||||
},
|
||||
abis: [IThirdwebRoyaltyAbi],
|
||||
features: {},
|
||||
@@ -118,7 +118,7 @@ export const FEATURE_PRIMARY_SALE = {
|
||||
namespace: "sales",
|
||||
docLinks: {
|
||||
sdk: "sdk.contractprimarysale",
|
||||
contracts: "PrimarySale",
|
||||
contracts: "primarysale",
|
||||
},
|
||||
abis: [IThirdwebPrimarySaleAbi],
|
||||
features: {},
|
||||
@@ -129,7 +129,7 @@ export const FEATURE_PLATFORM_FEE = {
|
||||
namespace: "platformFee",
|
||||
docLinks: {
|
||||
sdk: "sdk.platformfee",
|
||||
contracts: "PlatformFee",
|
||||
contracts: "platformfee",
|
||||
},
|
||||
abis: [IThirdwebPlatformFeeAbi],
|
||||
features: {},
|
||||
@@ -140,7 +140,7 @@ export const FEATURE_PERMISSIONS_ENUMERABLE = {
|
||||
namespace: "roles",
|
||||
docLinks: {
|
||||
sdk: "sdk.contractroles",
|
||||
contracts: "PermissionsEnumerable",
|
||||
contracts: "permissionsenumerable",
|
||||
},
|
||||
abis: [IPermissionsEnumerableAbi],
|
||||
features: {},
|
||||
@@ -151,7 +151,7 @@ export const FEATURE_PERMISSIONS = {
|
||||
namespace: "roles",
|
||||
docLinks: {
|
||||
sdk: "sdk.contractroles",
|
||||
contracts: "Permissions",
|
||||
contracts: "permissions",
|
||||
},
|
||||
abis: [IPermissionsAbi],
|
||||
features: {
|
||||
@@ -164,7 +164,7 @@ export const FEATURE_METADATA = {
|
||||
namespace: "metadata",
|
||||
docLinks: {
|
||||
sdk: "sdk.contractmetadata",
|
||||
contracts: "ContractMetadata",
|
||||
contracts: "contractmetadata",
|
||||
},
|
||||
abis: [IContractMetadataAbi],
|
||||
features: {},
|
||||
@@ -175,7 +175,8 @@ export const FEATURE_APPURI = {
|
||||
namespace: "appURI",
|
||||
docLinks: {
|
||||
sdk: "sdk.appURI",
|
||||
contracts: "AppURI",
|
||||
//TODO
|
||||
contracts: "",
|
||||
},
|
||||
abis: [IAppURI],
|
||||
features: {},
|
||||
@@ -186,7 +187,7 @@ export const FEATURE_OWNER = {
|
||||
namespace: "owner",
|
||||
docLinks: {
|
||||
sdk: "sdk.owner",
|
||||
contracts: "Ownable",
|
||||
contracts: "ownable",
|
||||
},
|
||||
abis: [IOwnableAbi],
|
||||
features: {},
|
||||
@@ -209,7 +210,8 @@ export const FEATURE_PACK_VRF = {
|
||||
namespace: "pack.vrf",
|
||||
docLinks: {
|
||||
sdk: "sdk.packvrf",
|
||||
contracts: "IPackVRFDirect",
|
||||
//TODO
|
||||
contracts: "",
|
||||
},
|
||||
abis: [IPackVRFAbi],
|
||||
features: {},
|
||||
@@ -220,7 +222,8 @@ export const FEATURE_PLUGIN_ROUTER = {
|
||||
namespace: "plugin.router",
|
||||
docLinks: {
|
||||
sdk: "sdk.pluginrouter",
|
||||
contracts: "IRouter",
|
||||
//TODO
|
||||
contracts: "",
|
||||
},
|
||||
abis: [getAllPluginsAbi],
|
||||
features: {},
|
||||
@@ -231,6 +234,7 @@ export const FEATURE_EXTENSION_ROUTER = {
|
||||
namespace: "extension.router",
|
||||
docLinks: {
|
||||
sdk: "",
|
||||
//TODO
|
||||
contracts: "",
|
||||
},
|
||||
abis: [getAllExtensionsAbi],
|
||||
|
||||
@@ -4,17 +4,23 @@ import {
|
||||
fetchExtendedReleaseMetadata,
|
||||
fetchPreDeployMetadata,
|
||||
} from "../../common";
|
||||
import {
|
||||
computeAddressInfra,
|
||||
computeCloneFactoryAddress,
|
||||
deployContractDeterministic,
|
||||
deployInfraWithSigner,
|
||||
getCreate2FactoryAddress,
|
||||
getDeploymentInfo,
|
||||
isContractDeployed,
|
||||
} from "../../common/any-evm-utils";
|
||||
import { deployCreate2Factory } from "../../common/any-evm-utils";
|
||||
import { getDeployArguments } from "../../common/deploy";
|
||||
import { resolveAddress } from "../../common/ens";
|
||||
import {
|
||||
buildDeployTransactionFunction,
|
||||
buildTransactionFunction,
|
||||
} from "../../common/transactions";
|
||||
import {
|
||||
EventType,
|
||||
getContractAddressByChainId,
|
||||
getNativeTokenByChainId,
|
||||
} from "../../constants";
|
||||
import { EventType, getContractAddressByChainId } from "../../constants";
|
||||
import {
|
||||
EditionDropInitializer,
|
||||
EditionInitializer,
|
||||
@@ -49,7 +55,6 @@ import {
|
||||
} from "../../types";
|
||||
import { ThirdwebSDK } from "../sdk";
|
||||
import {
|
||||
ContractType,
|
||||
DeploySchemaForPrebuiltContractType,
|
||||
NetworkInput,
|
||||
PrebuiltContractType,
|
||||
@@ -69,6 +74,7 @@ import {
|
||||
import { EventEmitter } from "eventemitter3";
|
||||
import invariant from "tiny-invariant";
|
||||
import { z } from "zod";
|
||||
import { DeploymentTransaction } from "../../types/any-evm/deploy-data";
|
||||
|
||||
const THIRDWEB_DEPLOYER = "0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024";
|
||||
|
||||
@@ -90,6 +96,7 @@ export class ContractDeployer extends RPCConnectionHandler {
|
||||
private storage: ThirdwebStorage;
|
||||
private events: EventEmitter<DeployEvents>;
|
||||
private deployMetadataCache: Record<string, any> = {};
|
||||
|
||||
private transactionListener = (event: any) => {
|
||||
if (event.status === "submitted") {
|
||||
this.events.emit("contractDeployed", {
|
||||
@@ -516,52 +523,20 @@ export class ContractDeployer extends RPCConnectionHandler {
|
||||
parsedMetadata,
|
||||
contractURI,
|
||||
signer,
|
||||
this.storage,
|
||||
);
|
||||
|
||||
const activeChainId = (await this.getProvider().getNetwork()).chainId;
|
||||
// fetch the publish URI from the ContractPublisher contract
|
||||
const publishedContract = await this.fetchPublishedContractFromPolygon(
|
||||
THIRDWEB_DEPLOYER,
|
||||
contractName,
|
||||
version,
|
||||
);
|
||||
// fetch the deploy metadata from the publish URI
|
||||
const deployMeta = await this.fetchAndCacheDeployMetadata(
|
||||
publishedContract.metadataUri,
|
||||
);
|
||||
let implementationAddress = deployMeta.extendedMetadata
|
||||
?.factoryDeploymentData?.implementationAddresses?.[
|
||||
activeChainId
|
||||
] as AddressOrEns;
|
||||
|
||||
if (implementationAddress) {
|
||||
// implementation exists on the current chain, continue with normal flow
|
||||
return this.deployContractFromUri.prepare(
|
||||
publishedContract.metadataUri,
|
||||
constructorParams,
|
||||
);
|
||||
} else {
|
||||
// implementation does NOT exist on chain, deploy the implementation first, then deploy a proxy
|
||||
implementationAddress = await this.deployContractFromUri(
|
||||
publishedContract.metadataUri,
|
||||
this.getConstructorParamsForImplementation(
|
||||
contractType,
|
||||
activeChainId,
|
||||
),
|
||||
{
|
||||
forceDirectDeploy: true,
|
||||
},
|
||||
);
|
||||
const resolvedImplementationAddress = await resolveAddress(
|
||||
implementationAddress,
|
||||
);
|
||||
return this.deployProxy.prepare(
|
||||
resolvedImplementationAddress,
|
||||
deployMeta.compilerMetadata.abi,
|
||||
"initialize",
|
||||
constructorParams,
|
||||
);
|
||||
}
|
||||
return this.deployContractFromUri.prepare(
|
||||
publishedContract.metadataUri,
|
||||
constructorParams,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -788,22 +763,8 @@ export class ContractDeployer extends RPCConnectionHandler {
|
||||
extendedMetadata.isDeployableViaFactory) &&
|
||||
!forceDirectDeploy
|
||||
) {
|
||||
console.log("Deploying directly...");
|
||||
const chainId = (await this.getProvider().getNetwork()).chainId;
|
||||
invariant(
|
||||
extendedMetadata.factoryDeploymentData.implementationAddresses,
|
||||
"implementationAddresses is required",
|
||||
);
|
||||
const implementationAddress = extendedMetadata.factoryDeploymentData
|
||||
.implementationAddresses[chainId] as AddressOrEns;
|
||||
const resolvedImplementationAddress = await resolveAddress(
|
||||
implementationAddress,
|
||||
);
|
||||
|
||||
invariant(
|
||||
resolvedImplementationAddress,
|
||||
`implementationAddress not found for chainId '${chainId}'`,
|
||||
);
|
||||
invariant(
|
||||
extendedMetadata.factoryDeploymentData
|
||||
.implementationInitializerFunction,
|
||||
@@ -819,36 +780,108 @@ export class ContractDeployer extends RPCConnectionHandler {
|
||||
constructorParamValues,
|
||||
);
|
||||
|
||||
if (extendedMetadata.isDeployableViaFactory) {
|
||||
// deploy via a factory (prioritise factory)
|
||||
invariant(
|
||||
extendedMetadata.factoryDeploymentData.factoryAddresses,
|
||||
"isDeployableViaFactory is true so factoryAddresses is required",
|
||||
let implementationAddress = extendedMetadata.factoryDeploymentData
|
||||
.implementationAddresses[chainId] as AddressOrEns;
|
||||
|
||||
if (implementationAddress) {
|
||||
const resolvedImplementationAddress = await resolveAddress(
|
||||
implementationAddress,
|
||||
);
|
||||
const factoryAddress = extendedMetadata.factoryDeploymentData
|
||||
.factoryAddresses[chainId] as AddressOrEns;
|
||||
|
||||
invariant(
|
||||
factoryAddress,
|
||||
`isDeployableViaFactory is true and factoryAddress not found for chainId '${chainId}'`,
|
||||
resolvedImplementationAddress,
|
||||
`implementationAddress not found for chainId '${chainId}'`,
|
||||
);
|
||||
const resolvedFactoryAddress = await resolveAddress(factoryAddress);
|
||||
return (await this.deployViaFactory.prepare(
|
||||
resolvedFactoryAddress,
|
||||
|
||||
if (extendedMetadata.isDeployableViaFactory) {
|
||||
// deploy via a factory (prioritise factory)
|
||||
invariant(
|
||||
extendedMetadata.factoryDeploymentData.factoryAddresses,
|
||||
"isDeployableViaFactory is true so factoryAddresses is required",
|
||||
);
|
||||
const factoryAddress = extendedMetadata.factoryDeploymentData
|
||||
.factoryAddresses[chainId] as AddressOrEns;
|
||||
invariant(
|
||||
factoryAddress,
|
||||
`isDeployableViaFactory is true and factoryAddress not found for chainId '${chainId}'`,
|
||||
);
|
||||
const resolvedFactoryAddress = await resolveAddress(factoryAddress);
|
||||
return (await this.deployViaFactory.prepare(
|
||||
resolvedFactoryAddress,
|
||||
resolvedImplementationAddress,
|
||||
compilerMetadata.abi,
|
||||
extendedMetadata.factoryDeploymentData
|
||||
.implementationInitializerFunction,
|
||||
paramValues,
|
||||
)) as unknown as DeployTransaction;
|
||||
} else if (extendedMetadata.isDeployableViaProxy) {
|
||||
// deploy a proxy directly
|
||||
return await this.deployProxy.prepare(
|
||||
resolvedImplementationAddress,
|
||||
compilerMetadata.abi,
|
||||
extendedMetadata.factoryDeploymentData
|
||||
.implementationInitializerFunction,
|
||||
paramValues,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// any evm deployment flow -- with signer
|
||||
|
||||
// 1. Deploy CREATE2 factory (if not already exists)
|
||||
const create2Factory = await deployCreate2Factory(signer, options);
|
||||
|
||||
// 2. get deployment info for any evm
|
||||
const deploymentInfo = await getDeploymentInfo(
|
||||
publishMetadataUri,
|
||||
this.storage,
|
||||
this.getProvider(),
|
||||
create2Factory,
|
||||
);
|
||||
|
||||
implementationAddress = deploymentInfo.predictedAddress;
|
||||
|
||||
// 3. deploy infra
|
||||
await deployInfraWithSigner(
|
||||
signer,
|
||||
this.getProvider(),
|
||||
this.storage,
|
||||
create2Factory,
|
||||
deploymentInfo.infraContractsToDeploy,
|
||||
options,
|
||||
);
|
||||
|
||||
// 4. deploy implementation contract
|
||||
await deployContractDeterministic(
|
||||
signer,
|
||||
deploymentInfo.bytecode,
|
||||
deploymentInfo.encodedArgs,
|
||||
create2Factory,
|
||||
options,
|
||||
deploymentInfo.predictedAddress,
|
||||
);
|
||||
|
||||
const resolvedImplementationAddress = await resolveAddress(
|
||||
implementationAddress,
|
||||
);
|
||||
|
||||
// 5. deploy proxy with TWStatelessFactory (Clone factory) and return address
|
||||
const cloneFactory = await computeCloneFactoryAddress(
|
||||
this.getProvider(),
|
||||
this.storage,
|
||||
create2Factory,
|
||||
);
|
||||
|
||||
options?.notifier?.("deploying", "proxy");
|
||||
const proxyDeployTransaction = (await this.deployViaFactory.prepare(
|
||||
cloneFactory,
|
||||
resolvedImplementationAddress,
|
||||
compilerMetadata.abi,
|
||||
extendedMetadata.factoryDeploymentData
|
||||
.implementationInitializerFunction,
|
||||
paramValues,
|
||||
)) as unknown as DeployTransaction;
|
||||
} else if (extendedMetadata.isDeployableViaProxy) {
|
||||
// deploy a proxy directly
|
||||
return await this.deployProxy.prepare(
|
||||
resolvedImplementationAddress,
|
||||
compilerMetadata.abi,
|
||||
extendedMetadata.factoryDeploymentData
|
||||
.implementationInitializerFunction,
|
||||
paramValues,
|
||||
);
|
||||
options?.notifier?.("deployed", "proxy");
|
||||
return proxyDeployTransaction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,6 +934,105 @@ export class ContractDeployer extends RPCConnectionHandler {
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @param publishMetadataUri
|
||||
* @param options
|
||||
*/
|
||||
public async getTransactionsForDeploy(
|
||||
publishMetadataUri: string,
|
||||
options?: DeployOptions,
|
||||
): Promise<DeploymentTransaction[]> {
|
||||
let transactions: DeploymentTransaction[] = [];
|
||||
const provider = this.getProvider();
|
||||
invariant(provider, "A provider is required");
|
||||
|
||||
const { extendedMetadata } = await this.fetchAndCacheDeployMetadata(
|
||||
publishMetadataUri,
|
||||
);
|
||||
const forceDirectDeploy = options?.forceDirectDeploy || false;
|
||||
if (
|
||||
extendedMetadata &&
|
||||
extendedMetadata.factoryDeploymentData &&
|
||||
(extendedMetadata.isDeployableViaProxy ||
|
||||
extendedMetadata.isDeployableViaFactory) &&
|
||||
!forceDirectDeploy
|
||||
) {
|
||||
const chainId = (await this.getProvider().getNetwork()).chainId;
|
||||
|
||||
let implementationAddress = extendedMetadata.factoryDeploymentData
|
||||
.implementationAddresses[chainId] as AddressOrEns;
|
||||
|
||||
if (!implementationAddress) {
|
||||
const create2FactoryAddress = await getCreate2FactoryAddress(
|
||||
this.getProvider(),
|
||||
);
|
||||
|
||||
transactions.push({
|
||||
contractType: "create2Factory",
|
||||
addresses: [create2FactoryAddress],
|
||||
});
|
||||
|
||||
const deploymentInfo = await getDeploymentInfo(
|
||||
publishMetadataUri,
|
||||
this.storage,
|
||||
this.getProvider(),
|
||||
create2FactoryAddress,
|
||||
);
|
||||
|
||||
implementationAddress = deploymentInfo.predictedAddress;
|
||||
transactions.push({
|
||||
contractType: "implementation",
|
||||
addresses: [implementationAddress],
|
||||
});
|
||||
|
||||
const infraAddresses = await Promise.all(
|
||||
deploymentInfo.infraContractsToDeploy.map((contract) => {
|
||||
return computeAddressInfra(
|
||||
contract,
|
||||
this.getProvider(),
|
||||
this.storage,
|
||||
create2FactoryAddress,
|
||||
);
|
||||
}),
|
||||
);
|
||||
transactions.push({
|
||||
contractType: "infra",
|
||||
addresses: [...infraAddresses],
|
||||
});
|
||||
|
||||
transactions = (
|
||||
await Promise.all(
|
||||
transactions.map(async (tx) => {
|
||||
const addresses = (
|
||||
await Promise.all(
|
||||
tx.addresses.map(async (address) => {
|
||||
const isDeployed = await isContractDeployed(
|
||||
address,
|
||||
provider,
|
||||
);
|
||||
return isDeployed ? null : address;
|
||||
}),
|
||||
)
|
||||
).filter(Boolean);
|
||||
return addresses.length > 0 ? tx : null;
|
||||
}),
|
||||
)
|
||||
).filter(Boolean) as DeploymentTransaction[];
|
||||
}
|
||||
transactions.push({
|
||||
contractType: "proxy",
|
||||
addresses: [],
|
||||
});
|
||||
} else {
|
||||
transactions.push({
|
||||
contractType: "custom",
|
||||
addresses: [],
|
||||
});
|
||||
}
|
||||
return transactions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to all deploy transactions from this deployer
|
||||
* @param listener the listener to add
|
||||
@@ -970,27 +1102,6 @@ export class ContractDeployer extends RPCConnectionHandler {
|
||||
return publishedContract;
|
||||
}
|
||||
|
||||
private getConstructorParamsForImplementation(
|
||||
contractType: ContractType,
|
||||
chainId: number,
|
||||
) {
|
||||
switch (contractType) {
|
||||
case MarketplaceInitializer.contractType:
|
||||
case MultiwrapInitializer.contractType:
|
||||
const nativeTokenWrapperAddress =
|
||||
getNativeTokenByChainId(chainId)?.wrapped?.address ||
|
||||
ethers.constants.AddressZero;
|
||||
return [nativeTokenWrapperAddress];
|
||||
case PackInitializer.contractType:
|
||||
const addr =
|
||||
getNativeTokenByChainId(chainId).wrapped.address ||
|
||||
ethers.constants.AddressZero;
|
||||
return [addr, ethers.constants.AddressZero];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private hasLocalFactory() {
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
return process.env.factoryAddress !== undefined;
|
||||
|
||||
@@ -7,24 +7,15 @@ import {
|
||||
FEATURE_EDITION_LAZY_MINTABLE_V2,
|
||||
FEATURE_EDITION_REVEALABLE,
|
||||
} from "../../constants/erc1155-features";
|
||||
import {
|
||||
BaseClaimConditionERC1155,
|
||||
BaseDelayedRevealERC1155,
|
||||
BaseDropERC1155,
|
||||
} from "../../types/eips";
|
||||
import { BaseDelayedRevealERC1155, BaseDropERC1155 } from "../../types/eips";
|
||||
import { UploadProgressEvent } from "../../types/events";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { TransactionResultWithId } from "../types";
|
||||
import { ContractWrapper } from "./contract-wrapper";
|
||||
import { DelayedReveal } from "./delayed-reveal";
|
||||
import { Erc1155 } from "./erc-1155";
|
||||
import { ERC1155Claimable } from "./erc-1155-claimable";
|
||||
import { Erc1155ClaimableWithConditions } from "./erc-1155-claimable-with-conditions";
|
||||
import { Transaction } from "./transactions";
|
||||
import type {
|
||||
DropERC1155_V2,
|
||||
IClaimableERC1155,
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import type { DropERC1155_V2 } from "@thirdweb-dev/contracts-js";
|
||||
import { TokensLazyMintedEvent } from "@thirdweb-dev/contracts-js/dist/declarations/src/LazyMint";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { ethers } from "ethers";
|
||||
@@ -65,19 +56,6 @@ export class Erc1155LazyMintable implements DetectableFeature {
|
||||
*/
|
||||
public revealer: DelayedReveal<BaseDelayedRevealERC1155> | undefined;
|
||||
|
||||
/**
|
||||
* Claim tokens and configure claim conditions
|
||||
* @remarks Let users claim NFTs. Define who can claim NFTs in the collection, when and how many.
|
||||
* @example
|
||||
* ```javascript
|
||||
* const quantity = 10;
|
||||
* const tokenId = 0;
|
||||
* await contract.erc1155.claimTo("0x...", 0, quantity);
|
||||
* ```
|
||||
*/
|
||||
public claimWithConditions: Erc1155ClaimableWithConditions | undefined;
|
||||
public claim: ERC1155Claimable | undefined;
|
||||
|
||||
private contractWrapper: ContractWrapper<BaseDropERC1155>;
|
||||
private erc1155: Erc1155;
|
||||
private storage: ThirdwebStorage;
|
||||
@@ -91,8 +69,6 @@ export class Erc1155LazyMintable implements DetectableFeature {
|
||||
this.contractWrapper = contractWrapper;
|
||||
|
||||
this.storage = storage;
|
||||
this.claim = this.detectErc1155Claimable();
|
||||
this.claimWithConditions = this.detectErc1155ClaimableWithConditions();
|
||||
this.revealer = this.detectErc1155Revealable();
|
||||
}
|
||||
|
||||
@@ -201,47 +177,6 @@ export class Erc1155LazyMintable implements DetectableFeature {
|
||||
* PRIVATE FUNCTIONS
|
||||
*******************************/
|
||||
|
||||
private detectErc1155Claimable(): ERC1155Claimable | undefined {
|
||||
if (
|
||||
detectContractFeature<IClaimableERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimCustom",
|
||||
)
|
||||
) {
|
||||
return new ERC1155Claimable(this.contractWrapper);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc1155ClaimableWithConditions():
|
||||
| Erc1155ClaimableWithConditions
|
||||
| undefined {
|
||||
if (
|
||||
detectContractFeature<BaseClaimConditionERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimConditionsV1",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimConditionsV2",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimPhasesV1",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimPhasesV2",
|
||||
)
|
||||
) {
|
||||
return new Erc1155ClaimableWithConditions(
|
||||
this.contractWrapper,
|
||||
this.storage,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc1155Revealable():
|
||||
| DelayedReveal<BaseDelayedRevealERC1155>
|
||||
| undefined {
|
||||
|
||||
@@ -28,6 +28,7 @@ import { EditionMetadataOrUri } from "../../schema/tokens/edition";
|
||||
import { ClaimOptions, UploadProgressEvent } from "../../types";
|
||||
import { AirdropInput } from "../../types/airdrop/airdrop";
|
||||
import {
|
||||
BaseClaimConditionERC1155,
|
||||
BaseDropERC1155,
|
||||
BaseERC1155,
|
||||
BaseSignatureMintERC1155,
|
||||
@@ -45,12 +46,15 @@ import { Transaction } from "./transactions";
|
||||
import type {
|
||||
DropERC1155,
|
||||
IBurnableERC1155,
|
||||
IClaimableERC1155,
|
||||
IERC1155Enumerable,
|
||||
IMintableERC1155,
|
||||
TokenERC1155,
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { BigNumber, BigNumberish, BytesLike, ethers } from "ethers";
|
||||
import { ERC1155Claimable } from "./erc-1155-claimable";
|
||||
import { Erc1155ClaimableWithConditions } from "./erc-1155-claimable-with-conditions";
|
||||
|
||||
/**
|
||||
* Standard ERC1155 NFT functions
|
||||
@@ -74,6 +78,8 @@ export class Erc1155<
|
||||
private burnable: Erc1155Burnable | undefined;
|
||||
private lazyMintable: Erc1155LazyMintable | undefined;
|
||||
private signatureMintable: Erc1155SignatureMintable | undefined;
|
||||
private claimWithConditions: Erc1155ClaimableWithConditions | undefined;
|
||||
private claimCustom: ERC1155Claimable | undefined;
|
||||
|
||||
protected contractWrapper: ContractWrapper<T>;
|
||||
protected storage: ThirdwebStorage;
|
||||
@@ -95,6 +101,8 @@ export class Erc1155<
|
||||
this.burnable = this.detectErc1155Burnable();
|
||||
this.lazyMintable = this.detectErc1155LazyMintable();
|
||||
this.signatureMintable = this.detectErc1155SignatureMintable();
|
||||
this.claimCustom = this.detectErc1155Claimable();
|
||||
this.claimWithConditions = this.detectErc1155ClaimableWithConditions();
|
||||
this._chainId = chainId;
|
||||
}
|
||||
|
||||
@@ -853,8 +861,8 @@ export class Erc1155<
|
||||
quantity: BigNumberish,
|
||||
options?: ClaimOptions,
|
||||
): Promise<Transaction> {
|
||||
const claimWithConditions = this.lazyMintable?.claimWithConditions;
|
||||
const claim = this.lazyMintable?.claim;
|
||||
const claimWithConditions = this.claimWithConditions;
|
||||
const claim = this.claimCustom;
|
||||
if (claimWithConditions) {
|
||||
return claimWithConditions.conditions.getClaimTransaction(
|
||||
destinationAddress,
|
||||
@@ -940,8 +948,8 @@ export class Erc1155<
|
||||
quantity: BigNumberish,
|
||||
options?: ClaimOptions,
|
||||
) => {
|
||||
const claimWithConditions = this.lazyMintable?.claimWithConditions;
|
||||
const claim = this.lazyMintable?.claim;
|
||||
const claimWithConditions = this.claimWithConditions;
|
||||
const claim = this.claimCustom;
|
||||
if (claimWithConditions) {
|
||||
return claimWithConditions.to.prepare(
|
||||
destinationAddress,
|
||||
@@ -982,7 +990,7 @@ export class Erc1155<
|
||||
*/
|
||||
get claimConditions() {
|
||||
return assertEnabled(
|
||||
this.lazyMintable?.claimWithConditions,
|
||||
this.claimWithConditions,
|
||||
FEATURE_EDITION_CLAIM_CONDITIONS_V2,
|
||||
).conditions;
|
||||
}
|
||||
@@ -1132,4 +1140,45 @@ export class Erc1155<
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc1155Claimable(): ERC1155Claimable | undefined {
|
||||
if (
|
||||
detectContractFeature<IClaimableERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimCustom",
|
||||
)
|
||||
) {
|
||||
return new ERC1155Claimable(this.contractWrapper);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc1155ClaimableWithConditions():
|
||||
| Erc1155ClaimableWithConditions
|
||||
| undefined {
|
||||
if (
|
||||
detectContractFeature<BaseClaimConditionERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimConditionsV1",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimConditionsV2",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimPhasesV1",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC1155>(
|
||||
this.contractWrapper,
|
||||
"ERC1155ClaimPhasesV2",
|
||||
)
|
||||
) {
|
||||
return new Erc1155ClaimableWithConditions(
|
||||
this.contractWrapper,
|
||||
this.storage,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,20 +7,13 @@ import {
|
||||
FEATURE_NFT_REVEALABLE,
|
||||
} from "../../constants/erc721-features";
|
||||
import { UploadProgressEvent } from "../../types";
|
||||
import {
|
||||
BaseClaimConditionERC721,
|
||||
BaseDelayedRevealERC721,
|
||||
BaseDropERC721,
|
||||
} from "../../types/eips";
|
||||
import { BaseDelayedRevealERC721, BaseDropERC721 } from "../../types/eips";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { TransactionResultWithId } from "../types";
|
||||
import { ContractWrapper } from "./contract-wrapper";
|
||||
import { DelayedReveal } from "./delayed-reveal";
|
||||
import { Erc721 } from "./erc-721";
|
||||
import { Erc721Claimable } from "./erc-721-claimable";
|
||||
import { Erc721ClaimableWithConditions } from "./erc-721-claimable-with-conditions";
|
||||
import { Transaction } from "./transactions";
|
||||
import type { IClaimableERC721 } from "@thirdweb-dev/contracts-js";
|
||||
import { TokensLazyMintedEvent } from "@thirdweb-dev/contracts-js/dist/declarations/src/LazyMint";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { ethers } from "ethers";
|
||||
@@ -70,18 +63,6 @@ export class Erc721LazyMintable implements DetectableFeature {
|
||||
*/
|
||||
public revealer: DelayedReveal<BaseDelayedRevealERC721> | undefined;
|
||||
|
||||
/**
|
||||
* Claim tokens and configure claim conditions
|
||||
* @remarks Let users claim NFTs. Define who can claim NFTs in the collection, when and how many.
|
||||
* @example
|
||||
* ```javascript
|
||||
* const quantity = 10;
|
||||
* await contract.erc721.claim(quantity);
|
||||
* ```
|
||||
*/
|
||||
public claimWithConditions: Erc721ClaimableWithConditions | undefined;
|
||||
public claim: Erc721Claimable | undefined;
|
||||
|
||||
private contractWrapper: ContractWrapper<BaseDropERC721>;
|
||||
private erc721: Erc721;
|
||||
private storage: ThirdwebStorage;
|
||||
@@ -96,8 +77,6 @@ export class Erc721LazyMintable implements DetectableFeature {
|
||||
|
||||
this.storage = storage;
|
||||
this.revealer = this.detectErc721Revealable();
|
||||
this.claimWithConditions = this.detectErc721ClaimableWithConditions();
|
||||
this.claim = this.detectErc721Claimable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,46 +173,4 @@ export class Erc721LazyMintable implements DetectableFeature {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc721ClaimableWithConditions():
|
||||
| Erc721ClaimableWithConditions
|
||||
| undefined {
|
||||
if (
|
||||
detectContractFeature<BaseClaimConditionERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimConditionsV1",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimConditionsV2",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimPhasesV1",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimPhasesV2",
|
||||
)
|
||||
) {
|
||||
return new Erc721ClaimableWithConditions(
|
||||
this.erc721,
|
||||
this.contractWrapper,
|
||||
this.storage,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc721Claimable(): Erc721Claimable | undefined {
|
||||
if (
|
||||
detectContractFeature<IClaimableERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimCustom",
|
||||
)
|
||||
) {
|
||||
return new Erc721Claimable(this.erc721, this.contractWrapper);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from "../../schema/contracts/tiered-drop";
|
||||
import { UploadProgressEvent } from "../../types/events";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { TransactionResult, TransactionResultWithId } from "../types";
|
||||
import { TransactionResultWithId } from "../types";
|
||||
import { ContractWrapper } from "./contract-wrapper";
|
||||
import { Erc721 } from "./erc-721";
|
||||
import type { TieredDrop, ISignatureAction } from "@thirdweb-dev/contracts-js";
|
||||
@@ -28,6 +28,8 @@ import {
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { BigNumberish, ethers } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
import { Transaction } from "./transactions";
|
||||
import { buildTransactionFunction } from "../../common/transactions";
|
||||
|
||||
export class Erc721TieredDrop implements DetectableFeature {
|
||||
featureName = FEATURE_NFT_TIERED_DROP.name;
|
||||
@@ -112,164 +114,182 @@ export class Erc721TieredDrop implements DetectableFeature {
|
||||
return nfts;
|
||||
}
|
||||
|
||||
public async createBatchWithTier(
|
||||
metadatas: NFTMetadataOrUri[],
|
||||
tier: string,
|
||||
options?: {
|
||||
onProgress: (event: UploadProgressEvent) => void;
|
||||
},
|
||||
): Promise<TransactionResultWithId<NFTMetadata>[]> {
|
||||
// TODO: Change this to on extension
|
||||
const startFileNumber = await this.erc721.nextTokenIdToMint();
|
||||
const batch = await uploadOrExtractURIs(
|
||||
metadatas,
|
||||
this.storage,
|
||||
startFileNumber.toNumber(),
|
||||
options,
|
||||
);
|
||||
const baseUri = getBaseUriFromBatch(batch);
|
||||
createBatchWithTier = buildTransactionFunction(
|
||||
async (
|
||||
metadatas: NFTMetadataOrUri[],
|
||||
tier: string,
|
||||
options?: {
|
||||
onProgress: (event: UploadProgressEvent) => void;
|
||||
},
|
||||
): Promise<Transaction<TransactionResultWithId<NFTMetadata>[]>> => {
|
||||
// TODO: Change this to on extension
|
||||
const startFileNumber = await this.erc721.nextTokenIdToMint();
|
||||
const batch = await uploadOrExtractURIs(
|
||||
metadatas,
|
||||
this.storage,
|
||||
startFileNumber.toNumber(),
|
||||
options,
|
||||
);
|
||||
const baseUri = getBaseUriFromBatch(batch);
|
||||
|
||||
const receipt = await this.contractWrapper.sendTransaction("lazyMint", [
|
||||
batch.length,
|
||||
baseUri.endsWith("/") ? baseUri : `${baseUri}/`,
|
||||
tier,
|
||||
ethers.utils.toUtf8Bytes(""),
|
||||
]);
|
||||
return Transaction.fromContractWrapper({
|
||||
contractWrapper: this.contractWrapper,
|
||||
method: "lazyMint",
|
||||
args: [
|
||||
batch.length,
|
||||
baseUri.endsWith("/") ? baseUri : `${baseUri}/`,
|
||||
tier,
|
||||
ethers.utils.toUtf8Bytes(""),
|
||||
],
|
||||
parse: (receipt) => {
|
||||
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
|
||||
"TokensLazyMinted",
|
||||
receipt?.logs,
|
||||
);
|
||||
|
||||
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
|
||||
"TokensLazyMinted",
|
||||
receipt?.logs,
|
||||
);
|
||||
|
||||
const startingIndex = event[0].args[1];
|
||||
const endingIndex = event[0].args[2];
|
||||
const results: TransactionResultWithId<NFTMetadata>[] = [];
|
||||
for (let id = startingIndex; id.lte(endingIndex); id = id.add(1)) {
|
||||
results.push({
|
||||
id,
|
||||
receipt,
|
||||
data: () => this.erc721.getTokenMetadata(id),
|
||||
const startingIndex = event[0].args[1];
|
||||
const endingIndex = event[0].args[2];
|
||||
const results: TransactionResultWithId<NFTMetadata>[] = [];
|
||||
for (let id = startingIndex; id.lte(endingIndex); id = id.add(1)) {
|
||||
results.push({
|
||||
id,
|
||||
receipt,
|
||||
data: () => this.erc721.getTokenMetadata(id),
|
||||
});
|
||||
}
|
||||
return results;
|
||||
},
|
||||
});
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public async createDelayedRevealBatchWithTier(
|
||||
placeholder: NFTMetadataInput,
|
||||
metadatas: NFTMetadataInput[],
|
||||
password: string,
|
||||
tier: string,
|
||||
options?: {
|
||||
onProgress: (event: UploadProgressEvent) => void;
|
||||
},
|
||||
): Promise<TransactionResultWithId<NFTMetadata>[]> {
|
||||
if (!password) {
|
||||
throw new Error("Password is required");
|
||||
}
|
||||
);
|
||||
|
||||
const placeholderUris = await this.storage.uploadBatch(
|
||||
[CommonNFTInput.parse(placeholder)],
|
||||
{
|
||||
rewriteFileNames: {
|
||||
fileStartNumber: 0,
|
||||
},
|
||||
createDelayedRevealBatchWithTier = buildTransactionFunction(
|
||||
async (
|
||||
placeholder: NFTMetadataInput,
|
||||
metadatas: NFTMetadataInput[],
|
||||
password: string,
|
||||
tier: string,
|
||||
options?: {
|
||||
onProgress: (event: UploadProgressEvent) => void;
|
||||
},
|
||||
);
|
||||
const placeholderUri = getBaseUriFromBatch(placeholderUris);
|
||||
const startFileNumber = await this.erc721.nextTokenIdToMint();
|
||||
const uris = await this.storage.uploadBatch(
|
||||
metadatas.map((m) => CommonNFTInput.parse(m)),
|
||||
{
|
||||
onProgress: options?.onProgress,
|
||||
rewriteFileNames: {
|
||||
fileStartNumber: startFileNumber.toNumber(),
|
||||
): Promise<Transaction<TransactionResultWithId<NFTMetadata>[]>> => {
|
||||
if (!password) {
|
||||
throw new Error("Password is required");
|
||||
}
|
||||
|
||||
const placeholderUris = await this.storage.uploadBatch(
|
||||
[CommonNFTInput.parse(placeholder)],
|
||||
{
|
||||
rewriteFileNames: {
|
||||
fileStartNumber: 0,
|
||||
},
|
||||
},
|
||||
);
|
||||
const placeholderUri = getBaseUriFromBatch(placeholderUris);
|
||||
const startFileNumber = await this.erc721.nextTokenIdToMint();
|
||||
const uris = await this.storage.uploadBatch(
|
||||
metadatas.map((m) => CommonNFTInput.parse(m)),
|
||||
{
|
||||
onProgress: options?.onProgress,
|
||||
rewriteFileNames: {
|
||||
fileStartNumber: startFileNumber.toNumber(),
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const baseUri = getBaseUriFromBatch(uris);
|
||||
const baseUriId = await this.contractWrapper.readContract.getBaseURICount();
|
||||
const chainId = await this.contractWrapper.getChainID();
|
||||
const hashedPassword = ethers.utils.solidityKeccak256(
|
||||
["string", "uint256", "uint256", "address"],
|
||||
[password, chainId, baseUriId, this.contractWrapper.readContract.address],
|
||||
);
|
||||
|
||||
const encryptedBaseUri =
|
||||
await this.contractWrapper.readContract.encryptDecrypt(
|
||||
ethers.utils.toUtf8Bytes(baseUri),
|
||||
hashedPassword,
|
||||
);
|
||||
|
||||
let data: string;
|
||||
const provenanceHash = ethers.utils.solidityKeccak256(
|
||||
["bytes", "bytes", "uint256"],
|
||||
[ethers.utils.toUtf8Bytes(baseUri), hashedPassword, chainId],
|
||||
);
|
||||
data = ethers.utils.defaultAbiCoder.encode(
|
||||
["bytes", "bytes32"],
|
||||
[encryptedBaseUri, provenanceHash],
|
||||
);
|
||||
const baseUri = getBaseUriFromBatch(uris);
|
||||
const baseUriId =
|
||||
await this.contractWrapper.readContract.getBaseURICount();
|
||||
const chainId = await this.contractWrapper.getChainID();
|
||||
const hashedPassword = ethers.utils.solidityKeccak256(
|
||||
["string", "uint256", "uint256", "address"],
|
||||
[
|
||||
password,
|
||||
chainId,
|
||||
baseUriId,
|
||||
this.contractWrapper.readContract.address,
|
||||
],
|
||||
);
|
||||
|
||||
const receipt = await this.contractWrapper.sendTransaction("lazyMint", [
|
||||
uris.length,
|
||||
placeholderUri.endsWith("/") ? placeholderUri : `${placeholderUri}/`,
|
||||
tier,
|
||||
data,
|
||||
]);
|
||||
const encryptedBaseUri =
|
||||
await this.contractWrapper.readContract.encryptDecrypt(
|
||||
ethers.utils.toUtf8Bytes(baseUri),
|
||||
hashedPassword,
|
||||
);
|
||||
|
||||
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
|
||||
"TokensLazyMinted",
|
||||
receipt?.logs,
|
||||
);
|
||||
const startingIndex = event[0].args[1];
|
||||
const endingIndex = event[0].args[2];
|
||||
const results: TransactionResultWithId<NFTMetadata>[] = [];
|
||||
for (let id = startingIndex; id.lte(endingIndex); id = id.add(1)) {
|
||||
results.push({
|
||||
id,
|
||||
receipt,
|
||||
data: () => this.erc721.getTokenMetadata(id),
|
||||
let data: string;
|
||||
const provenanceHash = ethers.utils.solidityKeccak256(
|
||||
["bytes", "bytes", "uint256"],
|
||||
[ethers.utils.toUtf8Bytes(baseUri), hashedPassword, chainId],
|
||||
);
|
||||
data = ethers.utils.defaultAbiCoder.encode(
|
||||
["bytes", "bytes32"],
|
||||
[encryptedBaseUri, provenanceHash],
|
||||
);
|
||||
|
||||
return Transaction.fromContractWrapper({
|
||||
contractWrapper: this.contractWrapper,
|
||||
method: "lazyMint",
|
||||
args: [
|
||||
uris.length,
|
||||
placeholderUri.endsWith("/") ? placeholderUri : `${placeholderUri}/`,
|
||||
tier,
|
||||
data,
|
||||
],
|
||||
parse: (receipt) => {
|
||||
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
|
||||
"TokensLazyMinted",
|
||||
receipt?.logs,
|
||||
);
|
||||
const startingIndex = event[0].args[1];
|
||||
const endingIndex = event[0].args[2];
|
||||
const results: TransactionResultWithId<NFTMetadata>[] = [];
|
||||
for (let id = startingIndex; id.lte(endingIndex); id = id.add(1)) {
|
||||
results.push({
|
||||
id,
|
||||
receipt,
|
||||
data: () => this.erc721.getTokenMetadata(id),
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public async reveal(
|
||||
batchId: BigNumberish,
|
||||
password: string,
|
||||
): Promise<TransactionResult> {
|
||||
if (!password) {
|
||||
throw new Error("Password is required");
|
||||
}
|
||||
const chainId = await this.contractWrapper.getChainID();
|
||||
const key = ethers.utils.solidityKeccak256(
|
||||
["string", "uint256", "uint256", "address"],
|
||||
[password, chainId, batchId, this.contractWrapper.readContract.address],
|
||||
);
|
||||
// performing the reveal locally to make sure it'd succeed before sending the transaction
|
||||
try {
|
||||
const decryptedUri = await this.contractWrapper
|
||||
.callStatic()
|
||||
.reveal(batchId, key);
|
||||
// basic sanity check for making sure decryptedUri is valid
|
||||
// this is optional because invalid decryption key would result in non-utf8 bytes and
|
||||
// ethers would throw when trying to decode it
|
||||
if (!decryptedUri.includes("://") || !decryptedUri.endsWith("/")) {
|
||||
reveal = buildTransactionFunction(
|
||||
async (batchId: BigNumberish, password: string) => {
|
||||
if (!password) {
|
||||
throw new Error("Password is required");
|
||||
}
|
||||
const chainId = await this.contractWrapper.getChainID();
|
||||
const key = ethers.utils.solidityKeccak256(
|
||||
["string", "uint256", "uint256", "address"],
|
||||
[password, chainId, batchId, this.contractWrapper.readContract.address],
|
||||
);
|
||||
// performing the reveal locally to make sure it'd succeed before sending the transaction
|
||||
try {
|
||||
const decryptedUri = await this.contractWrapper
|
||||
.callStatic()
|
||||
.reveal(batchId, key);
|
||||
// basic sanity check for making sure decryptedUri is valid
|
||||
// this is optional because invalid decryption key would result in non-utf8 bytes and
|
||||
// ethers would throw when trying to decode it
|
||||
if (!decryptedUri.includes("://") || !decryptedUri.endsWith("/")) {
|
||||
throw new Error("invalid password");
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error("invalid password");
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error("invalid password");
|
||||
}
|
||||
|
||||
return {
|
||||
receipt: await this.contractWrapper.sendTransaction("reveal", [
|
||||
batchId,
|
||||
key,
|
||||
]),
|
||||
};
|
||||
}
|
||||
return Transaction.fromContractWrapper({
|
||||
contractWrapper: this.contractWrapper,
|
||||
method: "reveal",
|
||||
args: [batchId, key],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
public async generate(
|
||||
payloadToSign: TieredDropPayloadInput,
|
||||
|
||||
@@ -25,7 +25,11 @@ import {
|
||||
} from "../../constants/erc721-features";
|
||||
import { Address, AddressOrEns } from "../../schema";
|
||||
import { ClaimOptions, UploadProgressEvent } from "../../types";
|
||||
import { BaseDropERC721, BaseERC721 } from "../../types/eips";
|
||||
import {
|
||||
BaseClaimConditionERC721,
|
||||
BaseDropERC721,
|
||||
BaseERC721,
|
||||
} from "../../types/eips";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { UpdateableNetwork } from "../interfaces/contract";
|
||||
import { NetworkInput, TransactionResultWithId } from "../types";
|
||||
@@ -40,6 +44,7 @@ import { Transaction } from "./transactions";
|
||||
import type {
|
||||
DropERC721,
|
||||
IBurnableERC721,
|
||||
IClaimableERC721,
|
||||
IERC721Supply,
|
||||
IMintableERC721,
|
||||
ISignatureMintERC721,
|
||||
@@ -50,6 +55,8 @@ import type {
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { BigNumber, BigNumberish, constants } from "ethers";
|
||||
import { Erc721Claimable } from "./erc-721-claimable";
|
||||
import { Erc721ClaimableWithConditions } from "./erc-721-claimable-with-conditions";
|
||||
|
||||
/**
|
||||
* Standard ERC721 NFT functions
|
||||
@@ -77,6 +84,8 @@ export class Erc721<
|
||||
private lazyMintable: Erc721LazyMintable | undefined;
|
||||
private tieredDropable: Erc721TieredDrop | undefined;
|
||||
private signatureMintable: Erc721WithQuantitySignatureMintable | undefined;
|
||||
private claimWithConditions: Erc721ClaimableWithConditions | undefined;
|
||||
private claimCustom: Erc721Claimable | undefined;
|
||||
protected contractWrapper: ContractWrapper<T>;
|
||||
protected storage: ThirdwebStorage;
|
||||
|
||||
@@ -98,6 +107,8 @@ export class Erc721<
|
||||
this.lazyMintable = this.detectErc721LazyMintable();
|
||||
this.tieredDropable = this.detectErc721TieredDrop();
|
||||
this.signatureMintable = this.detectErc721SignatureMintable();
|
||||
this.claimWithConditions = this.detectErc721ClaimableWithConditions();
|
||||
this.claimCustom = this.detectErc721Claimable();
|
||||
this._chainId = chainId;
|
||||
}
|
||||
|
||||
@@ -654,8 +665,8 @@ export class Erc721<
|
||||
quantity: BigNumberish,
|
||||
options?: ClaimOptions,
|
||||
): Promise<Transaction<TransactionResultWithId<NFT>[]>> => {
|
||||
const claimWithConditions = this.lazyMintable?.claimWithConditions;
|
||||
const claim = this.lazyMintable?.claim;
|
||||
const claimWithConditions = this.claimWithConditions;
|
||||
const claim = this.claimCustom;
|
||||
if (claimWithConditions) {
|
||||
return claimWithConditions.to.prepare(
|
||||
destinationAddress,
|
||||
@@ -685,8 +696,8 @@ export class Erc721<
|
||||
quantity: BigNumberish,
|
||||
options?: ClaimOptions,
|
||||
): Promise<Transaction> {
|
||||
const claimWithConditions = this.lazyMintable?.claimWithConditions;
|
||||
const claim = this.lazyMintable?.claim;
|
||||
const claimWithConditions = this.claimWithConditions;
|
||||
const claim = this.claimCustom;
|
||||
if (claimWithConditions) {
|
||||
return claimWithConditions.conditions.getClaimTransaction(
|
||||
destinationAddress,
|
||||
@@ -770,7 +781,7 @@ export class Erc721<
|
||||
*/
|
||||
get claimConditions() {
|
||||
return assertEnabled(
|
||||
this.lazyMintable?.claimWithConditions,
|
||||
this.claimWithConditions,
|
||||
FEATURE_NFT_CLAIM_CONDITIONS_V2,
|
||||
).conditions;
|
||||
}
|
||||
@@ -960,4 +971,46 @@ export class Erc721<
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc721ClaimableWithConditions():
|
||||
| Erc721ClaimableWithConditions
|
||||
| undefined {
|
||||
if (
|
||||
detectContractFeature<BaseClaimConditionERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimConditionsV1",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimConditionsV2",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimPhasesV1",
|
||||
) ||
|
||||
detectContractFeature<BaseClaimConditionERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimPhasesV2",
|
||||
)
|
||||
) {
|
||||
return new Erc721ClaimableWithConditions(
|
||||
this,
|
||||
this.contractWrapper,
|
||||
this.storage,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc721Claimable(): Erc721Claimable | undefined {
|
||||
if (
|
||||
detectContractFeature<IClaimableERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721ClaimCustom",
|
||||
)
|
||||
) {
|
||||
return new Erc721Claimable(this, this.contractWrapper);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ export class ContractFactory extends ContractWrapper<TWFactory> {
|
||||
metadata,
|
||||
contractURI,
|
||||
signer,
|
||||
this.storage,
|
||||
);
|
||||
|
||||
const encodedFunc = Contract.getInterface(ABI).encodeFunctionData(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { INFRA_CONTRACTS_MAP } from "../common/infra-data";
|
||||
import type { CONTRACTS_MAP, PREBUILT_CONTRACTS_MAP } from "../contracts";
|
||||
import type { SmartContract } from "../contracts/smart-contract";
|
||||
import type { Chain, ChainSlug, ChainId } from "@thirdweb-dev/chains";
|
||||
@@ -34,6 +35,9 @@ export type ContractsMap = typeof CONTRACTS_MAP;
|
||||
export type PrebuiltContractType = keyof PrebuiltContractsMap;
|
||||
export type ContractType = keyof ContractsMap;
|
||||
|
||||
export type InfraContractsMap = typeof INFRA_CONTRACTS_MAP;
|
||||
export type InfraContractType = keyof InfraContractsMap;
|
||||
|
||||
export type ValidContractInstance =
|
||||
| Awaited<ReturnType<ContractsMap[keyof PrebuiltContractsMap]["initialize"]>>
|
||||
| SmartContract;
|
||||
|
||||
@@ -42,9 +42,14 @@ export const AddressOrEnsSchema = z.union([AddressSchema, EnsSchema], {
|
||||
invalid_type_error: "Provided value was not a valid address or ENS name",
|
||||
});
|
||||
|
||||
export const RawDateSchema = z.date().transform((i) => {
|
||||
return BigNumber.from(Math.floor(i.getTime() / 1000));
|
||||
});
|
||||
export const RawDateSchema = z.union([
|
||||
z.date().transform((i) => {
|
||||
return BigNumber.from(Math.floor(i.getTime() / 1000));
|
||||
}),
|
||||
z.number().transform((i) => {
|
||||
return BigNumber.from(i);
|
||||
}),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Default to now
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { InfraContractType } from "../../core";
|
||||
|
||||
export type PrecomputedDeploymentData = {
|
||||
predictedAddress: string;
|
||||
bytecode: string;
|
||||
encodedArgs: any;
|
||||
};
|
||||
|
||||
export type DeploymentInfo = {
|
||||
bytecode: string;
|
||||
encodedArgs: any;
|
||||
predictedAddress: string;
|
||||
infraContractsToDeploy: InfraContractType[];
|
||||
};
|
||||
|
||||
export type KeylessTransaction = {
|
||||
signer: string;
|
||||
transaction: string;
|
||||
};
|
||||
|
||||
export type KeylessDeploymentInfo = {
|
||||
signer: string;
|
||||
transaction: string;
|
||||
deployment: string;
|
||||
};
|
||||
|
||||
export type DeployedContractType =
|
||||
| "proxy"
|
||||
| "infra"
|
||||
| "implementation"
|
||||
| "create2Factory"
|
||||
| "custom";
|
||||
|
||||
export type DeploymentTransaction = {
|
||||
contractType: DeployedContractType;
|
||||
addresses: string[];
|
||||
};
|
||||
@@ -2,9 +2,14 @@ import {
|
||||
FullPublishMetadata,
|
||||
PreDeployMetadataFetched,
|
||||
} from "../../schema/contracts/custom";
|
||||
import { DeployedContractType } from "../any-evm/deploy-data";
|
||||
|
||||
export type DeployOptions = {
|
||||
forceDirectDeploy?: boolean;
|
||||
notifier?: (
|
||||
status: "deploying" | "deployed",
|
||||
contractType: DeployedContractType,
|
||||
) => void;
|
||||
};
|
||||
|
||||
export type DeployMetadata = {
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import { NATIVE_TOKEN_ADDRESS, ThirdwebSDK } from "../../src/evm";
|
||||
import { SmartContract } from "../../src/evm/contracts/smart-contract";
|
||||
import { signers } from "./before-setup";
|
||||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
|
||||
import { expect, assert } from "chai";
|
||||
|
||||
describe("Any EVM Keyless Deploy", async () => {
|
||||
let contract: SmartContract;
|
||||
let sdk: ThirdwebSDK;
|
||||
let adminWallet: SignerWithAddress;
|
||||
let claimerWallet: SignerWithAddress;
|
||||
let notificationCounter: number;
|
||||
let transactionCount: number;
|
||||
|
||||
async function deployTieredDrop() {
|
||||
const mockPublisher = process.env.contractPublisherAddress;
|
||||
process.env.contractPublisherAddress =
|
||||
"0x664244560eBa21Bf82d7150C791bE1AbcD5B4cd7";
|
||||
const walletAddress = await sdk.wallet.getAddress();
|
||||
|
||||
// This needs to match the published contract for the currently used ABI
|
||||
const publishUri =
|
||||
"ipfs://QmXu9ezFNgXBX1juLZ7kwdf5KpTD1x9GPHnk14QB2NpUvK/0";
|
||||
console.log(
|
||||
"transactions: ",
|
||||
await sdk.deployer.getTransactionsForDeploy(publishUri),
|
||||
);
|
||||
transactionCount = (await sdk.deployer.getTransactionsForDeploy(publishUri))
|
||||
.length;
|
||||
|
||||
const address = await sdk.deployer.deployContractFromUri(
|
||||
publishUri,
|
||||
[
|
||||
walletAddress, // defaultAdmin
|
||||
"Tiered Drop #1", // name
|
||||
"TD", // symbol
|
||||
"ipfs://QmUj5kNz7Xe5AEhV2YvHiCKfMSL5YZpD4E18QLLYEsGBcd/0", // contractUri
|
||||
[], // trustedForwarders
|
||||
walletAddress, // saleRecipient
|
||||
walletAddress, // royaltyRecipient
|
||||
0, // royaltyBps
|
||||
],
|
||||
{
|
||||
forceDirectDeploy: false,
|
||||
notifier(status, contractType) {
|
||||
notificationCounter += 1;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
process.env.contractPublisherAddress = mockPublisher;
|
||||
const tieredDrop = await sdk.getContract(address);
|
||||
|
||||
return tieredDrop;
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
[adminWallet, claimerWallet] = signers;
|
||||
sdk = new ThirdwebSDK(adminWallet);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
sdk.updateSignerOrProvider(adminWallet);
|
||||
});
|
||||
|
||||
it("correct count of logs and transactions", async () => {
|
||||
notificationCounter = 0;
|
||||
transactionCount = 0;
|
||||
contract = await deployTieredDrop();
|
||||
expect(notificationCounter).to.equal(8);
|
||||
expect(transactionCount).to.equal(4);
|
||||
|
||||
notificationCounter = 0;
|
||||
transactionCount = 0;
|
||||
contract = await deployTieredDrop();
|
||||
expect(notificationCounter).to.equal(2);
|
||||
expect(transactionCount).to.equal(1);
|
||||
});
|
||||
});
|
||||
@@ -247,7 +247,7 @@ describe("Custom Contracts", async () => {
|
||||
try {
|
||||
c.roles.get("admin");
|
||||
} catch (e) {
|
||||
expectError(e, "contract does not implement the 'Permissions' Extension");
|
||||
expectError(e, "contract does not implement the 'permissions' Extension");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# @thirdweb-dev/unity-js-bridge
|
||||
|
||||
## 0.2.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ac8fa0b3`](https://github.com/thirdweb-dev/js/commit/ac8fa0b34545a2bc0b489a0551d476a9f560e851), [`b616dca7`](https://github.com/thirdweb-dev/js/commit/b616dca7eb861cd1d2adba3f3d1fe9c3b50f259e), [`2545a440`](https://github.com/thirdweb-dev/js/commit/2545a440dc272690cacbc23023f7b0a68f390c6e), [`b75bcef5`](https://github.com/thirdweb-dev/js/commit/b75bcef55bfdedc260b5b62bb4aff10a7d5c47b6), [`229a4741`](https://github.com/thirdweb-dev/js/commit/229a47413e422952ad946b8c09af32cc1fcdc7f0), [`c9027fce`](https://github.com/thirdweb-dev/js/commit/c9027fced0fffbf757bf0080bc4a49f5464df647)]:
|
||||
- @thirdweb-dev/sdk@3.10.10
|
||||
- @thirdweb-dev/wallets@0.2.15
|
||||
- @thirdweb-dev/auth@3.0.14
|
||||
|
||||
## 0.2.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
|
||||
- @thirdweb-dev/sdk@3.10.9
|
||||
|
||||
## 0.2.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310)]:
|
||||
- @thirdweb-dev/sdk@3.10.8
|
||||
- @thirdweb-dev/wallets@0.2.14
|
||||
- @thirdweb-dev/auth@3.0.13
|
||||
|
||||
## 0.2.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/unity-js-bridge",
|
||||
"version": "0.2.22",
|
||||
"version": "0.2.25",
|
||||
"main": "dist/thirdweb-unity-bridge.js",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { CoinbasePayIntegration, FundWalletOptions } from "@thirdweb-dev/pay";
|
||||
import { ThirdwebSDK, ChainIdOrName } from "@thirdweb-dev/sdk";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { DAppMetaData } from "@thirdweb-dev/wallets";
|
||||
import type { AbstractBrowserWallet } from "@thirdweb-dev/wallets/evm/wallets/base";
|
||||
import type { AbstractClientWallet } from "@thirdweb-dev/wallets/evm/wallets/base";
|
||||
import { CoinbaseWallet } from "@thirdweb-dev/wallets/evm/wallets/coinbase-wallet";
|
||||
import { DeviceBrowserWallet } from "@thirdweb-dev/wallets/evm/wallets/device-wallet";
|
||||
import { EthersWallet } from "@thirdweb-dev/wallets/evm/wallets/ethers";
|
||||
@@ -74,8 +74,8 @@ interface TWBridge {
|
||||
const w = window;
|
||||
|
||||
class ThirdwebBridge implements TWBridge {
|
||||
private walletMap: Map<string, AbstractBrowserWallet> = new Map();
|
||||
private activeWallet: AbstractBrowserWallet | undefined;
|
||||
private walletMap: Map<string, AbstractClientWallet> = new Map();
|
||||
private activeWallet: AbstractClientWallet | undefined;
|
||||
private initializedChain: ChainIdOrName | undefined;
|
||||
private activeSDK: ThirdwebSDK | undefined;
|
||||
private auth: ThirdwebAuth | undefined;
|
||||
@@ -116,7 +116,7 @@ class ThirdwebBridge implements TWBridge {
|
||||
sdkOptions.thirdwebApiKey = sdkOptions.thirdwebApiKey || API_KEY;
|
||||
this.activeSDK = new ThirdwebSDK(chain, sdkOptions, storage);
|
||||
for (let possibleWallet of WALLETS) {
|
||||
let walletInstance: AbstractBrowserWallet;
|
||||
let walletInstance: AbstractClientWallet;
|
||||
const dappMetadata: DAppMetaData = {
|
||||
name: sdkOptions.wallet?.appName || "thirdweb powered game",
|
||||
url: sdkOptions.wallet?.appUrl || "https://thirdweb.com",
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @thirdweb-dev/wallets
|
||||
|
||||
## 0.2.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#868](https://github.com/thirdweb-dev/js/pull/868) [`b616dca7`](https://github.com/thirdweb-dev/js/commit/b616dca7eb861cd1d2adba3f3d1fe9c3b50f259e) Thanks [@iketw](https://github.com/iketw)! - - Updates base wallet classes names
|
||||
|
||||
- Makes InjectedWallet params optional
|
||||
- Removes connector storage constructor param from Injected and MetaMask wallets
|
||||
|
||||
- [#872](https://github.com/thirdweb-dev/js/pull/872) [`2545a440`](https://github.com/thirdweb-dev/js/commit/2545a440dc272690cacbc23023f7b0a68f390c6e) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Rename Wallet Connect to WalletConnect
|
||||
|
||||
- [#859](https://github.com/thirdweb-dev/js/pull/859) [`229a4741`](https://github.com/thirdweb-dev/js/commit/229a47413e422952ad946b8c09af32cc1fcdc7f0) Thanks [@MananTank](https://github.com/MananTank)! - Fix Error when connecting to Safe in Vite
|
||||
|
||||
## 0.2.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#870](https://github.com/thirdweb-dev/js/pull/870) [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d) Thanks [@jnsdls](https://github.com/jnsdls)! - fix crash during SSR when "window" is undefined
|
||||
|
||||
- Updated dependencies [[`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
|
||||
- @thirdweb-dev/chains@0.1.11
|
||||
|
||||
## 0.2.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/wallets",
|
||||
"version": "0.2.13",
|
||||
"version": "0.2.15",
|
||||
"main": "dist/thirdweb-dev-wallets.cjs.js",
|
||||
"module": "dist/thirdweb-dev-wallets.esm.js",
|
||||
"types": "dist/thirdweb-dev-wallets.cjs.d.ts",
|
||||
|
||||
@@ -79,8 +79,8 @@ export class InjectedConnector extends Connector<
|
||||
shimDisconnect: true,
|
||||
shimChainChangedDisconnect: true,
|
||||
getProvider: () => {
|
||||
if (assertWindowEthereum(window)) {
|
||||
return window.ethereum;
|
||||
if (assertWindowEthereum(globalThis.window)) {
|
||||
return globalThis.window.ethereum;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,7 +3,13 @@ import { AbstractWallet } from "../../wallets/abstract";
|
||||
import type { SafeConnectionArgs } from "./types";
|
||||
import { ethers } from "ethers";
|
||||
import type { Signer } from "ethers";
|
||||
import { AbstractBrowserWallet } from "../../wallets/base";
|
||||
import { AbstractClientWallet } from "../../wallets/base";
|
||||
import {
|
||||
SafeService,
|
||||
SafeEthersSigner,
|
||||
} from "@safe-global/safe-ethers-adapters";
|
||||
import safeCoreSdk from "@safe-global/safe-core-sdk";
|
||||
import safeEthersLib from "@safe-global/safe-ethers-lib";
|
||||
|
||||
// excerpt from https://docs.gnosis-safe.io/backend/available-services
|
||||
const CHAIN_ID_TO_GNOSIS_SERVER_URL = {
|
||||
@@ -37,7 +43,7 @@ export class SafeConnector extends TWConnector<SafeConnectionArgs> {
|
||||
public previousConnector?: AbstractWallet;
|
||||
// private options: SafeOptions;
|
||||
private safeSigner?: Signer;
|
||||
personalWallet?: AbstractBrowserWallet;
|
||||
personalWallet?: AbstractClientWallet;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -88,23 +94,17 @@ export class SafeConnector extends TWConnector<SafeConnectionArgs> {
|
||||
throw new Error("Chain not supported");
|
||||
}
|
||||
|
||||
const [safeEthersAdapters, safeCoreSdk, safeEthersLib] = await Promise.all([
|
||||
import("@safe-global/safe-ethers-adapters"),
|
||||
import("@safe-global/safe-core-sdk"),
|
||||
import("@safe-global/safe-ethers-lib"),
|
||||
]);
|
||||
|
||||
const ethAdapter = new safeEthersLib.default({
|
||||
const ethAdapter = new safeEthersLib({
|
||||
ethers,
|
||||
signerOrProvider: signer,
|
||||
});
|
||||
|
||||
const safe = await safeCoreSdk.default.create({
|
||||
const safe = await safeCoreSdk.create({
|
||||
ethAdapter: ethAdapter as any,
|
||||
safeAddress,
|
||||
});
|
||||
const service = new safeEthersAdapters.SafeService(serverUrl);
|
||||
const safeSigner = new safeEthersAdapters.SafeEthersSigner(
|
||||
const service = new SafeService(serverUrl);
|
||||
const safeSigner = new SafeEthersSigner(
|
||||
safe as any,
|
||||
service,
|
||||
signer.provider,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { AbstractBrowserWallet } from "../../wallets/base";
|
||||
import type { AbstractClientWallet } from "../../wallets/base";
|
||||
import type { Chain } from "@thirdweb-dev/chains";
|
||||
|
||||
export interface SafeConnectionArgs {
|
||||
safeAddress: string;
|
||||
personalWallet: AbstractBrowserWallet;
|
||||
personalWallet: AbstractClientWallet;
|
||||
chain: Pick<Chain, "chainId" | "rpc">;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ export {
|
||||
UserRejectedRequestError,
|
||||
} from "../lib/wagmi-core";
|
||||
export type { EVMWallet } from "./interfaces";
|
||||
export type { ConnectParams, TWConnector } from "./interfaces/tw-connector";
|
||||
export { WagmiAdapter } from "./interfaces/tw-connector";
|
||||
export type { ConnectParams } from "./interfaces/tw-connector";
|
||||
export { TWConnector, WagmiAdapter } from "./interfaces/tw-connector";
|
||||
export type {
|
||||
AbstractWallet,
|
||||
WalletData,
|
||||
@@ -21,7 +21,7 @@ export type {
|
||||
export * from "./wallets/paper-wallet";
|
||||
// just the types
|
||||
export type { WalletOptions } from "./wallets/base";
|
||||
export { AbstractBrowserWallet } from "./wallets/base";
|
||||
export { AbstractClientWallet } from "./wallets/base";
|
||||
export * from "./wallets/coinbase-wallet";
|
||||
export * from "./wallets/device-wallet";
|
||||
export * from "./wallets/injected";
|
||||
|
||||
@@ -17,7 +17,7 @@ export type WalletMeta = {
|
||||
iconURL: string;
|
||||
};
|
||||
|
||||
export abstract class AbstractBrowserWallet<
|
||||
export abstract class AbstractClientWallet<
|
||||
TAdditionalOpts extends Record<string, any> = {},
|
||||
TConnectParams extends Record<string, any> = {},
|
||||
> extends AbstractWallet {
|
||||
@@ -28,7 +28,7 @@ export abstract class AbstractBrowserWallet<
|
||||
protected options?: WalletOptions<TAdditionalOpts>;
|
||||
static meta: WalletMeta;
|
||||
getMeta() {
|
||||
return (this.constructor as typeof AbstractBrowserWallet).meta;
|
||||
return (this.constructor as typeof AbstractClientWallet).meta;
|
||||
}
|
||||
|
||||
constructor(walletId: string, options?: WalletOptions<TAdditionalOpts>) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { CoinbaseWalletConnector } from "../connectors/coinbase-wallet";
|
||||
import { TWConnector, WagmiAdapter } from "../interfaces/tw-connector";
|
||||
import { AbstractBrowserWallet, WalletOptions } from "./base";
|
||||
import { AbstractClientWallet, WalletOptions } from "./base";
|
||||
import { Buffer } from "buffer";
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
@@ -10,7 +10,7 @@ if (typeof window !== "undefined") {
|
||||
|
||||
export type CoinbaseWalletOptions = WalletOptions<{ headlessMode?: boolean }>;
|
||||
|
||||
export class CoinbaseWallet extends AbstractBrowserWallet {
|
||||
export class CoinbaseWallet extends AbstractClientWallet {
|
||||
connector?: TWConnector;
|
||||
coinbaseConnector?: CoinbaseWalletConnector;
|
||||
static meta = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { AsyncStorage, createAsyncLocalStorage } from "../../core";
|
||||
import { TWConnector } from "../interfaces/tw-connector";
|
||||
import { AbstractWallet } from "./abstract";
|
||||
import { AbstractBrowserWallet, WalletOptions } from "./base";
|
||||
import { AbstractClientWallet, WalletOptions } from "./base";
|
||||
import { Chain, defaultChains, Ethereum } from "@thirdweb-dev/chains";
|
||||
import { ethers } from "ethers";
|
||||
|
||||
@@ -19,7 +19,7 @@ export type DeviceWalletConnectionArgs = {
|
||||
const STORAGE_KEY_DATA = "data";
|
||||
const STORAGE_KEY_ADDR = "address";
|
||||
|
||||
export class DeviceBrowserWallet extends AbstractBrowserWallet<
|
||||
export class DeviceBrowserWallet extends AbstractClientWallet<
|
||||
DeviceWalletOptions,
|
||||
DeviceWalletConnectionArgs
|
||||
> {
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import { AsyncStorage, createAsyncLocalStorage } from "../../core/AsyncStorage";
|
||||
import { TWConnector, WagmiAdapter } from "../interfaces/tw-connector";
|
||||
import { AbstractBrowserWallet, WalletOptions } from "./base";
|
||||
import { AbstractClientWallet, WalletOptions } from "./base";
|
||||
|
||||
export class InjectedWallet extends AbstractBrowserWallet {
|
||||
export class InjectedWallet extends AbstractClientWallet {
|
||||
connector?: TWConnector;
|
||||
connectorStorage: AsyncStorage;
|
||||
|
||||
static id = "injected" as const;
|
||||
public get walletName() {
|
||||
return "Injected Wallet";
|
||||
}
|
||||
|
||||
constructor(options: WalletOptions<{ connectorStorage?: AsyncStorage }>) {
|
||||
constructor(options?: WalletOptions) {
|
||||
super(InjectedWallet.id, options);
|
||||
this.connectorStorage =
|
||||
options.connectorStorage || createAsyncLocalStorage("connector");
|
||||
}
|
||||
|
||||
protected async getConnector(): Promise<TWConnector> {
|
||||
@@ -24,7 +20,7 @@ export class InjectedWallet extends AbstractBrowserWallet {
|
||||
this.connector = new WagmiAdapter(
|
||||
new InjectedConnector({
|
||||
chains: this.chains,
|
||||
connectorStorage: this.connectorStorage,
|
||||
connectorStorage: this.walletStorage,
|
||||
options: {
|
||||
shimDisconnect: true,
|
||||
},
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import { AsyncStorage, createAsyncLocalStorage } from "../../core/AsyncStorage";
|
||||
import type { WalletConnectV1Connector as WalletConnectV1ConnectorType } from "../connectors/wallet-connect-v1";
|
||||
import { TWConnector, WagmiAdapter } from "../interfaces/tw-connector";
|
||||
import { assertWindowEthereum } from "../utils/assertWindowEthereum";
|
||||
import { AbstractBrowserWallet, WalletOptions } from "./base";
|
||||
import { AbstractClientWallet, WalletOptions } from "./base";
|
||||
|
||||
type MetamaskAdditionalOptions = {
|
||||
/**
|
||||
* Storage interface to store whether metamask is connected or disconnected.
|
||||
*/
|
||||
connectorStorage?: AsyncStorage;
|
||||
/**
|
||||
* Whether to display the Wallet Connect QR code Modal for connecting to MetaMask on mobile if MetaMask is not injected.
|
||||
*/
|
||||
@@ -23,9 +18,8 @@ type ConnectWithQrCodeArgs = {
|
||||
onConnected: (accountAddress: string) => void;
|
||||
};
|
||||
|
||||
export class MetaMaskWallet extends AbstractBrowserWallet<MetamaskAdditionalOptions> {
|
||||
export class MetaMaskWallet extends AbstractClientWallet<MetamaskAdditionalOptions> {
|
||||
connector?: TWConnector;
|
||||
connectorStorage: AsyncStorage;
|
||||
walletConnectConnector?: WalletConnectV1ConnectorType;
|
||||
isInjected: boolean;
|
||||
|
||||
@@ -43,8 +37,6 @@ export class MetaMaskWallet extends AbstractBrowserWallet<MetamaskAdditionalOpti
|
||||
|
||||
constructor(options: MetamaskWalletOptions) {
|
||||
super(MetaMaskWallet.id, options);
|
||||
this.connectorStorage =
|
||||
options.connectorStorage || createAsyncLocalStorage("connector");
|
||||
|
||||
if (assertWindowEthereum(globalThis.window)) {
|
||||
this.isInjected = !!globalThis.window.ethereum?.isMetaMask;
|
||||
@@ -63,7 +55,7 @@ export class MetaMaskWallet extends AbstractBrowserWallet<MetamaskAdditionalOpti
|
||||
const { MetaMaskConnector } = await import("../connectors/metamask");
|
||||
const metamaskConnector = new MetaMaskConnector({
|
||||
chains: this.chains,
|
||||
connectorStorage: this.connectorStorage,
|
||||
connectorStorage: this.walletStorage,
|
||||
options: {
|
||||
shimDisconnect: true,
|
||||
},
|
||||
@@ -77,7 +69,7 @@ export class MetaMaskWallet extends AbstractBrowserWallet<MetamaskAdditionalOpti
|
||||
|
||||
const walletConnectConnector = new WalletConnectV1Connector({
|
||||
chains: this.chains,
|
||||
storage: this.connectorStorage,
|
||||
storage: this.walletStorage,
|
||||
options: {
|
||||
clientMeta: {
|
||||
name: this.dappMetadata.name,
|
||||
|
||||
@@ -3,13 +3,13 @@ import {
|
||||
PaperWalletAdditionalOptions,
|
||||
} from "../connectors/paper/types";
|
||||
import { TWConnector } from "../interfaces/tw-connector";
|
||||
import { AbstractBrowserWallet, WalletOptions } from "./base";
|
||||
import { AbstractClientWallet, WalletOptions } from "./base";
|
||||
import type { Chain } from "@thirdweb-dev/chains";
|
||||
import type { PaperWalletConnector } from "../connectors/paper";
|
||||
|
||||
export type PaperWalletOptions = WalletOptions<PaperWalletAdditionalOptions>;
|
||||
|
||||
export class PaperWallet extends AbstractBrowserWallet<
|
||||
export class PaperWallet extends AbstractClientWallet<
|
||||
PaperWalletAdditionalOptions,
|
||||
PaperWalletConnectionArgs
|
||||
> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ConnectParams, TWConnector } from "../interfaces/tw-connector";
|
||||
import { AbstractBrowserWallet, WalletOptions } from "./base";
|
||||
import { AbstractClientWallet, WalletOptions } from "./base";
|
||||
import type { Chain } from "@thirdweb-dev/chains";
|
||||
import { SafeConnectionArgs } from "../connectors/safe/types";
|
||||
import type { SafeConnectionArgs } from "../connectors/safe/types";
|
||||
import type { SafeConnector as SafeConnectorType } from "../connectors/safe";
|
||||
|
||||
export { SafeSupportedChainsSet } from "../connectors/safe";
|
||||
@@ -10,7 +10,7 @@ export { SafeSupportedChainsSet } from "../connectors/safe";
|
||||
export type { SafeConnectionArgs } from "../connectors/safe/types";
|
||||
|
||||
export type SafeWalletOptions = WalletOptions<{}>;
|
||||
export class SafeWallet extends AbstractBrowserWallet<{}, SafeConnectionArgs> {
|
||||
export class SafeWallet extends AbstractClientWallet<{}, SafeConnectionArgs> {
|
||||
connector?: SafeConnectorType;
|
||||
|
||||
static meta = {
|
||||
|
||||
@@ -2,13 +2,13 @@ import type { ConnectorData } from "../../lib/wagmi-core";
|
||||
import type { WalletConnectV1Connector } from "../connectors/wallet-connect-v1";
|
||||
import type WalletConnectProvider from "../connectors/wallet-connect-v1/walletconnect-legacy-provider";
|
||||
import { TWConnector, WagmiAdapter } from "../interfaces/tw-connector";
|
||||
import { AbstractBrowserWallet, WalletOptions } from "./base";
|
||||
import { AbstractClientWallet, WalletOptions } from "./base";
|
||||
|
||||
export type WalletConnectV1Options = {
|
||||
qrcode?: boolean;
|
||||
} & Omit<ConstructorParameters<typeof WalletConnectProvider>[0], "clientMeta">;
|
||||
|
||||
export class WalletConnectV1 extends AbstractBrowserWallet<WalletConnectV1Options> {
|
||||
export class WalletConnectV1 extends AbstractClientWallet<WalletConnectV1Options> {
|
||||
#walletConnectConnector?: WalletConnectV1Connector;
|
||||
#provider?: WalletConnectProvider;
|
||||
|
||||
@@ -17,7 +17,7 @@ export class WalletConnectV1 extends AbstractBrowserWallet<WalletConnectV1Option
|
||||
static id = "walletConnectV1";
|
||||
|
||||
static meta = {
|
||||
name: "Wallet Connect",
|
||||
name: "WalletConnect",
|
||||
iconURL:
|
||||
"ipfs://QmX58KPRaTC9JYZ7KriuBzeoEaV2P9eZcA3qbFnTHZazKw/wallet-connect.svg",
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ConnectorData } from "../../lib/wagmi-core";
|
||||
import type { WalletConnectConnector } from "../connectors/wallet-connect";
|
||||
import { TWConnector, WagmiAdapter } from "../interfaces/tw-connector";
|
||||
import { AbstractBrowserWallet, WalletOptions } from "./base";
|
||||
import { AbstractClientWallet, WalletOptions } from "./base";
|
||||
import type WalletConnectProvider from "@walletconnect/ethereum-provider";
|
||||
import { TW_WC_PROJECT_ID } from "../constants/wc";
|
||||
|
||||
@@ -10,7 +10,7 @@ export type WalletConnectOptions = {
|
||||
qrcode?: boolean;
|
||||
};
|
||||
|
||||
export class WalletConnect extends AbstractBrowserWallet<WalletConnectOptions> {
|
||||
export class WalletConnect extends AbstractClientWallet<WalletConnectOptions> {
|
||||
#walletConnectConnector?: WalletConnectConnector;
|
||||
#provider?: WalletConnectProvider;
|
||||
|
||||
@@ -19,7 +19,7 @@ export class WalletConnect extends AbstractBrowserWallet<WalletConnectOptions> {
|
||||
static id = "walletConnect";
|
||||
|
||||
static meta = {
|
||||
name: "Wallet Connect",
|
||||
name: "WalletConnect",
|
||||
iconURL:
|
||||
"ipfs://QmX58KPRaTC9JYZ7KriuBzeoEaV2P9eZcA3qbFnTHZazKw/wallet-connect.svg",
|
||||
};
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
diff --git a/node_modules/@walletconnect/legacy-types/dist/cjs/jsonrpc.d.ts b/node_modules/@walletconnect/legacy-types/dist/cjs/jsonrpc.d.ts
|
||||
index 7c2f8f0..0cca28c 100644
|
||||
--- a/node_modules/@walletconnect/legacy-types/dist/cjs/jsonrpc.d.ts
|
||||
+++ b/node_modules/@walletconnect/legacy-types/dist/cjs/jsonrpc.d.ts
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { IClientMeta, IConnector } from "./protocol";
|
||||
+import { IClientMeta, IConnector, IWalletConnectSession } from "./protocol";
|
||||
import { IEvents } from "./events";
|
||||
import { IQRCodeModal, IQRCodeModalOptions } from "./qrcode";
|
||||
export interface IRpcConnection extends IEvents {
|
||||
@@ -68,6 +68,7 @@ export interface IWCRpcConnectionOptions {
|
||||
signingMethods?: string[];
|
||||
qrcodeModalOptions?: IQRCodeModalOptions;
|
||||
clientMeta?: IClientMeta;
|
||||
+ session?: IWalletConnectSession;
|
||||
}
|
||||
export interface IWCEthRpcConnectionOptions extends IWCRpcConnectionOptions {
|
||||
rpc?: IRPCMap;
|
||||
diff --git a/node_modules/@walletconnect/legacy-types/dist/esm/jsonrpc.d.ts b/node_modules/@walletconnect/legacy-types/dist/esm/jsonrpc.d.ts
|
||||
index 7c2f8f0..0cca28c 100644
|
||||
--- a/node_modules/@walletconnect/legacy-types/dist/esm/jsonrpc.d.ts
|
||||
+++ b/node_modules/@walletconnect/legacy-types/dist/esm/jsonrpc.d.ts
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { IClientMeta, IConnector } from "./protocol";
|
||||
+import { IClientMeta, IConnector, IWalletConnectSession } from "./protocol";
|
||||
import { IEvents } from "./events";
|
||||
import { IQRCodeModal, IQRCodeModalOptions } from "./qrcode";
|
||||
export interface IRpcConnection extends IEvents {
|
||||
@@ -68,6 +68,7 @@ export interface IWCRpcConnectionOptions {
|
||||
signingMethods?: string[];
|
||||
qrcodeModalOptions?: IQRCodeModalOptions;
|
||||
clientMeta?: IClientMeta;
|
||||
+ session?: IWalletConnectSession;
|
||||
}
|
||||
export interface IWCEthRpcConnectionOptions extends IWCRpcConnectionOptions {
|
||||
rpc?: IRPCMap;
|
||||
Generated
+153
-2206
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,8 @@
|
||||
"@playwright/test": "1.31.2",
|
||||
"@vitejs/plugin-react": "^2",
|
||||
"serve": "^14.0.1",
|
||||
"vite": "^3"
|
||||
"vite": "^3",
|
||||
"vite-plugin-node-polyfills": "^0.7.0"
|
||||
},
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/test/e2e/vite-3"
|
||||
}
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { defineConfig } from "vite";
|
||||
import { nodePolyfills } from "vite-plugin-node-polyfills";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [
|
||||
react(),
|
||||
nodePolyfills({
|
||||
global: true,
|
||||
}),
|
||||
],
|
||||
define: {
|
||||
"process.env": {},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user