Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1119f63a47 | ||
|
|
32908b7683 | ||
|
|
6a4aab0b8a | ||
|
|
e87d166d2b | ||
|
|
af4b535637 | ||
|
|
a2df187bc1 | ||
|
|
ea0f9479a3 | ||
|
|
bbe329a656 | ||
|
|
05ebbc15a0 | ||
|
|
93bd57337b | ||
|
|
eb521d240a | ||
|
|
aa9b6acc3f | ||
|
|
4ca557ae4a | ||
|
|
93bdec061d | ||
|
|
c6e9406808 | ||
|
|
12ad7fead2 | ||
|
|
7d7685e3fa | ||
|
|
9640e0731f | ||
|
|
87021cee45 | ||
|
|
5305b42db5 | ||
|
|
c8ba96fa00 | ||
|
|
89c821d49e |
@@ -1,5 +1,19 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 3.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff)]:
|
||||
- @thirdweb-dev/wallets@0.2.19
|
||||
|
||||
## 3.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`93bdec06`](https://github.com/thirdweb-dev/js/commit/93bdec061dc05ab133e79f5f739dcae9b5393f53), [`ea0f9479`](https://github.com/thirdweb-dev/js/commit/ea0f9479a38d442201e367fce1234c130228fde6), [`05ebbc15`](https://github.com/thirdweb-dev/js/commit/05ebbc15a012855735fba2aa93887b88e14295d1), [`4ca557ae`](https://github.com/thirdweb-dev/js/commit/4ca557ae4ab225e39decc3b7a01a04c0d8e464c7), [`7d7685e3`](https://github.com/thirdweb-dev/js/commit/7d7685e3fab5780b3c1d26b8ef431b96f8486972), [`93bd5733`](https://github.com/thirdweb-dev/js/commit/93bd57337b7d2c2fcd252987d10df3206c839daf)]:
|
||||
- @thirdweb-dev/wallets@0.2.18
|
||||
|
||||
## 3.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "3.0.16",
|
||||
"version": "3.0.18",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#990](https://github.com/thirdweb-dev/js/pull/990) [`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - updated chains
|
||||
|
||||
## 0.1.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#954](https://github.com/thirdweb-dev/js/pull/954) [`5305b42d`](https://github.com/thirdweb-dev/js/commit/5305b42db554b69f903b3d95f3ba0eeddabd6114) Thanks [@jarrodwatts](https://github.com/jarrodwatts)! - useContract now types correctly for thirdweb generate
|
||||
|
||||
## 0.1.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Coinbit Mainnet",
|
||||
"chain": "Coinbit",
|
||||
"rpc": [
|
||||
"https://coinbit.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://coinbit-rpc-mainnet.chain.sbcrypto.app"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Gas IDR",
|
||||
"symbol": "GIDR",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://crypto.stockbit.com/",
|
||||
"shortName": "coinbit",
|
||||
"chainId": 112,
|
||||
"networkId": 112,
|
||||
"icon": {
|
||||
"url": "ipfs://QmdaQRUbAXJGfHeJ8jaB8WVh8CCmHExq8VjvAfXpLWWQEo",
|
||||
"width": 760,
|
||||
"height": 760,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://coinbit-explorer.chain.sbcrypto.app",
|
||||
"icon": {
|
||||
"url": "ipfs://bafybeifu5tpui7dk5cjoo54kde7pmuthvnl7sdykobuarsxgu7t2izurnq",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "coinbit"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "ARC Mainnet",
|
||||
"chain": "ARC",
|
||||
"icon": {
|
||||
"url": "ipfs://bafybeiady63oqduls2pm4aaykzjhahblagokhnpsc5qeq5dmkxqelh7i2i",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://arc.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-main-1.archiechain.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "ARC",
|
||||
"symbol": "ARC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://archiechain.io/",
|
||||
"shortName": "ARC",
|
||||
"chainId": 1243,
|
||||
"networkId": 1243,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "archiescan",
|
||||
"url": "https://app.archiescan.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "arc"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "ARC Testnet",
|
||||
"chain": "ARC",
|
||||
"icon": {
|
||||
"url": "ipfs://bafybeiady63oqduls2pm4aaykzjhahblagokhnpsc5qeq5dmkxqelh7i2i",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://arc-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-test-1.archiechain.io"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.archiechain.io"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "ARC",
|
||||
"symbol": "ARC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://archiechain.io/",
|
||||
"shortName": "TARC",
|
||||
"chainId": 1244,
|
||||
"networkId": 1244,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "archiescan",
|
||||
"url": "https://testnet.archiescan.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "arc-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "GIL Testnet",
|
||||
"chain": "GIL",
|
||||
"icon": {
|
||||
"url": "ipfs://QmeDXUAYgQxwaSJLsqWgTqnrJVwicgEyNf9199xAMyRkqA",
|
||||
"width": 243,
|
||||
"height": 243,
|
||||
"format": "svg"
|
||||
},
|
||||
"rpc": [
|
||||
"https://gil-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.giltestnet.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "GANG",
|
||||
"symbol": "GANG",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://gaussgang.com/",
|
||||
"shortName": "gil",
|
||||
"chainId": 1452,
|
||||
"networkId": 1452,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "GIL Explorer",
|
||||
"url": "https://explorer.giltestnet.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "gil-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Tenet Testnet",
|
||||
"title": "Tenet Testnet",
|
||||
"chain": "TENET",
|
||||
"icon": {
|
||||
"url": "ipfs://Qmc1gqjWTzNo4pyFSGtQuCu7kRSZZBUVybtTjHn2nNEEPA",
|
||||
"width": 640,
|
||||
"height": 640,
|
||||
"format": "svg"
|
||||
},
|
||||
"rpc": [
|
||||
"https://tenet-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.testnet.tenet.org"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.testnet.tenet.org"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "TENET",
|
||||
"symbol": "TENET",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://tenet.org/",
|
||||
"shortName": "tenet-testnet",
|
||||
"chainId": 155,
|
||||
"networkId": 155,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "TenetScan Testnet",
|
||||
"url": "https://testnet.tenetscan.io",
|
||||
"icon": {
|
||||
"url": "ipfs://Qmc1gqjWTzNo4pyFSGtQuCu7kRSZZBUVybtTjHn2nNEEPA",
|
||||
"width": 640,
|
||||
"height": 640,
|
||||
"format": "svg"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "tenet-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Tenet",
|
||||
"title": "Tenet Mainnet",
|
||||
"chain": "TENET",
|
||||
"icon": {
|
||||
"url": "ipfs://Qmc1gqjWTzNo4pyFSGtQuCu7kRSZZBUVybtTjHn2nNEEPA",
|
||||
"width": 640,
|
||||
"height": 640,
|
||||
"format": "svg"
|
||||
},
|
||||
"rpc": [
|
||||
"https://tenet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.tenet.org"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "TENET",
|
||||
"symbol": "TENET",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://tenet.org/",
|
||||
"shortName": "tenet",
|
||||
"chainId": 1559,
|
||||
"networkId": 1559,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "TenetScan Mainnet",
|
||||
"url": "https://tenetscan.io",
|
||||
"icon": {
|
||||
"url": "ipfs://Qmc1gqjWTzNo4pyFSGtQuCu7kRSZZBUVybtTjHn2nNEEPA",
|
||||
"width": 640,
|
||||
"height": 640,
|
||||
"format": "svg"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "tenet"
|
||||
} as const satisfies Chain;
|
||||
@@ -4,7 +4,7 @@ export default {
|
||||
"chain": "IRIShub",
|
||||
"rpc": [
|
||||
"https://irishub-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"http://34.80.202.172:8545"
|
||||
"https://evmrpc.nyancat.irisnet.org"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Gauss Mainnet",
|
||||
"chain": "Gauss",
|
||||
"icon": {
|
||||
"url": "ipfs://QmeDXUAYgQxwaSJLsqWgTqnrJVwicgEyNf9199xAMyRkqA",
|
||||
"width": 243,
|
||||
"height": 243,
|
||||
"format": "svg"
|
||||
},
|
||||
"rpc": [
|
||||
"https://gauss.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.gaussgang.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "GANG",
|
||||
"symbol": "GANG",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://gaussgang.com/",
|
||||
"shortName": "gauss",
|
||||
"chainId": 1777,
|
||||
"networkId": 1777,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Gauss Explorer",
|
||||
"url": "https://explorer.gaussgang.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "gauss"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Kerleano",
|
||||
"title": "Proof of Carbon Reduction testnet",
|
||||
"title": "Proof of Climate awaReness testnet",
|
||||
"chain": "CRC",
|
||||
"status": "active",
|
||||
"rpc": [
|
||||
@@ -13,7 +13,7 @@ export default {
|
||||
"https://github.com/ethereum-pocr/kerleano/blob/main/docs/faucet.md"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Carbon Reduction Coin",
|
||||
"name": "Climate awaReness Coin",
|
||||
"symbol": "CRC",
|
||||
"decimals": 18
|
||||
},
|
||||
@@ -21,10 +21,22 @@ export default {
|
||||
"shortName": "kerleano",
|
||||
"chainId": 1804,
|
||||
"networkId": 1804,
|
||||
"icon": {
|
||||
"url": "ipfs://QmRLwpq47tyEd3rfK4tKRhbTvyb3fc7PCutExnL1XAb37A",
|
||||
"width": 334,
|
||||
"height": 360,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Lite Explorer",
|
||||
"url": "https://ethereum-pocr.github.io/explorer/kerleano",
|
||||
"icon": {
|
||||
"url": "ipfs://QmRLwpq47tyEd3rfK4tKRhbTvyb3fc7PCutExnL1XAb37A",
|
||||
"width": 334,
|
||||
"height": 360,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "PoCRNet",
|
||||
"title": "Proof of Carbon Reduction mainnet",
|
||||
"title": "Proof of Climate awaReness mainnet",
|
||||
"chain": "CRC",
|
||||
"status": "active",
|
||||
"rpc": [
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Carbon Reduction Coin",
|
||||
"name": "Climate awaReness Coin",
|
||||
"symbol": "CRC",
|
||||
"decimals": 18
|
||||
},
|
||||
@@ -19,10 +19,22 @@ export default {
|
||||
"shortName": "pocrnet",
|
||||
"chainId": 2606,
|
||||
"networkId": 2606,
|
||||
"icon": {
|
||||
"url": "ipfs://QmRLwpq47tyEd3rfK4tKRhbTvyb3fc7PCutExnL1XAb37A",
|
||||
"width": 334,
|
||||
"height": 360,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Lite Explorer",
|
||||
"url": "https://ethereum-pocr.github.io/explorer/pocrnet",
|
||||
"icon": {
|
||||
"url": "ipfs://QmRLwpq47tyEd3rfK4tKRhbTvyb3fc7PCutExnL1XAb37A",
|
||||
"width": 334,
|
||||
"height": 360,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -21,7 +21,7 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Cronos Testnet Explorer",
|
||||
"url": "https://testnet.cronoscan.com",
|
||||
"url": "https://explorer.cronos.org/testnet",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -6,7 +6,9 @@ export default {
|
||||
"https://la-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.testnet.lachain.network"
|
||||
],
|
||||
"faucets": [],
|
||||
"faucets": [
|
||||
"https://faucet.lachain.network"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Test La Coin",
|
||||
"symbol": "TLA",
|
||||
@@ -21,7 +23,13 @@ export default {
|
||||
"shortName": "latestnet",
|
||||
"chainId": 418,
|
||||
"networkId": 418,
|
||||
"explorers": [],
|
||||
"explorers": [
|
||||
{
|
||||
"name": "LA Testnet Explorer",
|
||||
"url": "https://testexplorer.lachain.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "la-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -25,7 +25,7 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockexplorer",
|
||||
"url": "https://explorer.camino.foundation",
|
||||
"url": "https://suite.camino.network/explorer",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -20,11 +20,6 @@ export default {
|
||||
"chainId": 71401,
|
||||
"networkId": 71401,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "GWScout Explorer",
|
||||
"url": "https://gw-testnet-explorer.nervosdao.community",
|
||||
"standard": "none"
|
||||
},
|
||||
{
|
||||
"name": "GWScan Block Explorer",
|
||||
"url": "https://v1.testnet.gwscan.com",
|
||||
|
||||
@@ -17,11 +17,6 @@ export default {
|
||||
"chainId": 71402,
|
||||
"networkId": 71402,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "GWScout Explorer",
|
||||
"url": "https://gw-mainnet-explorer.nervosdao.community",
|
||||
"standard": "none"
|
||||
},
|
||||
{
|
||||
"name": "GWScan Block Explorer",
|
||||
"url": "https://v1.gwscan.com",
|
||||
|
||||
@@ -3,7 +3,7 @@ export default {
|
||||
"name": "TMY Chain",
|
||||
"chain": "TMY",
|
||||
"icon": {
|
||||
"url": "ipfs://QmXQu3ib9gTo23mdVgMqmrExga6SmAzDQTTctpVBNtfDu9",
|
||||
"url": "ipfs://Qmcd19ksUvNMD1XQFSC55jJhDPoF2zUzzV7woteFiugwBH",
|
||||
"width": 1024,
|
||||
"height": 1023,
|
||||
"format": "svg"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.13",
|
||||
"version": "0.1.15",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"browser": {
|
||||
|
||||
+1770
-2594
File diff suppressed because one or more lines are too long
@@ -1,5 +1,23 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.10.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`32908b76`](https://github.com/thirdweb-dev/js/commit/32908b76832c60e91a0a6e40dbdb1c8f56e9e5be), [`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff)]:
|
||||
- @thirdweb-dev/sdk@3.10.14
|
||||
- @thirdweb-dev/chains@0.1.15
|
||||
|
||||
## 0.10.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#964](https://github.com/thirdweb-dev/js/pull/964) [`89c821d4`](https://github.com/thirdweb-dev/js/commit/89c821d49e95e9319443acf25748ef614c1af396) Thanks [@nkrishang](https://github.com/nkrishang)! - Build deployArgs only on deploy --dynamic cmd
|
||||
|
||||
- Updated dependencies [[`5305b42d`](https://github.com/thirdweb-dev/js/commit/5305b42db554b69f903b3d95f3ba0eeddabd6114), [`eb521d24`](https://github.com/thirdweb-dev/js/commit/eb521d240ae7102d44fe2c5223b0a18d867e09ad), [`af4b5356`](https://github.com/thirdweb-dev/js/commit/af4b5356372ffa084c8d0e747d8def46c2ff892c), [`93bd5733`](https://github.com/thirdweb-dev/js/commit/93bd57337b7d2c2fcd252987d10df3206c839daf), [`a2df187b`](https://github.com/thirdweb-dev/js/commit/a2df187bc1867beb2e90853da70dac271f604f12), [`aa9b6acc`](https://github.com/thirdweb-dev/js/commit/aa9b6acc3f5a118c2b5fe9e46732e72c0fc69376)]:
|
||||
- @thirdweb-dev/chains@0.1.14
|
||||
- @thirdweb-dev/sdk@3.10.13
|
||||
|
||||
## 0.10.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -2,6 +2,7 @@ export const CREATE_MESSAGES = {
|
||||
typeOfProject: "What type of project do you want to create?",
|
||||
projectName: "What is your project named?",
|
||||
contractName: "What will be the name of your new smart contract?",
|
||||
extensionName: "What will be the name of your new extension?",
|
||||
chain: "Which blockchain do you want to use?",
|
||||
framework: "What framework do you want to use?",
|
||||
language: "What language do you want to use?",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.10.13",
|
||||
"version": "0.10.15",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -220,27 +220,29 @@ export async function processProject(
|
||||
const soliditySDKPackage = "@thirdweb-dev/contracts";
|
||||
let usesSoliditySDK = false;
|
||||
|
||||
if (selectedRouter.name === "thirdweb-router") {
|
||||
const deployArgs: TWRouterParams = {
|
||||
extensionRegistry: EXTENSION_REGISTRY_ADDRESS,
|
||||
extensionNames: selectedContracts.map((c) => c.name),
|
||||
};
|
||||
|
||||
const outputDeployArgs = JSON.stringify(deployArgs, undefined, 2);
|
||||
writeFileSync("./deployArgs.json", outputDeployArgs, "utf-8");
|
||||
info(
|
||||
"Deployment parameters written to deployArgs.json in your project directory",
|
||||
);
|
||||
} else {
|
||||
const deployArgs: RouterParams = await formatToExtensions(
|
||||
selectedContracts,
|
||||
);
|
||||
|
||||
const outputDeployArgs = JSON.stringify(deployArgs, undefined, 2);
|
||||
writeFileSync("./deployArgs.json", outputDeployArgs, "utf-8");
|
||||
info(
|
||||
"Deployment parameters written to deployArgs.json in your project directory",
|
||||
);
|
||||
if(options.dynamic) {
|
||||
if (selectedRouter.name === "thirdweb-router") {
|
||||
const deployArgs: TWRouterParams = {
|
||||
extensionRegistry: EXTENSION_REGISTRY_ADDRESS,
|
||||
extensionNames: selectedContracts.map((c) => c.name),
|
||||
};
|
||||
|
||||
const outputDeployArgs = JSON.stringify(deployArgs, undefined, 2);
|
||||
writeFileSync("./deployArgs.json", outputDeployArgs, "utf-8");
|
||||
info(
|
||||
"Deployment parameters written to deployArgs.json in your project directory",
|
||||
);
|
||||
} else {
|
||||
const deployArgs: RouterParams = await formatToExtensions(
|
||||
selectedContracts,
|
||||
);
|
||||
|
||||
const outputDeployArgs = JSON.stringify(deployArgs, undefined, 2);
|
||||
writeFileSync("./deployArgs.json", outputDeployArgs, "utf-8");
|
||||
info(
|
||||
"Deployment parameters written to deployArgs.json in your project directory",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const loader = spinner("Uploading contract data...");
|
||||
|
||||
@@ -321,7 +321,7 @@ export async function twCreate(
|
||||
const res = await prompts({
|
||||
type: "text",
|
||||
name: "path",
|
||||
message: CREATE_MESSAGES.contractName,
|
||||
message: projectType === "extension" ? CREATE_MESSAGES.extensionName : CREATE_MESSAGES.contractName,
|
||||
initial: defaultName,
|
||||
validate: (name: string) => {
|
||||
const isValid = /(^[a-z0-9A-Z]+$)|(^[a-z0-9A-Z]+\.sol$)/.test(name);
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 3.11.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`32908b76`](https://github.com/thirdweb-dev/js/commit/32908b76832c60e91a0a6e40dbdb1c8f56e9e5be), [`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff), [`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff)]:
|
||||
- @thirdweb-dev/sdk@3.10.14
|
||||
- @thirdweb-dev/wallets@0.2.19
|
||||
- @thirdweb-dev/chains@0.1.15
|
||||
|
||||
## 3.11.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#954](https://github.com/thirdweb-dev/js/pull/954) [`5305b42d`](https://github.com/thirdweb-dev/js/commit/5305b42db554b69f903b3d95f3ba0eeddabd6114) Thanks [@jarrodwatts](https://github.com/jarrodwatts)! - useContract now types correctly for thirdweb generate
|
||||
|
||||
- [#966](https://github.com/thirdweb-dev/js/pull/966) [`87021cee`](https://github.com/thirdweb-dev/js/commit/87021cee45e81a6504e4e2279e6d2abb10cab8ec) Thanks [@MananTank](https://github.com/MananTank)! - Connect Wallet UI improvements
|
||||
|
||||
- Allow from EOA => smart wallet / safe
|
||||
- Add warning to backup wallet for guest wallet
|
||||
- Show "Guest" instead of address for guest wallet
|
||||
|
||||
- [#977](https://github.com/thirdweb-dev/js/pull/977) [`93bd5733`](https://github.com/thirdweb-dev/js/commit/93bd57337b7d2c2fcd252987d10df3206c839daf) Thanks [@MananTank](https://github.com/MananTank)! - Fix Connect Wallet Open/Close issues
|
||||
|
||||
- Updated dependencies [[`93bdec06`](https://github.com/thirdweb-dev/js/commit/93bdec061dc05ab133e79f5f739dcae9b5393f53), [`ea0f9479`](https://github.com/thirdweb-dev/js/commit/ea0f9479a38d442201e367fce1234c130228fde6), [`05ebbc15`](https://github.com/thirdweb-dev/js/commit/05ebbc15a012855735fba2aa93887b88e14295d1), [`5305b42d`](https://github.com/thirdweb-dev/js/commit/5305b42db554b69f903b3d95f3ba0eeddabd6114), [`4ca557ae`](https://github.com/thirdweb-dev/js/commit/4ca557ae4ab225e39decc3b7a01a04c0d8e464c7), [`7d7685e3`](https://github.com/thirdweb-dev/js/commit/7d7685e3fab5780b3c1d26b8ef431b96f8486972), [`eb521d24`](https://github.com/thirdweb-dev/js/commit/eb521d240ae7102d44fe2c5223b0a18d867e09ad), [`af4b5356`](https://github.com/thirdweb-dev/js/commit/af4b5356372ffa084c8d0e747d8def46c2ff892c), [`93bd5733`](https://github.com/thirdweb-dev/js/commit/93bd57337b7d2c2fcd252987d10df3206c839daf), [`a2df187b`](https://github.com/thirdweb-dev/js/commit/a2df187bc1867beb2e90853da70dac271f604f12), [`aa9b6acc`](https://github.com/thirdweb-dev/js/commit/aa9b6acc3f5a118c2b5fe9e46732e72c0fc69376)]:
|
||||
- @thirdweb-dev/wallets@0.2.18
|
||||
- @thirdweb-dev/chains@0.1.14
|
||||
- @thirdweb-dev/sdk@3.10.13
|
||||
|
||||
## 3.11.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "3.11.9",
|
||||
"version": "3.11.11",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -77,12 +77,15 @@
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@solana/wallet-adapter-react": "^0.15.19",
|
||||
"@solana/web3.js": "^1.62.0",
|
||||
"@thirdweb-dev/auth": "workspace:*",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@types/mime": "3.0.0",
|
||||
"@types/react": "^18.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"eslint": "^8.21.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-inclusive-language": "^2.2.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
@@ -90,17 +93,15 @@
|
||||
"ethers": "^5.7.2",
|
||||
"prettier": "^2.7.1",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.7.4",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@thirdweb-dev/auth": "workspace:*"
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/react-query": "^4.0.10",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/wallets": "workspace:*",
|
||||
"@thirdweb-dev/storage": "workspace:*",
|
||||
"@thirdweb-dev/generated-abis": "workspace:^",
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
"@thirdweb-dev/storage": "workspace:*",
|
||||
"@thirdweb-dev/wallets": "workspace:*",
|
||||
"mime": "3.0.0",
|
||||
"tiny-invariant": "^1.2.0"
|
||||
},
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ThirdwebAuthProvider } from "../../evm/contexts/thirdweb-auth";
|
||||
import { useUpdateChainsWithApiKeys } from "../../evm/hooks/chain-hooks";
|
||||
import { ThirdwebSDKProvider } from "../../evm/providers/thirdweb-sdk-provider";
|
||||
import { ThirdwebSDKProviderProps } from "../../evm/providers/types";
|
||||
import { Wallet } from "../types/wallet";
|
||||
import { ConfiguredWallet } from "../types/wallet";
|
||||
import { ThirdwebThemeContext } from "./theme-context";
|
||||
import {
|
||||
ThirdwebWalletProvider,
|
||||
@@ -40,7 +40,7 @@ export interface ThirdwebProviderCoreProps<TChains extends Chain[]>
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
supportedWallets: Wallet[];
|
||||
supportedWallets: ConfiguredWallet[];
|
||||
|
||||
/**
|
||||
* Metadata to pass to wallet connect and walletlink wallet connect. (Used to show *which* dApp is being connected to in mobile wallets that support it)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DAppMetaData } from "../types/dAppMeta";
|
||||
import type { Wallet, WalletInstance } from "../types/wallet";
|
||||
import type { ConfiguredWallet, WalletInstance } from "../types/wallet";
|
||||
import { ThirdwebThemeContext } from "./theme-context";
|
||||
import { Chain } from "@thirdweb-dev/chains";
|
||||
import {
|
||||
@@ -44,21 +44,30 @@ type ConnectionStatus = "unknown" | "connected" | "disconnected" | "connecting";
|
||||
type ConnectFnArgs<I extends WalletInstance> =
|
||||
// if second argument is optional
|
||||
undefined extends WalletConnectParams<I>
|
||||
? [wallet: Wallet<I>, connectParams?: NonNullable<WalletConnectParams<I>>]
|
||||
? [
|
||||
wallet: ConfiguredWallet<I>,
|
||||
connectParams?: NonNullable<WalletConnectParams<I>>,
|
||||
]
|
||||
: // if second argument is required
|
||||
[wallet: Wallet<I>, connectParams: NonNullable<WalletConnectParams<I>>];
|
||||
[
|
||||
wallet: ConfiguredWallet<I>,
|
||||
connectParams: NonNullable<WalletConnectParams<I>>,
|
||||
];
|
||||
|
||||
type ThirdwebWalletContextData = {
|
||||
wallets: Wallet[];
|
||||
wallets: ConfiguredWallet[];
|
||||
signer?: Signer;
|
||||
activeWallet?: WalletInstance;
|
||||
activeWalletConfig?: ConfiguredWallet;
|
||||
connect: <I extends WalletInstance>(
|
||||
...args: ConnectFnArgs<I>
|
||||
) => Promise<void>;
|
||||
disconnect: () => Promise<void>;
|
||||
connectionStatus: ConnectionStatus;
|
||||
setConnectionStatus: (status: ConnectionStatus) => void;
|
||||
createWalletInstance: <I extends WalletInstance>(Wallet: Wallet<I>) => I;
|
||||
createWalletInstance: <I extends WalletInstance>(
|
||||
Wallet: ConfiguredWallet<I>,
|
||||
) => I;
|
||||
createWalletStorage: CreateAsyncStorage;
|
||||
switchChain: (chain: number) => Promise<void>;
|
||||
chainToConnect?: Chain;
|
||||
@@ -76,7 +85,7 @@ const ThirdwebWalletContext = createContext<
|
||||
export function ThirdwebWalletProvider(
|
||||
props: PropsWithChildren<{
|
||||
activeChain: Chain;
|
||||
supportedWallets: Wallet[];
|
||||
supportedWallets: ConfiguredWallet[];
|
||||
shouldAutoConnect?: boolean;
|
||||
createWalletStorage: CreateAsyncStorage;
|
||||
dAppMeta?: DAppMetaData;
|
||||
@@ -92,6 +101,10 @@ export function ThirdwebWalletProvider(
|
||||
WalletInstance | undefined
|
||||
>();
|
||||
|
||||
const [activeWalletConfig, setActiveConfig] = useState<
|
||||
ConfiguredWallet | undefined
|
||||
>();
|
||||
|
||||
if (!lastConnectedWalletStorage) {
|
||||
lastConnectedWalletStorage =
|
||||
props.createWalletStorage("coordinatorStorage");
|
||||
@@ -117,7 +130,7 @@ export function ThirdwebWalletProvider(
|
||||
}, [props.chains, props.dAppMeta, props.activeChain, theme]);
|
||||
|
||||
const createWalletInstance = useCallback(
|
||||
<I extends WalletInstance>(wallet: Wallet<I>): I => {
|
||||
<I extends WalletInstance>(wallet: ConfiguredWallet<I>): I => {
|
||||
return wallet.create(walletParams);
|
||||
},
|
||||
[walletParams],
|
||||
@@ -130,16 +143,38 @@ export function ThirdwebWalletProvider(
|
||||
}
|
||||
}, [activeWallet, props.chains]);
|
||||
|
||||
const getWalletConfig = useCallback(
|
||||
(wallet: WalletInstance) => {
|
||||
const id = wallet.walletId;
|
||||
|
||||
// find in personal wallets if wrapper wallet
|
||||
if (
|
||||
activeWalletConfig &&
|
||||
"config" in activeWalletConfig &&
|
||||
(activeWalletConfig.config as any).personalWallets
|
||||
) {
|
||||
// find in personal wallets
|
||||
return (activeWalletConfig.config as any).personalWallets.find(
|
||||
(w: ConfiguredWallet) => w.id === id,
|
||||
);
|
||||
}
|
||||
|
||||
return props.supportedWallets.find((w) => w.id === id);
|
||||
},
|
||||
[activeWalletConfig, props.supportedWallets],
|
||||
);
|
||||
|
||||
const handleWalletConnect = useCallback(
|
||||
async (
|
||||
wallet: WalletInstance,
|
||||
connectParams?: ConnectParams<Record<string, any>>,
|
||||
isAutoConnect = false,
|
||||
) => {
|
||||
setActiveWallet(wallet);
|
||||
setActiveConfig(getWalletConfig(wallet));
|
||||
setConnectionStatus("connected");
|
||||
const _signer = await wallet.getSigner();
|
||||
setSigner(_signer);
|
||||
setActiveWallet(wallet);
|
||||
setConnectionStatus("connected");
|
||||
|
||||
// it autoconnected, then the details is already saved in storage, no need to store again
|
||||
if (isAutoConnect) {
|
||||
@@ -169,7 +204,7 @@ export function ThirdwebWalletProvider(
|
||||
saveLastConnectedWalletInfo(walletInfo);
|
||||
}
|
||||
},
|
||||
[],
|
||||
[getWalletConfig],
|
||||
);
|
||||
|
||||
const storeLastActiveChainId = useCallback(async (chainId: number) => {
|
||||
@@ -256,7 +291,7 @@ export function ThirdwebWalletProvider(
|
||||
|
||||
if (personalWalletInfo) {
|
||||
type Config = {
|
||||
personalWallets: Wallet[];
|
||||
personalWallets: ConfiguredWallet[];
|
||||
};
|
||||
|
||||
const personalWallets =
|
||||
@@ -349,6 +384,7 @@ export function ThirdwebWalletProvider(
|
||||
setConnectionStatus("disconnected");
|
||||
setSigner(undefined);
|
||||
setActiveWallet(undefined);
|
||||
setActiveConfig(undefined);
|
||||
}, []);
|
||||
|
||||
const disconnectWallet = useCallback(async () => {
|
||||
@@ -358,11 +394,11 @@ export function ThirdwebWalletProvider(
|
||||
return;
|
||||
}
|
||||
|
||||
const personalWallet = activeWallet.getPersonalWallet();
|
||||
await activeWallet.disconnect();
|
||||
if (activeWallet.getPersonalWallet()) {
|
||||
await (
|
||||
activeWallet.getPersonalWallet() as AbstractClientWallet
|
||||
)?.disconnect();
|
||||
|
||||
if (personalWallet) {
|
||||
await (personalWallet as AbstractClientWallet)?.disconnect();
|
||||
}
|
||||
|
||||
onWalletDisconnect();
|
||||
@@ -401,6 +437,7 @@ export function ThirdwebWalletProvider(
|
||||
connect: connectWallet,
|
||||
signer,
|
||||
activeWallet,
|
||||
activeWalletConfig,
|
||||
connectionStatus,
|
||||
setConnectionStatus,
|
||||
createWalletInstance: createWalletInstance,
|
||||
|
||||
@@ -23,15 +23,42 @@ export type WalletClass<I extends WalletInstance = WalletInstance> = {
|
||||
meta: (typeof AbstractClientWallet)["meta"];
|
||||
};
|
||||
|
||||
export type Wallet<
|
||||
export type ConfiguredWallet<
|
||||
I extends WalletInstance = WalletInstance,
|
||||
Config extends Record<string, any> | undefined = undefined,
|
||||
> = {
|
||||
id: string;
|
||||
meta: (typeof AbstractClientWallet)["meta"];
|
||||
create: (options: WalletOptions) => I;
|
||||
connectUI?: React.FC<ConnectUIProps>;
|
||||
isInstalled?: () => boolean;
|
||||
} & (Config extends undefined
|
||||
? {}
|
||||
: {
|
||||
config: Config;
|
||||
});
|
||||
|
||||
export type ConnectUIProps = {
|
||||
/**
|
||||
* close the connect wallet modal
|
||||
* @param reset reset Connect Wallet Modal to initial state, so that if it's opened again, it will start from the wallet-selection screen
|
||||
*
|
||||
* default: `true`
|
||||
*/
|
||||
close: (reset?: boolean) => void;
|
||||
|
||||
/**
|
||||
* indicates whether the connect wallet modal is open or not
|
||||
*/
|
||||
isOpen: boolean;
|
||||
|
||||
/**
|
||||
* open the connect wallet modal
|
||||
*/
|
||||
open: () => void;
|
||||
|
||||
/**
|
||||
* go back to the wallet selector screen in connect wallet modal
|
||||
*/
|
||||
goBack: () => void;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
useQueryClient,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
import { getCachedAbiForContract } from "@thirdweb-dev/sdk";
|
||||
import { getCachedAbiForContract, TransactionResult } from "@thirdweb-dev/sdk";
|
||||
import type {
|
||||
Abi,
|
||||
CommonContractSchemaInput,
|
||||
@@ -32,10 +32,12 @@ import type {
|
||||
SUPPORTED_CHAIN_ID,
|
||||
ThirdwebSDK,
|
||||
ValidContractInstance,
|
||||
BaseContractForAddress,
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import type { CallOverrides, ContractInterface, providers } from "ethers";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import invariant from "tiny-invariant";
|
||||
import { ContractAddress as GeneratedContractAddress } from "@thirdweb-dev/generated-abis";
|
||||
|
||||
// contract type
|
||||
async function fetchContractType(
|
||||
@@ -150,6 +152,16 @@ export type UseContractResult<
|
||||
contract: TContract | undefined;
|
||||
};
|
||||
|
||||
export function useContract<
|
||||
TContractAddress extends ContractAddress | GeneratedContractAddress,
|
||||
>(
|
||||
contractAddress: RequiredParam<TContractAddress>,
|
||||
): UseContractResult<
|
||||
TContractAddress extends GeneratedContractAddress
|
||||
? SmartContract<BaseContractForAddress<TContractAddress>>
|
||||
: SmartContract
|
||||
>;
|
||||
|
||||
/**
|
||||
* Use this resolve a contract address to a smart contract instance.
|
||||
*
|
||||
@@ -514,12 +526,42 @@ export function useContractEvents(
|
||||
* @beta
|
||||
*/
|
||||
export function useContractRead<
|
||||
TContractInstance extends ValidContractInstance,
|
||||
TFunctionName extends Parameters<TContractInstance["call"]>[0],
|
||||
TContractAddress extends GeneratedContractAddress | ContractAddress,
|
||||
TContract extends TContractAddress extends GeneratedContractAddress
|
||||
? BaseContractForAddress<TContractAddress>
|
||||
: ValidContractInstance,
|
||||
TContractInstance extends TContractAddress extends GeneratedContractAddress
|
||||
? SmartContract<BaseContractForAddress<TContractAddress>>
|
||||
: ValidContractInstance,
|
||||
TFunctionName extends TContractAddress extends GeneratedContractAddress
|
||||
? TContract extends BaseContractForAddress<TContractAddress>
|
||||
? keyof TContract["functions"]
|
||||
: never
|
||||
: Parameters<TContractInstance["call"]>[0],
|
||||
TArgs extends TContractAddress extends GeneratedContractAddress
|
||||
? TContract extends BaseContractForAddress<TContractAddress>
|
||||
? TFunctionName extends keyof TContract["functions"]
|
||||
? Parameters<TContract["functions"][TFunctionName]>
|
||||
: unknown[]
|
||||
: unknown[]
|
||||
: unknown[],
|
||||
TReturnType extends TContractAddress extends GeneratedContractAddress
|
||||
? TContract extends BaseContractForAddress<TContractAddress>
|
||||
? TFunctionName extends keyof TContract["functions"]
|
||||
? ReturnType<TContract["functions"][TFunctionName]>
|
||||
: any
|
||||
: any
|
||||
: any,
|
||||
>(
|
||||
contract: RequiredParam<TContractInstance>,
|
||||
functionName: RequiredParam<TFunctionName | (string & {})>,
|
||||
args?: unknown[],
|
||||
contract: TContractInstance extends ValidContractInstance
|
||||
? RequiredParam<TContractInstance> | undefined
|
||||
: TContractAddress extends GeneratedContractAddress
|
||||
?
|
||||
| RequiredParam<SmartContract<BaseContractForAddress<TContractAddress>>>
|
||||
| undefined
|
||||
: RequiredParam<SmartContract> | undefined,
|
||||
functionName: RequiredParam<TFunctionName & string>,
|
||||
args?: TArgs,
|
||||
overrides?: CallOverrides,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -530,10 +572,10 @@ export function useContractRead<
|
||||
requiredParamInvariant(functionName, "function name must be provided");
|
||||
return (
|
||||
contract.call as (
|
||||
functionName: string,
|
||||
args?: unknown[],
|
||||
functionName: TFunctionName,
|
||||
args?: TArgs,
|
||||
overrides?: CallOverrides,
|
||||
) => Promise<any>
|
||||
) => Promise<TReturnType>
|
||||
)(functionName, args, overrides);
|
||||
},
|
||||
{
|
||||
@@ -561,11 +603,34 @@ export function useContractRead<
|
||||
* @beta
|
||||
*/
|
||||
export function useContractWrite<
|
||||
TContractInstance extends ValidContractInstance,
|
||||
TFunctionName extends Parameters<TContractInstance["call"]>[0],
|
||||
TContractAddress extends GeneratedContractAddress | ContractAddress,
|
||||
TContract extends TContractAddress extends GeneratedContractAddress
|
||||
? BaseContractForAddress<TContractAddress>
|
||||
: ValidContractInstance,
|
||||
TContractInstance extends TContractAddress extends GeneratedContractAddress
|
||||
? SmartContract<BaseContractForAddress<TContractAddress>>
|
||||
: ValidContractInstance,
|
||||
TFunctionName extends TContractAddress extends GeneratedContractAddress
|
||||
? TContract extends BaseContractForAddress<TContractAddress>
|
||||
? keyof TContract["functions"]
|
||||
: never
|
||||
: Parameters<TContractInstance["call"]>[0],
|
||||
TArgs extends TContractAddress extends GeneratedContractAddress
|
||||
? TContract extends BaseContractForAddress<TContractAddress>
|
||||
? TFunctionName extends keyof TContract["functions"]
|
||||
? Parameters<TContract["functions"][TFunctionName]>
|
||||
: unknown[]
|
||||
: unknown[]
|
||||
: any[],
|
||||
>(
|
||||
contract: RequiredParam<TContractInstance>,
|
||||
functionName: RequiredParam<TFunctionName | (string & {})>,
|
||||
contract: TContractInstance extends ValidContractInstance
|
||||
? RequiredParam<TContractInstance> | undefined
|
||||
: TContractAddress extends GeneratedContractAddress
|
||||
?
|
||||
| RequiredParam<SmartContract<BaseContractForAddress<TContractAddress>>>
|
||||
| undefined
|
||||
: RequiredParam<SmartContract> | undefined,
|
||||
functionName: RequiredParam<TFunctionName & string>,
|
||||
) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -576,7 +641,7 @@ export function useContractWrite<
|
||||
args,
|
||||
overrides,
|
||||
}: {
|
||||
args?: unknown[];
|
||||
args?: TArgs;
|
||||
overrides?: CallOverrides;
|
||||
}) => {
|
||||
requiredParamInvariant(contract, "contract must be defined");
|
||||
@@ -584,10 +649,10 @@ export function useContractWrite<
|
||||
|
||||
return (
|
||||
contract.call as (
|
||||
functionName: string,
|
||||
args?: unknown[],
|
||||
functionName: TFunctionName,
|
||||
args?: TArgs,
|
||||
overrides?: CallOverrides,
|
||||
) => Promise<any>
|
||||
) => Promise<TransactionResult>
|
||||
)(functionName, args, overrides);
|
||||
},
|
||||
{
|
||||
|
||||
@@ -34,7 +34,8 @@ export {
|
||||
export { shouldNeverPersistQuery } from "../core/query-utils/query-key";
|
||||
export type { RequiredParam } from "../core/query-utils/required-param";
|
||||
export type {
|
||||
Wallet,
|
||||
ConfiguredWallet,
|
||||
ConnectUIProps,
|
||||
WalletClass,
|
||||
WalletInstance,
|
||||
ExtraCoreWalletOptions,
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.2.11
|
||||
|
||||
## 0.2.10
|
||||
|
||||
## 0.2.9
|
||||
|
||||
## 0.2.8
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.2.9",
|
||||
"version": "0.2.11",
|
||||
"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,114 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.2.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`32908b76`](https://github.com/thirdweb-dev/js/commit/32908b76832c60e91a0a6e40dbdb1c8f56e9e5be), [`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff), [`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff)]:
|
||||
- @thirdweb-dev/sdk@3.10.14
|
||||
- @thirdweb-dev/wallets@0.2.19
|
||||
- @thirdweb-dev/chains@0.1.15
|
||||
- @thirdweb-dev/react-core@3.11.11
|
||||
|
||||
## 0.2.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#981](https://github.com/thirdweb-dev/js/pull/981) [`ea0f9479`](https://github.com/thirdweb-dev/js/commit/ea0f9479a38d442201e367fce1234c130228fde6) Thanks [@iketw](https://github.com/iketw)! - ## [ReactNative] Allow custom wallets be added to the ConnectWallet button modal
|
||||
|
||||
With this new API you can build your own wallet and wallet UI and integrate it into our ConnectWallet modal:
|
||||
|
||||
```
|
||||
import type { ConfiguredWallet, ConnectUIProps } from '@thirdweb-dev/react-native';
|
||||
import { createAsyncLocalStorage, ConnectUIProps } from '@thirdweb-dev/react-native';
|
||||
import { WalletOptions } from '@thirdweb-dev/wallets';
|
||||
|
||||
const WALLET_ID = "my-wallet-id";
|
||||
|
||||
export const myWallet = (): ConfiguredWallet => {
|
||||
const asyncStorage = createAsyncLocalStorage(WALLET_ID);
|
||||
const configuredWallet = {
|
||||
id: WALLET_ID,
|
||||
meta: {
|
||||
id: WALLET_ID,
|
||||
name: "My Custom Wallet", // This will be displayed in the connect wallet modal
|
||||
iconURL: "ipfs or https url to an image or svg" // This will be used to fetch the icon to show in the connect wallet modal
|
||||
},
|
||||
create: (options: WalletOptions) =>
|
||||
new MyWallet({
|
||||
...options,
|
||||
walletStorage: asyncStorage,
|
||||
}),
|
||||
connectUI(props: ConnectUIProps) {
|
||||
return <MyWalletUI {...props} />; // This will show up in the modal after the user selects your wallet
|
||||
},
|
||||
};
|
||||
|
||||
return configuredWallet;
|
||||
};
|
||||
```
|
||||
|
||||
You can then add the wallet to your `supportedWallets` in the `ThirdwebProvider`:
|
||||
|
||||
```
|
||||
import { Goerli } from '@thirdweb-dev/chains';
|
||||
import {
|
||||
ThirdwebProvider,
|
||||
metamaskWallet,
|
||||
} from '@thirdweb-dev/react-native';
|
||||
|
||||
const activeChain = Goerli;
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<ThirdwebProvider
|
||||
activeChain={activeChain}
|
||||
supportedChains={[activeChain]}
|
||||
supportedWallets={[
|
||||
myWallet(),
|
||||
metamaskWallet(),
|
||||
]}>
|
||||
<AppInner />
|
||||
</ThirdwebProvider>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
This new version exposes some utility functions:
|
||||
|
||||
1. `formatWalletConnectDisplayUri`
|
||||
|
||||
Formats the wallet connect `wc://` url for usage with custom wallet links
|
||||
|
||||
2. `shortenWalletAddress`
|
||||
|
||||
Shortens a wallet address for display purposes
|
||||
|
||||
3. `createAsyncLocalStorage` and `createSecureStorage`
|
||||
|
||||
You can use these methods to get wallet compatible storage types.
|
||||
|
||||
- `createAsyncLocalStorage` uses MMKV in the background
|
||||
- `createSecureStorage` uses Expo SecureStore in the background
|
||||
|
||||
- [#969](https://github.com/thirdweb-dev/js/pull/969) [`12ad7fea`](https://github.com/thirdweb-dev/js/commit/12ad7fead2059005684c0762cbe951d23b509151) Thanks [@iketw](https://github.com/iketw)! - [ReactNative] Remove gap prop for backward compat
|
||||
|
||||
- [#966](https://github.com/thirdweb-dev/js/pull/966) [`87021cee`](https://github.com/thirdweb-dev/js/commit/87021cee45e81a6504e4e2279e6d2abb10cab8ec) Thanks [@MananTank](https://github.com/MananTank)! - Connect Wallet UI improvements
|
||||
|
||||
- Allow from EOA => smart wallet / safe
|
||||
- Add warning to backup wallet for guest wallet
|
||||
- Show "Guest" instead of address for guest wallet
|
||||
|
||||
- [#977](https://github.com/thirdweb-dev/js/pull/977) [`93bd5733`](https://github.com/thirdweb-dev/js/commit/93bd57337b7d2c2fcd252987d10df3206c839daf) Thanks [@MananTank](https://github.com/MananTank)! - Fix Connect Wallet Open/Close issues
|
||||
|
||||
- [#968](https://github.com/thirdweb-dev/js/pull/968) [`9640e073`](https://github.com/thirdweb-dev/js/commit/9640e0731f812ab9beaaa0cc67b1c5b61725c460) Thanks [@iketw](https://github.com/iketw)! - [ReactNative] Add guest mode warnings
|
||||
|
||||
- Updated dependencies [[`93bdec06`](https://github.com/thirdweb-dev/js/commit/93bdec061dc05ab133e79f5f739dcae9b5393f53), [`ea0f9479`](https://github.com/thirdweb-dev/js/commit/ea0f9479a38d442201e367fce1234c130228fde6), [`05ebbc15`](https://github.com/thirdweb-dev/js/commit/05ebbc15a012855735fba2aa93887b88e14295d1), [`5305b42d`](https://github.com/thirdweb-dev/js/commit/5305b42db554b69f903b3d95f3ba0eeddabd6114), [`4ca557ae`](https://github.com/thirdweb-dev/js/commit/4ca557ae4ab225e39decc3b7a01a04c0d8e464c7), [`7d7685e3`](https://github.com/thirdweb-dev/js/commit/7d7685e3fab5780b3c1d26b8ef431b96f8486972), [`87021cee`](https://github.com/thirdweb-dev/js/commit/87021cee45e81a6504e4e2279e6d2abb10cab8ec), [`eb521d24`](https://github.com/thirdweb-dev/js/commit/eb521d240ae7102d44fe2c5223b0a18d867e09ad), [`af4b5356`](https://github.com/thirdweb-dev/js/commit/af4b5356372ffa084c8d0e747d8def46c2ff892c), [`93bd5733`](https://github.com/thirdweb-dev/js/commit/93bd57337b7d2c2fcd252987d10df3206c839daf), [`a2df187b`](https://github.com/thirdweb-dev/js/commit/a2df187bc1867beb2e90853da70dac271f604f12), [`aa9b6acc`](https://github.com/thirdweb-dev/js/commit/aa9b6acc3f5a118c2b5fe9e46732e72c0fc69376)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 0.2.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.2.9",
|
||||
"version": "0.2.11",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -45,6 +45,12 @@ export class noopStorage implements IAsyncStorage {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance of AsyncLocalStorage
|
||||
*
|
||||
* @param name Name to namespace the storage with
|
||||
* @returns A new instance of AsyncLocalStorage
|
||||
*/
|
||||
export function createAsyncLocalStorage(name: string) {
|
||||
return new AsyncLocalStorage(name);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ISecureStorage } from '@thirdweb-dev/react-core';
|
||||
import * as SecureStore from 'expo-secure-store';
|
||||
import { ISecureStorage } from "@thirdweb-dev/react-core";
|
||||
import * as SecureStore from "expo-secure-store";
|
||||
|
||||
const PREFIX = "__tw__";
|
||||
|
||||
@@ -17,7 +17,10 @@ export class SecureStorage implements ISecureStorage {
|
||||
}
|
||||
|
||||
setItem(key: string, value: string) {
|
||||
return this.asyncStorage.setItemAsync(`${PREFIX}_${this.name}_${key}`, value);
|
||||
return this.asyncStorage.setItemAsync(
|
||||
`${PREFIX}_${this.name}_${key}`,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
removeItem(key: string) {
|
||||
@@ -25,6 +28,12 @@ export class SecureStorage implements ISecureStorage {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance of SecureStorage implemented by Expo SecureStore
|
||||
*
|
||||
* @param name Name to namespace the storage with
|
||||
* @returns A new instance of SecureStorage
|
||||
*/
|
||||
export function createSecureStorage(name: string) {
|
||||
return new SecureStorage(name);
|
||||
}
|
||||
|
||||
+14
-15
@@ -11,14 +11,12 @@ import { WalletDetailsModalHeader } from "./WalletDetailsModalHeader";
|
||||
import { useWallet, useBalance, useDisconnect } from "@thirdweb-dev/react-core";
|
||||
import { useActiveChain } from "@thirdweb-dev/react-core/evm";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Linking, StyleSheet, View } from "react-native";
|
||||
import { StyleSheet, View } from "react-native";
|
||||
import { ExportLocalWalletModal } from "./ExportLocalWalletModal";
|
||||
import { Toast } from "../base/Toast";
|
||||
import { SmartWallet, walletIds } from "@thirdweb-dev/wallets";
|
||||
import { LocalWallet, SmartWallet, walletIds } from "@thirdweb-dev/wallets";
|
||||
import { SmartWalletAdditionalActions } from "./SmartWalletAdditionalActions";
|
||||
import { useSmartWallet } from "../../providers/context-provider";
|
||||
import { Link } from "../base/Link";
|
||||
import Box from "../base/Box";
|
||||
|
||||
export type ConnectWalletDetailsProps = {
|
||||
address: string;
|
||||
@@ -112,20 +110,17 @@ export const ConnectWalletDetails = ({
|
||||
>
|
||||
<PocketWalletIcon size={16} />
|
||||
<View style={styles.exportWalletInfo}>
|
||||
<Text variant="bodySmall">Export wallet</Text>
|
||||
<Text variant="bodySmall">Backup wallet</Text>
|
||||
</View>
|
||||
</BaseButton>
|
||||
|
||||
<Box flexDirection="row" alignItems="center" justifyContent="center">
|
||||
<Link
|
||||
text="Learn more"
|
||||
onPress={() =>
|
||||
Linking.openURL(
|
||||
"https://portal.thirdweb.com/wallet/local-wallet",
|
||||
)
|
||||
{activeWallet?.walletId === LocalWallet.id ? (
|
||||
<Text variant="error">
|
||||
{
|
||||
"This is a temporary guest wallet. Download a backup if you don't want to lose access to it."
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
</Text>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -179,7 +174,11 @@ export const ConnectWalletDetails = ({
|
||||
{balanceQuery.data?.displayValue.slice(0, 5)}{" "}
|
||||
{balanceQuery.data?.symbol}
|
||||
</Text>
|
||||
<Address variant="bodySmallSecondary" address={address} />
|
||||
{activeWallet?.walletId === LocalWallet.id ? (
|
||||
<Text variant="error">Guest</Text>
|
||||
) : (
|
||||
<Address variant="bodySmallSecondary" address={address} />
|
||||
)}
|
||||
</View>
|
||||
<WalletIcon size={32} iconUri={activeWallet?.getMeta().iconURL || ""} />
|
||||
</BaseButton>
|
||||
|
||||
+1
@@ -90,6 +90,7 @@ export const ExportLocalWalletModal = ({
|
||||
encoding: FileSystem.EncodingType.UTF8,
|
||||
},
|
||||
);
|
||||
setIsExporting(false);
|
||||
} catch (e) {
|
||||
console.error("Error writing the file", e);
|
||||
setError("Error writing the file. Please try again.");
|
||||
|
||||
+31
-26
@@ -41,12 +41,12 @@ export const SmartWalletAdditionalActions = ({
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (smartWallet) {
|
||||
if (smartWallet && !smartWalletAddress) {
|
||||
const addr = await smartWallet.getAddress();
|
||||
setSmartWalletAddress(addr);
|
||||
}
|
||||
})();
|
||||
}, [smartWallet]);
|
||||
}, [smartWallet, smartWalletAddress]);
|
||||
|
||||
const onWalletPress = () => {
|
||||
if (!wallet) {
|
||||
@@ -76,14 +76,12 @@ export const SmartWalletAdditionalActions = ({
|
||||
<WalletIcon size={32} iconUri={wallet?.getMeta().iconURL || ""} />
|
||||
) : null}
|
||||
<View style={styles.walletInfo}>
|
||||
{personalWalletAddress ? (
|
||||
<Address
|
||||
variant="bodyLarge"
|
||||
address={
|
||||
showSmartWallet ? smartWalletAddress : personalWalletAddress
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
<Address
|
||||
variant="bodyLarge"
|
||||
address={
|
||||
showSmartWallet ? smartWalletAddress : personalWalletAddress
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
<RightArrowIcon
|
||||
@@ -94,22 +92,29 @@ export const SmartWalletAdditionalActions = ({
|
||||
</BaseButton>
|
||||
{wallet?.walletId === LocalWallet.id ||
|
||||
activeWallet?.walletId === LocalWallet.id ? (
|
||||
<BaseButton
|
||||
backgroundColor="background"
|
||||
borderColor="border"
|
||||
mb="sm"
|
||||
style={styles.exportWallet}
|
||||
onPress={onExportPress}
|
||||
>
|
||||
<PocketWalletIcon size={16} />
|
||||
<View style={styles.exportWalletInfo}>
|
||||
<Text variant="bodySmall">
|
||||
{wallet?.walletId === LocalWallet.id
|
||||
? "Export personal wallet"
|
||||
: "Export wallet"}
|
||||
</Text>
|
||||
</View>
|
||||
</BaseButton>
|
||||
<>
|
||||
<BaseButton
|
||||
backgroundColor="background"
|
||||
borderColor="border"
|
||||
mb="sm"
|
||||
style={styles.exportWallet}
|
||||
onPress={onExportPress}
|
||||
>
|
||||
<PocketWalletIcon size={16} />
|
||||
<View style={styles.exportWalletInfo}>
|
||||
<Text variant="bodySmall">
|
||||
{wallet?.walletId === LocalWallet.id
|
||||
? "Backup personal wallet"
|
||||
: "Backup wallet"}
|
||||
</Text>
|
||||
</View>
|
||||
</BaseButton>
|
||||
<Text variant="error">
|
||||
{
|
||||
"This is a temporary guest wallet. Download a backup if you don't want to lose access to it."
|
||||
}
|
||||
</Text>
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
|
||||
+1
-2
@@ -46,11 +46,10 @@ export const WalletDetailsModalHeader = ({
|
||||
<Box
|
||||
flexDirection="row"
|
||||
mr="sm"
|
||||
gap="xs"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
<Address address={address} />
|
||||
<Address mr="xs" address={address} />
|
||||
<CopyIcon
|
||||
width={14}
|
||||
height={14}
|
||||
|
||||
+3
-3
@@ -5,16 +5,16 @@ import {
|
||||
import { ModalFooter } from "../../base/modal/ModalFooter";
|
||||
import { ModalHeaderTextClose } from "../../base/modal/ModalHeaderTextClose";
|
||||
import { ChooseWalletContent } from "./ChooseWalletContent";
|
||||
import { Wallet } from "@thirdweb-dev/react-core";
|
||||
import { ConfiguredWallet } from "@thirdweb-dev/react-core";
|
||||
import { ReactNode, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
export type ChooseWalletProps = {
|
||||
headerText?: ReactNode | string;
|
||||
subHeaderText?: ReactNode | string;
|
||||
onChooseWallet: (wallet: Wallet) => void;
|
||||
onChooseWallet: (wallet: ConfiguredWallet) => void;
|
||||
onClose: () => void;
|
||||
wallets: Wallet[];
|
||||
wallets: ConfiguredWallet[];
|
||||
excludeWalletIds?: string[];
|
||||
showGuestWalletAsButton?: boolean;
|
||||
};
|
||||
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
import { useMemo } from "react";
|
||||
import type { Wallet } from "@thirdweb-dev/react-core";
|
||||
import type { ConfiguredWallet } from "@thirdweb-dev/react-core";
|
||||
import { StyleSheet, View, FlatList } from "react-native";
|
||||
import { WalletButton } from "../../base/WalletButton";
|
||||
|
||||
interface InitialExplorerContentProps {
|
||||
wallets: Wallet[];
|
||||
wallets: ConfiguredWallet[];
|
||||
excludeWalletIds?: string[];
|
||||
onChooseWallet: (wallet: Wallet) => void;
|
||||
onChooseWallet: (wallet: ConfiguredWallet) => void;
|
||||
}
|
||||
|
||||
export const ChooseWalletContent = ({
|
||||
|
||||
@@ -4,27 +4,26 @@ import { TWModal } from "../base/modal/TWModal";
|
||||
import { ChooseWallet } from "./ChooseWallet/ChooseWallet";
|
||||
import { ConnectingWallet } from "./ConnectingWallet/ConnectingWallet";
|
||||
import {
|
||||
Wallet,
|
||||
ConfiguredWallet,
|
||||
useConnect,
|
||||
useIsConnecting,
|
||||
useThirdwebWallet,
|
||||
useWallets,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ActivityIndicator, StyleSheet } from "react-native";
|
||||
import { SmartWallet } from "@thirdweb-dev/wallets";
|
||||
import { SmartWalletFlow } from "./SmartWallet/SmartWalletFlow";
|
||||
import { LocalWalletFlow } from "./LocalWalletFlow";
|
||||
import { LocalWallet } from "../../wallets/wallets/local-wallet";
|
||||
|
||||
export const ConnectWalletFlow = () => {
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [activeWallet, setActiveWallet] = useState<Wallet | undefined>();
|
||||
const [activeWallet, setActiveWallet] = useState<
|
||||
ConfiguredWallet | undefined
|
||||
>();
|
||||
const [isConnecting, setIsConnecting] = useState(false);
|
||||
const supportedWallets = useWallets();
|
||||
const isWalletConnecting = useIsConnecting();
|
||||
const [showButtonSpinner, setShowButtonSpinner] = useState(false);
|
||||
const twWalletContext = useThirdwebWallet();
|
||||
|
||||
useEffect(() => {
|
||||
setShowButtonSpinner(isWalletConnecting);
|
||||
@@ -56,17 +55,19 @@ export const ConnectWalletFlow = () => {
|
||||
setModalVisible(true);
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
const onClose = (reset?: boolean) => {
|
||||
setModalVisible(false);
|
||||
reset();
|
||||
|
||||
if (reset) {
|
||||
resetModal();
|
||||
}
|
||||
};
|
||||
|
||||
const onLocalWalletImported = async (localWallet: LocalWallet) => {
|
||||
await localWallet.connect();
|
||||
twWalletContext?.handleWalletConnect(localWallet);
|
||||
const onOpenModal = () => {
|
||||
setModalVisible(true);
|
||||
};
|
||||
|
||||
const connectActiveWallet = async (wallet: Wallet) => {
|
||||
const connectActiveWallet = async (wallet: ConfiguredWallet) => {
|
||||
setIsConnecting(true);
|
||||
connect(wallet, {}).catch((error) => {
|
||||
console.error("Error connecting to the wallet", error);
|
||||
@@ -74,7 +75,7 @@ export const ConnectWalletFlow = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const onChooseWallet = (wallet: Wallet) => {
|
||||
const onChooseWallet = (wallet: ConfiguredWallet) => {
|
||||
setActiveWallet(() => wallet);
|
||||
|
||||
if (wallet.id !== SmartWallet.id) {
|
||||
@@ -83,34 +84,29 @@ export const ConnectWalletFlow = () => {
|
||||
};
|
||||
|
||||
const onBackPress = () => {
|
||||
reset();
|
||||
resetModal();
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
const resetModal = () => {
|
||||
setActiveWallet(undefined);
|
||||
setIsConnecting(false);
|
||||
};
|
||||
|
||||
function getComponentForWallet(activeWalletP: Wallet) {
|
||||
function getComponentForWallet(activeWalletP: ConfiguredWallet) {
|
||||
switch (activeWalletP.id) {
|
||||
case LocalWallet.id:
|
||||
return (
|
||||
<LocalWalletFlow
|
||||
onClose={onClose}
|
||||
onBackPress={supportedWallets.length > 1 ? onBackPress : undefined}
|
||||
onWalletImported={onLocalWalletImported}
|
||||
onConnectPress={() => connectActiveWallet(activeWalletP)}
|
||||
/>
|
||||
);
|
||||
case SmartWallet.id:
|
||||
return (
|
||||
<SmartWalletFlow
|
||||
onClose={() => {
|
||||
onClose();
|
||||
}}
|
||||
onConnect={onBackPress}
|
||||
/>
|
||||
);
|
||||
return <SmartWalletFlow onClose={onClose} onConnect={onBackPress} />;
|
||||
}
|
||||
|
||||
if (activeWalletP.connectUI) {
|
||||
return (
|
||||
<activeWalletP.connectUI
|
||||
goBack={onBackPress}
|
||||
close={onClose}
|
||||
isOpen={modalVisible}
|
||||
open={onOpenModal}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,9 +144,6 @@ export const ConnectWalletFlow = () => {
|
||||
onPress={onConnectPress}
|
||||
style={styles.connectWalletButton}
|
||||
>
|
||||
{/* {showButtonSpinner ? (
|
||||
<ActivityIndicator size="small" color="buttonTextColor" />
|
||||
) : ( */}
|
||||
<Text variant="bodyLarge" color="buttonTextColor">
|
||||
{showButtonSpinner ? (
|
||||
<ActivityIndicator size="small" color="buttonTextColor" />
|
||||
@@ -158,7 +151,6 @@ export const ConnectWalletFlow = () => {
|
||||
"Connect Wallet"
|
||||
)}
|
||||
</Text>
|
||||
{/* )} */}
|
||||
</BaseButton>
|
||||
</>
|
||||
);
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ import { useAppTheme } from "../../../styles/hooks";
|
||||
import Text from "../../base/Text";
|
||||
import { ModalFooter } from "../../base/modal/ModalFooter";
|
||||
import { ConnectWalletHeader } from "./ConnectingWalletHeader";
|
||||
import type { Wallet } from "@thirdweb-dev/react-core";
|
||||
import type { ConfiguredWallet } from "@thirdweb-dev/react-core";
|
||||
import { ReactNode } from "react";
|
||||
import { ActivityIndicator, Linking, StyleSheet, View } from "react-native";
|
||||
|
||||
@@ -12,7 +12,7 @@ export type ConnectingWalletProps = {
|
||||
content?: ReactNode;
|
||||
onClose: () => void;
|
||||
onBackPress: () => void;
|
||||
wallet: Wallet;
|
||||
wallet: ConfiguredWallet;
|
||||
};
|
||||
|
||||
export function ConnectingWallet({
|
||||
|
||||
@@ -3,25 +3,31 @@ import { ActivityIndicator, StyleSheet, View } from "react-native";
|
||||
import { ConnectWalletHeader } from "./ConnectingWallet/ConnectingWalletHeader";
|
||||
import Text from "../base/Text";
|
||||
import { ModalFooter } from "../base/modal/ModalFooter";
|
||||
import { LocalWallet } from "../../wallets/wallets/local-wallet";
|
||||
import { LocalWalletImportModal } from "./LocalWalletImportModal";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
ConfiguredWallet,
|
||||
ConnectUIProps,
|
||||
WalletInstance,
|
||||
useCreateWalletInstance,
|
||||
useThirdwebWallet,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
|
||||
export type LocalWalletFlowProps = {
|
||||
onClose: () => void;
|
||||
onBackPress?: () => void;
|
||||
onConnectPress: () => void;
|
||||
onWalletImported: (localWallet: LocalWallet) => void;
|
||||
type LocalWalletFlowUIProps = ConnectUIProps & {
|
||||
localWallet: ConfiguredWallet;
|
||||
onConnected?: (wallet: WalletInstance) => void;
|
||||
};
|
||||
|
||||
export function LocalWalletFlow({
|
||||
onClose,
|
||||
onBackPress,
|
||||
onConnectPress,
|
||||
onWalletImported,
|
||||
}: LocalWalletFlowProps) {
|
||||
goBack,
|
||||
close,
|
||||
localWallet,
|
||||
onConnected,
|
||||
}: LocalWalletFlowUIProps) {
|
||||
const [isImportModalVisible, setIsImportModalVisible] = useState(false);
|
||||
const [isCreatingWallet, setIsCreatingWallet] = useState(false);
|
||||
const handleWalletConnect = useThirdwebWallet().handleWalletConnect;
|
||||
const createInstance = useCreateWalletInstance();
|
||||
|
||||
const onImportPress = async () => {
|
||||
setIsImportModalVisible(true);
|
||||
@@ -31,19 +37,31 @@ export function LocalWalletFlow({
|
||||
setIsImportModalVisible(false);
|
||||
};
|
||||
|
||||
const onConnectPressInternal = () => {
|
||||
const onConnectPressInternal = async () => {
|
||||
setIsCreatingWallet(true);
|
||||
onConnectPress();
|
||||
|
||||
const localWalletInstance = await createInstance(localWallet);
|
||||
connect(localWalletInstance);
|
||||
};
|
||||
|
||||
const connect = async (wallet: WalletInstance) => {
|
||||
await wallet.connect();
|
||||
|
||||
if (onConnected) {
|
||||
onConnected(wallet);
|
||||
} else {
|
||||
handleWalletConnect(wallet);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConnectWalletHeader
|
||||
onBackPress={onBackPress}
|
||||
onBackPress={goBack}
|
||||
headerText="Guest Wallet"
|
||||
alignHeader="flex-start"
|
||||
subHeaderText={""}
|
||||
onClose={onClose}
|
||||
onClose={close}
|
||||
/>
|
||||
<View style={styles.connectingContainer}>
|
||||
<BaseButton
|
||||
@@ -68,7 +86,7 @@ export function LocalWalletFlow({
|
||||
|
||||
<LocalWalletImportModal
|
||||
isVisible={isImportModalVisible}
|
||||
onWalletImported={onWalletImported}
|
||||
onWalletImported={connect}
|
||||
onClose={onImportModalClose}
|
||||
/>
|
||||
</>
|
||||
|
||||
+12
-16
@@ -1,6 +1,6 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
Wallet,
|
||||
ConfiguredWallet,
|
||||
WalletInstance,
|
||||
useConnect,
|
||||
useCreateWalletInstance,
|
||||
@@ -8,10 +8,7 @@ import {
|
||||
useThirdwebWallet,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { SmartWalletObj } from "../../../wallets/wallets/smart-wallet";
|
||||
import {
|
||||
LocalWallet,
|
||||
localWallet,
|
||||
} from "../../../wallets/wallets/local-wallet";
|
||||
import { localWallet } from "../../../wallets/wallets/local-wallet";
|
||||
import { ChooseWallet } from "../ChooseWallet/ChooseWallet";
|
||||
import { LocalWalletFlow } from "../LocalWalletFlow";
|
||||
import { ModalHeaderTextClose } from "../../base/modal/ModalHeaderTextClose";
|
||||
@@ -75,7 +72,7 @@ export const SmartWalletFlow = ({
|
||||
}, [connectSmartWallet, connectedPersonalWallet, mismatch]);
|
||||
|
||||
const connectPersonalWallet = useCallback(
|
||||
async (wallet: Wallet) => {
|
||||
async (wallet: ConfiguredWallet) => {
|
||||
setIsConnecting(true);
|
||||
const walletInstance = createWalletInstance(wallet);
|
||||
await walletInstance.connect();
|
||||
@@ -85,15 +82,14 @@ export const SmartWalletFlow = ({
|
||||
[createWalletInstance],
|
||||
);
|
||||
|
||||
const onLocalWalletImported = async (localWalletImported: LocalWallet) => {
|
||||
const onConnectedLocalWallet = async (wallet: WalletInstance) => {
|
||||
setIsConnecting(true);
|
||||
await localWalletImported.connect();
|
||||
|
||||
connectSmartWallet(localWalletImported);
|
||||
connectSmartWallet(wallet);
|
||||
};
|
||||
|
||||
const onChoosePersonalWallet = useCallback(
|
||||
async (wallet: Wallet) => {
|
||||
async (wallet: ConfiguredWallet) => {
|
||||
// if (wallet.id === LocalWallet.id) {
|
||||
// setShowLocalWalletFlow(true);
|
||||
// } else {
|
||||
@@ -105,7 +101,6 @@ export const SmartWalletFlow = ({
|
||||
|
||||
const onLocalWalletBackPress = () => {
|
||||
setShowLocalWalletFlow(false);
|
||||
reset();
|
||||
};
|
||||
|
||||
const onConnectingClosePress = () => {
|
||||
@@ -153,7 +148,6 @@ export const SmartWalletFlow = ({
|
||||
alignItems="center"
|
||||
paddingHorizontal="md"
|
||||
paddingVertical="sm"
|
||||
gap="md"
|
||||
borderRadius="sm"
|
||||
backgroundColor="backgroundHighlight"
|
||||
onPress={onSwitchNetworkPress}
|
||||
@@ -168,10 +162,12 @@ export const SmartWalletFlow = ({
|
||||
if (showLocalWalletFlow) {
|
||||
return (
|
||||
<LocalWalletFlow
|
||||
onClose={onClose}
|
||||
onBackPress={onLocalWalletBackPress}
|
||||
onWalletImported={onLocalWalletImported}
|
||||
onConnectPress={() => connectPersonalWallet(localWallet())}
|
||||
close={onClose}
|
||||
goBack={onLocalWalletBackPress}
|
||||
onConnected={onConnectedLocalWallet}
|
||||
isOpen={false}
|
||||
open={() => {}}
|
||||
localWallet={localWallet()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
import { Theme } from "../../styles/theme";
|
||||
import { shortenString } from "../../utils/addresses";
|
||||
import { shortenWalletAddress } from "../../utils/addresses";
|
||||
import Text from "./Text";
|
||||
|
||||
type AddressProps = {
|
||||
address: string;
|
||||
variant?: keyof Theme["textVariants"];
|
||||
} & (typeof Text)["arguments"];
|
||||
|
||||
export const Address = ({
|
||||
address,
|
||||
variant = "bodyLarge",
|
||||
}: {
|
||||
address: string;
|
||||
variant?: keyof Theme["textVariants"];
|
||||
}) => {
|
||||
return <Text variant={variant}>{shortenString(address)}</Text>;
|
||||
...props
|
||||
}: AddressProps) => {
|
||||
return (
|
||||
<Text variant={variant} {...props}>
|
||||
{shortenWalletAddress(address)}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -31,14 +31,11 @@ export const WalletButton = ({
|
||||
backgroundColor="backgroundHighlight"
|
||||
onPress={onPress}
|
||||
>
|
||||
<Box
|
||||
flexDirection="row"
|
||||
justifyContent="flex-start"
|
||||
alignItems="center"
|
||||
gap="md"
|
||||
>
|
||||
<Box flexDirection="row" justifyContent="flex-start" alignItems="center">
|
||||
<ImageSvgUri imageUrl={walletIconUrl} width={32} height={32} />
|
||||
<Text variant="bodyLarge">{name}</Text>
|
||||
<Text ml="md" variant="bodyLarge">
|
||||
{name}
|
||||
</Text>
|
||||
</Box>
|
||||
{labelText ? <Label text={labelText} /> : <View />}
|
||||
</BaseButton>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ConfiguredWallet } from "@thirdweb-dev/react-core";
|
||||
import { metamaskWallet } from "../wallets/wallets/metamask-wallet";
|
||||
import { rainbowWallet } from "../wallets/wallets/rainbow-wallet";
|
||||
import { trustWallet } from "../wallets/wallets/trust-wallet";
|
||||
|
||||
export const DEFAULT_WALLETS = [
|
||||
export const DEFAULT_WALLETS: ConfiguredWallet[] = [
|
||||
metamaskWallet(),
|
||||
rainbowWallet(),
|
||||
trustWallet(),
|
||||
|
||||
@@ -16,6 +16,12 @@ export { useTrustWallet } from "./wallets/hooks/useTrustWallet";
|
||||
export { ConnectWallet } from "./components/ConnectWallet";
|
||||
export { Web3Button } from "./components/Web3Button";
|
||||
|
||||
// utilities
|
||||
export * from "./utils/uri";
|
||||
export * from "./utils/addresses";
|
||||
export { createAsyncLocalStorage } from "../core/AsyncStorage";
|
||||
export { createSecureStorage } from "../core/SecureStorage";
|
||||
|
||||
// providers
|
||||
// export * from "./providers/full";
|
||||
export * from "./providers/thirdweb-provider";
|
||||
|
||||
@@ -3,7 +3,7 @@ import { DEFAULT_API_KEY } from "../constants/rpc";
|
||||
import {
|
||||
ThirdwebProviderCore,
|
||||
ThirdwebProviderCoreProps,
|
||||
Wallet,
|
||||
ConfiguredWallet,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { PropsWithChildren } from "react";
|
||||
import type { Chain, defaultChains } from "@thirdweb-dev/chains";
|
||||
@@ -27,7 +27,7 @@ interface ThirdwebProviderProps<TChains extends Chain[]>
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
supportedWallets?: Wallet[];
|
||||
supportedWallets?: ConfiguredWallet[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,8 +12,6 @@ export type Palette = {
|
||||
iconSecondary: string;
|
||||
iconHighlight: string;
|
||||
|
||||
warning: string;
|
||||
|
||||
linkPrimary: string;
|
||||
|
||||
labelBackground: string;
|
||||
@@ -23,6 +21,10 @@ export type Palette = {
|
||||
black: string;
|
||||
white: string;
|
||||
red: string;
|
||||
|
||||
warning: string;
|
||||
|
||||
error: string;
|
||||
};
|
||||
|
||||
export const paletteBase = {
|
||||
@@ -30,6 +32,7 @@ export const paletteBase = {
|
||||
white: "white",
|
||||
red: "red",
|
||||
warning: "#F46565",
|
||||
error: "#D85252",
|
||||
};
|
||||
|
||||
export const paletteLight: Palette = {
|
||||
|
||||
@@ -39,4 +39,11 @@ export const textVariants = {
|
||||
fontSize: 13,
|
||||
lineHeight: 16,
|
||||
},
|
||||
error: {
|
||||
color: "error",
|
||||
fontWeight: "500",
|
||||
fontSize: 12,
|
||||
lineHeight: 16,
|
||||
textAlign: "center",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
export function shortenString(str: string, extraShort?: true) {
|
||||
/**
|
||||
* Shortens an EVM compatible address to show the first 6 and last 4 characters
|
||||
*
|
||||
* @param str The address to shorten
|
||||
* @param extraShort If true, show the first 4 and last 3 characters
|
||||
* @returns The shortened address
|
||||
*/
|
||||
export function shortenWalletAddress(str: string, extraShort?: true) {
|
||||
return `${str.substring(0, extraShort ? 4 : 6)}...${str.substring(
|
||||
str.length - (extraShort ? 3 : 4),
|
||||
)}`;
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
export function formatDisplayUri(
|
||||
/**
|
||||
* Build a WalletConnect display URI from a wc:// uri + a wallet specific link
|
||||
*
|
||||
* @param uri The wc:// uri
|
||||
* @param links The wallet specific links
|
||||
* @returns The WalletConnect display URI
|
||||
*/
|
||||
export function formatWalletConnectDisplayUri(
|
||||
uri: string,
|
||||
links: { universal: string; native: string },
|
||||
) {
|
||||
|
||||
@@ -14,8 +14,8 @@ import {
|
||||
Chain,
|
||||
ProviderRpcError,
|
||||
walletIds,
|
||||
WagmiConnector,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { Connector } from "@thirdweb-dev/wallets";
|
||||
import type { Address } from "abitype";
|
||||
import { providers } from "ethers";
|
||||
import { getAddress, hexValue } from "ethers/lib/utils.js";
|
||||
@@ -34,7 +34,7 @@ export type CoinbaseWalletConnectorOptions = WalletMobileSDKProviderOptions &
|
||||
chainId?: number;
|
||||
};
|
||||
|
||||
export class CoinbaseWalletConnector extends Connector<
|
||||
export class CoinbaseWalletConnector extends WagmiConnector<
|
||||
WalletMobileSDKEVMProvider,
|
||||
CoinbaseWalletConnectorOptions,
|
||||
providers.JsonRpcSigner
|
||||
|
||||
@@ -5,13 +5,13 @@ import type {
|
||||
} from "../connectors/coinbase-wallet";
|
||||
import {
|
||||
AbstractClientWallet,
|
||||
TWConnector,
|
||||
Connector,
|
||||
WagmiAdapter,
|
||||
WalletOptions,
|
||||
walletIds,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
Wallet,
|
||||
ConfiguredWallet,
|
||||
WalletOptions as WalletOptionsRC,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
|
||||
@@ -28,7 +28,7 @@ export class CoinbaseWallet extends AbstractClientWallet<CoinbaseWalletConnector
|
||||
"ipfs://QmcJBHopbwfJcLqJpX2xEufSS84aLbF7bHavYhaXUcrLaH/coinbase.svg",
|
||||
};
|
||||
|
||||
connector?: TWConnector;
|
||||
connector?: Connector;
|
||||
coinbaseConnector?: CoinbaseWalletConnector;
|
||||
provider?: CoinbaseWalletConnector["provider"];
|
||||
|
||||
@@ -49,7 +49,7 @@ export class CoinbaseWallet extends AbstractClientWallet<CoinbaseWalletConnector
|
||||
this.callbackURL = options.callbackURL;
|
||||
}
|
||||
|
||||
protected async getConnector(): Promise<TWConnector> {
|
||||
protected async getConnector(): Promise<Connector> {
|
||||
if (!this.connector) {
|
||||
// import the connector dynamically
|
||||
const { CoinbaseWalletConnector: CoinbaseWalletConnector } = await import(
|
||||
@@ -83,5 +83,5 @@ export const coinbaseWallet = (config?: { callbackURL?: URL }) => {
|
||||
create: (options: WalletOptionsRC) =>
|
||||
new CoinbaseWallet({ ...options, callbackURL: callbackURLNonNull }),
|
||||
config: config || {},
|
||||
} satisfies Wallet<CoinbaseWallet, { callbackURL?: URL }>;
|
||||
} satisfies ConfiguredWallet<CoinbaseWallet, { callbackURL?: URL }>;
|
||||
};
|
||||
|
||||
+16
-6
@@ -1,13 +1,14 @@
|
||||
import {
|
||||
LocalWallet as LocalWalletCore,
|
||||
TWConnector,
|
||||
Connector,
|
||||
walletIds,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { Wallet } from "@thirdweb-dev/react-core";
|
||||
import { ConfiguredWallet, ConnectUIProps } from "@thirdweb-dev/react-core";
|
||||
import type { WalletOptions } from "@thirdweb-dev/wallets";
|
||||
import { ethers, utils } from "ethers";
|
||||
import { createSecureStorage } from "../../../core/SecureStorage";
|
||||
import { createAsyncLocalStorage } from "../../../core/AsyncStorage";
|
||||
import { LocalWalletFlow } from "../../components/ConnectWalletFlow/LocalWalletFlow";
|
||||
|
||||
export class LocalWallet extends LocalWalletCore {
|
||||
static meta = {
|
||||
@@ -30,7 +31,7 @@ export class LocalWallet extends LocalWalletCore {
|
||||
return this.ethersWallet.address;
|
||||
}
|
||||
|
||||
protected async getConnector(): Promise<TWConnector> {
|
||||
protected async getConnector(): Promise<Connector> {
|
||||
if (!this.ethersWallet) {
|
||||
const data = await this.getSavedData();
|
||||
|
||||
@@ -49,10 +50,10 @@ export class LocalWallet extends LocalWalletCore {
|
||||
}
|
||||
}
|
||||
|
||||
export const localWallet = () => {
|
||||
export const localWallet = (): ConfiguredWallet => {
|
||||
const secureStorage = createSecureStorage(walletIds.localWallet);
|
||||
const asyncStorage = createAsyncLocalStorage(walletIds.localWallet);
|
||||
return {
|
||||
const configuredWallet = {
|
||||
id: LocalWallet.id,
|
||||
meta: LocalWallet.meta,
|
||||
create: (options: WalletOptions) =>
|
||||
@@ -61,5 +62,14 @@ export const localWallet = () => {
|
||||
walletStorage: asyncStorage,
|
||||
storage: secureStorage,
|
||||
}) as LocalWalletCore,
|
||||
} satisfies Wallet;
|
||||
connectUI(props: ConnectUIProps) {
|
||||
return <LocalWalletFlow {...props} localWallet={configuredWallet} />;
|
||||
},
|
||||
isInstalled() {
|
||||
// TODO
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
return configuredWallet;
|
||||
};
|
||||
@@ -4,11 +4,11 @@ import {
|
||||
WalletConnectV1,
|
||||
walletIds,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { formatDisplayUri } from "../../utils/uri";
|
||||
import { formatWalletConnectDisplayUri } from "../../utils/uri";
|
||||
import { Linking } from "react-native";
|
||||
import {
|
||||
WalletOptions as WalletOptionsRC,
|
||||
Wallet,
|
||||
ConfiguredWallet,
|
||||
ExtraCoreWalletOptions,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { createAsyncLocalStorage } from "../../../core/AsyncStorage";
|
||||
@@ -52,11 +52,11 @@ export class MetaMaskWallet extends WalletConnectV1 {
|
||||
const links = MetaMaskWallet.meta.links;
|
||||
|
||||
if (uri) {
|
||||
const fullUrl = formatDisplayUri(uri, links);
|
||||
const fullUrl = formatWalletConnectDisplayUri(uri, links);
|
||||
|
||||
Linking.openURL(fullUrl);
|
||||
} else {
|
||||
const fullUrl = formatDisplayUri("", links);
|
||||
const fullUrl = formatWalletConnectDisplayUri("", links);
|
||||
|
||||
Linking.openURL(fullUrl);
|
||||
}
|
||||
@@ -68,5 +68,5 @@ export const metamaskWallet = () => {
|
||||
id: MetaMaskWallet.id,
|
||||
meta: MetaMaskWallet.meta,
|
||||
create: (options: WalletOptionsRC) => new MetaMaskWallet(options),
|
||||
} satisfies Wallet;
|
||||
} satisfies ConfiguredWallet;
|
||||
};
|
||||
|
||||
@@ -3,11 +3,11 @@ import {
|
||||
WalletConnectV1Options,
|
||||
WalletConnectV1,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { formatDisplayUri } from "../../utils/uri";
|
||||
import { formatWalletConnectDisplayUri } from "../../utils/uri";
|
||||
import { Linking } from "react-native";
|
||||
import {
|
||||
WalletOptions as WalletOptionsRC,
|
||||
Wallet,
|
||||
ConfiguredWallet,
|
||||
ExtraCoreWalletOptions,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { createAsyncLocalStorage } from "../../../core/AsyncStorage";
|
||||
@@ -50,11 +50,11 @@ export class RainbowWallet extends WalletConnectV1 {
|
||||
const links = RainbowWallet.meta.links;
|
||||
|
||||
if (uri) {
|
||||
const fullUrl = formatDisplayUri(uri, links);
|
||||
const fullUrl = formatWalletConnectDisplayUri(uri, links);
|
||||
|
||||
Linking.openURL(fullUrl);
|
||||
} else {
|
||||
const fullUrl = formatDisplayUri("", links);
|
||||
const fullUrl = formatWalletConnectDisplayUri("", links);
|
||||
|
||||
Linking.openURL(fullUrl);
|
||||
}
|
||||
@@ -66,5 +66,5 @@ export const rainbowWallet = () => {
|
||||
id: RainbowWallet.id,
|
||||
meta: RainbowWallet.meta,
|
||||
create: (options: WalletOptionsRC) => new RainbowWallet(options),
|
||||
} satisfies Wallet;
|
||||
} satisfies ConfiguredWallet;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Wallet, WalletOptions } from "@thirdweb-dev/react-core";
|
||||
import type { ConfiguredWallet, WalletOptions } from "@thirdweb-dev/react-core";
|
||||
import { SmartWallet } from "@thirdweb-dev/wallets";
|
||||
import { DEFAULT_WALLETS } from "../../constants/wallets";
|
||||
|
||||
@@ -6,16 +6,16 @@ type SafeWalletConfig = {
|
||||
factoryAddress: string;
|
||||
thirdwebApiKey: string;
|
||||
gasless: boolean;
|
||||
personalWallets: Wallet[];
|
||||
personalWallets: ConfiguredWallet[];
|
||||
};
|
||||
|
||||
export type SmartWalletObj = Wallet & {
|
||||
export type SmartWalletObj = ConfiguredWallet & {
|
||||
config: SafeWalletConfig;
|
||||
};
|
||||
|
||||
export const smartWallet = (
|
||||
config: Omit<SafeWalletConfig, "personalWallets"> & {
|
||||
personalWallets?: Wallet[];
|
||||
personalWallets?: ConfiguredWallet[];
|
||||
},
|
||||
) => {
|
||||
return {
|
||||
@@ -27,5 +27,5 @@ export const smartWallet = (
|
||||
...config,
|
||||
personalWallets: config.personalWallets || DEFAULT_WALLETS,
|
||||
},
|
||||
} satisfies SmartWalletObj;
|
||||
} satisfies ConfiguredWallet<SmartWallet, SafeWalletConfig>;
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { createAsyncLocalStorage } from "../../../core/AsyncStorage";
|
||||
import { TW_WC_PROJECT_ID } from "../../constants/walletConnect";
|
||||
import { formatDisplayUri } from "../../utils/uri";
|
||||
import { formatWalletConnectDisplayUri } from "../../utils/uri";
|
||||
import type {
|
||||
WalletConnectOptions,
|
||||
WalletOptions,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
WalletOptions as WalletOptionsRC,
|
||||
Wallet,
|
||||
ConfiguredWallet,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { WalletConnect } from "@thirdweb-dev/wallets";
|
||||
import { Linking } from "react-native";
|
||||
@@ -51,11 +51,11 @@ export class TrustWallet extends WalletConnect {
|
||||
const links = TrustWallet.meta.links;
|
||||
|
||||
if (uri) {
|
||||
const fullUrl = formatDisplayUri(uri, links);
|
||||
const fullUrl = formatWalletConnectDisplayUri(uri, links);
|
||||
|
||||
Linking.openURL(fullUrl);
|
||||
} else {
|
||||
const fullUrl = formatDisplayUri("", links);
|
||||
const fullUrl = formatWalletConnectDisplayUri("", links);
|
||||
|
||||
Linking.openURL(fullUrl);
|
||||
}
|
||||
@@ -67,5 +67,5 @@ export const trustWallet = () => {
|
||||
id: TrustWallet.id,
|
||||
meta: TrustWallet.meta,
|
||||
create: (options: WalletOptionsRC) => new TrustWallet(options),
|
||||
} satisfies Wallet;
|
||||
} satisfies ConfiguredWallet;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.11.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`32908b76`](https://github.com/thirdweb-dev/js/commit/32908b76832c60e91a0a6e40dbdb1c8f56e9e5be), [`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff), [`6a4aab0b`](https://github.com/thirdweb-dev/js/commit/6a4aab0b8a2e0f6ff1b47992a3c1e5426a74f7ff)]:
|
||||
- @thirdweb-dev/sdk@3.10.14
|
||||
- @thirdweb-dev/wallets@0.2.19
|
||||
- @thirdweb-dev/chains@0.1.15
|
||||
- @thirdweb-dev/react-core@3.11.11
|
||||
|
||||
## 3.11.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#967](https://github.com/thirdweb-dev/js/pull/967) [`7d7685e3`](https://github.com/thirdweb-dev/js/commit/7d7685e3fab5780b3c1d26b8ef431b96f8486972) Thanks [@MananTank](https://github.com/MananTank)! - - Fix type of connect() for magic wallet
|
||||
|
||||
- enforce smsLogin, emailLogin restriction for magic wallet
|
||||
- update the icon for local wallet
|
||||
|
||||
- [#966](https://github.com/thirdweb-dev/js/pull/966) [`87021cee`](https://github.com/thirdweb-dev/js/commit/87021cee45e81a6504e4e2279e6d2abb10cab8ec) Thanks [@MananTank](https://github.com/MananTank)! - Connect Wallet UI improvements
|
||||
|
||||
- Allow from EOA => smart wallet / safe
|
||||
- Add warning to backup wallet for guest wallet
|
||||
- Show "Guest" instead of address for guest wallet
|
||||
|
||||
- [#977](https://github.com/thirdweb-dev/js/pull/977) [`93bd5733`](https://github.com/thirdweb-dev/js/commit/93bd57337b7d2c2fcd252987d10df3206c839daf) Thanks [@MananTank](https://github.com/MananTank)! - Fix Connect Wallet Open/Close issues
|
||||
|
||||
- Updated dependencies [[`93bdec06`](https://github.com/thirdweb-dev/js/commit/93bdec061dc05ab133e79f5f739dcae9b5393f53), [`ea0f9479`](https://github.com/thirdweb-dev/js/commit/ea0f9479a38d442201e367fce1234c130228fde6), [`05ebbc15`](https://github.com/thirdweb-dev/js/commit/05ebbc15a012855735fba2aa93887b88e14295d1), [`5305b42d`](https://github.com/thirdweb-dev/js/commit/5305b42db554b69f903b3d95f3ba0eeddabd6114), [`4ca557ae`](https://github.com/thirdweb-dev/js/commit/4ca557ae4ab225e39decc3b7a01a04c0d8e464c7), [`7d7685e3`](https://github.com/thirdweb-dev/js/commit/7d7685e3fab5780b3c1d26b8ef431b96f8486972), [`87021cee`](https://github.com/thirdweb-dev/js/commit/87021cee45e81a6504e4e2279e6d2abb10cab8ec), [`eb521d24`](https://github.com/thirdweb-dev/js/commit/eb521d240ae7102d44fe2c5223b0a18d867e09ad), [`af4b5356`](https://github.com/thirdweb-dev/js/commit/af4b5356372ffa084c8d0e747d8def46c2ff892c), [`93bd5733`](https://github.com/thirdweb-dev/js/commit/93bd57337b7d2c2fcd252987d10df3206c839daf), [`a2df187b`](https://github.com/thirdweb-dev/js/commit/a2df187bc1867beb2e90853da70dac271f604f12), [`aa9b6acc`](https://github.com/thirdweb-dev/js/commit/aa9b6acc3f5a118c2b5fe9e46732e72c0fc69376)]:
|
||||
- @thirdweb-dev/wallets@0.2.18
|
||||
- @thirdweb-dev/react-core@3.11.10
|
||||
- @thirdweb-dev/chains@0.1.14
|
||||
- @thirdweb-dev/sdk@3.10.13
|
||||
|
||||
## 3.11.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.11.9",
|
||||
"version": "3.11.11",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { spacing, Theme } from "../../../../design-system";
|
||||
import styled from "@emotion/styled";
|
||||
import { spacing, Theme } from "../design-system";
|
||||
|
||||
export function Steps({ step }: { step: 1 | 2 }) {
|
||||
return (
|
||||
@@ -55,11 +55,11 @@ export const BackButton: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
export const HelperLink = styled.a<{ theme?: Theme }>`
|
||||
export const HelperLink = styled.a<{ theme?: Theme; md?: boolean }>`
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
color: ${(p) => p.theme.link.primary};
|
||||
font-size: ${fontSize.sm};
|
||||
font-size: ${(p) => (p.md ? fontSize.md : fontSize.sm)};
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
${media.mobile} {
|
||||
|
||||
@@ -6,7 +6,9 @@ export function useSafe() {
|
||||
const connect = useConnect();
|
||||
return useCallback(
|
||||
async (connectProps: SafeConnectionArgs) => {
|
||||
const { safeWallet } = await import("../../../wallet/wallets/safeWallet");
|
||||
const { safeWallet } = await import(
|
||||
"../../../wallet/wallets/safe/safeWallet"
|
||||
);
|
||||
connect(safeWallet(), connectProps);
|
||||
},
|
||||
[connect],
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { useCallback } from "react";
|
||||
|
||||
// import { useConnect } from "../../../core/hooks/wallet-hooks";
|
||||
import { useConnect } from "@thirdweb-dev/react-core";
|
||||
import { MagicLinkAdditionalOptions } from "@thirdweb-dev/wallets/evm/wallets/magic";
|
||||
import { MagicLinkConnectOptions } from "@thirdweb-dev/wallets";
|
||||
|
||||
export function useMagic() {
|
||||
// const connect = useConnect();
|
||||
return useCallback(() => {
|
||||
throw new Error("not implemented yet");
|
||||
}, []);
|
||||
const connect = useConnect();
|
||||
return useCallback(
|
||||
async (options: MagicLinkConnectOptions & MagicLinkAdditionalOptions) => {
|
||||
const { magicLink } = await import(
|
||||
"../../../wallet/wallets/magic/magicLink"
|
||||
);
|
||||
return connect(magicLink(options), options);
|
||||
},
|
||||
[connect],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ export function useCoinbaseWallet() {
|
||||
return useCallback(
|
||||
async (connectOptions?: { chainId?: number }) => {
|
||||
const { coinbaseWallet } = await import(
|
||||
"../../../wallet/wallets/coinbaseWallet"
|
||||
"../../../wallet/wallets/coinbase/coinbaseWallet"
|
||||
);
|
||||
connect(coinbaseWallet(), connectOptions);
|
||||
return connect(coinbaseWallet(), connectOptions);
|
||||
},
|
||||
[connect],
|
||||
);
|
||||
|
||||
@@ -6,9 +6,9 @@ export function useMetamask() {
|
||||
return useCallback(
|
||||
async (connectOptions?: { chainId?: number }) => {
|
||||
const { metamaskWallet } = await import(
|
||||
"../../../wallet/wallets/metamaskWallet"
|
||||
"../../../wallet/wallets/metamask/metamaskWallet"
|
||||
);
|
||||
connect(metamaskWallet(), connectOptions);
|
||||
return connect(metamaskWallet(), connectOptions);
|
||||
},
|
||||
[connect],
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ export function usePaperWallet() {
|
||||
const { paperWallet } = await import(
|
||||
"../../../wallet/wallets/paperWallet"
|
||||
);
|
||||
connect(paperWallet({ clientId: options.clientId }), options);
|
||||
return connect(paperWallet({ clientId: options.clientId }), options);
|
||||
},
|
||||
[connect],
|
||||
);
|
||||
|
||||
@@ -8,7 +8,7 @@ export function useWalletConnectV1() {
|
||||
const { walletConnectV1 } = await import(
|
||||
"../../../wallet/wallets/walletConnectV1"
|
||||
);
|
||||
connect(walletConnectV1(), options);
|
||||
return connect(walletConnectV1(), options);
|
||||
},
|
||||
[connect],
|
||||
);
|
||||
@@ -21,7 +21,7 @@ export function useWalletConnect() {
|
||||
const { walletConnect } = await import(
|
||||
"../../../wallet/wallets/walletConnect"
|
||||
);
|
||||
connect(walletConnect(), options || {});
|
||||
return connect(walletConnect(), options || {});
|
||||
},
|
||||
[connect],
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export { useSafe } from "./connectors/gnosis";
|
||||
export { useMagic } from "./connectors/magic";
|
||||
|
||||
export { ConnectWallet } from "../wallet/ConnectWallet/ConnectWallet";
|
||||
export { NetworkSelector } from "../wallet/ConnectWallet/NetworkSelector";
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { DEFAULT_API_KEY } from "../constants/rpc";
|
||||
import {
|
||||
Wallet,
|
||||
ThirdwebProviderCore,
|
||||
ThirdwebProviderCoreProps,
|
||||
ConfiguredWallet,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { WalletUIStatesProvider } from "./wallet-ui-states-provider";
|
||||
import { ConnectModal } from "../../wallet/ConnectWallet/Connect";
|
||||
import { ConnectModal } from "../../wallet/ConnectWallet/ConnectModal";
|
||||
import { ThemeProvider } from "@emotion/react";
|
||||
import { darkTheme, lightTheme } from "../../design-system";
|
||||
import { PropsWithChildren } from "react";
|
||||
@@ -30,7 +30,7 @@ interface ThirdwebProviderProps<TChains extends Chain[]>
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
supportedWallets?: Wallet[];
|
||||
supportedWallets?: ConfiguredWallet[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ export const ThirdwebProvider = <
|
||||
children,
|
||||
...restProps
|
||||
}: PropsWithChildren<ThirdwebProviderProps<TChains>>) => {
|
||||
const wallets: Wallet[] = supportedWallets || defaultWallets;
|
||||
const wallets: ConfiguredWallet[] = supportedWallets || defaultWallets;
|
||||
|
||||
return (
|
||||
<WalletUIStatesProvider theme={theme}>
|
||||
|
||||
@@ -2,89 +2,37 @@ import { useState, createContext, useContext } from "react";
|
||||
|
||||
type BoolSetter = (value: boolean) => void;
|
||||
type ThemeSetter = (value: "light" | "dark") => void;
|
||||
type Screen =
|
||||
| "metamask/connecting"
|
||||
| "walletList"
|
||||
| "coinbase/connecting"
|
||||
| "coinbase/scan"
|
||||
| "metamask/scan"
|
||||
| "metamask/get-started"
|
||||
| "coinbase/get-started"
|
||||
| "safe/select-wallet"
|
||||
| "safe/form"
|
||||
| "wallets/get-started"
|
||||
| "localWallet/connect"
|
||||
| "localWallet/export"
|
||||
| "smartWallet/select-wallet"
|
||||
| "smartWallet/form"
|
||||
| "magic/connect";
|
||||
|
||||
type WalletWrapper = false | "safe" | "smartWallet";
|
||||
|
||||
const WalletWrapperConnection = createContext<WalletWrapper>(false);
|
||||
const SetWalletWrapperConnection = createContext<
|
||||
((value: WalletWrapper) => void) | undefined
|
||||
>(undefined);
|
||||
|
||||
const WalletModalOpen = createContext(false);
|
||||
const SetWalletModalOpen = createContext<BoolSetter | undefined>(undefined);
|
||||
const ScreenContext = createContext<Screen>("walletList");
|
||||
const SetScreenContext = createContext<
|
||||
React.Dispatch<React.SetStateAction<Screen>> | undefined
|
||||
>(undefined);
|
||||
|
||||
const ModalThemeContext = createContext<"light" | "dark">("dark");
|
||||
const SetModalThemeContext = createContext<ThemeSetter | undefined>(undefined);
|
||||
|
||||
export const WalletUIStatesProvider = (
|
||||
props: React.PropsWithChildren<{ theme?: "light" | "dark" }>,
|
||||
) => {
|
||||
const [isConnectingToWalletWrapper, setIsConnectingToWalletWrapper] =
|
||||
useState<WalletWrapper>(false);
|
||||
const [isWalletModalOpen, setIsWalletModalOpen] = useState(false);
|
||||
const [screen, setScreen] = useState<Screen>("walletList");
|
||||
|
||||
const [modalTheme, setModalTheme] = useState(props.theme || "dark");
|
||||
|
||||
return (
|
||||
<WalletWrapperConnection.Provider value={isConnectingToWalletWrapper}>
|
||||
<SetWalletWrapperConnection.Provider
|
||||
value={setIsConnectingToWalletWrapper}
|
||||
>
|
||||
<WalletModalOpen.Provider value={isWalletModalOpen}>
|
||||
<SetWalletModalOpen.Provider value={setIsWalletModalOpen}>
|
||||
<ScreenContext.Provider value={screen}>
|
||||
<SetScreenContext.Provider value={setScreen}>
|
||||
<ModalThemeContext.Provider value={modalTheme}>
|
||||
<SetModalThemeContext.Provider value={setModalTheme}>
|
||||
{props.children}
|
||||
</SetModalThemeContext.Provider>
|
||||
</ModalThemeContext.Provider>
|
||||
</SetScreenContext.Provider>
|
||||
</ScreenContext.Provider>
|
||||
</SetWalletModalOpen.Provider>
|
||||
</WalletModalOpen.Provider>
|
||||
</SetWalletWrapperConnection.Provider>
|
||||
</WalletWrapperConnection.Provider>
|
||||
<WalletModalOpen.Provider value={isWalletModalOpen}>
|
||||
<SetWalletModalOpen.Provider value={setIsWalletModalOpen}>
|
||||
<ModalThemeContext.Provider value={modalTheme}>
|
||||
<SetModalThemeContext.Provider value={setModalTheme}>
|
||||
{props.children}
|
||||
</SetModalThemeContext.Provider>
|
||||
</ModalThemeContext.Provider>
|
||||
</SetWalletModalOpen.Provider>
|
||||
</WalletModalOpen.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useIsConnectingToWalletWrapper = () => {
|
||||
return useContext(WalletWrapperConnection);
|
||||
};
|
||||
|
||||
export const useIsWalletModalOpen = () => {
|
||||
return useContext(WalletModalOpen);
|
||||
};
|
||||
|
||||
export const useSetIsConnectingToWalletWrapper = () => {
|
||||
const context = useContext(SetWalletWrapperConnection);
|
||||
if (context === undefined) {
|
||||
throw new Error(
|
||||
"useSetIsConnectingToWalletWrapper must be used within a UIProvider",
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export const useSetIsWalletModalOpen = () => {
|
||||
const context = useContext(SetWalletModalOpen);
|
||||
if (context === undefined) {
|
||||
@@ -93,18 +41,6 @@ export const useSetIsWalletModalOpen = () => {
|
||||
return context;
|
||||
};
|
||||
|
||||
export const useScreen = () => {
|
||||
return useContext(ScreenContext);
|
||||
};
|
||||
|
||||
export const useSetScreen = () => {
|
||||
const context = useContext(SetScreenContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useSetScreen must be used within a UIProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export const useModalTheme = () => {
|
||||
return useContext(ModalThemeContext);
|
||||
};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
export { localWallet } from "./wallet/wallets/localWallet";
|
||||
export { coinbaseWallet } from "./wallet/wallets/coinbaseWallet";
|
||||
export { metamaskWallet } from "./wallet/wallets/metamaskWallet";
|
||||
export { localWallet } from "./wallet/wallets/localWallet/localWallet";
|
||||
export { coinbaseWallet } from "./wallet/wallets/coinbase/coinbaseWallet";
|
||||
export { metamaskWallet } from "./wallet/wallets/metamask/metamaskWallet";
|
||||
export { paperWallet } from "./wallet/wallets/paperWallet";
|
||||
export { safeWallet } from "./wallet/wallets/safeWallet";
|
||||
export { safeWallet } from "./wallet/wallets/safe/safeWallet";
|
||||
export { walletConnect } from "./wallet/wallets/walletConnect";
|
||||
export { walletConnectV1 } from "./wallet/wallets/walletConnectV1";
|
||||
export { smartWallet } from "./wallet/wallets/smartWallet";
|
||||
export { magicLink } from "./wallet/wallets/magicLink";
|
||||
export { smartWallet } from "./wallet/wallets/smartWallet/smartWallet";
|
||||
export { magicLink } from "./wallet/wallets/magic/magicLink";
|
||||
|
||||
// at the moment we'll re-export everything from the evm package
|
||||
export * from "./evm";
|
||||
|
||||
@@ -1,418 +0,0 @@
|
||||
import { Modal } from "../../components/Modal";
|
||||
import { isMobile } from "../../evm/utils/isMobile";
|
||||
import { useInstalledWallets } from "../hooks/useInstalledWallets";
|
||||
import { WalletInfo } from "../types";
|
||||
import { WalletSelector } from "./WalletSelector";
|
||||
import { CoinbaseWalletSetup } from "./screens/Coinbase/CoinbaseConnecting";
|
||||
import { CoinbaseGetStarted } from "./screens/Coinbase/CoinbaseGetStarted";
|
||||
import { ScanCoinbase } from "./screens/Coinbase/CoinbaseScan";
|
||||
import { MetamaskConnecting } from "./screens/Metamask/MetamaskConnecting";
|
||||
import { MetamaskGetStarted } from "./screens/Metamask/MetamaskGetStarted";
|
||||
import { ScanMetamask } from "./screens/Metamask/MetamaskScan";
|
||||
import {
|
||||
Wallet,
|
||||
useConnect,
|
||||
useConnectionStatus,
|
||||
useDisconnect,
|
||||
useWallet,
|
||||
useWallets,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { SelectpersonalWallet } from "./screens/Safe/SelectPersonalWallet";
|
||||
import { SafeForm } from "./screens/Safe/SafeForm";
|
||||
import { GetStartedWithWallets } from "./screens/GetStartedWithWallets";
|
||||
import {
|
||||
useIsConnectingToWalletWrapper,
|
||||
useIsWalletModalOpen,
|
||||
useModalTheme,
|
||||
useScreen,
|
||||
useSetIsConnectingToWalletWrapper,
|
||||
useSetIsWalletModalOpen,
|
||||
useSetScreen,
|
||||
} from "../../evm/providers/wallet-ui-states-provider";
|
||||
import { ifWaiting } from "../../evm/utils/ifWaiting";
|
||||
import { ThemeProvider } from "@emotion/react";
|
||||
import { darkTheme, lightTheme } from "../../design-system";
|
||||
import { LocalWalletSetup } from "./screens/LocalWallet/LocalWalletSetup";
|
||||
import { SmartWalletForm } from "./screens/SmartWallet/SmartWalletForm";
|
||||
import { MagicConnect } from "./screens/Magic/MagicConnect";
|
||||
import { SmartWalletSelect } from "./screens/SmartWallet/SmartWalletSelect";
|
||||
import { SmartWalletObj } from "../wallets/smartWallet";
|
||||
import { SafeWalletObj } from "../wallets/safeWallet";
|
||||
import { walletIds } from "@thirdweb-dev/wallets";
|
||||
import { WalletsInfoCtx } from "./walletInfo";
|
||||
|
||||
export const ConnectModal = () => {
|
||||
const modalTheme = useModalTheme();
|
||||
const isConnectingToWalletWrapper = useIsConnectingToWalletWrapper();
|
||||
const showScreen = useScreen();
|
||||
const setShowScreen = useSetScreen();
|
||||
const setIsConnectingToWalletWrapper = useSetIsConnectingToWalletWrapper();
|
||||
const isWalletModalOpen = useIsWalletModalOpen();
|
||||
const setIsWalletModalOpen = useSetIsWalletModalOpen();
|
||||
const connectionStatus = useConnectionStatus();
|
||||
const disconnect = useDisconnect();
|
||||
|
||||
const connect = useConnect();
|
||||
const wallets = useWallets();
|
||||
const activeWallet = useWallet();
|
||||
const installedWallets = useInstalledWallets();
|
||||
|
||||
// to hide the modal temporarily when showing the third party Modal to avoid z-index issues
|
||||
const [hideModal, setHideModal] = useState(false);
|
||||
|
||||
const closeModalAndReset = useCallback(() => {
|
||||
setShowScreen("walletList");
|
||||
setIsConnectingToWalletWrapper(false);
|
||||
setIsWalletModalOpen(false);
|
||||
}, [setIsConnectingToWalletWrapper, setIsWalletModalOpen, setShowScreen]);
|
||||
|
||||
const onConnect = useCallback(() => {
|
||||
if (isConnectingToWalletWrapper === "safe") {
|
||||
setShowScreen("safe/form");
|
||||
} else if (isConnectingToWalletWrapper === "smartWallet") {
|
||||
setShowScreen("smartWallet/form");
|
||||
} else {
|
||||
closeModalAndReset();
|
||||
}
|
||||
}, [closeModalAndReset, isConnectingToWalletWrapper, setShowScreen]);
|
||||
|
||||
const onConnectError = useCallback(() => {
|
||||
if (isConnectingToWalletWrapper === "safe") {
|
||||
setShowScreen("safe/select-wallet");
|
||||
} else if (isConnectingToWalletWrapper === "smartWallet") {
|
||||
setShowScreen("smartWallet/select-wallet");
|
||||
} else {
|
||||
setShowScreen("walletList");
|
||||
}
|
||||
}, [isConnectingToWalletWrapper, setShowScreen]);
|
||||
|
||||
const onlyOneWallet = wallets.length === 1;
|
||||
|
||||
const handleBack = useCallback(() => {
|
||||
if (isConnectingToWalletWrapper === "safe") {
|
||||
setShowScreen("safe/select-wallet");
|
||||
} else if (isConnectingToWalletWrapper === "smartWallet") {
|
||||
setShowScreen("smartWallet/select-wallet");
|
||||
} else {
|
||||
setShowScreen("walletList");
|
||||
}
|
||||
}, [isConnectingToWalletWrapper, setShowScreen]);
|
||||
|
||||
type GetWalletInfo = (wallet: Wallet) => WalletInfo;
|
||||
const getWalletInfo: GetWalletInfo = useCallback(
|
||||
(wallet: Wallet) => ({
|
||||
wallet,
|
||||
installed:
|
||||
wallet.id in installedWallets &&
|
||||
installedWallets[wallet.id as keyof typeof installedWallets],
|
||||
connect: async () => {
|
||||
// Metamask
|
||||
if (wallet.id === walletIds.metamask) {
|
||||
if (installedWallets.metamask) {
|
||||
try {
|
||||
await ifWaiting({
|
||||
for: connect(wallet, {}),
|
||||
moreThan: 100,
|
||||
do: () => {
|
||||
setShowScreen("metamask/connecting");
|
||||
},
|
||||
});
|
||||
|
||||
onConnect();
|
||||
} catch (e) {
|
||||
onConnectError();
|
||||
}
|
||||
}
|
||||
|
||||
// if metamask is not injected
|
||||
else {
|
||||
// on mobile, open metamask app link
|
||||
if (isMobile()) {
|
||||
window.open(
|
||||
`https://metamask.app.link/dapp/${window.location.toString()}`,
|
||||
);
|
||||
} else {
|
||||
// on desktop, show the metamask scan qr code
|
||||
setShowScreen("metamask/scan");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Coinbase Wallet
|
||||
else if (wallet.id === walletIds.coinbase) {
|
||||
if (installedWallets.coinbaseWallet) {
|
||||
try {
|
||||
await ifWaiting({
|
||||
for: connect(wallet, {}),
|
||||
moreThan: 100,
|
||||
do: () => {
|
||||
setShowScreen("coinbase/connecting");
|
||||
},
|
||||
});
|
||||
onConnect();
|
||||
} catch (e) {
|
||||
onConnectError();
|
||||
}
|
||||
} else {
|
||||
if (isMobile()) {
|
||||
// coinbase will redirect to download page for coinbase wallet apps
|
||||
connect(wallet, {});
|
||||
} else {
|
||||
setShowScreen("coinbase/scan");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Safe
|
||||
else if (wallet.id === walletIds.safe) {
|
||||
setIsConnectingToWalletWrapper("safe");
|
||||
setShowScreen("safe/select-wallet");
|
||||
}
|
||||
|
||||
// Smart Wallet
|
||||
else if (wallet.id === walletIds.smartWallet) {
|
||||
setIsConnectingToWalletWrapper("smartWallet");
|
||||
setShowScreen("smartWallet/select-wallet");
|
||||
}
|
||||
|
||||
// Local Wallet
|
||||
else if (wallet.id === walletIds.localWallet) {
|
||||
setShowScreen("localWallet/connect");
|
||||
}
|
||||
|
||||
// Magic link
|
||||
else if (wallet.id === walletIds.magicLink) {
|
||||
setShowScreen("magic/connect");
|
||||
}
|
||||
|
||||
// others ( they handle their own connection flow)
|
||||
else {
|
||||
try {
|
||||
setHideModal(true);
|
||||
await connect(wallet, {});
|
||||
onConnect();
|
||||
setHideModal(false);
|
||||
} catch (e) {
|
||||
onConnectError();
|
||||
setHideModal(false);
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
[
|
||||
connect,
|
||||
installedWallets,
|
||||
onConnect,
|
||||
onConnectError,
|
||||
setIsConnectingToWalletWrapper,
|
||||
setShowScreen,
|
||||
],
|
||||
);
|
||||
|
||||
const smartWalletObj = wallets.find((w) => w.id === walletIds.smartWallet) as
|
||||
| SmartWalletObj
|
||||
| undefined;
|
||||
|
||||
const safeWalletObj = wallets.find((w) => w.id === walletIds.safe) as
|
||||
| SafeWalletObj
|
||||
| undefined;
|
||||
|
||||
const walletsInfo: WalletInfo[] = (() => {
|
||||
if (isConnectingToWalletWrapper === "safe") {
|
||||
return safeWalletObj?.config.personalWallets.map(getWalletInfo) || [];
|
||||
}
|
||||
|
||||
if (isConnectingToWalletWrapper === "smartWallet") {
|
||||
return smartWalletObj?.config.personalWallets.map(getWalletInfo) || [];
|
||||
}
|
||||
return wallets.map(getWalletInfo);
|
||||
})();
|
||||
|
||||
// if only one wallet, auto select it
|
||||
const connected = useRef(false);
|
||||
useEffect(() => {
|
||||
if (
|
||||
showScreen === "walletList" &&
|
||||
wallets.length === 1 &&
|
||||
!activeWallet &&
|
||||
isWalletModalOpen &&
|
||||
!connected.current
|
||||
) {
|
||||
connected.current = true;
|
||||
walletsInfo[0].connect();
|
||||
}
|
||||
}, [
|
||||
walletsInfo,
|
||||
showScreen,
|
||||
wallets.length,
|
||||
activeWallet,
|
||||
isWalletModalOpen,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
// if the modal is closed, and isConnectingToWalletWrapper is true, open again and connected
|
||||
if (
|
||||
isConnectingToWalletWrapper &&
|
||||
!isWalletModalOpen &&
|
||||
connectionStatus === "connected"
|
||||
) {
|
||||
setIsWalletModalOpen(true);
|
||||
}
|
||||
}, [
|
||||
isConnectingToWalletWrapper,
|
||||
isWalletModalOpen,
|
||||
connectionStatus,
|
||||
setIsWalletModalOpen,
|
||||
]);
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
theme={
|
||||
typeof modalTheme === "object"
|
||||
? modalTheme
|
||||
: modalTheme === "light"
|
||||
? lightTheme
|
||||
: darkTheme
|
||||
}
|
||||
>
|
||||
<WalletsInfoCtx.Provider value={walletsInfo}>
|
||||
<Modal
|
||||
style={{
|
||||
maxWidth: "480px",
|
||||
}}
|
||||
open={hideModal ? false : isWalletModalOpen}
|
||||
setOpen={(value) => {
|
||||
setIsWalletModalOpen(value);
|
||||
|
||||
if (!value) {
|
||||
if (!isConnectingToWalletWrapper) {
|
||||
closeModalAndReset();
|
||||
if (connectionStatus === "connecting") {
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{showScreen === "walletList" && (
|
||||
<WalletSelector
|
||||
onGetStarted={() => {
|
||||
setShowScreen("wallets/get-started");
|
||||
}}
|
||||
onGuestConnect={() => {
|
||||
setShowScreen("localWallet/connect");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "metamask/get-started" && (
|
||||
<MetamaskGetStarted
|
||||
onBack={() => {
|
||||
setShowScreen("metamask/scan");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "coinbase/get-started" && (
|
||||
<CoinbaseGetStarted
|
||||
onBack={() => {
|
||||
setShowScreen("coinbase/scan");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "metamask/connecting" && (
|
||||
<MetamaskConnecting onBack={handleBack} />
|
||||
)}
|
||||
|
||||
{showScreen === "metamask/scan" && (
|
||||
<ScanMetamask
|
||||
onBack={handleBack}
|
||||
onConnected={onConnect}
|
||||
onGetStarted={() => {
|
||||
setShowScreen("metamask/get-started");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "coinbase/scan" && (
|
||||
<ScanCoinbase
|
||||
onBack={handleBack}
|
||||
onConnected={onConnect}
|
||||
onGetStarted={() => {
|
||||
setShowScreen("coinbase/get-started");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "coinbase/connecting" && (
|
||||
<CoinbaseWalletSetup onBack={handleBack} />
|
||||
)}
|
||||
|
||||
{showScreen === "safe/select-wallet" && (
|
||||
<SelectpersonalWallet
|
||||
safeWallet={safeWalletObj as SafeWalletObj}
|
||||
onBack={() => {
|
||||
if (onlyOneWallet) {
|
||||
return;
|
||||
}
|
||||
setIsConnectingToWalletWrapper(false);
|
||||
setShowScreen("walletList");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "safe/form" && (
|
||||
<SafeForm
|
||||
safeWallet={safeWalletObj as SafeWalletObj}
|
||||
onBack={handleBack}
|
||||
onConnect={() => {
|
||||
closeModalAndReset();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "wallets/get-started" && (
|
||||
<GetStartedWithWallets
|
||||
onBack={handleBack}
|
||||
walletInfo={walletsInfo[0]}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "localWallet/connect" && (
|
||||
<LocalWalletSetup onBack={handleBack} onConnected={onConnect} />
|
||||
)}
|
||||
|
||||
{showScreen === "smartWallet/form" && (
|
||||
<SmartWalletForm
|
||||
smartWallet={smartWalletObj as SmartWalletObj}
|
||||
onBack={handleBack}
|
||||
onConnect={() => {
|
||||
closeModalAndReset();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "smartWallet/select-wallet" && (
|
||||
<SmartWalletSelect
|
||||
smartWallet={smartWalletObj as SmartWalletObj}
|
||||
onBack={() => {
|
||||
if (onlyOneWallet) {
|
||||
return;
|
||||
}
|
||||
setShowScreen("walletList");
|
||||
setIsConnectingToWalletWrapper(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showScreen === "magic/connect" && (
|
||||
<MagicConnect onBack={handleBack} onConnect={onConnect} />
|
||||
)}
|
||||
</Modal>
|
||||
</WalletsInfoCtx.Provider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,119 @@
|
||||
import { Modal } from "../../components/Modal";
|
||||
import { WalletSelector } from "./WalletSelector";
|
||||
import {
|
||||
ConfiguredWallet,
|
||||
useConnectionStatus,
|
||||
useWallets,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import {
|
||||
useIsWalletModalOpen,
|
||||
useModalTheme,
|
||||
useSetIsWalletModalOpen,
|
||||
} from "../../evm/providers/wallet-ui-states-provider";
|
||||
import { ThemeProvider } from "@emotion/react";
|
||||
import { darkTheme, lightTheme } from "../../design-system";
|
||||
import { useState, useCallback, useEffect } from "react";
|
||||
import { GetStartedWithWallets } from "./screens/GetStartedWithWallets";
|
||||
import { reservedScreens } from "./constants";
|
||||
import { HeadlessConnectUI } from "../wallets/headlessConnectUI";
|
||||
|
||||
export const ConnectModal = () => {
|
||||
const modalTheme = useModalTheme();
|
||||
const [screen, setScreen] = useState<string | ConfiguredWallet>(
|
||||
reservedScreens.main,
|
||||
);
|
||||
const isWalletModalOpen = useIsWalletModalOpen();
|
||||
const setIsWalletModalOpen = useSetIsWalletModalOpen();
|
||||
const connectionStatus = useConnectionStatus();
|
||||
const configuredWallets = useWallets();
|
||||
|
||||
const handleClose = useCallback(
|
||||
(reset = true) => {
|
||||
if (reset) {
|
||||
setScreen(reservedScreens.main);
|
||||
}
|
||||
setIsWalletModalOpen(false);
|
||||
},
|
||||
[setIsWalletModalOpen],
|
||||
);
|
||||
|
||||
const handleBack = useCallback(() => {
|
||||
setScreen(reservedScreens.main);
|
||||
}, [setScreen]);
|
||||
|
||||
const isWrapper =
|
||||
typeof screen !== "string" &&
|
||||
"config" in screen &&
|
||||
!!(screen.config as any).personalWallets;
|
||||
|
||||
// if the modal is closed, rendering a wrapper, personal wallet is connected - open modal back
|
||||
useEffect(() => {
|
||||
if (isWrapper && !isWalletModalOpen && connectionStatus === "connected") {
|
||||
setIsWalletModalOpen(true);
|
||||
}
|
||||
}, [isWalletModalOpen, connectionStatus, setIsWalletModalOpen, isWrapper]);
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
theme={
|
||||
typeof modalTheme === "object"
|
||||
? modalTheme
|
||||
: modalTheme === "light"
|
||||
? lightTheme
|
||||
: darkTheme
|
||||
}
|
||||
>
|
||||
<Modal
|
||||
style={{
|
||||
maxWidth: "480px",
|
||||
}}
|
||||
open={isWalletModalOpen}
|
||||
setOpen={(value) => {
|
||||
setIsWalletModalOpen(value);
|
||||
if (!value) {
|
||||
setScreen(reservedScreens.main); // reset screen
|
||||
}
|
||||
}}
|
||||
>
|
||||
{screen === reservedScreens.main && (
|
||||
<WalletSelector
|
||||
configuredWallets={configuredWallets}
|
||||
onGetStarted={() => {
|
||||
setScreen(reservedScreens.getStarted);
|
||||
}}
|
||||
selectWallet={(wallet) => {
|
||||
setScreen(wallet);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{screen === reservedScreens.getStarted && (
|
||||
<GetStartedWithWallets onBack={handleBack} />
|
||||
)}
|
||||
|
||||
{typeof screen !== "string" && screen.connectUI && (
|
||||
<screen.connectUI
|
||||
goBack={handleBack}
|
||||
close={handleClose}
|
||||
isOpen={isWalletModalOpen}
|
||||
open={() => {
|
||||
setIsWalletModalOpen(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{typeof screen !== "string" && !screen.connectUI && (
|
||||
<HeadlessConnectUI
|
||||
goBack={handleBack}
|
||||
close={handleClose}
|
||||
isOpen={isWalletModalOpen}
|
||||
open={() => {
|
||||
setIsWalletModalOpen(true);
|
||||
}}
|
||||
configuredWallet={screen}
|
||||
/>
|
||||
)}
|
||||
</Modal>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useContext, useState } from "react";
|
||||
import {
|
||||
useIsConnectingToWalletWrapper,
|
||||
useSetIsWalletModalOpen,
|
||||
useSetModalTheme,
|
||||
} from "../../evm/providers/wallet-ui-states-provider";
|
||||
@@ -54,7 +53,6 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
|
||||
const activeWallet = useWallet();
|
||||
const themeFromProvider = useContext(ThirdwebThemeContext);
|
||||
const theme = props.theme || themeFromProvider || "dark";
|
||||
const isConnectingToWalletWrapper = useIsConnectingToWalletWrapper();
|
||||
const connectionStatus = useConnectionStatus();
|
||||
|
||||
const isLoading =
|
||||
@@ -122,7 +120,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
|
||||
)}
|
||||
|
||||
{!requiresSignIn &&
|
||||
(!activeWallet || isConnectingToWalletWrapper ? (
|
||||
(!activeWallet ? (
|
||||
// connect wallet button
|
||||
<AnimatedButton
|
||||
disabled={isLoading}
|
||||
|
||||
@@ -21,9 +21,14 @@ import { ExitIcon } from "./icons/ExitIcon";
|
||||
import { keyframes } from "@emotion/react";
|
||||
import styled from "@emotion/styled";
|
||||
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
||||
import { ChevronRightIcon, ShuffleIcon } from "@radix-ui/react-icons";
|
||||
import { defaultChains, Localhost } from "@thirdweb-dev/chains";
|
||||
import {
|
||||
ChevronRightIcon,
|
||||
PinBottomIcon,
|
||||
ShuffleIcon,
|
||||
} from "@radix-ui/react-icons";
|
||||
import { Localhost } from "@thirdweb-dev/chains";
|
||||
import {
|
||||
useActiveChain,
|
||||
useAddress,
|
||||
useBalance,
|
||||
useChainId,
|
||||
@@ -32,8 +37,9 @@ import {
|
||||
useSupportedChains,
|
||||
useThirdwebWallet,
|
||||
useWallet,
|
||||
WalletInstance,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { fadeInAnimation } from "../../components/FadeIn";
|
||||
import {
|
||||
AbstractClientWallet,
|
||||
@@ -44,8 +50,8 @@ import {
|
||||
import { Flex } from "../../components/basic";
|
||||
import { FundsIcon } from "./icons/FundsIcon";
|
||||
import { utils } from "ethers";
|
||||
import { GenericWalletIcon } from "./icons/GenericWalletIcon";
|
||||
import { ExportLocalWallet } from "./screens/LocalWallet/ExportLocalWallet";
|
||||
import { ExportLocalWallet } from "../wallets/localWallet/ExportLocalWallet";
|
||||
import { ErrorMessage } from "../../components/formElements";
|
||||
|
||||
export type DropDownPosition = {
|
||||
side: "top" | "bottom" | "left" | "right";
|
||||
@@ -68,25 +74,12 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
const address = useAddress();
|
||||
const balanceQuery = useBalance();
|
||||
const activeWallet = useWallet();
|
||||
const walletContext = useThirdwebWallet();
|
||||
const [personalWalletBalance, setPersonalWalletBalance] = useState<
|
||||
string | undefined
|
||||
>(undefined);
|
||||
const [personalWalletAddress, setPersonalWalletAddress] = useState<
|
||||
string | undefined
|
||||
>(undefined);
|
||||
const [showExportModal, setShowExportModal] = useState(false);
|
||||
const [wrapperWallet, setWrapperWallet] = useState<
|
||||
WalletInstance | undefined
|
||||
>();
|
||||
|
||||
const chain = useMemo(() => {
|
||||
return chains.find((_chain) => _chain.chainId === walletChainId);
|
||||
}, [walletChainId, chains]);
|
||||
|
||||
const unknownChain = useMemo(() => {
|
||||
if (!chain) {
|
||||
return defaultChains.find((c) => c.chainId === walletChainId);
|
||||
}
|
||||
}, [walletChainId, chain]);
|
||||
|
||||
const chain = useActiveChain();
|
||||
const activeWalletIconURL = activeWallet?.getMeta().iconURL || "";
|
||||
|
||||
const [showNetworkSelector, setShowNetworkSelector] = useState(false);
|
||||
@@ -100,24 +93,6 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
|
||||
const disableSwitchChain = !!personalWallet;
|
||||
|
||||
// get personal wallet address and balance
|
||||
useEffect(() => {
|
||||
if (!personalWallet) {
|
||||
setPersonalWalletAddress(undefined);
|
||||
setPersonalWalletBalance(undefined);
|
||||
return;
|
||||
}
|
||||
personalWallet.getAddress().then((_address) => {
|
||||
setPersonalWalletAddress(_address);
|
||||
});
|
||||
|
||||
personalWallet.getSigner().then((signer) => {
|
||||
signer.getBalance().then((balance) => {
|
||||
setPersonalWalletBalance(utils.formatEther(balance));
|
||||
});
|
||||
});
|
||||
}, [personalWallet]);
|
||||
|
||||
const trigger = (
|
||||
<WalletInfoButton
|
||||
type="button"
|
||||
@@ -141,9 +116,24 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
<Skeleton height={fontSize.sm} width="82px" />
|
||||
)}
|
||||
<Spacer y="xs" />
|
||||
<WalletAddress className={`${TW_CONNECTED_WALLET}__address`}>
|
||||
{shortenString(address || "")}
|
||||
</WalletAddress>
|
||||
|
||||
{activeWallet?.walletId === walletIds.localWallet ? (
|
||||
<ErrorMessage
|
||||
style={{
|
||||
lineHeight: 1,
|
||||
minWidth: "70px",
|
||||
fontSize: fontSize.xs,
|
||||
}}
|
||||
>
|
||||
Guest
|
||||
</ErrorMessage>
|
||||
) : address ? (
|
||||
<WalletAddress className={`${TW_CONNECTED_WALLET}__address`}>
|
||||
{shortenString(address || "")}
|
||||
</WalletAddress>
|
||||
) : (
|
||||
<Skeleton height={fontSize.xs} width="88px" />
|
||||
)}
|
||||
</ColFlex>
|
||||
|
||||
<Img
|
||||
@@ -156,81 +146,39 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
);
|
||||
|
||||
const networkSwitcherButton = (
|
||||
<MenuButton
|
||||
id="current-network"
|
||||
type="button"
|
||||
disabled={disableSwitchChain}
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
setShowNetworkSelector(true);
|
||||
}}
|
||||
<ToolTip
|
||||
tip={
|
||||
disableSwitchChain ? "Network Switching is disabled" : "Switch Network"
|
||||
}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
position: "relative",
|
||||
<MenuButton
|
||||
type="button"
|
||||
disabled={disableSwitchChain}
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
setShowNetworkSelector(true);
|
||||
}}
|
||||
>
|
||||
<ChainIcon chain={chain || unknownChain} size={iconSize.lg} active />
|
||||
</div>
|
||||
{chain?.name || unknownChain?.name || `Unknown chain #${walletChainId}`}
|
||||
<StyledChevronRightIcon
|
||||
width={iconSize.sm}
|
||||
height={iconSize.sm}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
marginLeft: "auto",
|
||||
}}
|
||||
/>
|
||||
</MenuButton>
|
||||
);
|
||||
|
||||
const switchToPersonalWallet = personalWallet && (
|
||||
<MenuButton
|
||||
type="button"
|
||||
onClick={() => {
|
||||
walletContext.handleWalletConnect(personalWallet);
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={personalWallet.getMeta().iconURL}
|
||||
width={iconSize.lg}
|
||||
height={iconSize.lg}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<ChainIcon chain={chain} size={iconSize.lg} active />
|
||||
</div>
|
||||
{chain?.name || `Unknown chain #${walletChainId}`}
|
||||
<StyledChevronRightIcon
|
||||
width={iconSize.sm}
|
||||
height={iconSize.sm}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
marginLeft: "auto",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ColFlex>
|
||||
{personalWalletBalance ? (
|
||||
<WalletBalance>
|
||||
{String(personalWalletBalance).slice(0, 5)}{" "}
|
||||
{balanceQuery.data?.symbol}
|
||||
</WalletBalance>
|
||||
) : (
|
||||
<Skeleton height={fontSize.sm} width="82px" />
|
||||
)}
|
||||
<Spacer y="xxs" />
|
||||
<WalletAddress>
|
||||
{shortenString(personalWalletAddress || "")}
|
||||
</WalletAddress>
|
||||
</ColFlex>
|
||||
|
||||
<StyledChevronRightIcon
|
||||
width={iconSize.sm}
|
||||
height={iconSize.sm}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
marginLeft: "auto",
|
||||
}}
|
||||
/>
|
||||
</MenuButton>
|
||||
</MenuButton>
|
||||
</ToolTip>
|
||||
);
|
||||
|
||||
const content = (
|
||||
@@ -305,7 +253,7 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
|
||||
{/* Network Switcher */}
|
||||
<div>
|
||||
<DropdownLabel htmlFor="current-network">Current Network</DropdownLabel>
|
||||
<DropdownLabel>Current Network</DropdownLabel>
|
||||
<Spacer y="sm" />
|
||||
{networkSwitcherButton}
|
||||
</div>
|
||||
@@ -314,13 +262,31 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
{personalWallet && (
|
||||
<div>
|
||||
<Spacer y="lg" />
|
||||
<DropdownLabel htmlFor="current-network">
|
||||
Personal Wallet
|
||||
<DropdownLabel>Switch to Personal Wallet</DropdownLabel>
|
||||
<Spacer y="xs" />
|
||||
<WalletSwitcher
|
||||
wallet={personalWallet}
|
||||
onSwitch={() => {
|
||||
setWrapperWallet(activeWallet);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Switch to Wrapper Wallet */}
|
||||
{wrapperWallet && (
|
||||
<div>
|
||||
<Spacer y="lg" />
|
||||
<DropdownLabel>
|
||||
Switch to {wrapperWallet.getMeta().name}
|
||||
</DropdownLabel>
|
||||
<Spacer y="sm" />
|
||||
<ToolTip tip="Switch To Personal Wallet">
|
||||
{switchToPersonalWallet}
|
||||
</ToolTip>
|
||||
<Spacer y="xs" />
|
||||
<WalletSwitcher
|
||||
wallet={wrapperWallet}
|
||||
onSwitch={() => {
|
||||
setWrapperWallet(undefined);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -334,6 +300,9 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
(activeWallet as MetaMaskWallet).switchAccount();
|
||||
setOpen(false);
|
||||
}}
|
||||
style={{
|
||||
fontSize: fontSize.sm,
|
||||
}}
|
||||
>
|
||||
<ShuffleIcon width={iconSize.sm} height={iconSize.sm} />
|
||||
Switch Account
|
||||
@@ -386,10 +355,21 @@ export const ConnectedWalletDetails: React.FC<{
|
||||
}}
|
||||
>
|
||||
<SecondaryIconContainer>
|
||||
<GenericWalletIcon size={iconSize.sm} />
|
||||
<PinBottomIcon width={iconSize.sm} height={iconSize.sm} />
|
||||
</SecondaryIconContainer>
|
||||
Export Wallet{" "}
|
||||
Backup wallet{" "}
|
||||
</MenuButton>
|
||||
<Spacer y="sm" />
|
||||
<ErrorMessage
|
||||
style={{
|
||||
fontSize: fontSize.xs,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
This is a temporary guest wallet <br />
|
||||
Backup if you {`don't `}
|
||||
want to lose access to it
|
||||
</ErrorMessage>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -581,6 +561,12 @@ const MenuButton = styled.button<{ theme?: Theme }>`
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled]:hover {
|
||||
transition: box-shadow 250ms ease, border-color 250ms ease;
|
||||
border: 1px solid ${(props) => props.theme.text.danger};
|
||||
box-shadow: 0 0 0 1px ${(props) => props.theme.text.danger};
|
||||
}
|
||||
`;
|
||||
|
||||
const MenuLink = MenuButton.withComponent("a");
|
||||
@@ -611,3 +597,81 @@ const SecondaryIconContainer = styled.div<{ theme?: Theme }>`
|
||||
justify-content: center;
|
||||
color: ${(props) => props.theme.icon.secondary};
|
||||
`;
|
||||
|
||||
function WalletSwitcher({
|
||||
wallet,
|
||||
onSwitch,
|
||||
}: {
|
||||
wallet: WalletInstance;
|
||||
onSwitch: () => void;
|
||||
}) {
|
||||
const walletContext = useThirdwebWallet();
|
||||
const balanceQuery = useBalance();
|
||||
const [walletBalance, setWalletBalance] = useState<string | undefined>(
|
||||
undefined,
|
||||
);
|
||||
const [address, setAddress] = useState<string | undefined>(undefined);
|
||||
|
||||
// get personal wallet address and balance
|
||||
useEffect(() => {
|
||||
if (!wallet) {
|
||||
setAddress(undefined);
|
||||
setWalletBalance(undefined);
|
||||
return;
|
||||
}
|
||||
wallet.getAddress().then((_address) => {
|
||||
setAddress(_address);
|
||||
});
|
||||
|
||||
wallet.getSigner().then((signer) => {
|
||||
signer.getBalance().then((balance) => {
|
||||
setWalletBalance(utils.formatEther(balance));
|
||||
});
|
||||
});
|
||||
}, [wallet]);
|
||||
|
||||
return (
|
||||
<MenuButton
|
||||
type="button"
|
||||
onClick={() => {
|
||||
walletContext.handleWalletConnect(wallet);
|
||||
onSwitch();
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={wallet.getMeta().iconURL}
|
||||
width={iconSize.lg}
|
||||
height={iconSize.lg}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ColFlex>
|
||||
{walletBalance ? (
|
||||
<WalletBalance>
|
||||
{String(walletBalance).slice(0, 5)} {balanceQuery.data?.symbol}
|
||||
</WalletBalance>
|
||||
) : (
|
||||
<Skeleton height={fontSize.sm} width="82px" />
|
||||
)}
|
||||
<Spacer y="xxs" />
|
||||
<WalletAddress>{shortenString(address || "")}</WalletAddress>
|
||||
</ColFlex>
|
||||
|
||||
<StyledChevronRightIcon
|
||||
width={iconSize.sm}
|
||||
height={iconSize.sm}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
marginLeft: "auto",
|
||||
}}
|
||||
/>
|
||||
</MenuButton>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,35 +11,43 @@ import {
|
||||
Theme,
|
||||
} from "../../design-system";
|
||||
import styled from "@emotion/styled";
|
||||
import { useWalletInfo, useWalletsInfo } from "./walletInfo";
|
||||
import { WalletInfo } from "../types";
|
||||
import { ConfiguredWallet } from "@thirdweb-dev/react-core";
|
||||
import { useConfiguredWallet } from "../hooks/useConfiguredWallet";
|
||||
import { walletIds } from "@thirdweb-dev/wallets";
|
||||
|
||||
export const WalletSelector: React.FC<{
|
||||
configuredWallets: ConfiguredWallet[];
|
||||
selectWallet: (wallet: ConfiguredWallet) => void;
|
||||
onGetStarted: () => void;
|
||||
onGuestConnect: () => void;
|
||||
}> = (props) => {
|
||||
const _allWalletsInfo = useWalletsInfo();
|
||||
const allWalletsInfo = _allWalletsInfo.filter(
|
||||
(w) => w.wallet.id !== walletIds.localWallet,
|
||||
const localWalletInfo = useConfiguredWallet("localWallet", false);
|
||||
const configuredWallets = props.configuredWallets.filter(
|
||||
(w) => w.id !== walletIds.localWallet,
|
||||
);
|
||||
const localWalletInfo = useWalletInfo("localWallet", false);
|
||||
|
||||
const showGetStarted =
|
||||
!localWalletInfo && !!allWalletsInfo[0].wallet.meta.urls;
|
||||
!localWalletInfo && !!props.configuredWallets[0].meta.urls;
|
||||
|
||||
return (
|
||||
<>
|
||||
<ModalTitle>Choose your wallet</ModalTitle>
|
||||
<Spacer y="xl" />
|
||||
|
||||
<WalletSelection walletsInfo={allWalletsInfo} />
|
||||
<WalletSelection
|
||||
configuredWallets={configuredWallets}
|
||||
selectWallet={props.selectWallet}
|
||||
/>
|
||||
|
||||
{localWalletInfo && (
|
||||
<>
|
||||
<Spacer y="xl" />
|
||||
<Flex justifyContent="center">
|
||||
<Button variant="link" onClick={props.onGuestConnect}>
|
||||
<Button
|
||||
variant="link"
|
||||
onClick={() => {
|
||||
props.selectWallet(localWalletInfo);
|
||||
}}
|
||||
>
|
||||
Continue as guest
|
||||
</Button>
|
||||
</Flex>
|
||||
@@ -66,15 +74,19 @@ export const WalletSelector: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
export const WalletSelection: React.FC<{ walletsInfo: WalletInfo[] }> = ({
|
||||
walletsInfo,
|
||||
}) => {
|
||||
export const WalletSelection: React.FC<{
|
||||
configuredWallets: ConfiguredWallet[];
|
||||
selectWallet: (wallet: ConfiguredWallet) => void;
|
||||
}> = (props) => {
|
||||
// show the installed wallets first
|
||||
const sortedWalletsInfo = walletsInfo.sort((a, b) => {
|
||||
if (a.installed && !b.installed) {
|
||||
const configuredWallets = props.configuredWallets.sort((a, b) => {
|
||||
const aInstalled = a.isInstalled ? a.isInstalled() : false;
|
||||
const bInstalled = b.isInstalled ? b.isInstalled() : false;
|
||||
|
||||
if (aInstalled && !bInstalled) {
|
||||
return -1;
|
||||
}
|
||||
if (!a.installed && b.installed) {
|
||||
if (!aInstalled && bInstalled) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -82,23 +94,26 @@ export const WalletSelection: React.FC<{ walletsInfo: WalletInfo[] }> = ({
|
||||
|
||||
return (
|
||||
<WalletList>
|
||||
{sortedWalletsInfo.map((walletInfo) => {
|
||||
{configuredWallets.map((configuredWallet) => {
|
||||
const isInstalled = configuredWallet.isInstalled
|
||||
? configuredWallet.isInstalled()
|
||||
: false;
|
||||
return (
|
||||
<li key={walletInfo.wallet.id}>
|
||||
<li key={configuredWallet.id}>
|
||||
<WalletButton
|
||||
type="button"
|
||||
onClick={() => {
|
||||
walletInfo.connect();
|
||||
props.selectWallet(configuredWallet);
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={walletInfo.wallet.meta.iconURL}
|
||||
src={configuredWallet.meta.iconURL}
|
||||
width={iconSize.lg}
|
||||
height={iconSize.lg}
|
||||
loading="eager"
|
||||
/>
|
||||
<WalletName>{walletInfo.wallet.meta.name}</WalletName>
|
||||
{walletInfo.installed && <InstallBadge> Installed </InstallBadge>}
|
||||
<WalletName>{configuredWallet.meta.name}</WalletName>
|
||||
{isInstalled && <InstallBadge> Installed </InstallBadge>}
|
||||
</WalletButton>
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export const reservedScreens = {
|
||||
main: "main",
|
||||
getStarted: "getStarted",
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
import { IconFC } from "./types";
|
||||
|
||||
export const GenericWalletIcon: IconFC = ({ size }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height={size}
|
||||
viewBox="0 96 960 960"
|
||||
width={size}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M652 640q25 0 44.5-19.5t19.5-45q0-25.5-19.5-44.5T652 512q-25 0-44.5 19T588 575.5q0 25.5 19.5 45T652 640ZM180 823v53-600 547Zm0 113q-23 0-41.5-18T120 876V276q0-23 18.5-41.5T180 216h600q24 0 42 18.5t18 41.5v134h-60V276H180v600h600V743h60v133q0 24-18 42t-42 18H180Zm358-173q-34 0-54-20t-20-53V463q0-34 20-53.5t54-19.5h270q34 0 54 19.5t20 53.5v227q0 33-20 53t-54 20H538Zm284-60V450H524v253h298Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
import { ConnectingScreen } from "../ConnectingScreen";
|
||||
import { useWalletInfo } from "../../walletInfo";
|
||||
|
||||
export const CoinbaseWalletSetup: React.FC<{
|
||||
onBack: () => void;
|
||||
}> = ({ onBack }) => {
|
||||
const coinbase = useWalletInfo("coinbase", true);
|
||||
|
||||
return (
|
||||
<ConnectingScreen
|
||||
onBack={onBack}
|
||||
walletName={coinbase.wallet.meta.name}
|
||||
walletIconURL={coinbase.wallet.meta.iconURL}
|
||||
supportLink="https://help.coinbase.com/en/wallet/other-topics/troubleshooting-and-tips"
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
import { GetStartedScreen } from "../GetStartedScreen";
|
||||
import { useWalletInfo } from "../../walletInfo";
|
||||
|
||||
export const CoinbaseGetStarted: React.FC<{
|
||||
onBack: () => void;
|
||||
}> = ({ onBack }) => {
|
||||
const coinbaseWalletObj = useWalletInfo("coinbase", true);
|
||||
const { name, iconURL } = coinbaseWalletObj.wallet.meta;
|
||||
|
||||
return (
|
||||
<GetStartedScreen
|
||||
walletIconURL={iconURL}
|
||||
walletName={name}
|
||||
chromeExtensionLink="https://chrome.google.com/webstore/detail/coinbase-wallet-extension/hnfanknocfeofbddgcijnmhnfnkdnaad"
|
||||
googlePlayStoreLink="https://play.google.com/store/apps/details?id=org.toshi"
|
||||
appleStoreLink="https://apps.apple.com/us/app/coinbase-wallet-nfts-crypto/id1278383455"
|
||||
onBack={onBack}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -8,14 +8,17 @@ import {
|
||||
import { fontSize, iconSize, spacing, Theme } from "../../../design-system";
|
||||
import { GetStartedScreen } from "./GetStartedScreen";
|
||||
import styled from "@emotion/styled";
|
||||
import { WalletInfo } from "../../types";
|
||||
import { SecondaryText } from "../../../components/text";
|
||||
import { useWallets } from "@thirdweb-dev/react-core";
|
||||
|
||||
export const GetStartedWithWallets: React.FC<{
|
||||
onBack: () => void;
|
||||
walletInfo: WalletInfo;
|
||||
}> = ({ walletInfo, onBack }) => {
|
||||
const { meta } = walletInfo.wallet;
|
||||
}> = ({ onBack }) => {
|
||||
const configuredWallets = useWallets();
|
||||
console.log({
|
||||
configuredWallets,
|
||||
});
|
||||
const { meta } = configuredWallets[0];
|
||||
|
||||
return (
|
||||
<GetStartedScreen
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
import { Spacer } from "../../../../components/Spacer";
|
||||
import { Button } from "../../../../components/buttons";
|
||||
import { FormFooter, Label } from "../../../../components/formElements";
|
||||
import {
|
||||
ModalTitle,
|
||||
ModalDescription,
|
||||
} from "../../../../components/modalElements";
|
||||
import { Theme, iconSize } from "../../../../design-system";
|
||||
import styled from "@emotion/styled";
|
||||
import { fontSize } from "../../../../design-system";
|
||||
import { EyeClosedIcon, EyeOpenIcon } from "@radix-ui/react-icons";
|
||||
import { FormFieldWithIconButton } from "../../../../components/formFields";
|
||||
import { useEffect, useState } from "react";
|
||||
import { shortenAddress } from "../../../../evm/utils/addresses";
|
||||
import { LocalWallet } from "@thirdweb-dev/wallets";
|
||||
import { GenericWalletIcon } from "../../icons/GenericWalletIcon";
|
||||
|
||||
export const ExportLocalWallet: React.FC<{
|
||||
onBack: () => void;
|
||||
onExport: () => void;
|
||||
localWallet: LocalWallet;
|
||||
}> = (props) => {
|
||||
const [password, setPassword] = useState("");
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [isWrongPassword, setIsWrongPassword] = useState(false);
|
||||
const [address, setAddress] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
props.localWallet.getAddress().then((add) => {
|
||||
setAddress(add);
|
||||
});
|
||||
}, [props.localWallet]);
|
||||
|
||||
const exportFromLocalStorage = async () => {
|
||||
if (!props.localWallet) {
|
||||
throw new Error("invalid state");
|
||||
}
|
||||
|
||||
try {
|
||||
// await props.localWallet.import({
|
||||
// encryptedJson: walletData.data,
|
||||
// password,
|
||||
// });
|
||||
|
||||
const json = await props.localWallet.export({
|
||||
strategy: "encryptedJson",
|
||||
password,
|
||||
});
|
||||
|
||||
downloadAsFile(JSON.parse(json), "wallet.json", "application/json");
|
||||
props.onExport();
|
||||
} catch (e) {
|
||||
setIsWrongPassword(true);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<GenericWalletIcon size={iconSize.xl} />
|
||||
<Spacer y="lg" />
|
||||
<ModalTitle
|
||||
style={{
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
Export Wallet
|
||||
</ModalTitle>
|
||||
|
||||
<Spacer y="md" />
|
||||
|
||||
<ModalDescription>
|
||||
This will download a JSON file containing your wallet information onto
|
||||
your device encrypted with the password.
|
||||
</ModalDescription>
|
||||
|
||||
<Spacer y="xl" />
|
||||
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
exportFromLocalStorage();
|
||||
}}
|
||||
>
|
||||
<Label>Wallet Address</Label>
|
||||
<Spacer y="sm" />
|
||||
|
||||
<SavedWalletAddress>
|
||||
{address ? shortenAddress(address) : "Loading"}
|
||||
</SavedWalletAddress>
|
||||
|
||||
<Spacer y="lg" />
|
||||
|
||||
{/* Hidden Account Address as Username */}
|
||||
<input
|
||||
type="text"
|
||||
name="username"
|
||||
autoComplete="off"
|
||||
value={address}
|
||||
disabled
|
||||
style={{ display: "none" }}
|
||||
/>
|
||||
|
||||
{/* password */}
|
||||
<FormFieldWithIconButton
|
||||
noSave
|
||||
required
|
||||
name="current-password"
|
||||
autocomplete="current-password"
|
||||
id="current-password"
|
||||
onChange={(value) => {
|
||||
setPassword(value);
|
||||
setIsWrongPassword(false);
|
||||
}}
|
||||
right={{
|
||||
onClick: () => setShowPassword(!showPassword),
|
||||
icon: showPassword ? <EyeClosedIcon /> : <EyeOpenIcon />,
|
||||
}}
|
||||
label="Password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
value={password}
|
||||
error={isWrongPassword ? "Wrong Password" : ""}
|
||||
/>
|
||||
|
||||
<Spacer y="xl" />
|
||||
|
||||
<FormFooter>
|
||||
<Button disabled={isWrongPassword} variant="inverted" type="submit">
|
||||
Export
|
||||
</Button>
|
||||
</FormFooter>
|
||||
</form>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
function downloadAsFile(data: any, fileName: string, fileType: string) {
|
||||
const blob = new Blob([JSON.stringify(data, null, 2)], {
|
||||
type: fileType,
|
||||
});
|
||||
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = fileName;
|
||||
document.body.appendChild(a);
|
||||
a.style.display = "none";
|
||||
a.click();
|
||||
URL.revokeObjectURL(a.href);
|
||||
}
|
||||
|
||||
const SavedWalletAddress = styled.p<{ theme?: Theme }>`
|
||||
font-size: ${fontSize.md};
|
||||
color: ${(props) => props.theme.text.secondary};
|
||||
margin: 0;
|
||||
`;
|
||||
@@ -1,51 +0,0 @@
|
||||
import { Spinner } from "../../../../components/Spinner";
|
||||
import styled from "@emotion/styled";
|
||||
import { useLocalWalletInfo } from "./useLocalWalletInfo";
|
||||
import {
|
||||
CreateLocalWallet_Guest,
|
||||
CreateLocalWallet_Password,
|
||||
} from "./CreateLocalWallet";
|
||||
import { ReconnectLocalWallet } from "./ReconnectLocalWallet";
|
||||
import { LocalWalletObj } from "../../../wallets/localWallet";
|
||||
import { useWalletInfo } from "../../walletInfo";
|
||||
|
||||
export const LocalWalletSetup: React.FC<{
|
||||
onBack: () => void;
|
||||
onConnected: () => void;
|
||||
}> = (props) => {
|
||||
const { walletData } = useLocalWalletInfo();
|
||||
|
||||
const localWalletInfo = useWalletInfo("localWallet", true);
|
||||
|
||||
const wallet = localWalletInfo.wallet as LocalWalletObj;
|
||||
|
||||
if (!wallet.config.persist) {
|
||||
return <CreateLocalWallet_Guest {...props} />;
|
||||
}
|
||||
|
||||
if (walletData === "loading") {
|
||||
return (
|
||||
<LoadingSpinnerContainer>
|
||||
<Spinner size="lg" color="primary" />
|
||||
</LoadingSpinnerContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (walletData) {
|
||||
return (
|
||||
<ReconnectLocalWallet
|
||||
onConnected={props.onConnected}
|
||||
onBack={props.onBack}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <CreateLocalWallet_Password {...props} />;
|
||||
};
|
||||
|
||||
const LoadingSpinnerContainer = styled.div`
|
||||
height: 300px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
@@ -1,19 +0,0 @@
|
||||
import { iconSize } from "../../../../design-system";
|
||||
import { Img } from "../../../../components/Img";
|
||||
import { Spacer } from "../../../../components/Spacer";
|
||||
import { BackButton } from "../../../../components/modalElements";
|
||||
import { Wallet } from "@thirdweb-dev/react-core";
|
||||
|
||||
export const LocalWalletModalHeader: React.FC<{
|
||||
onBack: () => void;
|
||||
meta: Wallet["meta"];
|
||||
}> = (props) => {
|
||||
return (
|
||||
<>
|
||||
<BackButton onClick={props.onBack} />
|
||||
<Spacer y="md" />
|
||||
<Img src={props.meta.iconURL} width={iconSize.xl} height={iconSize.xl} />
|
||||
<Spacer y="sm" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
import { ConnectingScreen } from "../ConnectingScreen";
|
||||
import { useWalletInfo } from "../../walletInfo";
|
||||
|
||||
export const MetamaskConnecting: React.FC<{
|
||||
onBack: () => void;
|
||||
}> = (props) => {
|
||||
const metamaskInfo = useWalletInfo("metamask", true);
|
||||
const { name, iconURL } = metamaskInfo.wallet.meta;
|
||||
return (
|
||||
<ConnectingScreen
|
||||
onBack={props.onBack}
|
||||
walletName={name}
|
||||
walletIconURL={iconURL}
|
||||
supportLink="https://support.metamask.io/hc/en-us/articles/4406430256539-User-Guide-Troubleshooting"
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
import { GetStartedScreen } from "../GetStartedScreen";
|
||||
import { useWalletInfo } from "../../walletInfo";
|
||||
|
||||
export const MetamaskGetStarted: React.FC<{
|
||||
onBack: () => void;
|
||||
}> = (props) => {
|
||||
const walletInfo = useWalletInfo("metamask", true);
|
||||
const { name, iconURL } = walletInfo?.wallet.meta;
|
||||
|
||||
return (
|
||||
<GetStartedScreen
|
||||
walletIconURL={iconURL}
|
||||
walletName={name}
|
||||
chromeExtensionLink="https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn"
|
||||
googlePlayStoreLink="https://play.google.com/store/apps/details?id=io.metamask"
|
||||
appleStoreLink="https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202"
|
||||
onBack={props.onBack}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,69 +0,0 @@
|
||||
import { walletIds } from "@thirdweb-dev/wallets";
|
||||
import { Img } from "../../../../components/Img";
|
||||
import { Spacer } from "../../../../components/Spacer";
|
||||
import { Flex } from "../../../../components/basic";
|
||||
import { Button } from "../../../../components/buttons";
|
||||
import {
|
||||
BackButton,
|
||||
ModalTitle,
|
||||
ModalDescription,
|
||||
} from "../../../../components/modalElements";
|
||||
import { iconSize, spacing } from "../../../../design-system";
|
||||
import { WalletSelection } from "../../WalletSelector";
|
||||
import styled from "@emotion/styled";
|
||||
import { SmartWalletObj } from "../../../wallets/smartWallet";
|
||||
import { useWalletInfo, useWalletsInfo } from "../../walletInfo";
|
||||
|
||||
export const SmartWalletSelect: React.FC<{
|
||||
onBack: () => void;
|
||||
smartWallet: SmartWalletObj;
|
||||
}> = (props) => {
|
||||
const guestWallet = useWalletInfo("localWallet", false);
|
||||
const allWalletsInfo = useWalletsInfo();
|
||||
|
||||
const walletsInfo = allWalletsInfo.filter(
|
||||
(w) =>
|
||||
w.wallet.id !== walletIds.smartWallet &&
|
||||
w.wallet.id !== walletIds.safe &&
|
||||
w.wallet.id !== walletIds.localWallet,
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<BackButton onClick={props.onBack} />
|
||||
<IconContainer>
|
||||
<Img
|
||||
src={props.smartWallet.meta.iconURL}
|
||||
width={iconSize.xl}
|
||||
height={iconSize.xl}
|
||||
/>
|
||||
</IconContainer>
|
||||
<Spacer y="lg" />
|
||||
<ModalTitle>Choose your wallet</ModalTitle>
|
||||
<Spacer y="sm" />
|
||||
|
||||
<ModalDescription>
|
||||
Select a personal wallet to connect to smart wallet
|
||||
</ModalDescription>
|
||||
|
||||
<Spacer y="lg" />
|
||||
|
||||
<WalletSelection walletsInfo={walletsInfo} />
|
||||
|
||||
{guestWallet && (
|
||||
<>
|
||||
<Spacer y="xl" />
|
||||
<Flex justifyContent="center">
|
||||
<Button variant="link" onClick={guestWallet.connect}>
|
||||
Continue as guest
|
||||
</Button>
|
||||
</Flex>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const IconContainer = styled.div`
|
||||
margin-top: ${spacing.lg};
|
||||
`;
|
||||
@@ -1,29 +0,0 @@
|
||||
import { walletIds } from "@thirdweb-dev/wallets";
|
||||
import { createContext, useContext } from "react";
|
||||
import { WalletInfo } from "../types";
|
||||
|
||||
export const WalletsInfoCtx = createContext<WalletInfo[]>([]);
|
||||
|
||||
export function useWalletInfo(
|
||||
id: keyof typeof walletIds,
|
||||
required: true,
|
||||
): WalletInfo;
|
||||
export function useWalletInfo(
|
||||
id: keyof typeof walletIds,
|
||||
required: false,
|
||||
): WalletInfo | undefined;
|
||||
export function useWalletInfo(
|
||||
id: keyof typeof walletIds,
|
||||
required: true | false,
|
||||
): WalletInfo | undefined {
|
||||
const walletsInfo = useContext(WalletsInfoCtx);
|
||||
const found = walletsInfo.find((w) => w.wallet.id === id);
|
||||
if (required && !found) {
|
||||
throw new Error(`Wallet ${id} not found`);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
export function useWalletsInfo() {
|
||||
return useContext(WalletsInfoCtx);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { walletIds } from "@thirdweb-dev/wallets";
|
||||
import { ConfiguredWallet, useWallets } from "@thirdweb-dev/react-core";
|
||||
|
||||
// TODO :may be this is not needed anymore - only used in a few places
|
||||
|
||||
export function useConfiguredWallet(
|
||||
id: keyof typeof walletIds,
|
||||
required: true,
|
||||
): ConfiguredWallet;
|
||||
export function useConfiguredWallet(
|
||||
id: keyof typeof walletIds,
|
||||
required: false,
|
||||
): ConfiguredWallet | undefined;
|
||||
export function useConfiguredWallet(
|
||||
id: keyof typeof walletIds,
|
||||
required: true | false,
|
||||
): ConfiguredWallet | undefined {
|
||||
const wallets = useWallets();
|
||||
const found = wallets.find((w) => w.id === id);
|
||||
if (required && !found) {
|
||||
throw new Error(`Wallet ${id} not found`);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { Wallet } from "@thirdweb-dev/react-core";
|
||||
|
||||
export type WalletInfo = {
|
||||
wallet: Wallet;
|
||||
installed: boolean;
|
||||
connect: () => Promise<void>;
|
||||
};
|
||||
@@ -0,0 +1,103 @@
|
||||
import {
|
||||
ConfiguredWallet,
|
||||
ConnectUIProps,
|
||||
useConnect,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { ConnectingScreen } from "../../ConnectWallet/screens/ConnectingScreen";
|
||||
import { isMobile } from "../../../evm/utils/isMobile";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { GetStartedScreen } from "../../ConnectWallet/screens/GetStartedScreen";
|
||||
import { CoinbaseScan } from "./CoinbaseScan";
|
||||
|
||||
type CoinbaseConnectUIProps = ConnectUIProps & {
|
||||
configuredWallet: ConfiguredWallet;
|
||||
};
|
||||
|
||||
export const CoinbaseConnectUI = ({
|
||||
configuredWallet,
|
||||
close,
|
||||
goBack,
|
||||
}: CoinbaseConnectUIProps) => {
|
||||
const connect = useConnect();
|
||||
const { meta } = configuredWallet;
|
||||
const [screen, setScreen] = useState<
|
||||
"connecting" | "loading" | "scanning" | "get-started"
|
||||
>("loading");
|
||||
|
||||
const connectPrompted = useRef(false);
|
||||
useEffect(() => {
|
||||
if (screen !== "loading") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectPrompted.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isInstalled = configuredWallet.isInstalled
|
||||
? configuredWallet.isInstalled()
|
||||
: false;
|
||||
|
||||
// if loading
|
||||
(async () => {
|
||||
if (isInstalled) {
|
||||
try {
|
||||
connectPrompted.current = true;
|
||||
setScreen("connecting");
|
||||
await connect(configuredWallet);
|
||||
close();
|
||||
} catch (e) {
|
||||
goBack();
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
// if metamask is not injected
|
||||
else {
|
||||
if (isMobile()) {
|
||||
// coinbase will redirect to download page for coinbase wallet apps
|
||||
connect(configuredWallet);
|
||||
} else {
|
||||
setScreen("scanning");
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, [screen, configuredWallet, close, connect, goBack]);
|
||||
|
||||
if (screen === "connecting" || screen === "loading") {
|
||||
return (
|
||||
<ConnectingScreen
|
||||
onBack={goBack}
|
||||
walletName={meta.name}
|
||||
walletIconURL={meta.iconURL}
|
||||
supportLink="https://help.coinbase.com/en/wallet/other-topics/troubleshooting-and-tips"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (screen === "get-started") {
|
||||
return (
|
||||
<GetStartedScreen
|
||||
walletIconURL={meta.iconURL}
|
||||
walletName={meta.name}
|
||||
chromeExtensionLink={meta.urls?.chrome}
|
||||
googlePlayStoreLink={meta.urls?.android}
|
||||
appleStoreLink={meta.urls?.ios}
|
||||
onBack={goBack}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (screen === "scanning") {
|
||||
return (
|
||||
<CoinbaseScan
|
||||
onBack={goBack}
|
||||
onConnected={close}
|
||||
onGetStarted={() => setScreen("get-started")}
|
||||
configuredWallet={configuredWallet}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
+11
-14
@@ -1,28 +1,25 @@
|
||||
import { ScanScreen } from "../ScanScreen";
|
||||
import { CoinbaseWallet } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
ConfiguredWallet,
|
||||
useCreateWalletInstance,
|
||||
useThirdwebWallet,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useWalletInfo } from "../../walletInfo";
|
||||
import { ScanScreen } from "../../ConnectWallet/screens/ScanScreen";
|
||||
|
||||
export const ScanCoinbase: React.FC<{
|
||||
export const CoinbaseScan: React.FC<{
|
||||
onBack: () => void;
|
||||
onGetStarted: () => void;
|
||||
onConnected: () => void;
|
||||
}> = (props) => {
|
||||
configuredWallet: ConfiguredWallet;
|
||||
}> = ({ configuredWallet, onConnected, onGetStarted, onBack }) => {
|
||||
const createInstance = useCreateWalletInstance();
|
||||
const [qrCodeUri, setQrCodeUri] = useState<string | undefined>(undefined);
|
||||
const twWalletContext = useThirdwebWallet();
|
||||
const { onConnected } = props;
|
||||
const coinbaseWalletInfo = useWalletInfo("coinbase", true);
|
||||
const cbWalletObj = coinbaseWalletInfo?.wallet;
|
||||
const { name, iconURL } = cbWalletObj.meta;
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const wallet = createInstance(cbWalletObj) as InstanceType<
|
||||
const wallet = createInstance(configuredWallet) as InstanceType<
|
||||
typeof CoinbaseWallet
|
||||
>;
|
||||
|
||||
@@ -39,15 +36,15 @@ export const ScanCoinbase: React.FC<{
|
||||
onConnected();
|
||||
});
|
||||
})();
|
||||
}, [createInstance, twWalletContext, onConnected, cbWalletObj]);
|
||||
}, [createInstance, twWalletContext, onConnected, configuredWallet]);
|
||||
|
||||
return (
|
||||
<ScanScreen
|
||||
onBack={props.onBack}
|
||||
onGetStarted={props.onGetStarted}
|
||||
onBack={onBack}
|
||||
onGetStarted={onGetStarted}
|
||||
qrCodeUri={qrCodeUri}
|
||||
walletName={name}
|
||||
walletIconURL={iconURL}
|
||||
walletName={configuredWallet.meta.name}
|
||||
walletIconURL={configuredWallet.meta.iconURL}
|
||||
/>
|
||||
);
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user