Compare commits
31
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04c607ccde | ||
|
|
926dd7b03f | ||
|
|
e00dd12357 | ||
|
|
cdc08c5528 | ||
|
|
4df0c2ee10 | ||
|
|
48a8f9385e | ||
|
|
a91776e121 | ||
|
|
f5aed34d3c | ||
|
|
0f02706906 | ||
|
|
eb463735e2 | ||
|
|
adec589ead | ||
|
|
e5246f2667 | ||
|
|
b29ec675f9 | ||
|
|
b30566c684 | ||
|
|
182a4e7e8f | ||
|
|
8b82f3c59c | ||
|
|
f59b729f8b | ||
|
|
387dddbd87 | ||
|
|
911e14fcac | ||
|
|
cd6b07b591 | ||
|
|
154c55add5 | ||
|
|
f202f597ca | ||
|
|
91f0245be7 | ||
|
|
ae74b8ef62 | ||
|
|
5a373a7509 | ||
|
|
088547f763 | ||
|
|
586e91dbe6 | ||
|
|
f65578d637 | ||
|
|
447d984653 | ||
|
|
34a3bb8ae3 | ||
|
|
bc003c2fef |
@@ -1,5 +1,33 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 3.2.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@1.1.22
|
||||
|
||||
## 3.2.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`eb463735`](https://github.com/thirdweb-dev/js/commit/eb463735e2f784cd1d212a982835af95cf60766b), [`0f027069`](https://github.com/thirdweb-dev/js/commit/0f027069064bebe647f9235fa86ef7f165ffc7b3)]:
|
||||
- @thirdweb-dev/wallets@1.1.21
|
||||
|
||||
## 3.2.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@1.1.20
|
||||
|
||||
## 3.2.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@1.1.19
|
||||
|
||||
## 3.2.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "3.2.35",
|
||||
"version": "3.2.39",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1558](https://github.com/thirdweb-dev/js/pull/1558) [`926dd7b0`](https://github.com/thirdweb-dev/js/commit/926dd7b03f38ed25ca303dc23d3323d5edd28005) Thanks [@Marfuen](https://github.com/Marfuen)! - Updating chains list
|
||||
|
||||
## 0.1.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1540](https://github.com/thirdweb-dev/js/pull/1540) [`b30566c6`](https://github.com/thirdweb-dev/js/commit/b30566c68436ad94ddc938a380eccc13a8a7147d) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - updated chains
|
||||
|
||||
- [#1422](https://github.com/thirdweb-dev/js/pull/1422) [`0f027069`](https://github.com/thirdweb-dev/js/commit/0f027069064bebe647f9235fa86ef7f165ffc7b3) Thanks [@Marfuen](https://github.com/Marfuen)! - CLI will now use an OAuth like login flow to authenticate the device with the wallet on the dashboard.
|
||||
Any actions performed by the CLI will be linked to your account / wallet on the dashboard, including but not limited to tracking your usage, and billing as needed.
|
||||
|
||||
- [#1551](https://github.com/thirdweb-dev/js/pull/1551) [`f5aed34d`](https://github.com/thirdweb-dev/js/commit/f5aed34d3c71065c3f45df2c1eb84ba9c36162d5) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Update chains
|
||||
|
||||
## 0.1.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1530](https://github.com/thirdweb-dev/js/pull/1530) [`911e14fc`](https://github.com/thirdweb-dev/js/commit/911e14fcac743b07fa1a66440c72d662c08e971c) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Add Chiliz Spicy testnet
|
||||
|
||||
## 0.1.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1518](https://github.com/thirdweb-dev/js/pull/1518) [`34a3bb8a`](https://github.com/thirdweb-dev/js/commit/34a3bb8ae3c1d7a506e5568a9e79ab7e469557a8) Thanks [@nkrishang](https://github.com/nkrishang)! - Update contracts package
|
||||
|
||||
## 0.1.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -15,7 +15,9 @@ export default {
|
||||
"https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com"
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
"wss://mainnet.gateway.tenderly.co"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
|
||||
@@ -7,7 +7,9 @@ export default {
|
||||
"https://optimism-mainnet.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://mainnet.optimism.io",
|
||||
"https://optimism.publicnode.com"
|
||||
"https://optimism.publicnode.com",
|
||||
"https://optimism.gateway.tenderly.co",
|
||||
"wss://optimism.gateway.tenderly.co"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -10,7 +10,9 @@ export default {
|
||||
"https://rpc.sepolia.org",
|
||||
"https://rpc2.sepolia.org",
|
||||
"https://rpc-sepolia.rockx.com",
|
||||
"https://rpc.sepolia.ethpandaops.io"
|
||||
"https://rpc.sepolia.ethpandaops.io",
|
||||
"https://sepolia.gateway.tenderly.co",
|
||||
"wss://sepolia.gateway.tenderly.co"
|
||||
],
|
||||
"faucets": [
|
||||
"http://fauceth.komputing.org?chain=11155111&address=${ADDRESS}"
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "DeBank Testnet",
|
||||
"chain": "DeBank",
|
||||
"rpc": [],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmW9pBps8WHRRWmyXhjLZrjZJUe8F48hUu7z98bu2RVsjN",
|
||||
"width": 400,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
},
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://debank.com",
|
||||
"shortName": "debank-testnet",
|
||||
"chainId": 115,
|
||||
"networkId": 115,
|
||||
"explorers": [],
|
||||
"testnet": true,
|
||||
"slug": "debank-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,25 +0,0 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "DeBank Mainnet",
|
||||
"chain": "DeBank",
|
||||
"rpc": [],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmW9pBps8WHRRWmyXhjLZrjZJUe8F48hUu7z98bu2RVsjN",
|
||||
"width": 400,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
},
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://debank.com",
|
||||
"shortName": "debank-mainnet",
|
||||
"chainId": 116,
|
||||
"networkId": 116,
|
||||
"explorers": [],
|
||||
"testnet": false,
|
||||
"slug": "debank"
|
||||
} as const satisfies Chain;
|
||||
@@ -17,8 +17,14 @@ export default {
|
||||
"symbol": "MC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://gaming.meritcircle.io",
|
||||
"shortName": "BEAM",
|
||||
"infoURL": "https://www.onbeam.com",
|
||||
"shortName": "beam-testnet",
|
||||
"icon": {
|
||||
"url": "ipfs://QmQJ21NWyGGDraicVEzS1Uqq1yXahM9NCuNZgnfYvtspdt",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"chainId": 13337,
|
||||
"networkId": 13337,
|
||||
"explorers": [
|
||||
|
||||
@@ -18,7 +18,9 @@ export default {
|
||||
"https://rpc-mainnet.maticvigil.com",
|
||||
"https://rpc-mainnet.matic.quiknode.pro",
|
||||
"https://matic-mainnet-full-rpc.bwarelabs.com",
|
||||
"https://polygon-bor.publicnode.com"
|
||||
"https://polygon-bor.publicnode.com",
|
||||
"https://polygon.gateway.tenderly.co",
|
||||
"wss://polygon.gateway.tenderly.co"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Redbelly Network Mainnet",
|
||||
"shortName": "rbn",
|
||||
"chain": "RBN",
|
||||
"chainId": 151,
|
||||
"networkId": 151,
|
||||
"rpc": [],
|
||||
"faucets": [],
|
||||
"infoURL": "https://redbelly.network",
|
||||
"nativeCurrency": {
|
||||
"name": "Redbelly Network Coin",
|
||||
"symbol": "RBNT",
|
||||
"decimals": 18
|
||||
},
|
||||
"status": "incubating",
|
||||
"testnet": false,
|
||||
"slug": "redbelly-network"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Redbelly Network Devnet",
|
||||
"shortName": "rbn-devnet",
|
||||
"chain": "RBN",
|
||||
"chainId": 152,
|
||||
"networkId": 152,
|
||||
"rpc": [],
|
||||
"faucets": [],
|
||||
"infoURL": "https://redbelly.network",
|
||||
"nativeCurrency": {
|
||||
"name": "Redbelly Network Coin",
|
||||
"symbol": "RBNT",
|
||||
"decimals": 18
|
||||
},
|
||||
"status": "incubating",
|
||||
"testnet": false,
|
||||
"slug": "redbelly-network-devnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Redbelly Network Testnet",
|
||||
"shortName": "rbn-testnet",
|
||||
"chain": "RBN",
|
||||
"chainId": 153,
|
||||
"networkId": 153,
|
||||
"rpc": [],
|
||||
"faucets": [],
|
||||
"infoURL": "https://redbelly.network",
|
||||
"nativeCurrency": {
|
||||
"name": "Redbelly Network Coin",
|
||||
"symbol": "RBNT",
|
||||
"decimals": 18
|
||||
},
|
||||
"status": "incubating",
|
||||
"testnet": true,
|
||||
"slug": "redbelly-network-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Redbelly Network TGE",
|
||||
"shortName": "rbn-tge",
|
||||
"chain": "RBN",
|
||||
"chainId": 154,
|
||||
"networkId": 154,
|
||||
"rpc": [],
|
||||
"faucets": [],
|
||||
"infoURL": "https://redbelly.network",
|
||||
"nativeCurrency": {
|
||||
"name": "Redbelly Network Coin",
|
||||
"symbol": "RBNT",
|
||||
"decimals": 18
|
||||
},
|
||||
"testnet": false,
|
||||
"slug": "redbelly-network-tge"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Omni Testnet 1",
|
||||
"name": "Omni Testnet",
|
||||
"chain": "Omni",
|
||||
"rpc": [
|
||||
"https://omni-testnet-1.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet-1.omni.network"
|
||||
"https://omni-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet.omni.network"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
@@ -24,10 +24,10 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Omni Explorer",
|
||||
"url": "https://testnet-1.explorer.omni.network",
|
||||
"url": "https://testnet.explorer.omni.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "omni-testnet-1"
|
||||
"slug": "omni-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -11,8 +11,8 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://horizen-gobi-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://gobi-testnet.horizenlabs.io/ethv1",
|
||||
"https://rpc.ankr.com/horizen_testnet_evm"
|
||||
"https://gobi-rpc.horizenlabs.io/ethv1",
|
||||
"https://rpc.ankr.com/horizen_gobi_testnet"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Bitchain Mainnet",
|
||||
"chain": "Bit",
|
||||
"rpc": [
|
||||
"https://bitchain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.bitchain.biz/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Bitcoin",
|
||||
"symbol": "BTC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.bitchain.biz/",
|
||||
"shortName": "bit",
|
||||
"chainId": 198,
|
||||
"networkId": 198,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Bitchain Scan",
|
||||
"url": "https://explorer.bitchain.biz",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "bitchain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "DeBank Testnet",
|
||||
"chain": "DeBank",
|
||||
"rpc": [
|
||||
"https://debank-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"http://rpc.testnet.debank.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmW9pBps8WHRRWmyXhjLZrjZJUe8F48hUu7z98bu2RVsjN",
|
||||
"width": 400,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
},
|
||||
"nativeCurrency": {
|
||||
"name": "DeBank USD",
|
||||
"symbol": "USD",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://debank.com",
|
||||
"shortName": "dbk",
|
||||
"chainId": 2021398,
|
||||
"networkId": 2021398,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "DeBank Chain Explorer",
|
||||
"url": "https://explorer.testnet.debank.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "debank-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "opBNB Mainnet",
|
||||
"chain": "opBNB",
|
||||
"rpc": [
|
||||
"https://opbnb.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://opbnb-mainnet-rpc.bnbchain.org"
|
||||
],
|
||||
"faucets": [
|
||||
"https://free-online-app.com/faucet-for-eth-evm-chains"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "BNB Chain Native Token",
|
||||
"symbol": "BNB",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://opbnb.bnbchain.org/en",
|
||||
"shortName": "obnb",
|
||||
"chainId": 204,
|
||||
"networkId": 204,
|
||||
"slip44": 714,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "opbnbscan",
|
||||
"url": "http://mainnet.opbnbscan.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "opbnb"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Nautilus Mainnet",
|
||||
"chain": "ETH",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNutSgM7n6aJPPDiofe9Dm1epy1RcYTMvugukLUK2vmPM",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://nautilus.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://api.nautilus.nautchain.xyz"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Zebec",
|
||||
"symbol": "ZBC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.nautchain.xyz",
|
||||
"shortName": "NAUTCHAIN",
|
||||
"chainId": 22222,
|
||||
"networkId": 22222,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Nautscan",
|
||||
"url": "https://nautscan.com",
|
||||
"standard": "EIP3091",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNutSgM7n6aJPPDiofe9Dm1epy1RcYTMvugukLUK2vmPM",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "nautilus"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Morphism Testnet",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://morphism-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-testnet.morphism.xyz"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://morphism.xyz",
|
||||
"shortName": "tmorph",
|
||||
"chainId": 2710,
|
||||
"networkId": 2710,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Morphism Testnet Explorer",
|
||||
"url": "https://explorer-testnet.morphism.xyz",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"parent": {
|
||||
"type": "L2",
|
||||
"chain": "eip155-1",
|
||||
"bridges": [
|
||||
{
|
||||
"url": "https://bridge-testnet.morphism.xyz"
|
||||
}
|
||||
]
|
||||
},
|
||||
"testnet": true,
|
||||
"slug": "morphism-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -6,8 +6,8 @@ export default {
|
||||
"https://boba-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet.boba.network",
|
||||
"https://replica.boba.network",
|
||||
"http://boba-ethereum.gateway.tenderly.co",
|
||||
"http://gateway.tenderly.co/public/boba-ethereum",
|
||||
"https://boba-ethereum.gateway.tenderly.co",
|
||||
"https://gateway.tenderly.co/public/boba-ethereum",
|
||||
"wss://boba-ethereum.gateway.tenderly.co/",
|
||||
"wss://gateway.tenderly.co/public/boba-ethereum"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Dubxcoin network",
|
||||
"chain": "DUBX",
|
||||
"rpc": [
|
||||
"https://dubxcoin-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpcmain.arabianchain.org"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Dubxcoin mainnet",
|
||||
"symbol": "DUBX",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://arabianchain.org",
|
||||
"shortName": "dubx",
|
||||
"chainId": 3269,
|
||||
"networkId": 3269,
|
||||
"testnet": false,
|
||||
"slug": "dubxcoin-network"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Dubxcoin testnet",
|
||||
"chain": "TESTDUBX",
|
||||
"rpc": [
|
||||
"https://dubxcoin-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpctestnet.arabianchain.org"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.arabianchain.org/"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Dubxcoin testnet",
|
||||
"symbol": "TDUBX",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://arabianchain.org",
|
||||
"shortName": "testdubx",
|
||||
"chainId": 3270,
|
||||
"networkId": 3270,
|
||||
"testnet": true,
|
||||
"slug": "dubxcoin-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Xpla Testnet",
|
||||
"chain": "XPLATest",
|
||||
"rpc": [
|
||||
"https://xpla-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://dimension-rpc.xpla.dev"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.xpla.io"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "XPLA",
|
||||
"symbol": "XPLA",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://xpla.io",
|
||||
"shortName": "xplatest",
|
||||
"chainId": 3701,
|
||||
"networkId": 3701,
|
||||
"icon": {
|
||||
"url": "ipfs://Qmf4GoxfpeA5VGqu7KP5eyv1WKaCpNDbvMxq1MjQBwFWxq",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "XPLA Explorer",
|
||||
"url": "https://explorer.xpla.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"redFlags": [
|
||||
"reusedChainId"
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "xpla-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "KalyChain Mainnet",
|
||||
"chain": "KLC",
|
||||
"icon": {
|
||||
"url": "ipfs://QmUaXcPewLuQtY5a7xPTzJyVdjkH487VfV7gSR8UXrbxQ3",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://kalychain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.kalychain.io/rpc"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "KalyCoin",
|
||||
"symbol": "KLC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://kalychain.io",
|
||||
"shortName": "kalymainnet",
|
||||
"chainId": 3888,
|
||||
"networkId": 3888,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "KalyScan",
|
||||
"url": "https://kalyscan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "kalychain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "KalyChain Testnet",
|
||||
"chain": "KLC",
|
||||
"icon": {
|
||||
"url": "ipfs://QmUaXcPewLuQtY5a7xPTzJyVdjkH487VfV7gSR8UXrbxQ3",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://kalychain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnetrpc.kalychain.io/rpc"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "KalyCoin",
|
||||
"symbol": "KLC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://kalychain.io",
|
||||
"shortName": "kalytestnet",
|
||||
"chainId": 3889,
|
||||
"networkId": 3889,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "KalyScan",
|
||||
"url": "https://testnet.kalyscan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "kalychain-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,14 +1,12 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Unicorn Ultra Testnet",
|
||||
"name": "U2U Solaris Mainnet",
|
||||
"chain": "u2u",
|
||||
"rpc": [
|
||||
"https://unicorn-ultra-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-testnet.uniultra.xyz"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.uniultra.xyz"
|
||||
"https://u2u-solaris.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-mainnet.uniultra.xyz"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Unicorn Ultra",
|
||||
"symbol": "U2U",
|
||||
@@ -33,10 +31,10 @@ export default {
|
||||
"format": "png"
|
||||
},
|
||||
"name": "U2U Explorer",
|
||||
"url": "https://testnet.uniultra.xyz",
|
||||
"url": "https://u2uscan.xyz",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "unicorn-ultra-testnet"
|
||||
"testnet": false,
|
||||
"slug": "u2u-solaris"
|
||||
} as const satisfies Chain;
|
||||
@@ -7,7 +7,9 @@ export default {
|
||||
"https://optimism-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://goerli.optimism.io",
|
||||
"https://optimism-goerli.publicnode.com"
|
||||
"https://optimism-goerli.publicnode.com",
|
||||
"https://optimism-goerli.gateway.tenderly.co",
|
||||
"wss://optimism-goerli.gateway.tenderly.co"
|
||||
],
|
||||
"faucets": [
|
||||
"https://coinbase.com/faucets/optimism-goerli-faucet"
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Beam",
|
||||
"chain": "BEAM",
|
||||
"rpc": [
|
||||
"https://beam.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/beam/mainnet/rpc"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Merit Circle",
|
||||
"symbol": "MC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.onbeam.com",
|
||||
"shortName": "beam",
|
||||
"icon": {
|
||||
"url": "ipfs://QmQJ21NWyGGDraicVEzS1Uqq1yXahM9NCuNZgnfYvtspdt",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"chainId": 4337,
|
||||
"networkId": 4337,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Beam Explorer",
|
||||
"url": "https://subnets.avax.network/beam",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "beam"
|
||||
} as const satisfies Chain;
|
||||
@@ -3,7 +3,7 @@ export default {
|
||||
"name": "Xpla Testnet",
|
||||
"chain": "XPLA",
|
||||
"rpc": [
|
||||
"https://xpla-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://xpla-testnet-xpla-test.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://cube-evm-rpc.xpla.dev"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
@@ -34,5 +34,5 @@ export default {
|
||||
"redFlags": [
|
||||
"reusedChainId"
|
||||
],
|
||||
"slug": "xpla-testnet"
|
||||
"slug": "xpla-testnet-xpla-test"
|
||||
} as const satisfies Chain;
|
||||
@@ -9,7 +9,9 @@ export default {
|
||||
"wss://goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://rpc.goerli.mudit.blog/",
|
||||
"https://ethereum-goerli.publicnode.com"
|
||||
"https://ethereum-goerli.publicnode.com",
|
||||
"https://goerli.gateway.tenderly.co",
|
||||
"wss://goerli.gateway.tenderly.co"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.paradigm.xyz/",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "opBNB",
|
||||
"name": "Opbnb Testnet",
|
||||
"chain": "opBNB",
|
||||
"shortName": "opBNB",
|
||||
"chainId": 5611,
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
"decimals": 18
|
||||
},
|
||||
"rpc": [
|
||||
"https://opbnb.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://opbnb-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://opbnb-testnet-rpc.bnbchain.org"
|
||||
],
|
||||
"explorers": [
|
||||
@@ -31,5 +31,5 @@ export default {
|
||||
"width": 512,
|
||||
"format": "svg"
|
||||
},
|
||||
"slug": "opbnb"
|
||||
"slug": "opbnb-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -5,8 +5,8 @@ export default {
|
||||
"rpc": [
|
||||
"https://boba-bnb.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://bnb.boba.network",
|
||||
"http://boba-bnb.gateway.tenderly.co/",
|
||||
"http://gateway.tenderly.co/public/boba-bnb",
|
||||
"https://boba-bnb.gateway.tenderly.co/",
|
||||
"https://gateway.tenderly.co/public/boba-bnb",
|
||||
"https://replica.bnb.boba.network",
|
||||
"wss://boba-bnb.gateway.tenderly.co/",
|
||||
"wss://gateway.tenderly.co/public/boba-bnb"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Tanssi EVM ContainerChain",
|
||||
"chain": "EVMCC",
|
||||
"rpc": [
|
||||
"https://tanssi-evm-containerchain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://fraa-dancebox-3001-rpc.a.dancebox.tanssi.network",
|
||||
"wss://fraa-dancebox-3001-rpc.a.dancebox.tanssi.network"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Unit",
|
||||
"symbol": "Unit",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://tanssi.network",
|
||||
"shortName": "TanssiCC",
|
||||
"chainId": 5678,
|
||||
"networkId": 5678,
|
||||
"explorers": [],
|
||||
"testnet": false,
|
||||
"slug": "tanssi-evm-containerchain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "VELO Labs Mainnet",
|
||||
"chain": "NOVA chain",
|
||||
"rpc": [
|
||||
"https://velo-labs.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://nova.velo.org"
|
||||
],
|
||||
"faucets": [
|
||||
"https://nova-faucet.velo.org"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Nova",
|
||||
"symbol": "NOVA",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://velo.org",
|
||||
"shortName": "VELO",
|
||||
"chainId": 56789,
|
||||
"networkId": 56789,
|
||||
"icon": {
|
||||
"url": "ipfs://QmYqvnW2jwPEKUv8BdaV4sbL8Audcwosat6SPn4GqYtKxc",
|
||||
"width": 225,
|
||||
"height": 225,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "novascan",
|
||||
"url": "https://novascan.velo.org",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "velo-labs"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "JuncaGlobal Chain Testnet",
|
||||
"chain": "JuncaGlobal Test Chain",
|
||||
"rpc": [
|
||||
"https://juncaglobal-chain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-testnet.juncachain.com",
|
||||
"wss://ws-testnet.juncachain.com"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet-testnet.juncachain.com"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "JuncaGlobal Chain Testnet Native Token",
|
||||
"symbol": "JGCT",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://junca-cash.world",
|
||||
"shortName": "junca",
|
||||
"chainId": 669,
|
||||
"networkId": 669,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://scan-testnet.juncachain.com",
|
||||
"icon": {
|
||||
"url": "ipfs://QmYtUimyqHkkFxYdbXXRbUqNg2VLPUg6Uu2C2nmFWowiZM",
|
||||
"width": 551,
|
||||
"height": 540,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "juncaglobal-chain-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Horizen EON",
|
||||
"name": "Horizen EON Mainnet",
|
||||
"shortName": "EON",
|
||||
"chain": "EON",
|
||||
"icon": {
|
||||
@@ -11,7 +11,8 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://horizen-eon.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://eon-rpc.horizenlabs.io/ethv1"
|
||||
"https://eon-rpc.horizenlabs.io/ethv1",
|
||||
"https://rpc.ankr.com/horizen_eon"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Amplify Subnet",
|
||||
"chain": "AMPLIFY",
|
||||
"rpc": [
|
||||
"https://amplify-subnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/amplify/testnet/rpc"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "AMP",
|
||||
"symbol": "AMP",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.avax.network",
|
||||
"shortName": "amplify",
|
||||
"chainId": 78430,
|
||||
"networkId": 78430,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "AMPLIFY Explorer",
|
||||
"url": "https://subnets-test.avax.network/amplify",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "amplify-subnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Bulletin Subnet",
|
||||
"chain": "BULLETIN",
|
||||
"rpc": [
|
||||
"https://bulletin-subnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/bulletin/testnet/rpc"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "BLT",
|
||||
"symbol": "BLT",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.avax.network",
|
||||
"shortName": "bulletin",
|
||||
"chainId": 78431,
|
||||
"networkId": 78431,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "BULLETIN Explorer",
|
||||
"url": "https://subnets-test.avax.network/bulletin",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "bulletin-subnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Conduit Subnet",
|
||||
"chain": "CONDUIT",
|
||||
"rpc": [
|
||||
"https://conduit-subnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/conduit/testnet/rpc"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "CON",
|
||||
"symbol": "CON",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.avax.network",
|
||||
"shortName": "conduit",
|
||||
"chainId": 78432,
|
||||
"networkId": 78432,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "CONDUIT Explorer",
|
||||
"url": "https://subnets-test.avax.network/conduit",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "conduit-subnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -16,7 +16,9 @@ export default {
|
||||
"https://matic-mumbai.chainstacklabs.com",
|
||||
"https://rpc-mumbai.maticvigil.com",
|
||||
"https://matic-testnet-archive-rpc.bwarelabs.com",
|
||||
"https://polygon-mumbai-bor.publicnode.com"
|
||||
"https://polygon-mumbai-bor.publicnode.com",
|
||||
"https://polygon-mumbai.gateway.tenderly.co",
|
||||
"wss://polygon-mumbai.gateway.tenderly.co"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.polygon.technology/"
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "BeOne Chain Testnet",
|
||||
"chain": "BOC",
|
||||
"name": "Testnet BeOne Chain",
|
||||
"chain": "tBOC",
|
||||
"rpc": [
|
||||
"https://beone-chain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://pre-boc1.beonechain.com",
|
||||
"https://pre-boc2.beonechain.com",
|
||||
"https://pre-boc3.beonechain.com"
|
||||
"https://testnet-beone-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://pre-boc1.beonechain.com"
|
||||
],
|
||||
"faucets": [
|
||||
"https://testnet.beonescan.com/faucet"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "BeOne Chain Testnet",
|
||||
"symbol": "BOC",
|
||||
"name": "Testnet BeOne Chain",
|
||||
"symbol": "tBOC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://testnet.beonescan.com",
|
||||
@@ -28,7 +26,7 @@ export default {
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "BeOne Chain Testnet",
|
||||
"name": "Testnet BeOne Chain",
|
||||
"url": "https://testnet.beonescan.com",
|
||||
"icon": {
|
||||
"url": "ipfs://QmbVLQnaMDu86bPyKgCvTGhFBeYwjr15hQnrCcsp1EkAGL",
|
||||
@@ -40,5 +38,5 @@ export default {
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "beone-chain-testnet"
|
||||
"slug": "testnet-beone-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -5,7 +5,10 @@ export default {
|
||||
"rpc": [
|
||||
"https://base.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet.base.org/",
|
||||
"https://developer-access-mainnet.base.org/"
|
||||
"https://developer-access-mainnet.base.org/",
|
||||
"https://base.gateway.tenderly.co",
|
||||
"wss://base.gateway.tenderly.co",
|
||||
"https://base.publicnode.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -4,6 +4,9 @@ export default {
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://base-goerli.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://base-goerli.publicnode.com",
|
||||
"wss://base-goerli.gateway.tenderly.co",
|
||||
"https://base-goerli.gateway.tenderly.co",
|
||||
"https://goerli.base.org"
|
||||
],
|
||||
"faucets": [
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Aerie Network",
|
||||
"chain": "Aerie",
|
||||
"rpc": [
|
||||
"https://aerie-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet.aerielab.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Aerie",
|
||||
"symbol": "AER",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://aerielab.io/",
|
||||
"shortName": "Aerie",
|
||||
"chainId": 84886,
|
||||
"networkId": 84886,
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreig54jss26xllpjbclmfgwvot72m4ku7qxignhlqei6mijvwi2m4pu",
|
||||
"width": 1062,
|
||||
"height": 1069,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Aerie Explorer",
|
||||
"url": "https://explorer.aerielab.io",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreig54jss26xllpjbclmfgwvot72m4ku7qxignhlqei6mijvwi2m4pu",
|
||||
"width": 1062,
|
||||
"height": 1069,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "aerie-network"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Nautilus Proteus Testnet",
|
||||
"chain": "ETH",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNutSgM7n6aJPPDiofe9Dm1epy1RcYTMvugukLUK2vmPM",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://nautilus-proteus-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://api.proteus.nautchain.xyz/solana"
|
||||
],
|
||||
"faucets": [
|
||||
"https://proteusfaucet.nautchain.xyz"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Zebec Test Token",
|
||||
"symbol": "tZBC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.nautchain.xyz",
|
||||
"shortName": "NAUTTest",
|
||||
"chainId": 88002,
|
||||
"networkId": 88002,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Nautscan",
|
||||
"url": "https://proteus.nautscan.com",
|
||||
"standard": "EIP3091",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNutSgM7n6aJPPDiofe9Dm1epy1RcYTMvugukLUK2vmPM",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "nautilus-proteus-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Spicy Chain",
|
||||
"chain": "Spicy",
|
||||
"rpc": [
|
||||
"https://spicy-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://spicy-rpc.chiliz.com/"
|
||||
],
|
||||
"faucets": [
|
||||
"https://spicy-faucet.chiliz.com/"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Chiliz",
|
||||
"symbol": "CHZ",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://chiliz.com/",
|
||||
"shortName": "Spicy",
|
||||
"chainId": 88882,
|
||||
"networkId": 88882,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Spicy Explorer",
|
||||
"url": "http://spicy-explorer.chiliz.com/",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"icon": {
|
||||
"url": "ipfs://QmTGYofJ8VLkeNY4J69AvXi8e126kmbHmf34wLFoJ1FKAK",
|
||||
"width": 400,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
},
|
||||
"testnet": true,
|
||||
"slug": "spicy-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -7,7 +7,9 @@ export default {
|
||||
"https://testnet.bnb.boba.network",
|
||||
"wss://wss.testnet.bnb.boba.network",
|
||||
"https://replica.testnet.bnb.boba.network",
|
||||
"wss://replica-wss.testnet.bnb.boba.network"
|
||||
"wss://replica-wss.testnet.bnb.boba.network",
|
||||
"https://boba-bnb-testnet.gateway.tenderly.co",
|
||||
"wss://boba-bnb-testnet.gateway.tenderly.co"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -10,7 +10,8 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://mind-smart-chain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet-msc.mindchain.info/"
|
||||
"https://testnet-msc.mindchain.info/",
|
||||
"wss://testnet-msc.mindchain.info/ws"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.mindchain.info/"
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Spicy Chain",
|
||||
chain: "Spicy",
|
||||
rpc: ["https://spicy-rpc.chiliz.com/"],
|
||||
faucets: ["https://spicy-faucet.chiliz.com/"],
|
||||
nativeCurrency: {
|
||||
name: "Chiliz",
|
||||
symbol: "CHZ",
|
||||
decimals: 18,
|
||||
},
|
||||
infoURL: "https://chiliz.com/",
|
||||
shortName: "Spicy",
|
||||
chainId: 88882,
|
||||
networkId: 88882,
|
||||
explorers: [
|
||||
{
|
||||
name: "Spicy Explorer",
|
||||
url: "http://spicy-explorer.chiliz.com/",
|
||||
standard: "none",
|
||||
},
|
||||
],
|
||||
icon: {
|
||||
url: "ipfs://QmTGYofJ8VLkeNY4J69AvXi8e126kmbHmf34wLFoJ1FKAK",
|
||||
width: 400,
|
||||
height: 400,
|
||||
format: "png",
|
||||
},
|
||||
testnet: true,
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Partial<Chain>} */
|
||||
export default {
|
||||
name: "Opbnb Testnet",
|
||||
slug: "opbnb-testnet",
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.46",
|
||||
"version": "0.1.50",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"browser": {
|
||||
|
||||
+107
-19
File diff suppressed because one or more lines are too long
@@ -75,7 +75,6 @@ export function getChainRPCs(
|
||||
*
|
||||
* @param chain - The chain config to assemble RPC URLs from
|
||||
* @param clientId - The client id to use for the RPC URL
|
||||
* @param secretKey - The secret key to use for the RPC URL
|
||||
* @returns The first valid RPC URL for the chain
|
||||
*/
|
||||
export function getValidChainRPCs(
|
||||
|
||||
@@ -18,6 +18,7 @@ const CHAIN_RPC_TEST_CASES: [ChainRPCOptions, string[]][] = [
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -27,6 +28,7 @@ const CHAIN_RPC_TEST_CASES: [ChainRPCOptions, string[]][] = [
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -36,12 +38,16 @@ const CHAIN_RPC_TEST_CASES: [ChainRPCOptions, string[]][] = [
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
// infura is supported for both http and ws
|
||||
[
|
||||
{ mode: "ws", infuraApiKey: "SAMPLE_KEY" },
|
||||
["wss://mainnet.infura.io/ws/v3/SAMPLE_KEY"],
|
||||
[
|
||||
"wss://mainnet.infura.io/ws/v3/SAMPLE_KEY",
|
||||
"wss://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -53,12 +59,6 @@ describe("chains/utils", () => {
|
||||
},
|
||||
);
|
||||
|
||||
test("Should throw error if no processedRPCs (getChainRPCs(%p))", () => {
|
||||
expect(() => {
|
||||
getChainRPCs(Ethereum, { mode: "ws" });
|
||||
}).toThrowError('No RPC available for chainId "1" with mode ws');
|
||||
});
|
||||
|
||||
test.each([
|
||||
[
|
||||
undefined,
|
||||
@@ -68,6 +68,7 @@ describe("chains/utils", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -78,6 +79,7 @@ describe("chains/utils", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -88,6 +90,7 @@ describe("chains/utils", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -98,24 +101,13 @@ describe("chains/utils", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
])("getValidChainRPCs(Ethereum, %s, %s) = %p", (clientId, mode, expected) => {
|
||||
expect(getValidChainRPCs(Ethereum, clientId, mode)).toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
[undefined, "ws"],
|
||||
["SAMPLE_CLIENT_KEY", "ws"],
|
||||
])(
|
||||
"Should throw error if no processedRPCs (getValidChainRPCs(Ethereum, %s, %s))",
|
||||
(clientId, mode) => {
|
||||
expect(() => {
|
||||
getValidChainRPCs(Ethereum, clientId, mode);
|
||||
}).toThrowError('No RPC available for chainId "1" with mode ws');
|
||||
},
|
||||
);
|
||||
|
||||
test.each(CHAIN_RPC_TEST_CASES)(
|
||||
"getChainRPC(%p) = %p",
|
||||
(options, expected) => {
|
||||
@@ -174,6 +166,7 @@ describe("chains/utils", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -187,6 +180,7 @@ describe("chains/utils", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -210,6 +204,7 @@ describe("chains/utils with APP_BUNDLE_ID", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -220,6 +215,7 @@ describe("chains/utils with APP_BUNDLE_ID", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -230,6 +226,7 @@ describe("chains/utils with APP_BUNDLE_ID", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -240,6 +237,7 @@ describe("chains/utils with APP_BUNDLE_ID", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
],
|
||||
])("getValidChainRPCs(Ethereum, %s, %s) = %p", (clientId, mode, expected) => {
|
||||
@@ -257,6 +255,7 @@ describe("chains/utils with APP_BUNDLE_ID", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -270,6 +269,7 @@ describe("chains/utils with APP_BUNDLE_ID", () => {
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com",
|
||||
"https://mainnet.gateway.tenderly.co",
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,5 +1,58 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1558](https://github.com/thirdweb-dev/js/pull/1558) [`926dd7b0`](https://github.com/thirdweb-dev/js/commit/926dd7b03f38ed25ca303dc23d3323d5edd28005) Thanks [@Marfuen](https://github.com/Marfuen)! - Updated descriptions for publish and deploy. Print out the login url for users without browsers. Remove the Release command (Use "Publish" instead).
|
||||
|
||||
- Updated dependencies [[`926dd7b0`](https://github.com/thirdweb-dev/js/commit/926dd7b03f38ed25ca303dc23d3323d5edd28005), [`e00dd123`](https://github.com/thirdweb-dev/js/commit/e00dd123579f75752b6fe4fcf613d2cae5419e19)]:
|
||||
- @thirdweb-dev/chains@0.1.50
|
||||
- @thirdweb-dev/sdk@3.10.58
|
||||
- @thirdweb-dev/wallets@1.1.22
|
||||
- @thirdweb-dev/auth@3.2.39
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1422](https://github.com/thirdweb-dev/js/pull/1422) [`0f027069`](https://github.com/thirdweb-dev/js/commit/0f027069064bebe647f9235fa86ef7f165ffc7b3) Thanks [@Marfuen](https://github.com/Marfuen)! - CLI will now use an OAuth like login flow to authenticate the device with the wallet on the dashboard.
|
||||
Any actions performed by the CLI will be linked to your account / wallet on the dashboard, including but not limited to tracking your usage, and billing as needed.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`eb463735`](https://github.com/thirdweb-dev/js/commit/eb463735e2f784cd1d212a982835af95cf60766b), [`adec589e`](https://github.com/thirdweb-dev/js/commit/adec589ead8ceff1b57169e05a3e6733b4652cc7), [`b30566c6`](https://github.com/thirdweb-dev/js/commit/b30566c68436ad94ddc938a380eccc13a8a7147d), [`0f027069`](https://github.com/thirdweb-dev/js/commit/0f027069064bebe647f9235fa86ef7f165ffc7b3), [`f5aed34d`](https://github.com/thirdweb-dev/js/commit/f5aed34d3c71065c3f45df2c1eb84ba9c36162d5)]:
|
||||
- @thirdweb-dev/wallets@1.1.21
|
||||
- @thirdweb-dev/sdk@3.10.57
|
||||
- @thirdweb-dev/chains@0.1.49
|
||||
- @thirdweb-dev/storage@1.2.9
|
||||
- @thirdweb-dev/auth@3.2.38
|
||||
|
||||
## 0.11.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1538](https://github.com/thirdweb-dev/js/pull/1538) [`8b82f3c5`](https://github.com/thirdweb-dev/js/commit/8b82f3c59cad6bd1167c13cb0b8a1cdc36475ab8) Thanks [@iketw](https://github.com/iketw)! - Adds support for creating PWA Vite apps
|
||||
|
||||
You can now run:
|
||||
|
||||
```bash
|
||||
npx thirdweb@nightly create --template pwa-vite-typescript-starter
|
||||
```
|
||||
|
||||
- Updated dependencies [[`f59b729f`](https://github.com/thirdweb-dev/js/commit/f59b729f8b09aa86655b8e8a70fba644fc52009b), [`911e14fc`](https://github.com/thirdweb-dev/js/commit/911e14fcac743b07fa1a66440c72d662c08e971c), [`cd6b07b5`](https://github.com/thirdweb-dev/js/commit/cd6b07b591606d2671794cebebf8edcb59076c32)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 0.11.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`586e91db`](https://github.com/thirdweb-dev/js/commit/586e91dbe610588cc7b24fade59172fed6481074), [`34a3bb8a`](https://github.com/thirdweb-dev/js/commit/34a3bb8ae3c1d7a506e5568a9e79ab7e469557a8), [`91f0245b`](https://github.com/thirdweb-dev/js/commit/91f0245be78ae523e1faea26b1032bfb283467d9), [`f65578d6`](https://github.com/thirdweb-dev/js/commit/f65578d637decc8b87cada5b5b0c8c504064d9d5), [`5a373a75`](https://github.com/thirdweb-dev/js/commit/5a373a75090da7e1e05724ed1a3a3a6aa9f7fd21), [`ae74b8ef`](https://github.com/thirdweb-dev/js/commit/ae74b8ef6200dba8affa8b52e7d834c5552350d0), [`bc003c2f`](https://github.com/thirdweb-dev/js/commit/bc003c2fef33fcf7ce5981d8634911ac4bcaa927), [`447d9846`](https://github.com/thirdweb-dev/js/commit/447d984653f77af6860ae907072e768b584b263d), [`f65578d6`](https://github.com/thirdweb-dev/js/commit/f65578d637decc8b87cada5b5b0c8c504064d9d5)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 0.11.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.11.18",
|
||||
"version": "0.12.1",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -37,9 +37,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"@thirdweb-dev/auth": "workspace:*",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
"@thirdweb-dev/storage": "workspace:*",
|
||||
"@thirdweb-dev/wallets": "workspace:*",
|
||||
"async-retry": "^1.3.3",
|
||||
"commander": "^9.1.0",
|
||||
"detect-package-manager": "^2.0.1",
|
||||
@@ -53,10 +55,10 @@
|
||||
"prompts": "^2.4.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"solc": "0.8.17",
|
||||
"sync-disk-cache": "^2.1.0",
|
||||
"tar": "^6.1.15",
|
||||
"update-notifier": "^6.0.2",
|
||||
"validate-npm-package-name": "^4.0.0",
|
||||
"xdg-app-paths": "^8.3.0",
|
||||
"yaml": "^2.3.1"
|
||||
},
|
||||
"bin": {
|
||||
|
||||
+253
-65
@@ -1,105 +1,293 @@
|
||||
import { LocalWallet } from "@thirdweb-dev/wallets";
|
||||
import assert from "assert";
|
||||
import chalk from "chalk";
|
||||
import prompts from "prompts";
|
||||
import Cache, { CacheEntry } from "sync-disk-cache";
|
||||
import { ApiResponse } from "../lib/types";
|
||||
import os from "os";
|
||||
import fs from "fs";
|
||||
import http from "http";
|
||||
import open from "open";
|
||||
import ora from "ora";
|
||||
import url from "url";
|
||||
import { logger, spinner } from "../core/helpers/logger";
|
||||
import { ThirdwebAuth } from "@thirdweb-dev/auth";
|
||||
import { ICredsConfig } from "../lib/types";
|
||||
import { generateStateParameter } from "../lib/utils";
|
||||
import crypto from "node:crypto";
|
||||
|
||||
type LoginProps = {
|
||||
browser: boolean;
|
||||
configPaths: ConfigPaths;
|
||||
};
|
||||
|
||||
const defaultLoginProps = {
|
||||
browser: true,
|
||||
configPaths: {
|
||||
credsConfigPath: "",
|
||||
cliWalletPath: "",
|
||||
tokenPath: "",
|
||||
},
|
||||
};
|
||||
|
||||
type ConfigPaths = {
|
||||
credsConfigPath: string;
|
||||
cliWalletPath: string;
|
||||
tokenPath: string;
|
||||
}
|
||||
|
||||
export async function loginUser(
|
||||
cache: Cache,
|
||||
configPaths: ConfigPaths,
|
||||
options?: { new: boolean },
|
||||
showLogs?: boolean,
|
||||
) {
|
||||
const keyFound = getSession(cache);
|
||||
if (keyFound && !options?.new) {
|
||||
const { credsConfigPath, tokenPath } = configPaths;
|
||||
const authToken = await getSession(tokenPath, credsConfigPath);
|
||||
if (authToken && !options?.new) {
|
||||
if (showLogs) {
|
||||
console.log(chalk.green("You are already logged in"));
|
||||
}
|
||||
return keyFound;
|
||||
globalThis["TW_AUTH_TOKEN"] = authToken;
|
||||
return authToken;
|
||||
} else {
|
||||
const apiKey = await createSession(cache);
|
||||
return apiKey;
|
||||
const token = await authenticateUser({ browser: true, configPaths });
|
||||
if (!token) {
|
||||
throw new Error("Failed to login");
|
||||
}
|
||||
|
||||
globalThis["TW_AUTH_TOKEN"] = token;
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
export async function logoutUser(cache: Cache) {
|
||||
export async function logoutUser(credsConfigPath: string, tokenPath: string, cliWalletPath: string) {
|
||||
try {
|
||||
cache.remove("api-secret-key");
|
||||
console.log(chalk.green("You have been logged out"));
|
||||
ora("Logging out...").start();
|
||||
const dirExists = fs.existsSync(credsConfigPath) && fs.existsSync(tokenPath);
|
||||
if (!dirExists) {
|
||||
ora().warn(chalk.yellow("You are already logged out, did you mean to login?"));
|
||||
return;
|
||||
}
|
||||
fs.unlinkSync(credsConfigPath);
|
||||
fs.unlinkSync(tokenPath);
|
||||
// TODO: We can consider not removing this on logout later, once we want to implement teams. For now this wallet will be ephemeral.
|
||||
fs.unlinkSync(cliWalletPath);
|
||||
ora().succeed(chalk.green("You have been logged out"));
|
||||
} catch (error) {
|
||||
console.log(chalk.red("Something went wrong", error));
|
||||
}
|
||||
}
|
||||
|
||||
export function getSession(cache: Cache) {
|
||||
export async function getSession(tokenPath: string, configCredsPath: string) {
|
||||
if (!fs.existsSync(tokenPath) || !fs.existsSync(configCredsPath)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const apiKey: CacheEntry = cache.get("api-secret-key");
|
||||
return apiKey.value;
|
||||
return fs.readFileSync(tokenPath, "utf8");
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createSession(cache: Cache) {
|
||||
try {
|
||||
const isWindows = os.type() === "Windows_NT";
|
||||
if (isWindows) {
|
||||
console.log(chalk.yellow("Windows detected: if you are using powershell, there are some known issues with it that we are actively working on, please use git bash or the command prompt. Thank you for your understanding."));
|
||||
}
|
||||
const response = await prompts({
|
||||
type: "invisible",
|
||||
name: "apiSecretKey",
|
||||
message: `Please enter your API secret key, you can find or create it on ${chalk.blue(
|
||||
"https://thirdweb.com/create-api-key",
|
||||
)}`,
|
||||
export const authenticateUser = async (
|
||||
props: LoginProps = defaultLoginProps,
|
||||
) => {
|
||||
const { credsConfigPath, cliWalletPath, tokenPath } = props.configPaths;
|
||||
const waitForDashboard = spinner("Waiting for a response from the dashboard").clear();
|
||||
|
||||
// Get or generate a localwallet.
|
||||
const wallet = await getOrGenerateLocalWallet(credsConfigPath, cliWalletPath);
|
||||
const walletAddress = await wallet.getAddress();
|
||||
const domain = "thirdweb.com";
|
||||
const auth = new ThirdwebAuth(wallet, domain);
|
||||
|
||||
// Generate the login payload to pass to the dashboard.
|
||||
const loggedIn = await auth.login({
|
||||
domain: domain,
|
||||
address: walletAddress,
|
||||
});
|
||||
|
||||
// In this case the state is the loggedIn object.
|
||||
const ourState = generateStateParameter(32);
|
||||
const payload = encodeURIComponent(JSON.stringify(loggedIn));
|
||||
const urlToOpen = `https://thirdweb.com/cli/login?payload=${payload}&#${ourState}`;
|
||||
|
||||
let server: http.Server;
|
||||
let loginTimeoutHandle: NodeJS.Timeout;
|
||||
const timerPromise = new Promise<void>((resolve, reject) => {
|
||||
loginTimeoutHandle = setTimeout(() => {
|
||||
logger.error("Login session timed out, server didn't receive a response in 5 minutes. Please try again.");
|
||||
server.close();
|
||||
clearTimeout(loginTimeoutHandle);
|
||||
reject(new Error("Login session timed out, server didn't receive a response in 5 minutes. Please try again."));
|
||||
}, 300000);
|
||||
});
|
||||
|
||||
const loginPromise = new Promise<string>((resolve, reject) => {
|
||||
server = http.createServer(async (req, res) => {
|
||||
function finish(error?: Error) {
|
||||
clearTimeout(loginTimeoutHandle);
|
||||
server.close((closeErr?: Error) => {
|
||||
if (error || closeErr) {
|
||||
reject(error || closeErr);
|
||||
}
|
||||
});
|
||||
}
|
||||
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
||||
res.setHeader('Access-Control-Allow-Origin', "https://thirdweb.com");
|
||||
res.setHeader('Access-Control-Allow-Methods', 'POST');
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.setHeader('Access-Control-Allow-Headers', 'content-type, baggage, sentry-trace');
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
assert(req.url, "This request doesn't have a URL");
|
||||
const { pathname, query } = url.parse(req.url, true);
|
||||
switch (pathname) {
|
||||
case "/auth/callback": {
|
||||
if (query.failed) {
|
||||
res.writeHead(500, "Unable to authenticate with the dashboard!");
|
||||
res.end("Unable to authenticate with the dashboard!", () => {
|
||||
finish(new Error("Unable to authenticate with the dashboard!"));
|
||||
})
|
||||
reject(chalk.red("Something went wrong! Unable to authenticate with the dashboard."));
|
||||
waitForDashboard.stop();
|
||||
}
|
||||
if (query.token) {
|
||||
const token = Array.isArray(query.token) ? query.token[0] : query.token;
|
||||
const theirState = Array.isArray(query.state)
|
||||
? query.state[0]
|
||||
: query.state;
|
||||
|
||||
// Check if the state sent back is the same as the one we sent.
|
||||
if (theirState !== ourState) {
|
||||
res.writeHead(400, { "Content-Type": "text/plain" }); // send a 400 response
|
||||
res.end("Unauthorized request, state mismatch", () => {
|
||||
finish(new Error("Unauthorized request, state mismatch"));
|
||||
});
|
||||
reject(
|
||||
new Error(chalk.red("\nUnauthorized request, state mismatch")),
|
||||
);
|
||||
waitForDashboard.stop();
|
||||
} else {
|
||||
// Save the token to the config file.
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
fs.writeFileSync(tokenPath, token), {
|
||||
encoding: "utf8",
|
||||
mode: 0o600,
|
||||
};
|
||||
res.end(() => {
|
||||
waitForDashboard.clear();
|
||||
console.log(chalk.green(`Successfully linked your account to this device`));
|
||||
finish();
|
||||
});
|
||||
logger.info(chalk.green(`\nSuccessfully logged in.`));
|
||||
resolve(token); // resolve promise with secretKey
|
||||
}
|
||||
} else {
|
||||
res.writeHead(400, { "Content-Type": "text/plain" });
|
||||
res.end("No authToken received", () => {
|
||||
finish(new Error("No authToken received"));
|
||||
});
|
||||
reject(new Error(chalk.red("\nNo authToken received")));
|
||||
waitForDashboard.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const keyPassed = response.apiSecretKey;
|
||||
if (!keyPassed) {
|
||||
console.log(chalk.red("You need to pass an API secret key"));
|
||||
process.exit(1);
|
||||
}
|
||||
server.listen(8976);
|
||||
});
|
||||
console.log(`Automatically attempting to open a link to authenticate with our dashboard...\n`);
|
||||
waitForDashboard.start();
|
||||
// Adding this timeout since it feels weird for the browser to open before the spinner.
|
||||
setTimeout(async () => {
|
||||
await open(urlToOpen);
|
||||
}, 2000);
|
||||
|
||||
if (keyPassed.length === 32) {
|
||||
console.log(chalk.red(`This is not a valid secret key. To get your secret key
|
||||
1. Create an API key at https://thirdweb.com/create-api-key
|
||||
2. Store and copy your Secret Key. This will be shown only once.
|
||||
3. Paste it in the CLI when prompted`));
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(chalk.yellow(`If the browser doesn't open, please use this link to authenticate:\n`));
|
||||
console.log(chalk.yellow(urlToOpen + '\n'));
|
||||
|
||||
return Promise.race([timerPromise, loginPromise]);
|
||||
};
|
||||
|
||||
async function getOrCreatePassword(configCredsPath: string): Promise<string> {
|
||||
const passwordFileExists = fs.existsSync(configCredsPath);
|
||||
if (!passwordFileExists) {
|
||||
// Generate a random password for the CLI to be able to import / export the wallet.
|
||||
return crypto.randomUUID();
|
||||
} else {
|
||||
const file = fs.readFileSync(configCredsPath, "utf8");
|
||||
try {
|
||||
await validateKey(response.apiSecretKey);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
JSON.parse(file);
|
||||
} catch (e) {
|
||||
// If it fails to parse the password we should just delete the file and generate a new password, since this password is not shown to the user.
|
||||
fs.unlinkSync(configCredsPath);
|
||||
return getOrCreatePassword(configCredsPath);
|
||||
}
|
||||
cache.set("api-secret-key", response.apiSecretKey);
|
||||
return response.apiSecretKey;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
const { password } = JSON.parse(file) as ICredsConfig;
|
||||
return password;
|
||||
}
|
||||
}
|
||||
|
||||
export async function validateKey(apiSecretKey: string) {
|
||||
const fetch = (await import("node-fetch")).default;
|
||||
// TODO: CHANGE THIS TO PROD BEFORE MERGING!!!
|
||||
const response = await fetch(
|
||||
`https://api.thirdweb.com/v1/keys/use?scope=storage`,
|
||||
{
|
||||
async function getOrGenerateLocalWallet(configCredsPath: string, cliWalletPath: string) {
|
||||
// Get or prompt for password.
|
||||
const password = await getOrCreatePassword(configCredsPath);
|
||||
const wallet = new LocalWallet();
|
||||
const foundWallet = fs.existsSync(cliWalletPath);
|
||||
|
||||
if (foundWallet) {
|
||||
const walletJson = fs.readFileSync(cliWalletPath, "utf8");
|
||||
try {
|
||||
// See if file is valid before proceeding.
|
||||
JSON.parse(walletJson);
|
||||
|
||||
await wallet.import({
|
||||
encryptedJson: walletJson,
|
||||
password,
|
||||
});
|
||||
return wallet;
|
||||
} catch (e) {
|
||||
// Wallet file is not valid json, create a new one.
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, generate a new wallet.
|
||||
wallet.generate();
|
||||
const walletExported = await wallet.export({
|
||||
strategy: "encryptedJson",
|
||||
password,
|
||||
});
|
||||
|
||||
// write wallet
|
||||
fs.writeFileSync(cliWalletPath, walletExported, {
|
||||
encoding: "utf8",
|
||||
mode: 0o600,
|
||||
});
|
||||
|
||||
// write password
|
||||
fs.writeFileSync(configCredsPath, JSON.stringify({
|
||||
password: password,
|
||||
}), "utf8");
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
export const validateKey = async (apiSecretKey: string) => {
|
||||
const apiUrl = "https://api.thirdweb.com/v1/keys/use";
|
||||
try {
|
||||
const response = await fetch(`${apiUrl}?scope=storage`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-secret-key": apiSecretKey,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
const apiResponse = (await response.json()) as ApiResponse;
|
||||
if (response.status !== 200) {
|
||||
throw new Error("Unauthorized key");
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const { error } = apiResponse;
|
||||
throw new Error(chalk.red(error.message));
|
||||
} else {
|
||||
return apiSecretKey;
|
||||
} catch (error) {
|
||||
throw new Error(chalk.red("Unauthorized key"));
|
||||
}
|
||||
}
|
||||
};
|
||||
+100
-81
@@ -3,11 +3,11 @@ import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import chalk from "chalk";
|
||||
import { exec, spawn } from "child_process";
|
||||
import { Command } from "commander";
|
||||
import fs from "fs";
|
||||
import open from "open";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import prompts from "prompts";
|
||||
import Cache, { CacheEntry } from "sync-disk-cache";
|
||||
import xdgAppPaths from "xdg-app-paths";
|
||||
import { loginUser, logoutUser, validateKey } from "../auth";
|
||||
import { detectExtensions } from "../common/feature-detector";
|
||||
import { processProject } from "../common/processor";
|
||||
@@ -24,11 +24,17 @@ import { upload } from "../storage/command";
|
||||
const main = async () => {
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
const skipIntro = process.env.THIRDWEB_CLI_SKIP_INTRO === "true";
|
||||
const configDir = xdgAppPaths(".thirdweb").config();
|
||||
const cacheDir = xdgAppPaths(".thirdweb").cache();
|
||||
const lastVersionCheckCachePath = path.join(
|
||||
cacheDir,
|
||||
"last-version-check.txt",
|
||||
);
|
||||
const credsConfigPath = path.join(configDir, "creds.json");
|
||||
const cliWalletPath = path.join(configDir, "wallet.json");
|
||||
const tokenPath = path.join(configDir, "auth-token.txt");
|
||||
|
||||
const program = new Command();
|
||||
const cache = new Cache("thirdweb-cli", {
|
||||
location: path.join(os.homedir(), ".thirdweb", "creds"),
|
||||
});
|
||||
|
||||
// yes this has to look like this, eliminates whitespace
|
||||
if (!skipIntro) {
|
||||
@@ -41,25 +47,41 @@ const main = async () => {
|
||||
$$ |$$\\ $$ | $$ |$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ ____|$$ | $$ |
|
||||
\\$$$$ |$$ | $$ |$$ |$$ | \\$$$$$$$ |\\$$$$$\\$$$$ |\\$$$$$$$\\ $$$$$$$ |
|
||||
\\____/ \\__| \\__|\\__|\\__| \\_______| \\_____\\____/ \\_______|\\_______/ `);
|
||||
console.info(`\n 💎 thirdweb-cli v${cliVersion} 💎\n`);
|
||||
console.info(`\n 💎 thirdweb v${cliVersion} 💎\n`);
|
||||
}
|
||||
|
||||
program
|
||||
.name("thirdweb-cli")
|
||||
.name("thirdweb")
|
||||
.description("Official thirdweb command line interface")
|
||||
.version(cliVersion, "-v, --version")
|
||||
.option("--skip-update-check", "Skip check for auto updates")
|
||||
.hook("preAction", async () => {
|
||||
const regenerateConfig = !fs.existsSync(configDir);
|
||||
const regenerateCache = !fs.existsSync(cacheDir);
|
||||
|
||||
// Create config directory if it doesn't exist
|
||||
if (regenerateConfig) {
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Create cache directory if it doesn't exist
|
||||
if (regenerateCache) {
|
||||
fs.mkdirSync(cacheDir, { recursive: true });
|
||||
}
|
||||
|
||||
if (skipIntro || program.opts().skipUpdateCheck) {
|
||||
return;
|
||||
}
|
||||
|
||||
let shouldCheckVersion = true;
|
||||
try {
|
||||
const lastCheckCache: CacheEntry = cache.get("last-version-check");
|
||||
const lastVersionCheckCache = fs.readFileSync(
|
||||
lastVersionCheckCachePath,
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
if (lastCheckCache.isCached) {
|
||||
const lastVersionCheck = new Date(lastCheckCache.value);
|
||||
if (lastVersionCheckCache) {
|
||||
const lastVersionCheck = new Date(lastVersionCheckCache);
|
||||
// Don't check for updates if already checked within past 24 hours
|
||||
if (Date.now() - lastVersionCheck.getTime() < 1000 * 60 * 60 * 24) {
|
||||
shouldCheckVersion = false;
|
||||
@@ -88,7 +110,14 @@ const main = async () => {
|
||||
|
||||
try {
|
||||
// Set cache to prevent checking for updates again for 24 hours
|
||||
cache.set("last-version-check", new Date().toISOString());
|
||||
fs.writeFileSync(
|
||||
lastVersionCheckCachePath,
|
||||
new Date().toISOString(),
|
||||
{
|
||||
encoding: "utf-8",
|
||||
mode: 0o600,
|
||||
},
|
||||
);
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
@@ -267,7 +296,7 @@ const main = async () => {
|
||||
|
||||
program
|
||||
.command("deploy")
|
||||
.description("Deploy your (or team) contracts securely to blockchains")
|
||||
.description("Securely deploy your contract to any EVM network without having to deal with scripts, private keys, or ABIs")
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--clean", "clear the cache before building")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
@@ -300,66 +329,31 @@ const main = async () => {
|
||||
"Deploy a dynamic smart contract made up of extensions to blockchains",
|
||||
)
|
||||
.option("--zksync", "Deploy on ZKSync")
|
||||
.option("-k, --key <key>", "API key to authorize usage")
|
||||
.option("-k, --key <key>", "API secret key to authorize usage")
|
||||
.action(async (options) => {
|
||||
let apiSecretKey = "";
|
||||
let secretKey = "";
|
||||
// If no key is passed in, prompt the user to login. If it is passed in, use it.
|
||||
if (!options.key) {
|
||||
apiSecretKey = await loginUser(cache);
|
||||
await loginUser({
|
||||
credsConfigPath,
|
||||
cliWalletPath,
|
||||
tokenPath,
|
||||
});
|
||||
} else {
|
||||
// Don't need to validate anymore? Also, should probably rely on the underlying service to throw that error.
|
||||
await validateKey(options.key);
|
||||
apiSecretKey = options.key;
|
||||
secretKey = options.key;
|
||||
}
|
||||
const url = await deploy(options, apiSecretKey);
|
||||
const url = await deploy(options, secretKey);
|
||||
if (url && !options.ci) {
|
||||
await open(url);
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command("release")
|
||||
.description("[Deprecated] use 'publish' instead.")
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option(
|
||||
"-f, --file [name]",
|
||||
"Filter for contract files that contain the file name",
|
||||
)
|
||||
.option(
|
||||
"-cn, --contract-name [name]",
|
||||
"Filter for contracts that contain this contract name",
|
||||
)
|
||||
.option("--clean", "clear the cache before building")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("--ci", "Continuous Integration mode")
|
||||
.option("-k, --key <key>", "API key to authorize usage")
|
||||
.action(async (options) => {
|
||||
let apiSecretKey = "";
|
||||
// If no key is passed in, prompt the user to login. If it is passed in, use it.
|
||||
if (!options.key) {
|
||||
apiSecretKey = await loginUser(cache);
|
||||
} else {
|
||||
await validateKey(options.key);
|
||||
apiSecretKey = options.key;
|
||||
}
|
||||
logger.warn(
|
||||
"'release' is deprecated and will be removed in a future update. Please use 'publish' instead.",
|
||||
);
|
||||
const url = await processProject(options, "publish", apiSecretKey);
|
||||
info(
|
||||
`Open this link to publish your contracts: ${chalk.blueBright(
|
||||
url.toString(),
|
||||
)}`,
|
||||
);
|
||||
if (url && !options.ci) {
|
||||
await open(url.toString());
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command("publish")
|
||||
.description(
|
||||
"Publish your protocol so other devs can deploy them and unlock SDKs, Dashboards and Analytics",
|
||||
"Get a shareable page for your contract with a README, changelog, and version control. Enable one-click deploys to any EVM network",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option(
|
||||
@@ -374,17 +368,22 @@ const main = async () => {
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("--ci", "Continuous Integration mode")
|
||||
.option("-k, --key <key>", "API key to authorize usage")
|
||||
.option("-k, --key <key>", "API secret key to authorize usage")
|
||||
.action(async (options) => {
|
||||
let apiSecretKey = "";
|
||||
let secretKey = "";
|
||||
// If no key is passed in, prompt the user to login. If it is passed in, use it.
|
||||
if (!options.key) {
|
||||
apiSecretKey = await loginUser(cache);
|
||||
await loginUser({
|
||||
credsConfigPath,
|
||||
cliWalletPath,
|
||||
tokenPath,
|
||||
});
|
||||
} else {
|
||||
// Don't need to validate anymore? Also, should probably rely on the underlying service to throw that error.
|
||||
await validateKey(options.key);
|
||||
apiSecretKey = options.key;
|
||||
secretKey = options.key;
|
||||
}
|
||||
const url = await processProject(options, "publish", apiSecretKey);
|
||||
const url = await processProject(options, "publish", secretKey);
|
||||
info(
|
||||
`Open this link to publish your contracts: ${chalk.blueBright(
|
||||
url.toString(),
|
||||
@@ -399,19 +398,31 @@ const main = async () => {
|
||||
.command("upload")
|
||||
.description("Upload any file or directory to decentralized storage (IPFS)")
|
||||
.argument("[upload]", "path to file or directory to upload")
|
||||
.option("-k, --key <key>", "API key to authorize usage")
|
||||
.option("-k, --key <key>", "API secret key to authorize usage")
|
||||
.action(async (_path, options) => {
|
||||
let apiSecretKey = "";
|
||||
let secretKey = "";
|
||||
let storage: ThirdwebStorage;
|
||||
// If no key is passed in, prompt the user to login. If it is passed in, use it.
|
||||
if (!options.key) {
|
||||
apiSecretKey = await loginUser(cache);
|
||||
await loginUser({
|
||||
credsConfigPath,
|
||||
cliWalletPath,
|
||||
tokenPath,
|
||||
});
|
||||
} else {
|
||||
// Don't need to validate anymore? Also, should probably rely on the underlying service to throw that error.
|
||||
await validateKey(options.key);
|
||||
apiSecretKey = options.key;
|
||||
secretKey = options.key;
|
||||
}
|
||||
const storage = new ThirdwebStorage({
|
||||
secretKey: apiSecretKey,
|
||||
});
|
||||
|
||||
if (secretKey) {
|
||||
storage = new ThirdwebStorage({
|
||||
secretKey,
|
||||
});
|
||||
} else {
|
||||
storage = new ThirdwebStorage();
|
||||
}
|
||||
|
||||
try {
|
||||
const uri = await upload(storage, _path);
|
||||
info(
|
||||
@@ -438,7 +449,7 @@ const main = async () => {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
logger.error(chalk.redBright("Failed to upload files"), err);
|
||||
logger.error(chalk.redBright(err.message ? err.message : err));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -460,36 +471,44 @@ const main = async () => {
|
||||
"Preload ABIs and generate types for your smart contract to strongly type the thirdweb SDK",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-k, --key <key>", "API key to authorize usage")
|
||||
.option("-k, --key <key>", "API secret key to authorize usage")
|
||||
.action(async (options) => {
|
||||
let apiSecretKey = "";
|
||||
let secretKey = "";
|
||||
// If no key is passed in, prompt the user to login. If it is passed in, use it.
|
||||
if (!options.key) {
|
||||
apiSecretKey = await loginUser(cache);
|
||||
await loginUser({
|
||||
credsConfigPath,
|
||||
cliWalletPath,
|
||||
tokenPath,
|
||||
});
|
||||
} else {
|
||||
// Don't need to validate anymore? Also, should probably rely on the underlying service to throw that error.
|
||||
await validateKey(options.key);
|
||||
apiSecretKey = options.key;
|
||||
secretKey = options.key;
|
||||
}
|
||||
await generate(options, apiSecretKey);
|
||||
await generate(options, secretKey);
|
||||
});
|
||||
|
||||
program
|
||||
.command("login")
|
||||
.description(
|
||||
"Authenticate with the thirdweb CLI using your API secret key or replace an existing API secret key",
|
||||
"Authorize your device to use the thirdweb CLI by authenticating with your wallet from our dashboard",
|
||||
)
|
||||
.option("-n, --new", "Login with a new API secret key", false)
|
||||
.action(async (options) => {
|
||||
await loginUser(cache, options, true);
|
||||
await loginUser({
|
||||
credsConfigPath,
|
||||
cliWalletPath,
|
||||
tokenPath,
|
||||
}, options, true);
|
||||
});
|
||||
|
||||
program
|
||||
.command("logout")
|
||||
.description(
|
||||
"Logout of the thirdweb CLI, effectively removing your API secret key from your machine",
|
||||
"Logout of the thirdweb CLI",
|
||||
)
|
||||
.action(async () => {
|
||||
await logoutUser(cache);
|
||||
await logoutUser(credsConfigPath, tokenPath, cliWalletPath);
|
||||
});
|
||||
|
||||
await program.parseAsync();
|
||||
|
||||
@@ -32,12 +32,18 @@ import {
|
||||
export async function processProject(
|
||||
options: any,
|
||||
command: "deploy" | "publish",
|
||||
apiSecretKey: string,
|
||||
secretKey: string,
|
||||
) {
|
||||
// TODO: allow overriding the default storage
|
||||
const storage = new ThirdwebStorage({
|
||||
secretKey: apiSecretKey,
|
||||
});
|
||||
let storage: ThirdwebStorage;
|
||||
if (secretKey) {
|
||||
storage = new ThirdwebStorage({
|
||||
secretKey,
|
||||
});
|
||||
} else {
|
||||
// Since the auth key is being set in the global context, we don't need to pass anything here.
|
||||
storage = new ThirdwebStorage();
|
||||
}
|
||||
|
||||
logger.setSettings({
|
||||
minLevel: options.debug ? "debug" : "info",
|
||||
@@ -240,7 +246,7 @@ export async function processProject(
|
||||
} else {
|
||||
const deployArgs: RouterParams = await formatToExtensions(
|
||||
selectedContracts,
|
||||
apiSecretKey,
|
||||
secretKey,
|
||||
);
|
||||
|
||||
const outputDeployArgs = JSON.stringify(deployArgs, undefined, 2);
|
||||
@@ -345,9 +351,9 @@ export async function processProject(
|
||||
loader.succeed("Upload successful");
|
||||
|
||||
return getUrl(combinedURIs, command);
|
||||
} catch (e) {
|
||||
} catch (err: any) {
|
||||
loader.fail("Error uploading metadata");
|
||||
throw e;
|
||||
throw new Error(err.message ? err.message : err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,8 +362,8 @@ export function getUrl(hashes: string[], command: string) {
|
||||
if (hashes.length === 1) {
|
||||
url = new URL(
|
||||
THIRDWEB_URL +
|
||||
`/contracts/${command}/` +
|
||||
encodeURIComponent(hashes[0].replace("ipfs://", "")),
|
||||
`/contracts/${command}/` +
|
||||
encodeURIComponent(hashes[0].replace("ipfs://", "")),
|
||||
);
|
||||
} else {
|
||||
url = new URL(THIRDWEB_URL + "/contracts/" + command);
|
||||
@@ -370,14 +376,20 @@ export function getUrl(hashes: string[], command: string) {
|
||||
|
||||
async function formatToExtensions(
|
||||
contracts: ContractPayload[],
|
||||
apiSecretKey: string,
|
||||
secretKey: string,
|
||||
): Promise<{
|
||||
extensions: Extension[];
|
||||
extensionDeployArgs: ExtensionDeployArgs[];
|
||||
}> {
|
||||
const storage = new ThirdwebStorage({
|
||||
secretKey: apiSecretKey,
|
||||
});
|
||||
let storage: ThirdwebStorage;
|
||||
if (secretKey) {
|
||||
storage = new ThirdwebStorage({
|
||||
secretKey,
|
||||
});
|
||||
} else {
|
||||
// Since the auth key is being set in the global context, we don't need to pass anything here.
|
||||
storage = new ThirdwebStorage();
|
||||
}
|
||||
const extensions: Extension[] = [];
|
||||
const extensionDeployArgs: ExtensionDeployArgs[] = [];
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ export async function twCreate(
|
||||
if (options.reactNative) {
|
||||
framework = "react-native";
|
||||
}
|
||||
if (options.pwaVite) {
|
||||
framework = "pwa-vite";
|
||||
}
|
||||
|
||||
if (options.solana) {
|
||||
chain = "solana";
|
||||
@@ -239,6 +242,7 @@ export async function twCreate(
|
||||
{ title: "Next.js", value: "next" },
|
||||
{ title: "Create React App", value: "cra" },
|
||||
{ title: "Vite", value: "vite" },
|
||||
{ title: "PWA Vite", value: "pwa-vite" },
|
||||
{ title: "React Native", value: "react-native" },
|
||||
{ title: "Node.js", value: "node" },
|
||||
{ title: "Express", value: "express" },
|
||||
@@ -265,6 +269,8 @@ export async function twCreate(
|
||||
if (typeof res.project === "string") {
|
||||
language = res.project.trim();
|
||||
}
|
||||
} else if (framework === "pwa-vite" || framework === "pwa-next") {
|
||||
language = "typescript";
|
||||
} else {
|
||||
const res = await prompts({
|
||||
type: "select",
|
||||
|
||||
@@ -220,7 +220,7 @@ export async function createApp({
|
||||
}
|
||||
|
||||
let startOrDev: string | undefined;
|
||||
if (framework && (framework === "next" || framework === "vite")) {
|
||||
if (framework && (framework.includes("next") || framework.includes("vite"))) {
|
||||
startOrDev = "dev";
|
||||
} else if (template) {
|
||||
startOrDev = await getStartOrDev(template);
|
||||
|
||||
@@ -8,11 +8,17 @@ import { upload } from "../storage/command";
|
||||
export async function deployApp(
|
||||
distPath = "dist",
|
||||
projectPath = ".",
|
||||
apiSecretKey: string,
|
||||
secretKey: string,
|
||||
) {
|
||||
const storage = new ThirdwebStorage({
|
||||
secretKey: apiSecretKey,
|
||||
});
|
||||
let storage: ThirdwebStorage;
|
||||
if (secretKey) {
|
||||
storage = new ThirdwebStorage({
|
||||
secretKey,
|
||||
});
|
||||
} else {
|
||||
// Since the auth key is being set in the global context, we don't need to pass anything here.
|
||||
storage = new ThirdwebStorage();
|
||||
}
|
||||
const detectedPackageManager = await detectPackageManager(projectPath, {});
|
||||
const detectedFramework = await detectFramework(
|
||||
projectPath,
|
||||
@@ -74,8 +80,8 @@ export async function deployApp(
|
||||
"ipfs://",
|
||||
"https://cf-ipfs.com/ipfs/",
|
||||
)}`;
|
||||
} catch (err) {
|
||||
console.error("Can't upload project", err);
|
||||
} catch (err: any) {
|
||||
console.error(err.message ? err.message : err);
|
||||
return Promise.reject("Can't upload project");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ type DeployOptions = {
|
||||
distPath?: string;
|
||||
};
|
||||
|
||||
export async function deploy(options: DeployOptions, apiSecretKey: string) {
|
||||
export async function deploy(options: DeployOptions, secretKey: string) {
|
||||
if (options.name) {
|
||||
const url = generateDashboardUrl(options.name, options.contractVersion);
|
||||
|
||||
@@ -33,7 +33,7 @@ export async function deploy(options: DeployOptions, apiSecretKey: string) {
|
||||
|
||||
if (options.app) {
|
||||
try {
|
||||
const url = await deployApp(options.distPath, options.path, apiSecretKey);
|
||||
const url = await deployApp(options.distPath, options.path, secretKey);
|
||||
info(`Here is the link to your app: ${chalk.blueBright(url.toString())}`);
|
||||
return url.toString();
|
||||
} catch (err) {
|
||||
@@ -44,7 +44,7 @@ export async function deploy(options: DeployOptions, apiSecretKey: string) {
|
||||
}
|
||||
}
|
||||
|
||||
const url = await processProject(options, "deploy", apiSecretKey);
|
||||
const url = await processProject(options, "deploy", secretKey);
|
||||
info(
|
||||
`Open this link to deploy your contracts: ${chalk.blueBright(
|
||||
url.toString(),
|
||||
|
||||
@@ -14,7 +14,7 @@ import { info } from "../core/helpers/logger";
|
||||
import { GenerateOptions, ThirdwebConfig } from "./types";
|
||||
import { CHAIN_OPTIONS, getContractsForAddresses } from "./utils";
|
||||
|
||||
export async function generate(options: GenerateOptions, apiSecretKey: string) {
|
||||
export async function generate(options: GenerateOptions, secretKey: string) {
|
||||
const projectPath: string = options.path?.replace(/\/$/, "") || ".";
|
||||
let contracts: DeployedContract[] = [];
|
||||
|
||||
@@ -55,8 +55,7 @@ export async function generate(options: GenerateOptions, apiSecretKey: string) {
|
||||
const numberOfNewContracts =
|
||||
contracts.length - thirdwebConfig.contracts.length;
|
||||
info(
|
||||
`Updated thirdweb.json with ${numberOfNewContracts} new contract${
|
||||
numberOfNewContracts === 1 ? "" : "s"
|
||||
`Updated thirdweb.json with ${numberOfNewContracts} new contract${numberOfNewContracts === 1 ? "" : "s"
|
||||
}`,
|
||||
);
|
||||
}
|
||||
@@ -86,19 +85,22 @@ export async function generate(options: GenerateOptions, apiSecretKey: string) {
|
||||
);
|
||||
|
||||
info(
|
||||
`Created a thirdweb.json file with configuration for ${
|
||||
contracts.length
|
||||
} contract${
|
||||
contracts.length === 1 ? "" : "s"
|
||||
`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 each contract
|
||||
ora(`Downloading ABIs for contracts configured in 'thirdweb.json'`).info();
|
||||
const storage = new ThirdwebStorage({
|
||||
secretKey: apiSecretKey,
|
||||
});
|
||||
let storage: ThirdwebStorage;
|
||||
if (secretKey) {
|
||||
storage = new ThirdwebStorage({
|
||||
secretKey,
|
||||
});
|
||||
} else {
|
||||
storage = new ThirdwebStorage();
|
||||
}
|
||||
const metadata: {
|
||||
address: string;
|
||||
metadata: Awaited<ReturnType<typeof fetchContractMetadataFromAddress>>;
|
||||
@@ -187,8 +189,7 @@ export async function generate(options: GenerateOptions, apiSecretKey: string) {
|
||||
}
|
||||
|
||||
ora(
|
||||
`Downloaded and cached ABIs for ${metadata.length} smart contract${
|
||||
metadata.length === 1 ? "" : "s"
|
||||
`Downloaded and cached ABIs for ${metadata.length} smart contract${metadata.length === 1 ? "" : "s"
|
||||
}`,
|
||||
).succeed();
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { DeployedContract } from "@thirdweb-dev/sdk";
|
||||
|
||||
export type AuthConfig = {
|
||||
secretKey?: string;
|
||||
authToken?: string;
|
||||
}
|
||||
|
||||
export type ThirdwebConfig = {
|
||||
chainIds: number[];
|
||||
contracts: DeployedContract[];
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
declare module globalThis {
|
||||
// eslint-disable-next-line no-var
|
||||
var TW_AUTH_TOKEN: string;
|
||||
}
|
||||
@@ -4,6 +4,11 @@ import {
|
||||
PackageManagerType,
|
||||
} from "../core/types/ProjectType";
|
||||
|
||||
export type ICredsConfig = {
|
||||
password: string;
|
||||
expiration: number;
|
||||
}
|
||||
|
||||
export type IProcessContractAppTypeArgs = {
|
||||
detectedPackageManager: PackageManagerType;
|
||||
thirdwebDepsToUpdate: Set<string>;
|
||||
@@ -43,4 +48,4 @@ export type ApiResponse = {
|
||||
statusCode: number;
|
||||
message: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -4,6 +4,11 @@ import path from "path";
|
||||
import { PackageManagerType } from "../core/types/ProjectType";
|
||||
import { runCommand } from "../create/helpers/run-command";
|
||||
import { IProcessAppTypeArgs, IProcessContractAppTypeArgs } from "./types";
|
||||
import crypto from "crypto";
|
||||
|
||||
export function generateStateParameter(length: number) {
|
||||
return crypto.randomBytes(length).toString("hex");
|
||||
}
|
||||
|
||||
export function convertDependenciesToStringFormat(dependenciesObject: object) {
|
||||
return Object.entries(dependenciesObject).map(([pkg, versionDetails]) => {
|
||||
|
||||
@@ -69,9 +69,9 @@ export async function upload(
|
||||
);
|
||||
try {
|
||||
uri = await storage.upload(file, { uploadWithoutDirectory: true });
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
spin.fail("Failed to upload file to IPFS.");
|
||||
return Promise.reject(err);
|
||||
return Promise.reject(err.message ? err.message : err);
|
||||
}
|
||||
spin.succeed("Successfully uploaded file to IPFS.");
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/contracts-js
|
||||
|
||||
## 1.3.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1518](https://github.com/thirdweb-dev/js/pull/1518) [`34a3bb8a`](https://github.com/thirdweb-dev/js/commit/34a3bb8ae3c1d7a506e5568a9e79ab7e469557a8) Thanks [@nkrishang](https://github.com/nkrishang)! - Update contracts package
|
||||
|
||||
## 1.3.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/contracts-js",
|
||||
"version": "1.3.11",
|
||||
"version": "1.3.12",
|
||||
"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.8.3"
|
||||
"@thirdweb-dev/contracts": "3.9.3-0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.22.9",
|
||||
|
||||
@@ -1,5 +1,50 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 3.14.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`926dd7b0`](https://github.com/thirdweb-dev/js/commit/926dd7b03f38ed25ca303dc23d3323d5edd28005), [`e00dd123`](https://github.com/thirdweb-dev/js/commit/e00dd123579f75752b6fe4fcf613d2cae5419e19)]:
|
||||
- @thirdweb-dev/chains@0.1.50
|
||||
- @thirdweb-dev/sdk@3.10.58
|
||||
- @thirdweb-dev/wallets@1.1.22
|
||||
- @thirdweb-dev/auth@3.2.39
|
||||
|
||||
## 3.14.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`eb463735`](https://github.com/thirdweb-dev/js/commit/eb463735e2f784cd1d212a982835af95cf60766b), [`adec589e`](https://github.com/thirdweb-dev/js/commit/adec589ead8ceff1b57169e05a3e6733b4652cc7), [`b30566c6`](https://github.com/thirdweb-dev/js/commit/b30566c68436ad94ddc938a380eccc13a8a7147d), [`0f027069`](https://github.com/thirdweb-dev/js/commit/0f027069064bebe647f9235fa86ef7f165ffc7b3), [`f5aed34d`](https://github.com/thirdweb-dev/js/commit/f5aed34d3c71065c3f45df2c1eb84ba9c36162d5)]:
|
||||
- @thirdweb-dev/wallets@1.1.21
|
||||
- @thirdweb-dev/sdk@3.10.57
|
||||
- @thirdweb-dev/chains@0.1.49
|
||||
- @thirdweb-dev/storage@1.2.9
|
||||
- @thirdweb-dev/auth@3.2.38
|
||||
|
||||
## 3.14.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f59b729f`](https://github.com/thirdweb-dev/js/commit/f59b729f8b09aa86655b8e8a70fba644fc52009b), [`911e14fc`](https://github.com/thirdweb-dev/js/commit/911e14fcac743b07fa1a66440c72d662c08e971c), [`cd6b07b5`](https://github.com/thirdweb-dev/js/commit/cd6b07b591606d2671794cebebf8edcb59076c32)]:
|
||||
- @thirdweb-dev/sdk@3.10.56
|
||||
- @thirdweb-dev/chains@0.1.48
|
||||
- @thirdweb-dev/wallets@1.1.20
|
||||
- @thirdweb-dev/auth@3.2.37
|
||||
|
||||
## 3.14.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1522](https://github.com/thirdweb-dev/js/pull/1522) [`088547f7`](https://github.com/thirdweb-dev/js/commit/088547f763294f1641c01ffe1aabac585f255dc0) Thanks [@MananTank](https://github.com/MananTank)! - - New prop `switchToActiveChain` added to `ConnectWallet`` component to show "Switch Network" button if wallet is not connected to the `activeChain`passed to the`ThirdwebProvider`
|
||||
- Add max-height on `ConnectWallet` modal
|
||||
- Local Wallet UI adjustments
|
||||
- Updated dependencies [[`586e91db`](https://github.com/thirdweb-dev/js/commit/586e91dbe610588cc7b24fade59172fed6481074), [`34a3bb8a`](https://github.com/thirdweb-dev/js/commit/34a3bb8ae3c1d7a506e5568a9e79ab7e469557a8), [`91f0245b`](https://github.com/thirdweb-dev/js/commit/91f0245be78ae523e1faea26b1032bfb283467d9), [`f65578d6`](https://github.com/thirdweb-dev/js/commit/f65578d637decc8b87cada5b5b0c8c504064d9d5), [`5a373a75`](https://github.com/thirdweb-dev/js/commit/5a373a75090da7e1e05724ed1a3a3a6aa9f7fd21), [`ae74b8ef`](https://github.com/thirdweb-dev/js/commit/ae74b8ef6200dba8affa8b52e7d834c5552350d0), [`bc003c2f`](https://github.com/thirdweb-dev/js/commit/bc003c2fef33fcf7ce5981d8634911ac4bcaa927), [`447d9846`](https://github.com/thirdweb-dev/js/commit/447d984653f77af6860ae907072e768b584b263d), [`f65578d6`](https://github.com/thirdweb-dev/js/commit/f65578d637decc8b87cada5b5b0c8c504064d9d5)]:
|
||||
- @thirdweb-dev/sdk@3.10.55
|
||||
- @thirdweb-dev/chains@0.1.47
|
||||
- @thirdweb-dev/storage@1.2.8
|
||||
- @thirdweb-dev/wallets@1.1.19
|
||||
- @thirdweb-dev/auth@3.2.36
|
||||
|
||||
## 3.14.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "3.14.35",
|
||||
"version": "3.14.39",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -98,7 +98,7 @@
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/react-query": "^4.32.0",
|
||||
"@tanstack/react-query": "^4.33.0",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/generated-abis": "workspace:^",
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
|
||||
@@ -152,6 +152,7 @@ export const ThirdwebProviderCore = <TChains extends Chain[]>({
|
||||
autoSwitch={props.autoSwitch}
|
||||
autoConnectTimeout={props.autoConnectTimeout}
|
||||
clientId={props.clientId}
|
||||
activeChainSetExplicitly={!!props.activeChain}
|
||||
>
|
||||
<ThirdwebSDKProviderWrapper
|
||||
queryClient={props.queryClient}
|
||||
|
||||
@@ -89,6 +89,7 @@ type ThirdwebWalletContextData = {
|
||||
* Get wallet config object from wallet instance
|
||||
*/
|
||||
getWalletConfig: (walletInstance: WalletInstance) => WalletConfig | undefined;
|
||||
activeChainSetExplicitly: boolean;
|
||||
};
|
||||
|
||||
const ThirdwebWalletContext = /* @__PURE__ */ createContext<
|
||||
@@ -106,6 +107,7 @@ export function ThirdwebWalletProvider(
|
||||
autoSwitch?: boolean;
|
||||
autoConnectTimeout?: number;
|
||||
clientId?: string;
|
||||
activeChainSetExplicitly: boolean;
|
||||
}>,
|
||||
) {
|
||||
const [signer, setSigner] = useState<Signer | undefined>(undefined);
|
||||
@@ -480,6 +482,7 @@ export function ThirdwebWalletProvider(
|
||||
getWalletConfig: (walletInstance: WalletInstance) => {
|
||||
return walletInstanceToConfig.get(walletInstance);
|
||||
},
|
||||
activeChainSetExplicitly: props.activeChainSetExplicitly,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
} from "@tanstack/react-query";
|
||||
import { getCachedAbiForContract, TransactionResult } from "@thirdweb-dev/sdk";
|
||||
import type {
|
||||
Abi,
|
||||
CommonContractSchemaInput,
|
||||
ContractEvent,
|
||||
ContractForPrebuiltContractType,
|
||||
@@ -33,6 +32,7 @@ import type {
|
||||
ThirdwebSDK,
|
||||
ValidContractInstance,
|
||||
BaseContractForAddress,
|
||||
PublishedMetadata,
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import type { CallOverrides, ContractInterface, providers } from "ethers";
|
||||
import { useEffect, useMemo } from "react";
|
||||
@@ -88,19 +88,11 @@ export const contractType = {
|
||||
|
||||
// end contract type
|
||||
|
||||
type FetchCompilerMetadataReturnType = {
|
||||
name: string;
|
||||
metadata: Record<string, any>;
|
||||
abi: Abi;
|
||||
info: Record<string, any>;
|
||||
licenses: string[];
|
||||
};
|
||||
|
||||
// contract compiler metadata
|
||||
function fetchCompilerMetadata(
|
||||
contractAddress: RequiredParam<ContractAddress>,
|
||||
sdk: RequiredParam<ThirdwebSDK>,
|
||||
): Promise<FetchCompilerMetadataReturnType> | null {
|
||||
): Promise<PublishedMetadata> | null {
|
||||
if (!contractAddress || !sdk) {
|
||||
return null;
|
||||
}
|
||||
@@ -114,7 +106,7 @@ function fetchCompilerMetadata(
|
||||
|
||||
export function useCompilerMetadata(
|
||||
contractAddress: RequiredParam<ContractAddress>,
|
||||
): UseQueryResult<FetchCompilerMetadataReturnType | null> {
|
||||
): UseQueryResult<PublishedMetadata | null> {
|
||||
const sdk = useSDK();
|
||||
|
||||
return useQueryWithNetwork(
|
||||
|
||||
@@ -251,6 +251,9 @@ export { ThirdwebSDKProvider } from "./providers/thirdweb-sdk-provider";
|
||||
export { useSDK, useSDKChainId } from "./hooks/useSDK";
|
||||
export type { ThirdwebSDKProviderProps } from "./providers/types";
|
||||
|
||||
// utils
|
||||
export { invalidateContractAndBalances } from "./utils/cache-keys";
|
||||
|
||||
// types
|
||||
export type {
|
||||
Chain,
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.2.58
|
||||
|
||||
## 0.2.57
|
||||
|
||||
## 0.2.56
|
||||
|
||||
## 0.2.55
|
||||
|
||||
## 0.2.54
|
||||
|
||||
## 0.2.53
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.2.54",
|
||||
"version": "0.2.58",
|
||||
"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,63 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.2.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1546](https://github.com/thirdweb-dev/js/pull/1546) [`cdc08c55`](https://github.com/thirdweb-dev/js/commit/cdc08c55282d5873972b85217c42ba2f97a1ffed) Thanks [@iketw](https://github.com/iketw)! - Use regular import for coinbase connector in React Native
|
||||
|
||||
- Updated dependencies [[`926dd7b0`](https://github.com/thirdweb-dev/js/commit/926dd7b03f38ed25ca303dc23d3323d5edd28005), [`e00dd123`](https://github.com/thirdweb-dev/js/commit/e00dd123579f75752b6fe4fcf613d2cae5419e19)]:
|
||||
- @thirdweb-dev/chains@0.1.50
|
||||
- @thirdweb-dev/sdk@3.10.58
|
||||
- @thirdweb-dev/react-core@3.14.39
|
||||
- @thirdweb-dev/wallets@1.1.22
|
||||
|
||||
## 0.2.57
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`eb463735`](https://github.com/thirdweb-dev/js/commit/eb463735e2f784cd1d212a982835af95cf60766b), [`adec589e`](https://github.com/thirdweb-dev/js/commit/adec589ead8ceff1b57169e05a3e6733b4652cc7), [`b30566c6`](https://github.com/thirdweb-dev/js/commit/b30566c68436ad94ddc938a380eccc13a8a7147d), [`0f027069`](https://github.com/thirdweb-dev/js/commit/0f027069064bebe647f9235fa86ef7f165ffc7b3), [`f5aed34d`](https://github.com/thirdweb-dev/js/commit/f5aed34d3c71065c3f45df2c1eb84ba9c36162d5)]:
|
||||
- @thirdweb-dev/wallets@1.1.21
|
||||
- @thirdweb-dev/sdk@3.10.57
|
||||
- @thirdweb-dev/chains@0.1.49
|
||||
- @thirdweb-dev/storage@1.2.9
|
||||
- @thirdweb-dev/react-core@3.14.38
|
||||
|
||||
## 0.2.56
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1536](https://github.com/thirdweb-dev/js/pull/1536) [`387dddbd`](https://github.com/thirdweb-dev/js/commit/387dddbd87ff6c1a53ffaf663564a44b89a3a2a5) Thanks [@iketw](https://github.com/iketw)! - Adds switchToActiveChain prop to the ConnectWallet button.
|
||||
|
||||
When set to true it will show a "Switch Network" button if the wallet
|
||||
is connected to a different chain than the `activeChain` provided in `ThirdwebProvider`
|
||||
|
||||
**Note:** IF you support multiple networks in your app this prop should
|
||||
be set to `false` to allow users to switch between networks.
|
||||
|
||||
Usage:
|
||||
|
||||
```javascript
|
||||
<ConnectWallet switchToActiveChain={true} />
|
||||
```
|
||||
|
||||
- Updated dependencies [[`f59b729f`](https://github.com/thirdweb-dev/js/commit/f59b729f8b09aa86655b8e8a70fba644fc52009b), [`911e14fc`](https://github.com/thirdweb-dev/js/commit/911e14fcac743b07fa1a66440c72d662c08e971c), [`cd6b07b5`](https://github.com/thirdweb-dev/js/commit/cd6b07b591606d2671794cebebf8edcb59076c32)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 0.2.55
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`586e91db`](https://github.com/thirdweb-dev/js/commit/586e91dbe610588cc7b24fade59172fed6481074), [`34a3bb8a`](https://github.com/thirdweb-dev/js/commit/34a3bb8ae3c1d7a506e5568a9e79ab7e469557a8), [`91f0245b`](https://github.com/thirdweb-dev/js/commit/91f0245be78ae523e1faea26b1032bfb283467d9), [`f65578d6`](https://github.com/thirdweb-dev/js/commit/f65578d637decc8b87cada5b5b0c8c504064d9d5), [`5a373a75`](https://github.com/thirdweb-dev/js/commit/5a373a75090da7e1e05724ed1a3a3a6aa9f7fd21), [`ae74b8ef`](https://github.com/thirdweb-dev/js/commit/ae74b8ef6200dba8affa8b52e7d834c5552350d0), [`bc003c2f`](https://github.com/thirdweb-dev/js/commit/bc003c2fef33fcf7ce5981d8634911ac4bcaa927), [`447d9846`](https://github.com/thirdweb-dev/js/commit/447d984653f77af6860ae907072e768b584b263d), [`f65578d6`](https://github.com/thirdweb-dev/js/commit/f65578d637decc8b87cada5b5b0c8c504064d9d5), [`088547f7`](https://github.com/thirdweb-dev/js/commit/088547f763294f1641c01ffe1aabac585f255dc0)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 0.2.54
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.2.54",
|
||||
"version": "0.2.58",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -28,7 +28,7 @@
|
||||
"@magic-sdk/provider": "17.2.0",
|
||||
"@magic-sdk/react-native-bare": "^18.5.0",
|
||||
"@shopify/restyle": "^2.4.2",
|
||||
"@tanstack/react-query": "^4.32.0",
|
||||
"@tanstack/react-query": "^4.33.0",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/react-core": "workspace:*",
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
|
||||
@@ -3,11 +3,18 @@ import {
|
||||
ConnectWalletDetailsProps,
|
||||
WalletDetailsButton,
|
||||
} from "./ConnectWalletDetails/WalletDetailsButton";
|
||||
import { useAddress } from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { Animated } from "react-native";
|
||||
import {
|
||||
useAddress,
|
||||
useNetworkMismatch,
|
||||
useSwitchChain,
|
||||
useWalletContext,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { ActivityIndicator, Animated, StyleSheet } from "react-native";
|
||||
import { ConnectWalletButton } from "./ConnectWalletFlow/ConnectWalletButton";
|
||||
import { ConnectWalletButtonProps } from "./ConnectWalletFlow/ConnectWalletButton";
|
||||
import BaseButton from "./base/BaseButton";
|
||||
import Text from "./base/Text";
|
||||
|
||||
export type ConnectWalletProps = {
|
||||
/**
|
||||
@@ -26,6 +33,17 @@ export type ConnectWalletProps = {
|
||||
* @default false
|
||||
*/
|
||||
hideTestnetFaucet?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to show "Switch Network" button if the wallet is connected,
|
||||
* but it is not connected to the `activeChain` provided in `ThirdwebProvider`
|
||||
*
|
||||
* Please, note that if you support multiple networks in your app this prop should
|
||||
* be set to `false` to allow users to switch between networks.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
switchToActiveChain?: boolean;
|
||||
} & ConnectWalletButtonProps;
|
||||
|
||||
export const ConnectWallet = ({
|
||||
@@ -35,9 +53,15 @@ export const ConnectWallet = ({
|
||||
modalTitle,
|
||||
extraRows,
|
||||
hideTestnetFaucet,
|
||||
switchToActiveChain,
|
||||
}: ConnectWalletProps) => {
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current;
|
||||
const address = useAddress();
|
||||
const isNetworkMismatch = useNetworkMismatch();
|
||||
const { activeChainSetExplicitly } = useWalletContext();
|
||||
const { activeChain } = useWalletContext();
|
||||
const switchChain = useSwitchChain();
|
||||
const [switching, setSwitching] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
Animated.timing(fadeAnim, {
|
||||
@@ -51,12 +75,38 @@ export const ConnectWallet = ({
|
||||
<ThemeProvider theme={theme}>
|
||||
<Animated.View style={{ opacity: fadeAnim }}>
|
||||
{address ? (
|
||||
<WalletDetailsButton
|
||||
address={address}
|
||||
detailsButton={detailsButton}
|
||||
extraRows={extraRows}
|
||||
hideTestnetFaucet={hideTestnetFaucet}
|
||||
/>
|
||||
switchToActiveChain &&
|
||||
isNetworkMismatch &&
|
||||
activeChainSetExplicitly ? (
|
||||
<BaseButton
|
||||
backgroundColor="buttonBackgroundColor"
|
||||
onPress={async () => {
|
||||
setSwitching(true);
|
||||
try {
|
||||
await switchChain(activeChain.chainId);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
setSwitching(false);
|
||||
}}
|
||||
style={styles.connectWalletButton}
|
||||
>
|
||||
{switching ? (
|
||||
<ActivityIndicator size="small" color="buttonTextColor" />
|
||||
) : (
|
||||
<Text variant="bodyLarge" color="buttonTextColor">
|
||||
Switch Network
|
||||
</Text>
|
||||
)}
|
||||
</BaseButton>
|
||||
) : (
|
||||
<WalletDetailsButton
|
||||
address={address}
|
||||
detailsButton={detailsButton}
|
||||
extraRows={extraRows}
|
||||
hideTestnetFaucet={hideTestnetFaucet}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<ConnectWalletButton
|
||||
modalTitle={modalTitle}
|
||||
@@ -68,3 +118,17 @@ export const ConnectWallet = ({
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
connectWalletButton: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
borderRadius: 8,
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 10,
|
||||
minWidth: 150,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { noopStorage } from "../../../core/AsyncStorage";
|
||||
import type {
|
||||
CoinbaseWalletConnector,
|
||||
CoinbaseWalletConnector as CoinbaseWalletConnectorType,
|
||||
CoinbaseWalletConnectorOptions,
|
||||
} from "../connectors/coinbase-wallet";
|
||||
import { CoinbaseWalletConnector } from "../connectors/coinbase-wallet";
|
||||
import {
|
||||
AbstractClientWallet,
|
||||
Connector,
|
||||
@@ -28,8 +29,8 @@ export class CoinbaseWallet extends AbstractClientWallet<CoinbaseWalletConnector
|
||||
};
|
||||
|
||||
connector?: Connector;
|
||||
coinbaseConnector?: CoinbaseWalletConnector;
|
||||
provider?: CoinbaseWalletConnector["provider"];
|
||||
coinbaseConnector?: CoinbaseWalletConnectorType;
|
||||
provider?: CoinbaseWalletConnectorType["provider"];
|
||||
|
||||
static id = walletIds.coinbase;
|
||||
public get walletName() {
|
||||
@@ -50,11 +51,6 @@ export class CoinbaseWallet extends AbstractClientWallet<CoinbaseWalletConnector
|
||||
|
||||
protected async getConnector(): Promise<Connector> {
|
||||
if (!this.connector) {
|
||||
// import the connector dynamically
|
||||
const { CoinbaseWalletConnector: CoinbaseWalletConnector } = await import(
|
||||
"../connectors/coinbase-wallet"
|
||||
);
|
||||
|
||||
const cbConnector = new CoinbaseWalletConnector({
|
||||
chains: this.chains,
|
||||
options: {
|
||||
|
||||
@@ -1,5 +1,52 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.14.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`926dd7b0`](https://github.com/thirdweb-dev/js/commit/926dd7b03f38ed25ca303dc23d3323d5edd28005), [`e00dd123`](https://github.com/thirdweb-dev/js/commit/e00dd123579f75752b6fe4fcf613d2cae5419e19)]:
|
||||
- @thirdweb-dev/chains@0.1.50
|
||||
- @thirdweb-dev/sdk@3.10.58
|
||||
- @thirdweb-dev/react-core@3.14.39
|
||||
- @thirdweb-dev/wallets@1.1.22
|
||||
|
||||
## 3.14.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1532](https://github.com/thirdweb-dev/js/pull/1532) [`b29ec675`](https://github.com/thirdweb-dev/js/commit/b29ec675f9c41c49c015af2427d5402367c06c73) Thanks [@MananTank](https://github.com/MananTank)! - Export ConnectModalInline component
|
||||
|
||||
- [#1544](https://github.com/thirdweb-dev/js/pull/1544) [`eb463735`](https://github.com/thirdweb-dev/js/commit/eb463735e2f784cd1d212a982835af95cf60766b) Thanks [@iketw](https://github.com/iketw)! - Adds support for Rainbow's new browser extension
|
||||
|
||||
- Updated dependencies [[`eb463735`](https://github.com/thirdweb-dev/js/commit/eb463735e2f784cd1d212a982835af95cf60766b), [`adec589e`](https://github.com/thirdweb-dev/js/commit/adec589ead8ceff1b57169e05a3e6733b4652cc7), [`b30566c6`](https://github.com/thirdweb-dev/js/commit/b30566c68436ad94ddc938a380eccc13a8a7147d), [`0f027069`](https://github.com/thirdweb-dev/js/commit/0f027069064bebe647f9235fa86ef7f165ffc7b3), [`f5aed34d`](https://github.com/thirdweb-dev/js/commit/f5aed34d3c71065c3f45df2c1eb84ba9c36162d5)]:
|
||||
- @thirdweb-dev/wallets@1.1.21
|
||||
- @thirdweb-dev/sdk@3.10.57
|
||||
- @thirdweb-dev/chains@0.1.49
|
||||
- @thirdweb-dev/react-core@3.14.38
|
||||
|
||||
## 3.14.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f59b729f`](https://github.com/thirdweb-dev/js/commit/f59b729f8b09aa86655b8e8a70fba644fc52009b), [`911e14fc`](https://github.com/thirdweb-dev/js/commit/911e14fcac743b07fa1a66440c72d662c08e971c), [`cd6b07b5`](https://github.com/thirdweb-dev/js/commit/cd6b07b591606d2671794cebebf8edcb59076c32)]:
|
||||
- @thirdweb-dev/sdk@3.10.56
|
||||
- @thirdweb-dev/chains@0.1.48
|
||||
- @thirdweb-dev/react-core@3.14.37
|
||||
- @thirdweb-dev/wallets@1.1.20
|
||||
|
||||
## 3.14.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1522](https://github.com/thirdweb-dev/js/pull/1522) [`088547f7`](https://github.com/thirdweb-dev/js/commit/088547f763294f1641c01ffe1aabac585f255dc0) Thanks [@MananTank](https://github.com/MananTank)! - - New prop `switchToActiveChain` added to `ConnectWallet`` component to show "Switch Network" button if wallet is not connected to the `activeChain`passed to the`ThirdwebProvider`
|
||||
- Add max-height on `ConnectWallet` modal
|
||||
- Local Wallet UI adjustments
|
||||
- Updated dependencies [[`586e91db`](https://github.com/thirdweb-dev/js/commit/586e91dbe610588cc7b24fade59172fed6481074), [`34a3bb8a`](https://github.com/thirdweb-dev/js/commit/34a3bb8ae3c1d7a506e5568a9e79ab7e469557a8), [`91f0245b`](https://github.com/thirdweb-dev/js/commit/91f0245be78ae523e1faea26b1032bfb283467d9), [`5a373a75`](https://github.com/thirdweb-dev/js/commit/5a373a75090da7e1e05724ed1a3a3a6aa9f7fd21), [`ae74b8ef`](https://github.com/thirdweb-dev/js/commit/ae74b8ef6200dba8affa8b52e7d834c5552350d0), [`bc003c2f`](https://github.com/thirdweb-dev/js/commit/bc003c2fef33fcf7ce5981d8634911ac4bcaa927), [`447d9846`](https://github.com/thirdweb-dev/js/commit/447d984653f77af6860ae907072e768b584b263d), [`f65578d6`](https://github.com/thirdweb-dev/js/commit/f65578d637decc8b87cada5b5b0c8c504064d9d5), [`088547f7`](https://github.com/thirdweb-dev/js/commit/088547f763294f1641c01ffe1aabac585f255dc0)]:
|
||||
- @thirdweb-dev/sdk@3.10.55
|
||||
- @thirdweb-dev/chains@0.1.47
|
||||
- @thirdweb-dev/react-core@3.14.36
|
||||
- @thirdweb-dev/wallets@1.1.19
|
||||
|
||||
## 3.14.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.14.35",
|
||||
"version": "3.14.39",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -131,7 +131,7 @@
|
||||
"@radix-ui/react-tabs": "^1.0.4",
|
||||
"@radix-ui/react-tooltip": "^1.0.6",
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@tanstack/react-query": "^4.32.0",
|
||||
"@tanstack/react-query": "^4.33.0",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/react-core": "workspace:*",
|
||||
"@thirdweb-dev/wallets": "workspace:*",
|
||||
|
||||
@@ -152,7 +152,7 @@ const DialogContent = styled.div<{ theme?: Theme }>`
|
||||
}
|
||||
`;
|
||||
|
||||
const DialogTitle = /* @__PURE__ */ styled(/* @__PURE__ */ Dialog.Title)<{
|
||||
const DialogTitle = /* @__PURE__ */ styled.h2<{
|
||||
theme?: Theme;
|
||||
}>`
|
||||
margin: 0;
|
||||
|
||||
@@ -18,6 +18,7 @@ export const FormFieldWithIconButton: React.FC<{
|
||||
error?: string;
|
||||
noSave?: boolean;
|
||||
dataTest?: string;
|
||||
placeholder?: string;
|
||||
}> = (props) => {
|
||||
return (
|
||||
<div>
|
||||
@@ -42,6 +43,7 @@ export const FormFieldWithIconButton: React.FC<{
|
||||
: undefined
|
||||
}
|
||||
data-test={props.dataTest}
|
||||
placeholder={props.placeholder}
|
||||
/>
|
||||
|
||||
<InputButton type="button" onClick={props.right.onClick}>
|
||||
|
||||
@@ -2,10 +2,9 @@ import { type Theme, fontSize, media } from "../design-system";
|
||||
import { iconSize } from "../design-system";
|
||||
import { IconButton } from "./buttons";
|
||||
import styled from "@emotion/styled";
|
||||
import { Title } from "@radix-ui/react-dialog";
|
||||
import { ChevronLeftIcon } from "@radix-ui/react-icons";
|
||||
|
||||
export const ModalTitle = /* @__PURE__ */ styled(Title)<{
|
||||
export const ModalTitle = /* @__PURE__ */ styled.h2<{
|
||||
theme?: Theme;
|
||||
centerOnMobile?: boolean;
|
||||
}>`
|
||||
|
||||
@@ -7,6 +7,8 @@ export { useSafe } from "./connectors/gnosis";
|
||||
export { useMagic } from "./connectors/magic";
|
||||
|
||||
export { ConnectWallet } from "../wallet/ConnectWallet/ConnectWallet";
|
||||
export { ConnectModalInline } from "../wallet/ConnectWallet/ConnectModal";
|
||||
|
||||
export { NetworkSelector } from "../wallet/ConnectWallet/NetworkSelector";
|
||||
export type { NetworkSelectorProps } from "../wallet/ConnectWallet/NetworkSelector";
|
||||
|
||||
|
||||
@@ -10,25 +10,41 @@ import {
|
||||
import {
|
||||
ModalConfigCtx,
|
||||
SetModalConfigCtx,
|
||||
WalletUIStatesProvider,
|
||||
useIsWalletModalOpen,
|
||||
useSetIsWalletModalOpen,
|
||||
} from "../../evm/providers/wallet-ui-states-provider";
|
||||
import { ThemeProvider } from "@emotion/react";
|
||||
import { darkTheme, lightTheme } from "../../design-system";
|
||||
import {
|
||||
Theme,
|
||||
darkTheme,
|
||||
lightTheme,
|
||||
radius,
|
||||
spacing,
|
||||
} from "../../design-system";
|
||||
import { useState, useCallback, useEffect, useRef, useContext } from "react";
|
||||
import { GetStartedWithWallets } from "./screens/GetStartedWithWallets";
|
||||
import { reservedScreens } from "./constants";
|
||||
import { HeadlessConnectUI } from "../wallets/headlessConnectUI";
|
||||
import styled from "@emotion/styled";
|
||||
import { scrollbar } from "../../design-system/styles";
|
||||
|
||||
export const ConnectModal = () => {
|
||||
const { theme, title } = useContext(ModalConfigCtx);
|
||||
export const ConnectModalContent = (props: {
|
||||
screen: string | WalletConfig;
|
||||
setScreen: (screen: string | WalletConfig) => void;
|
||||
theme?: "light" | "dark";
|
||||
title?: string;
|
||||
}) => {
|
||||
const { screen, setScreen } = props;
|
||||
const modalConfig = useContext(ModalConfigCtx);
|
||||
const title = props.title || modalConfig.title;
|
||||
const theme = props.theme || modalConfig.theme;
|
||||
const walletConfigs = useWallets();
|
||||
const initialScreen =
|
||||
walletConfigs.length === 1 && !walletConfigs[0].selectUI
|
||||
? walletConfigs[0]
|
||||
: reservedScreens.main;
|
||||
|
||||
const [screen, setScreen] = useState<string | WalletConfig>(initialScreen);
|
||||
const isWalletModalOpen = useIsWalletModalOpen();
|
||||
const setIsWalletModalOpen = useSetIsWalletModalOpen();
|
||||
const connectionStatus = useConnectionStatus();
|
||||
@@ -47,7 +63,13 @@ export const ConnectModal = () => {
|
||||
}
|
||||
setIsWalletModalOpen(false);
|
||||
},
|
||||
[setIsWalletModalOpen, initialScreen, connectionStatus, disconnect],
|
||||
[
|
||||
connectionStatus,
|
||||
setIsWalletModalOpen,
|
||||
setScreen,
|
||||
initialScreen,
|
||||
disconnect,
|
||||
],
|
||||
);
|
||||
|
||||
const handleBack = useCallback(() => {
|
||||
@@ -95,9 +117,59 @@ export const ConnectModal = () => {
|
||||
: darkTheme
|
||||
}
|
||||
>
|
||||
{screen === reservedScreens.main && (
|
||||
<WalletSelector
|
||||
title={title}
|
||||
walletConfigs={walletConfigs}
|
||||
onGetStarted={() => {
|
||||
setScreen(reservedScreens.getStarted);
|
||||
}}
|
||||
selectWallet={setScreen}
|
||||
/>
|
||||
)}
|
||||
|
||||
{screen === reservedScreens.getStarted && (
|
||||
<GetStartedWithWallets onBack={handleBack} />
|
||||
)}
|
||||
|
||||
{WalletConnectUI && (
|
||||
<WalletConnectUI
|
||||
supportedWallets={walletConfigs}
|
||||
theme={theme}
|
||||
goBack={handleBack}
|
||||
close={handleClose}
|
||||
isOpen={isWalletModalOpen}
|
||||
open={() => {
|
||||
setIsWalletModalOpen(true);
|
||||
}}
|
||||
walletConfig={screen}
|
||||
selectionData={walletModalConfig.data}
|
||||
setSelectionData={(data) => {
|
||||
setWalletModalConfig((config) => ({
|
||||
...config,
|
||||
data,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectModal = () => {
|
||||
const { theme } = useContext(ModalConfigCtx);
|
||||
const { screen, setScreen, initialScreen } = useScreen();
|
||||
const isWalletModalOpen = useIsWalletModalOpen();
|
||||
const setIsWalletModalOpen = useSetIsWalletModalOpen();
|
||||
const connectionStatus = useConnectionStatus();
|
||||
const disconnect = useDisconnect();
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
|
||||
<Modal
|
||||
style={{
|
||||
maxWidth: "480px",
|
||||
maxWidth: "450px",
|
||||
maxHeight: "70vh",
|
||||
}}
|
||||
open={isWalletModalOpen}
|
||||
setOpen={(value) => {
|
||||
@@ -110,42 +182,62 @@ export const ConnectModal = () => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{screen === reservedScreens.main && (
|
||||
<WalletSelector
|
||||
title={title}
|
||||
walletConfigs={walletConfigs}
|
||||
onGetStarted={() => {
|
||||
setScreen(reservedScreens.getStarted);
|
||||
}}
|
||||
selectWallet={setScreen}
|
||||
/>
|
||||
)}
|
||||
|
||||
{screen === reservedScreens.getStarted && (
|
||||
<GetStartedWithWallets onBack={handleBack} />
|
||||
)}
|
||||
|
||||
{WalletConnectUI && (
|
||||
<WalletConnectUI
|
||||
supportedWallets={walletConfigs}
|
||||
theme={theme}
|
||||
goBack={handleBack}
|
||||
close={handleClose}
|
||||
isOpen={isWalletModalOpen}
|
||||
open={() => {
|
||||
setIsWalletModalOpen(true);
|
||||
}}
|
||||
walletConfig={screen}
|
||||
selectionData={walletModalConfig.data}
|
||||
setSelectionData={(data) => {
|
||||
setWalletModalConfig((config) => ({
|
||||
...config,
|
||||
data,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<ConnectModalContent screen={screen} setScreen={setScreen} />
|
||||
</Modal>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectModalInline = (props: {
|
||||
theme?: "light" | "dark";
|
||||
title?: string;
|
||||
className?: string;
|
||||
}) => {
|
||||
const { screen, setScreen } = useScreen();
|
||||
return (
|
||||
<WalletUIStatesProvider theme={props.theme}>
|
||||
<ThemeProvider theme={props.theme === "light" ? lightTheme : darkTheme}>
|
||||
<ConnectModalInlineContainer className={props.className}>
|
||||
<ConnectModalContent
|
||||
screen={screen}
|
||||
setScreen={setScreen}
|
||||
theme={props.theme}
|
||||
title={props.title}
|
||||
/>
|
||||
</ConnectModalInlineContainer>
|
||||
</ThemeProvider>
|
||||
</WalletUIStatesProvider>
|
||||
);
|
||||
};
|
||||
|
||||
function useScreen() {
|
||||
const walletConfigs = useWallets();
|
||||
const initialScreen =
|
||||
walletConfigs.length === 1 && !walletConfigs[0].selectUI
|
||||
? walletConfigs[0]
|
||||
: reservedScreens.main;
|
||||
|
||||
const [screen, setScreen] = useState<string | WalletConfig>(initialScreen);
|
||||
return {
|
||||
screen,
|
||||
setScreen,
|
||||
initialScreen,
|
||||
};
|
||||
}
|
||||
|
||||
const ConnectModalInlineContainer = styled.div<{ theme?: Theme }>`
|
||||
background: ${(p) => p.theme.bg.base};
|
||||
padding: ${spacing.lg};
|
||||
border-radius: ${radius.xl};
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
${(p) =>
|
||||
scrollbar({
|
||||
track: "transparent",
|
||||
thumb: p.theme.bg.elevated,
|
||||
hover: p.theme.bg.highlighted,
|
||||
})}
|
||||
`;
|
||||
|
||||
@@ -7,9 +7,12 @@ import {
|
||||
useConnectionStatus,
|
||||
useLogin,
|
||||
useLogout,
|
||||
useNetworkMismatch,
|
||||
useSwitchChain,
|
||||
useThirdwebAuthContext,
|
||||
useUser,
|
||||
useWallet,
|
||||
useWalletContext,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useContext, useState } from "react";
|
||||
import {
|
||||
@@ -54,6 +57,17 @@ type ConnectWalletProps = {
|
||||
* @default false
|
||||
*/
|
||||
hideTestnetFaucet?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to show "Switch Network" button if the wallet is connected,
|
||||
* but it is not connected to the `activeChain` provided in `ThirdwebProvider`
|
||||
*
|
||||
* Please, note that if you support multiple networks in your app this prop should
|
||||
* be set to `false` to allow users to switch between networks.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
switchToActiveChain?: boolean;
|
||||
};
|
||||
|
||||
const TW_CONNECT_WALLET = "tw-connect-wallet";
|
||||
@@ -83,6 +97,8 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
|
||||
const { user } = useUser();
|
||||
const { login } = useLogin();
|
||||
const { logout } = useLogout();
|
||||
const isNetworkMismatch = useNetworkMismatch();
|
||||
const { activeChainSetExplicitly } = useWalletContext();
|
||||
|
||||
const requiresSignIn = props.auth?.loginOptional
|
||||
? false
|
||||
@@ -108,61 +124,87 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Sign In Button */}
|
||||
{requiresSignIn && (
|
||||
<Button
|
||||
variant="inverted"
|
||||
onClick={signIn}
|
||||
data-theme={theme}
|
||||
className={`${TW_CONNECT_WALLET}--sign-in ${props.className || ""}}`}
|
||||
style={props.style}
|
||||
>
|
||||
<Flex
|
||||
alignItems="center"
|
||||
gap="sm"
|
||||
style={{
|
||||
paddingRight: spacing.xs,
|
||||
borderRight: "1px solid",
|
||||
marginRight: spacing.xs,
|
||||
}}
|
||||
>
|
||||
<LockIcon size={iconSize.sm} />
|
||||
<span> Sign in </span>
|
||||
</Flex>
|
||||
<span>{shortenAddress(address || "", true)}</span>
|
||||
</Button>
|
||||
)}
|
||||
{(() => {
|
||||
// wallet is not connected
|
||||
if (!activeWallet) {
|
||||
// Connect Wallet button
|
||||
return (
|
||||
<AnimatedButton
|
||||
disabled={isLoading}
|
||||
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
|
||||
}
|
||||
onClick={() => {
|
||||
setModalConfig({
|
||||
title: props.modalTitle || "Choose your wallet",
|
||||
theme,
|
||||
data: undefined,
|
||||
});
|
||||
setIsWalletModalOpen(true);
|
||||
}}
|
||||
data-test="connect-wallet-button"
|
||||
>
|
||||
{isLoading ? <Spinner size="sm" color="inverted" /> : btnTitle}
|
||||
</AnimatedButton>
|
||||
);
|
||||
}
|
||||
|
||||
{!requiresSignIn &&
|
||||
(!activeWallet ? (
|
||||
// connect wallet button
|
||||
<AnimatedButton
|
||||
disabled={isLoading}
|
||||
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
|
||||
}
|
||||
onClick={() => {
|
||||
setModalConfig({
|
||||
title: props.modalTitle || "Choose your wallet",
|
||||
theme,
|
||||
data: undefined,
|
||||
});
|
||||
setIsWalletModalOpen(true);
|
||||
}}
|
||||
data-test="connect-wallet-button"
|
||||
>
|
||||
{isLoading ? <Spinner size="sm" color="inverted" /> : btnTitle}
|
||||
</AnimatedButton>
|
||||
) : (
|
||||
// switch network button
|
||||
if (
|
||||
props.switchToActiveChain &&
|
||||
isNetworkMismatch &&
|
||||
activeChainSetExplicitly
|
||||
) {
|
||||
return (
|
||||
<SwitchNetworkButton
|
||||
style={props.style}
|
||||
theme={theme}
|
||||
className={props.className}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// sign in button
|
||||
else if (requiresSignIn) {
|
||||
return (
|
||||
<Button
|
||||
variant="inverted"
|
||||
onClick={signIn}
|
||||
data-theme={theme}
|
||||
className={`${TW_CONNECT_WALLET}--sign-in ${
|
||||
props.className || ""
|
||||
}`}
|
||||
style={props.style}
|
||||
data-test="sign-in-button"
|
||||
>
|
||||
<Flex
|
||||
alignItems="center"
|
||||
gap="sm"
|
||||
style={{
|
||||
paddingRight: spacing.xs,
|
||||
borderRight: "1px solid",
|
||||
marginRight: spacing.xs,
|
||||
}}
|
||||
>
|
||||
<LockIcon size={iconSize.sm} />
|
||||
<span> Sign in </span>
|
||||
</Flex>
|
||||
<span>{shortenAddress(address || "", true)}</span>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
// wallet details button
|
||||
return (
|
||||
<ConnectedWalletDetails
|
||||
networkSelector={props.networkSelector}
|
||||
dropdownPosition={props.dropdownPosition}
|
||||
@@ -178,11 +220,52 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
);
|
||||
})()}
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
function SwitchNetworkButton(props: {
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
theme: "dark" | "light";
|
||||
}) {
|
||||
const { activeChain } = useWalletContext();
|
||||
const switchChain = useSwitchChain();
|
||||
const [switching, setSwitching] = useState(false);
|
||||
|
||||
return (
|
||||
<AnimatedButton
|
||||
className={`${TW_CONNECT_WALLET}--switch-network ${
|
||||
props.className || ""
|
||||
}`}
|
||||
variant="inverted"
|
||||
type="button"
|
||||
data-theme={props.theme}
|
||||
data-is-loading={switching}
|
||||
data-test="switch-network-button"
|
||||
disabled={switching}
|
||||
onClick={async () => {
|
||||
setSwitching(true);
|
||||
try {
|
||||
await switchChain(activeChain.chainId);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
setSwitching(false);
|
||||
}}
|
||||
style={{
|
||||
minWidth: "140px",
|
||||
...props.style,
|
||||
}}
|
||||
aria-label={switching ? "Switching Network" : undefined}
|
||||
>
|
||||
{switching ? <Spinner size="sm" color="inverted" /> : "Switch Network"}
|
||||
</AnimatedButton>
|
||||
);
|
||||
}
|
||||
|
||||
const AnimatedButton = /* @__PURE__ */ styled(Button)`
|
||||
animation: ${fadeInAnimation} 300ms ease;
|
||||
`;
|
||||
|
||||
@@ -113,7 +113,7 @@ export const WalletSelection: React.FC<{
|
||||
});
|
||||
|
||||
return (
|
||||
<WalletList>
|
||||
<WalletListContainer>
|
||||
{walletConfigs.map((walletConfig) => {
|
||||
const isInstalled = walletConfig.isInstalled
|
||||
? walletConfig.isInstalled()
|
||||
@@ -150,11 +150,11 @@ export const WalletSelection: React.FC<{
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</WalletList>
|
||||
</WalletListContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const WalletList = styled.ul`
|
||||
const WalletListContainer = styled.ul`
|
||||
all: unset;
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Spacer } from "../../../components/Spacer";
|
||||
import { Button } from "../../../components/buttons";
|
||||
import { FormFooter, Label } from "../../../components/formElements";
|
||||
import { Label } from "../../../components/formElements";
|
||||
import {
|
||||
ModalTitle,
|
||||
ModalDescription,
|
||||
@@ -172,7 +172,7 @@ export const ExportLocalWallet: React.FC<{
|
||||
|
||||
<SavedWalletAddress>{shortenAddress(savedAddress)}</SavedWalletAddress>
|
||||
|
||||
<Spacer y="lg" />
|
||||
<Spacer y="xl" />
|
||||
|
||||
{passwordIsRequired && (
|
||||
<>
|
||||
@@ -207,22 +207,21 @@ export const ExportLocalWallet: React.FC<{
|
||||
error={isWrongPassword ? "Wrong Password" : ""}
|
||||
dataTest="current-password"
|
||||
/>
|
||||
<Spacer y="xl" />
|
||||
<Spacer y="md" />
|
||||
</>
|
||||
)}
|
||||
|
||||
<FormFooter>
|
||||
<Button
|
||||
disabled={exportDisabled}
|
||||
variant="inverted"
|
||||
style={{
|
||||
opacity: exportDisabled ? 0.5 : 1,
|
||||
}}
|
||||
type="submit"
|
||||
>
|
||||
Backup
|
||||
</Button>
|
||||
</FormFooter>
|
||||
<Button
|
||||
disabled={exportDisabled}
|
||||
variant="inverted"
|
||||
style={{
|
||||
opacity: exportDisabled ? 0.5 : 1,
|
||||
width: "100%",
|
||||
}}
|
||||
type="submit"
|
||||
>
|
||||
Backup
|
||||
</Button>
|
||||
</form>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { EyeClosedIcon, EyeOpenIcon } from "@radix-ui/react-icons";
|
||||
import { WalletConfig, useWalletContext } from "@thirdweb-dev/react-core";
|
||||
import { useState } from "react";
|
||||
import { FormFooter, Label } from "../../../components/formElements";
|
||||
import { Label } from "../../../components/formElements";
|
||||
import { spacing } from "../../../design-system";
|
||||
import { Spinner } from "../../../components/Spinner";
|
||||
import { shortenAddress } from "../../../evm/utils/addresses";
|
||||
@@ -131,6 +131,7 @@ export const ReconnectLocalWallet: React.FC<ReconnectLocalWalletProps> = (
|
||||
meta={meta}
|
||||
hideBack={!props.renderBackButton}
|
||||
/>
|
||||
|
||||
<ModalTitle
|
||||
style={{
|
||||
textAlign: "left",
|
||||
@@ -138,12 +139,13 @@ export const ReconnectLocalWallet: React.FC<ReconnectLocalWalletProps> = (
|
||||
>
|
||||
Guest Wallet
|
||||
</ModalTitle>
|
||||
|
||||
<Spacer y="xs" />
|
||||
<ModalDescription>
|
||||
Connect to saved wallet on your device
|
||||
</ModalDescription>
|
||||
|
||||
<Spacer y="lg" />
|
||||
<Spacer y="xl" />
|
||||
|
||||
<Label>Saved Wallet</Label>
|
||||
|
||||
@@ -153,7 +155,7 @@ export const ReconnectLocalWallet: React.FC<ReconnectLocalWalletProps> = (
|
||||
{savedAddress === "" ? "Loading..." : shortenAddress(savedAddress)}
|
||||
</SecondaryText>
|
||||
|
||||
<Spacer y="lg" />
|
||||
<Spacer y="xl" />
|
||||
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
@@ -190,27 +192,27 @@ export const ReconnectLocalWallet: React.FC<ReconnectLocalWalletProps> = (
|
||||
value={password}
|
||||
error={isWrongPassword ? "Wrong Password" : ""}
|
||||
dataTest="current-password"
|
||||
placeholder="Enter your password"
|
||||
/>
|
||||
|
||||
<Spacer y="lg" />
|
||||
<Spacer y="md" />
|
||||
|
||||
{/* Connect Button */}
|
||||
<FormFooter>
|
||||
<Button
|
||||
variant="inverted"
|
||||
type="submit"
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: spacing.sm,
|
||||
}}
|
||||
>
|
||||
Connect
|
||||
{isConnecting && <Spinner size="sm" color="inverted" />}
|
||||
</Button>
|
||||
</FormFooter>
|
||||
<Button
|
||||
variant="inverted"
|
||||
type="submit"
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: spacing.sm,
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
Connect
|
||||
{isConnecting && <Spinner size="sm" color="inverted" />}
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<Spacer y="xxl" />
|
||||
<Spacer y="xl" />
|
||||
|
||||
<Button
|
||||
variant="link"
|
||||
|
||||
@@ -18,7 +18,7 @@ export const LocalWalletModalHeader: React.FC<{
|
||||
</>
|
||||
)}
|
||||
<Img src={props.meta.iconURL} width={iconSize.xl} height={iconSize.xl} />
|
||||
<Spacer y="sm" />
|
||||
<Spacer y="md" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { ConnectUIProps, useConnect } from "@thirdweb-dev/react-core";
|
||||
import { WalletConnect } from "@thirdweb-dev/wallets";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { isMobile } from "../../../evm/utils/isMobile";
|
||||
import { ConnectingScreen } from "../../ConnectWallet/screens/ConnectingScreen";
|
||||
import { GetStartedScreen } from "../../ConnectWallet/screens/GetStartedScreen";
|
||||
import { isMobile } from "../../../evm/utils/isMobile";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { RainbowScan } from "./RainbowScan";
|
||||
import { WCOpenURI } from "../../ConnectWallet/screens/WCOpenUri";
|
||||
import { GetStartedScreen } from "../../ConnectWallet/screens/GetStartedScreen";
|
||||
import { RainbowWallet } from "@thirdweb-dev/wallets";
|
||||
|
||||
export const RainbowConnectUI = (props: ConnectUIProps<WalletConnect>) => {
|
||||
export const RainbowConnectUI = (props: ConnectUIProps<RainbowWallet>) => {
|
||||
const [screen, setScreen] = useState<
|
||||
"connecting" | "scanning" | "get-started" | "open-wc-uri"
|
||||
"connecting" | "scanning" | "get-started"
|
||||
>("connecting");
|
||||
const { walletConfig, close } = props;
|
||||
const connect = useConnect();
|
||||
@@ -24,14 +23,34 @@ export const RainbowConnectUI = (props: ConnectUIProps<WalletConnect>) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const isInstalled = walletConfig.isInstalled
|
||||
? walletConfig.isInstalled()
|
||||
: false;
|
||||
|
||||
// if loading
|
||||
(async () => {
|
||||
// on mobile, open rainbow app link
|
||||
if (isMobile()) {
|
||||
setScreen("open-wc-uri");
|
||||
} else {
|
||||
// on desktop, show the rainbow scan qr code
|
||||
setScreen("scanning");
|
||||
if (isInstalled) {
|
||||
try {
|
||||
connectPrompted.current = true;
|
||||
setScreen("connecting");
|
||||
await connect(walletConfig);
|
||||
close();
|
||||
} catch (e) {
|
||||
goBack();
|
||||
}
|
||||
}
|
||||
|
||||
// if rainbow is not injected
|
||||
else {
|
||||
// on mobile, open rainbow app link
|
||||
if (isMobile()) {
|
||||
window.open(
|
||||
`https://rainbow.app.link/dapp/${window.location.toString()}`,
|
||||
);
|
||||
} else {
|
||||
// on desktop, show the rainbow scan qr code
|
||||
setScreen("scanning");
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, [walletConfig, close, connect, goBack]);
|
||||
@@ -43,24 +62,7 @@ export const RainbowConnectUI = (props: ConnectUIProps<WalletConnect>) => {
|
||||
onBack={props.goBack}
|
||||
walletName={walletConfig.meta.name}
|
||||
walletIconURL={walletConfig.meta.iconURL}
|
||||
supportLink="https://rainbow.me/"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (screen === "open-wc-uri") {
|
||||
return (
|
||||
<WCOpenURI
|
||||
hideBackButton={hideBackButton}
|
||||
onBack={props.goBack}
|
||||
onConnected={close}
|
||||
walletConfig={walletConfig}
|
||||
supportLink="https://rainbow.me/"
|
||||
appUriPrefix={{
|
||||
ios: "rainbow://",
|
||||
android: "https://rnbwapp.com/",
|
||||
other: "https://rnbwapp.com/",
|
||||
}}
|
||||
supportLink="https://support.rainbow.io/hc/en-us/articles/4406430256539-User-Guide-Troubleshooting"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -83,7 +85,7 @@ export const RainbowConnectUI = (props: ConnectUIProps<WalletConnect>) => {
|
||||
if (screen === "scanning") {
|
||||
return (
|
||||
<RainbowScan
|
||||
onBack={props.goBack}
|
||||
onBack={goBack}
|
||||
onConnected={close}
|
||||
onGetStarted={() => {
|
||||
setScreen("get-started");
|
||||
|
||||
@@ -4,14 +4,14 @@ import {
|
||||
useWalletContext,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import type { WalletConnect } from "@thirdweb-dev/wallets";
|
||||
import type { RainbowWallet } from "@thirdweb-dev/wallets";
|
||||
import type { WalletConfig } from "@thirdweb-dev/react-core";
|
||||
|
||||
export const RainbowScan: React.FC<{
|
||||
onBack: () => void;
|
||||
onGetStarted: () => void;
|
||||
onConnected: () => void;
|
||||
walletConfig: WalletConfig<WalletConnect>;
|
||||
walletConfig: WalletConfig<RainbowWallet>;
|
||||
hideBackButton: boolean;
|
||||
}> = ({ onBack, onConnected, onGetStarted, walletConfig, hideBackButton }) => {
|
||||
const createInstance = useCreateWalletInstance();
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { WalletOptions, WalletConfig } from "@thirdweb-dev/react-core";
|
||||
import { WalletConnect } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
RainbowWallet,
|
||||
getInjectedRainbowProvider,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { RainbowConnectUI } from "./RainbowConnectUI";
|
||||
import { rainbowWalletUris } from "./rainbowWalletUris";
|
||||
import { handelWCSessionRequest } from "../handleWCSessionRequest";
|
||||
|
||||
type RainbowWalletOptions = {
|
||||
/**
|
||||
@@ -16,33 +17,22 @@ type RainbowWalletOptions = {
|
||||
|
||||
export const rainbowWallet = (
|
||||
options?: RainbowWalletOptions,
|
||||
): WalletConfig<WalletConnect> => {
|
||||
): WalletConfig<RainbowWallet> => {
|
||||
return {
|
||||
id: "rainbow",
|
||||
meta: {
|
||||
name: "Rainbow Wallet",
|
||||
iconURL:
|
||||
"ipfs://QmSZn47p4DVVBfzvg9BAX2EqwnPxkT1YAE7rUnrtd9CybQ/rainbow-logo.png",
|
||||
urls: {
|
||||
android: "https://rnbwapp.com/e/Va41HWS6Oxb",
|
||||
ios: "https://rnbwapp.com/e/OeMdmkJ6Oxb",
|
||||
},
|
||||
},
|
||||
id: RainbowWallet.id,
|
||||
meta: RainbowWallet.meta,
|
||||
create: (walletOptions: WalletOptions) => {
|
||||
const wallet = new WalletConnect({
|
||||
const wallet = new RainbowWallet({
|
||||
...walletOptions,
|
||||
walletId: "rainbow",
|
||||
projectId: options?.projectId,
|
||||
qrcode: false,
|
||||
});
|
||||
|
||||
handelWCSessionRequest(wallet, rainbowWalletUris);
|
||||
|
||||
return wallet;
|
||||
},
|
||||
connectUI: RainbowConnectUI,
|
||||
isInstalled() {
|
||||
return false;
|
||||
return !!getInjectedRainbowProvider();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user