Compare commits
27
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7faab1c09b | ||
|
|
8bb0a6d874 | ||
|
|
b1ede491fb | ||
|
|
f674da7b44 | ||
|
|
748e3e7856 | ||
|
|
738c0ec6c4 | ||
|
|
e4356e76d1 | ||
|
|
8a0dd070d4 | ||
|
|
39bd963015 | ||
|
|
84fc3b6fab | ||
|
|
49ec2d171e | ||
|
|
b92aabe450 | ||
|
|
470e0a144d | ||
|
|
b6bb73b34c | ||
|
|
9886c858d9 | ||
|
|
25de32d45d | ||
|
|
d495a4b8a6 | ||
|
|
2b0fb9d22f | ||
|
|
e9b69300d1 | ||
|
|
4f8438335e | ||
|
|
c3645c451b | ||
|
|
482f6d1b58 | ||
|
|
799d98e862 | ||
|
|
8db78299ea | ||
|
|
1119f63a47 | ||
|
|
32908b7683 | ||
|
|
6a4aab0b8a |
+4
-1
@@ -16,4 +16,7 @@ public/dist
|
||||
yalc.lock
|
||||
build/
|
||||
playwright-report/
|
||||
.vscode/
|
||||
.vscode/
|
||||
|
||||
# Artifacts
|
||||
packages/cli/artifacts/
|
||||
@@ -1,5 +1,21 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 3.0.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1013](https://github.com/thirdweb-dev/js/pull/1013) [`b92aabe4`](https://github.com/thirdweb-dev/js/commit/b92aabe450f40b248fd1b7533f1d3bc7f8f25288) Thanks [@adam-maj](https://github.com/adam-maj)! - Expose request on onUser hook
|
||||
|
||||
- Updated dependencies [[`738c0ec6`](https://github.com/thirdweb-dev/js/commit/738c0ec6c4190aa2252233c1382aed5d982cc7b8), [`d495a4b8`](https://github.com/thirdweb-dev/js/commit/d495a4b8a6e0599e5b4611620f3fded80a411173), [`4f843833`](https://github.com/thirdweb-dev/js/commit/4f8438335e3e3731b67ae271cb34c383832242a0)]:
|
||||
- @thirdweb-dev/wallets@0.2.20
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "3.0.17",
|
||||
"version": "3.0.19",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -51,7 +51,7 @@ export async function getUser<
|
||||
return authenticatedUser;
|
||||
}
|
||||
|
||||
const data = await ctx.callbacks.onUser(authenticatedUser);
|
||||
const data = await ctx.callbacks.onUser(authenticatedUser, req);
|
||||
if (!data) {
|
||||
return authenticatedUser;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ export async function getUser<
|
||||
return authenticatedUser;
|
||||
}
|
||||
|
||||
const data = await ctx.callbacks.onUser(authenticatedUser);
|
||||
const data = await ctx.callbacks.onUser(authenticatedUser, req);
|
||||
if (!data) {
|
||||
return authenticatedUser;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#996](https://github.com/thirdweb-dev/js/pull/996) [`c3645c45`](https://github.com/thirdweb-dev/js/commit/c3645c451b5e9a0fcf651fa07eb0e31ebf1882ca) Thanks [@MananTank](https://github.com/MananTank)! - - add `theme` in `ConfiguredWallet.connectUI`'s props - to use theme aware UI for wallets
|
||||
|
||||
- add `useWalletConfig` hook to get the `ConfiguredWallet` object for active wallet
|
||||
- add hooks `useSetConnectedWallet`, `useSetConnectionStatus`
|
||||
- rename `useActiveChain` to `useChain` - keep the `useActiveChain` also with deprecated tag
|
||||
- make `useSafe` hook await-able by returning the promise of connect() call
|
||||
- add hook `useSmartWallet`
|
||||
- allow rendering custom wallet details button via `<ConnectWallet detailsButton={} />` prop
|
||||
- Rename "Export" to "Backup" in local wallet UI
|
||||
|
||||
- [#1011](https://github.com/thirdweb-dev/js/pull/1011) [`470e0a14`](https://github.com/thirdweb-dev/js/commit/470e0a144db6aa03e7789e231bbdfae43144f0e0) Thanks [@MananTank](https://github.com/MananTank)! - rename ConfiguredWallet to WalletConfig
|
||||
|
||||
```diff
|
||||
- import { ConfiguredWallet } from '@thirdweb-dev/react';
|
||||
+ import { WalletConfig } from '@thirdweb-dev/react';
|
||||
```
|
||||
|
||||
- [#995](https://github.com/thirdweb-dev/js/pull/995) [`482f6d1b`](https://github.com/thirdweb-dev/js/commit/482f6d1b58ac99b331fc750d3eeb6082556fd526) Thanks [@iketw](https://github.com/iketw)! - [Chains] Update chains
|
||||
|
||||
- [#989](https://github.com/thirdweb-dev/js/pull/989) [`8db78299`](https://github.com/thirdweb-dev/js/commit/8db78299ea6cfb51d93b91bb1a351644a83c73d2) Thanks [@iketw](https://github.com/iketw)! - [React/ReactNative] Updated useThirdwebWallet to useWalletContext
|
||||
|
||||
## 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
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Joseon Mainnet",
|
||||
"chain": "Joseon",
|
||||
"icon": {
|
||||
"url": "ipfs://QmQjwcNRCLXU8JBtSkPLUnbWVrpoqbnZVffpJ9Bu8rG34e",
|
||||
"width": 148,
|
||||
"height": 148,
|
||||
"format": "svg"
|
||||
},
|
||||
"rpc": [
|
||||
"https://joseon.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.modchain.net/blockchain.joseon.com/rpc"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Joseon Mun",
|
||||
"symbol": "JSM",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.joseon.com/",
|
||||
"shortName": "mun",
|
||||
"chainId": 1392,
|
||||
"networkId": 1392,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "BlockExplorer",
|
||||
"url": "https://www.blockexplorer.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "joseon"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Genesys Mainnet",
|
||||
"chain": "Genesys",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreie6nai3yhykcdlsyshn5lbcbyba5y7zwsqg6owcfek2urhoucr6rm",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://genesys.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.genesys.network"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Genesys",
|
||||
"symbol": "GSYS",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.genesys.network/",
|
||||
"shortName": "Genesys",
|
||||
"chainId": 16507,
|
||||
"networkId": 16507,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "GchainExplorer",
|
||||
"url": "https://gchainexplorer.genesys.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "genesys"
|
||||
} 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,21 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Structx Mainnet",
|
||||
"chain": "utx",
|
||||
"rpc": [
|
||||
"https://structx.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet.structx.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Notes",
|
||||
"symbol": "utx",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://structx.io",
|
||||
"shortName": "utx",
|
||||
"chainId": 208,
|
||||
"networkId": 208,
|
||||
"testnet": false,
|
||||
"slug": "structx"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "SOMA Network Testnet",
|
||||
"chain": "SOMA",
|
||||
"rpc": [
|
||||
"https://soma-network-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://data-testnet-v1.somanetwork.io/"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.somanetwork.io"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "SMA",
|
||||
"symbol": "tSMA",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://somanetwork.io",
|
||||
"shortName": "sma",
|
||||
"chainId": 2323,
|
||||
"networkId": 2323,
|
||||
"icon": {
|
||||
"url": "ipfs://QmadSU2tcyvuzssDYGJ4rVLag43QLnKwcBerZR2zKLVU2N",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "SOMA Testnet Explorer",
|
||||
"icon": {
|
||||
"url": "ipfs://QmadSU2tcyvuzssDYGJ4rVLag43QLnKwcBerZR2zKLVU2N",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
},
|
||||
"url": "https://testnet.somascan.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "soma-network-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "LaChain",
|
||||
"chain": "LaChain",
|
||||
"rpc": [
|
||||
"https://lachain-lachain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc1.mainnet.lachain.network",
|
||||
"https://rpc2.mainnet.lachain.network"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "LaCoin",
|
||||
"symbol": "LAC",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
}
|
||||
],
|
||||
"infoURL": "",
|
||||
"shortName": "lachain",
|
||||
"chainId": 274,
|
||||
"networkId": 274,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "LaChain Explorer",
|
||||
"url": "https://explorer.lachain.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "lachain-lachain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Razor Skale Chain",
|
||||
"chain": "Razor Schain",
|
||||
"icon": {
|
||||
"url": "ipfs://QmUdwAZJfyKGZnfPGDsCnNvGu123mdd57kTGj1Y3EWVuWK",
|
||||
"width": 900,
|
||||
"height": 900,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://razor-skale-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet.skalenodes.com/v1/turbulent-unique-scheat"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.razorscan.io/"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "sFuel",
|
||||
"symbol": "SFUEL",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://razor.network",
|
||||
"shortName": "razor",
|
||||
"chainId": 278611351,
|
||||
"networkId": 278611351,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "turbulent-unique-scheat",
|
||||
"url": "https://turbulent-unique-scheat.explorer.mainnet.skalenodes.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "razor-skale-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,45 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Fastex Chain (Bahamut) Oasis Testnet",
|
||||
"title": "Bahamut testnet Oasis",
|
||||
"icon": {
|
||||
"url": "ipfs://QmSemioP83RXnDWwTZbet8VpwJxcFRboX4B3pcdhLZGodP",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"format": "png"
|
||||
},
|
||||
"chain": "Fastex Chain (Bahamut)",
|
||||
"rpc": [
|
||||
"https://fastex-chain-bahamut-oasis-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc1.oasis.bahamutchain.com"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.oasis.fastexchain.com"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "FTN",
|
||||
"symbol": "FTN",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://fastexchain.com",
|
||||
"shortName": "Oasis",
|
||||
"chainId": 4090,
|
||||
"networkId": 4090,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://oasis.ftnscan.com",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "fastex-chain-bahamut-oasis-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -22,7 +22,7 @@ export default {
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://fastex.com",
|
||||
"shortName": "ftn",
|
||||
"shortName": "fastexTestnet",
|
||||
"chainId": 424242,
|
||||
"networkId": 424242,
|
||||
"explorers": [
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Worlds Caldera",
|
||||
"chain": "WCal",
|
||||
"rpc": [
|
||||
"https://worlds-caldera.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://worlds-test.calderachain.xyz/http"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://caldera.xyz/",
|
||||
"shortName": "worldscal",
|
||||
"chainId": 4281033,
|
||||
"networkId": 4281033,
|
||||
"icon": {
|
||||
"url": "ipfs://QmdwQDr6vmBtXmK2TmknkEuZNoaDqTasFdZdu3DRw8b2wt",
|
||||
"width": 1000,
|
||||
"height": 1628,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [],
|
||||
"testnet": true,
|
||||
"slug": "worlds-caldera"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "ARZIO Chain",
|
||||
"chain": "ARZIO",
|
||||
"icon": {
|
||||
"url": "ipfs://QmUwqGWGjjQweTprn5LBirAwRjYnteTiFLCVpSNHrfMmSL",
|
||||
"width": 150,
|
||||
"height": 150,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://arzio-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://chain-rpc.arzio.co"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "ARZIO",
|
||||
"symbol": "AZO",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://chain.arzio.co",
|
||||
"shortName": "arzio",
|
||||
"chainId": 456,
|
||||
"networkId": 456,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "ARZIO Scan",
|
||||
"url": "https://scan.arzio.co",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "arzio-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -2,7 +2,10 @@ import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Camino C-Chain",
|
||||
"chain": "CAM",
|
||||
"rpc": [],
|
||||
"rpc": [
|
||||
"https://camino-c-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://api.camino.network/ext/bc/C/rpc"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Camino",
|
||||
@@ -22,7 +25,7 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockexplorer",
|
||||
"url": "https://explorer.camino.foundation/mainnet",
|
||||
"url": "https://suite.camino.network/explorer",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -25,7 +25,7 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockexplorer",
|
||||
"url": "https://explorer.camino.foundation",
|
||||
"url": "https://suite.camino.network/explorer",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Opside Testnet Pre-Alpha",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://opside-testnet-pre-alpha.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://pre-alpha-us-http-geth.opside.network",
|
||||
"https://pre-alpha-hk-http-geth.opside.network"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "IDE Test Token",
|
||||
"symbol": "IDE",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://opsi.de/",
|
||||
"shortName": "Opside-Testnet",
|
||||
"chainId": 51178,
|
||||
"networkId": 51178,
|
||||
"icon": {
|
||||
"url": "ipfs://QmZnE2ygPL2ZGuzHGvFCHmrqxwdurrhz3K1yPnwLzKbgay",
|
||||
"width": 401,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "OpsideTestnetInfo",
|
||||
"url": "https://pre-alpha.opside.info",
|
||||
"icon": {
|
||||
"url": "ipfs://QmZnE2ygPL2ZGuzHGvFCHmrqxwdurrhz3K1yPnwLzKbgay",
|
||||
"width": 401,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "opside-testnet-pre-alpha"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,44 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Sahara",
|
||||
"title": "Bahamut mainnet Sahara",
|
||||
"chain": "Bahamut",
|
||||
"icon": {
|
||||
"url": "ipfs://QmSemioP83RXnDWwTZbet8VpwJxcFRboX4B3pcdhLZGodP",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://sahara.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc1.sahara.bahamutchain.com",
|
||||
"https://rpc2.sahara.bahamutchain.com"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "FTN",
|
||||
"symbol": "FTN",
|
||||
"decimals": 18
|
||||
},
|
||||
"shortName": "ftn",
|
||||
"infoURL": "https://fastexchain.com",
|
||||
"chainId": 5165,
|
||||
"networkId": 5165,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://ftnscan.com",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "sahara"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "GuapcoinX",
|
||||
"chain": "GuapcoinX",
|
||||
"rpc": [
|
||||
"https://guapcoinx.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-mainnet.guapcoinx.com/",
|
||||
"https://rpc-mainnet-1.guapcoinx.com/",
|
||||
"https://rpc-mainnet-2.guapcoinx.com/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "GuapcoinX",
|
||||
"symbol": "GuapX",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://guapcoin.org/",
|
||||
"shortName": "GuapX",
|
||||
"chainId": 71111,
|
||||
"networkId": 71111,
|
||||
"icon": {
|
||||
"url": "ipfs://QmcDTR7982VQKDDz2Mh4fZbnE9hn67MuFPWQv1MimCqPvB",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "GuapcoinX Explorer",
|
||||
"url": "http://explorer.guapcoinx.com",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmcDTR7982VQKDDz2Mh4fZbnE9hn67MuFPWQv1MimCqPvB",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "guapcoinx"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Raba Network Mainnet",
|
||||
"chain": "Raba",
|
||||
"icon": {
|
||||
"url": "ipfs://QmatP9qMHEYoXqRDyHMTyjYRQa6j6Gk7pmv1QLxQkvpGRP",
|
||||
"width": 787,
|
||||
"height": 750,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://raba-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.x.raba.app/",
|
||||
"wss://rpc.x.raba.app/ws/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Raba",
|
||||
"symbol": "RABA",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://x.raba.app/",
|
||||
"shortName": "raba",
|
||||
"chainId": 7484,
|
||||
"networkId": 7484,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "raba",
|
||||
"url": "https://x.raba.app/explorer",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "raba-network"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "BitEth",
|
||||
"chain": "BTE",
|
||||
"rpc": [
|
||||
"https://biteth.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.biteth.org"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "BitEth",
|
||||
"symbol": "BTE",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://biteth.org",
|
||||
"shortName": "BitEth",
|
||||
"chainId": 8086,
|
||||
"networkId": 8086,
|
||||
"explorers": [],
|
||||
"testnet": false,
|
||||
"slug": "biteth"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "CURVE Mainnet",
|
||||
"chain": "CURVE",
|
||||
"icon": {
|
||||
"url": "ipfs://QmTjV3TTR5aLb7fi7tjx8gcDvYtqBpusqhCSaznVxJ7NJg",
|
||||
"width": 150,
|
||||
"height": 150,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://curve.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet-rpc.curvescan.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Curve",
|
||||
"symbol": "CURVE",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://curvescan.io",
|
||||
"shortName": "CURVEm",
|
||||
"chainId": 827431,
|
||||
"networkId": 827431,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "CURVE Mainnet",
|
||||
"url": "https://curvescan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "curve"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "AltLayer Testnet",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://altlayer-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet-rollup-api.altlayer.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://altlayer.io",
|
||||
"shortName": "alt-testnet",
|
||||
"chainId": 9997,
|
||||
"networkId": 9997,
|
||||
"icon": {
|
||||
"url": "ipfs://QmcEfZJU7NMn9ycTAcEooQgGNfa2nYBToSUZHdFCFadcjb",
|
||||
"width": 1080,
|
||||
"height": 1025,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://testnet-rollup-explorer.altlayer.io",
|
||||
"icon": {
|
||||
"url": "ipfs://bafybeifu5tpui7dk5cjoo54kde7pmuthvnl7sdykobuarsxgu7t2izurnq",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "altlayer-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.14",
|
||||
"version": "0.1.16",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.10.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#926](https://github.com/thirdweb-dev/js/pull/926) [`84fc3b6f`](https://github.com/thirdweb-dev/js/commit/84fc3b6fab112b91563348f1a88820bd49a2f9b3) Thanks [@Marfuen](https://github.com/Marfuen)! - Added detect-project command, reorganized folder structure for detecting, added many more detections.
|
||||
|
||||
- [#926](https://github.com/thirdweb-dev/js/pull/926) [`84fc3b6f`](https://github.com/thirdweb-dev/js/commit/84fc3b6fab112b91563348f1a88820bd49a2f9b3) Thanks [@Marfuen](https://github.com/Marfuen)! - Added log to see detected app type to the "detect-project" command
|
||||
|
||||
- Updated dependencies [[`e9b69300`](https://github.com/thirdweb-dev/js/commit/e9b69300d15b233609f1ed897256ec9a1eef3e28), [`49ec2d17`](https://github.com/thirdweb-dev/js/commit/49ec2d171ecb1c9240398b7b486a452eb9429979), [`799d98e8`](https://github.com/thirdweb-dev/js/commit/799d98e86258677ab72931fa8397aee653fe8b34), [`c3645c45`](https://github.com/thirdweb-dev/js/commit/c3645c451b5e9a0fcf651fa07eb0e31ebf1882ca), [`470e0a14`](https://github.com/thirdweb-dev/js/commit/470e0a144db6aa03e7789e231bbdfae43144f0e0), [`482f6d1b`](https://github.com/thirdweb-dev/js/commit/482f6d1b58ac99b331fc750d3eeb6082556fd526), [`e4356e76`](https://github.com/thirdweb-dev/js/commit/e4356e76d1506624afe2eb6feeaf57dc376f372f), [`9886c858`](https://github.com/thirdweb-dev/js/commit/9886c858d9c8d0f677aba6572dbf5cc6c876edf2), [`8db78299`](https://github.com/thirdweb-dev/js/commit/8db78299ea6cfb51d93b91bb1a351644a83c73d2)]:
|
||||
- @thirdweb-dev/sdk@3.10.15
|
||||
- @thirdweb-dev/chains@0.1.16
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.10.14",
|
||||
"version": "0.10.16",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -15,6 +15,7 @@
|
||||
"@types/cross-spawn": "^6.0.2",
|
||||
"@types/inquirer": "^8.2.1",
|
||||
"@types/jest": "^29.2.1",
|
||||
"@types/js-yaml": "^4.0.5",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/prompts": "^2.0.14",
|
||||
"@types/rimraf": "^3.0.0",
|
||||
@@ -34,6 +35,7 @@
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
"@thirdweb-dev/storage": "workspace:*",
|
||||
@@ -44,6 +46,7 @@
|
||||
"ethers": "^5.7.2",
|
||||
"got": "11.8.5",
|
||||
"inquirer": "^8.2.3",
|
||||
"js-yaml": "^4.1.0",
|
||||
"open": "^8.4.0",
|
||||
"prompts": "^2.4.2",
|
||||
"rimraf": "^3.0.2",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
import { detectExtensions } from "../common/feature-detector";
|
||||
import { detectProjectV2 } from "../common/project-detector-v2";
|
||||
import { processProject } from "../common/processor";
|
||||
import { cliVersion, pkg } from "../constants/urls";
|
||||
import { info, logger, spinner } from "../core/helpers/logger";
|
||||
@@ -406,6 +407,17 @@ const main = async () => {
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("detect-project")
|
||||
.description(
|
||||
"Detect the type of project your are running and let you know what it is.",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.action(async (options) => {
|
||||
await detectProjectV2(options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("generate")
|
||||
.description(
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import detectPackageManager from "../core/detection/detectPackageManager";
|
||||
import detectFramework from "../core/detection/detectFramework";
|
||||
import detectLibrary from "../core/detection/detectLibrary";
|
||||
import detectLanguage from "../core/detection/detectLanguage";
|
||||
import { logger } from "../core/helpers/logger";
|
||||
import path from "path";
|
||||
import { ContractLibrariesType, contractLibraries } from "../core/types/ProjectType";
|
||||
|
||||
export async function detectProjectV2(options: any) {
|
||||
logger.setSettings({
|
||||
minLevel: options.debug ? "debug" : "info",
|
||||
});
|
||||
|
||||
let projectPath = process.cwd();
|
||||
if (options.path) {
|
||||
logger.debug("Overriding project path to " + options.path);
|
||||
|
||||
const resolvedPath = (options.path as string).startsWith("/")
|
||||
? options.path
|
||||
: path.resolve(`${projectPath}/${options.path}`);
|
||||
projectPath = resolvedPath;
|
||||
}
|
||||
|
||||
logger.debug("Processing project at path " + projectPath);
|
||||
|
||||
const detectedPackageManager = await detectPackageManager(
|
||||
projectPath,
|
||||
options,
|
||||
);
|
||||
const detectedLanguage = await detectLanguage(projectPath, options);
|
||||
const detectedLibrary = await detectLibrary(
|
||||
projectPath,
|
||||
options,
|
||||
detectedPackageManager,
|
||||
);
|
||||
const detectedFramework = await detectFramework(
|
||||
projectPath,
|
||||
options,
|
||||
detectedPackageManager,
|
||||
);
|
||||
const detectedAppType = contractLibraries.includes(detectedFramework as ContractLibrariesType) ? "contract" : "app";
|
||||
|
||||
logger.debug("Detected package manager: " + detectedPackageManager);
|
||||
logger.debug("Detected library: " + detectedLibrary);
|
||||
logger.debug("Detected language: " + detectedLanguage);
|
||||
logger.debug("Detected framework: " + detectedFramework);
|
||||
logger.debug("Detected app type: " + detectedAppType);
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
import { ALWAYS_SUGGESTED } from "../constants/features";
|
||||
import build from "../core/builder/build";
|
||||
import detect from "../core/detection/detect";
|
||||
import detectPackageManager from "../core/detection/detectPackageManager";
|
||||
import { logger, spinner } from "../core/helpers/logger";
|
||||
import { createContractsPrompt } from "../core/helpers/selector";
|
||||
import { ContractFeatures, Feature } from "../core/interfaces/ContractFeatures";
|
||||
import { ContractPayload } from "../core/interfaces/ContractPayload";
|
||||
import { getPkgManager } from "../create/helpers/get-pkg-manager";
|
||||
import { detectFeatures, FeatureWithEnabled } from "@thirdweb-dev/sdk";
|
||||
import chalk from "chalk";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import ora from "ora";
|
||||
import path from "path";
|
||||
|
||||
export async function detectProject(options: any) {
|
||||
logger.setSettings({
|
||||
minLevel: options.debug ? "debug" : "info",
|
||||
});
|
||||
|
||||
let projectPath = process.cwd();
|
||||
if (options.path) {
|
||||
logger.debug("Overriding project path to " + options.path);
|
||||
|
||||
const resolvedPath = (options.path as string).startsWith("/")
|
||||
? options.path
|
||||
: path.resolve(`${projectPath}/${options.path}`);
|
||||
projectPath = resolvedPath;
|
||||
}
|
||||
|
||||
logger.debug("Processing project at path " + projectPath);
|
||||
|
||||
const packageManagerType = await detectPackageManager(projectPath, options);
|
||||
console.log(packageManagerType);
|
||||
const projectType = await detect(projectPath, options);
|
||||
|
||||
let compiledResult;
|
||||
const compileLoader = spinner("Compiling project...");
|
||||
try {
|
||||
compiledResult = await build(projectPath, projectType, options);
|
||||
} catch (e) {
|
||||
compileLoader.fail("Compilation failed");
|
||||
logger.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
compileLoader.succeed("Compilation successful");
|
||||
|
||||
let selectedContracts: ContractPayload[] = [];
|
||||
if (compiledResult.contracts.length === 1) {
|
||||
selectedContracts = [compiledResult.contracts[0]];
|
||||
} else {
|
||||
if (options.all) {
|
||||
selectedContracts = compiledResult.contracts;
|
||||
} else {
|
||||
const choices = compiledResult.contracts.map((c) => ({
|
||||
name: c.name,
|
||||
value: c,
|
||||
}));
|
||||
const prompt = createContractsPrompt(
|
||||
choices,
|
||||
"Choose which contracts to run detection on",
|
||||
);
|
||||
const selection: Record<string, ContractPayload> = await prompt.run();
|
||||
selectedContracts = Object.keys(selection).map((key) => selection[key]);
|
||||
}
|
||||
}
|
||||
|
||||
let contractsWithFeatures: ContractFeatures[] = selectedContracts.map(
|
||||
(contract) => {
|
||||
const abi: Parameters<typeof detectFeatures>[0] = JSON.parse(
|
||||
contract.metadata,
|
||||
)["output"]["abi"];
|
||||
const features = extractFeatures(detectFeatures(abi));
|
||||
|
||||
const enabledFeatures: Feature[] = features.enabledFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/interfaces/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
const suggestedFeatures: Feature[] = features.suggestedFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/interfaces/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
name: contract.name,
|
||||
enabledFeatures,
|
||||
suggestedFeatures,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
contractsWithFeatures.map((contractWithFeatures) => {
|
||||
logger.info(`\n`);
|
||||
if (contractWithFeatures.enabledFeatures.length === 0) {
|
||||
ora(
|
||||
`No extensions detected on ${chalk.blueBright(
|
||||
contractWithFeatures.name,
|
||||
)}`,
|
||||
).stopAndPersist({ symbol: "🔎" });
|
||||
} else {
|
||||
ora(
|
||||
`Detected extension on ${chalk.blueBright(contractWithFeatures.name)}`,
|
||||
).stopAndPersist({ symbol: "🔎" });
|
||||
contractWithFeatures.enabledFeatures.map((feature) => {
|
||||
logger.info(`✔️ ${chalk.green(feature.name)}`);
|
||||
});
|
||||
}
|
||||
logger.info(``);
|
||||
ora(`Suggested extensions`).info();
|
||||
contractWithFeatures.suggestedFeatures.map((feature) => {
|
||||
logger.info(
|
||||
`${chalk.dim(chalk.gray(`-`))} ${chalk.gray(
|
||||
feature.name,
|
||||
)} - ${chalk.dim(chalk.gray(feature.reference))}`,
|
||||
);
|
||||
});
|
||||
|
||||
let deployCmd = `npx thirdweb@latest deploy`;
|
||||
if (existsSync(projectPath + "/package.json")) {
|
||||
const packageManager = getPkgManager();
|
||||
const useYarn = packageManager === "yarn";
|
||||
const pkgJson = JSON.parse(
|
||||
readFileSync(projectPath + "/package.json", "utf-8"),
|
||||
);
|
||||
if (pkgJson?.scripts?.deploy === deployCmd) {
|
||||
deployCmd = `${packageManager}${useYarn ? "" : " run"} deploy`;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(``);
|
||||
ora(
|
||||
`Once you're done writing your contracts, you can run the following command to deploy them:`,
|
||||
).info();
|
||||
logger.info(``);
|
||||
logger.info(` ${chalk.cyan(deployCmd)}`);
|
||||
logger.info(``);
|
||||
});
|
||||
}
|
||||
|
||||
function extractFeatures(
|
||||
input: ReturnType<typeof detectFeatures>,
|
||||
enabledFeatures: FeatureWithEnabled[] = [],
|
||||
suggestedFeatures: FeatureWithEnabled[] = [],
|
||||
parent = "__ROOT__",
|
||||
) {
|
||||
if (!input) {
|
||||
return {
|
||||
enabledFeatures,
|
||||
suggestedFeatures,
|
||||
};
|
||||
}
|
||||
for (const featureKey in input) {
|
||||
const feature = input[featureKey];
|
||||
// if feature is enabled, then add it to enabledFeatures
|
||||
if (feature.enabled) {
|
||||
enabledFeatures.push(feature);
|
||||
}
|
||||
// otherwise if it is disabled, but it's parent is enabled or suggested, then add it to suggestedFeatures
|
||||
else if (
|
||||
enabledFeatures.findIndex((f) => f.name === parent) > -1 ||
|
||||
ALWAYS_SUGGESTED.includes(feature.name)
|
||||
) {
|
||||
suggestedFeatures.push(feature);
|
||||
}
|
||||
// recurse
|
||||
extractFeatures(
|
||||
feature.features,
|
||||
enabledFeatures,
|
||||
suggestedFeatures,
|
||||
feature.name,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
enabledFeatures,
|
||||
suggestedFeatures,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import { info } from "../helpers/logger";
|
||||
import { FrameworkType, PackageManagerType } from "../types/ProjectType";
|
||||
import inquirer from "inquirer";
|
||||
import NextDetector from "./frameworks/next";
|
||||
import CRADetector from "./frameworks/cra";
|
||||
import RemixDetector from "./frameworks/remix";
|
||||
import GatsbyDetector from "./frameworks/gatsby";
|
||||
import VueDetector from "./frameworks/vue";
|
||||
import ReactNativeCLIDetector from "./frameworks/reactNativeCli";
|
||||
import DjangoDetector from "./frameworks/django";
|
||||
import ExpoDetector from "./frameworks/expo";
|
||||
import FoundryDetector from "./frameworks/foundry";
|
||||
import HardhatDetector from "./frameworks/hardhat";
|
||||
import { FrameworkDetector } from "./detector";
|
||||
import TruffleDetector from "./frameworks/truffle";
|
||||
import BrownieDetector from "./frameworks/brownie";
|
||||
import FastAPIDetector from "./frameworks/fastAPI";
|
||||
import FlaskDetector from "./frameworks/flask";
|
||||
import PopulusDetector from "./frameworks/populus";
|
||||
import FastifyDetector from "./frameworks/fastify";
|
||||
import EchoDetector from "./frameworks/echo";
|
||||
import FiberDetector from "./frameworks/fiber";
|
||||
import GinDetector from "./frameworks/gin";
|
||||
import RevelDetector from "./frameworks/revel";
|
||||
import ZenjectDetector from "./frameworks/zenject";
|
||||
|
||||
export default async function detect(
|
||||
path: string,
|
||||
options: any,
|
||||
detectedPackageManager: PackageManagerType,
|
||||
): Promise<FrameworkType> {
|
||||
// We could optimize further if we want, by only running the detectors that match the package manager.
|
||||
const frameworkDetectors: FrameworkDetector[] = [
|
||||
new BrownieDetector(),
|
||||
new CRADetector(),
|
||||
new DjangoDetector(),
|
||||
new EchoDetector(),
|
||||
new ExpoDetector(),
|
||||
new FastAPIDetector(),
|
||||
new FastifyDetector(),
|
||||
new FiberDetector(),
|
||||
new FlaskDetector(),
|
||||
new FoundryDetector(),
|
||||
new GatsbyDetector(),
|
||||
new GinDetector(),
|
||||
new HardhatDetector(),
|
||||
new NextDetector(),
|
||||
new PopulusDetector(),
|
||||
new ReactNativeCLIDetector(),
|
||||
new RemixDetector(),
|
||||
new RevelDetector(),
|
||||
new TruffleDetector(),
|
||||
new VueDetector(),
|
||||
new ZenjectDetector(),
|
||||
];
|
||||
|
||||
const possibleFrameworks = frameworkDetectors
|
||||
.filter((detector) => detector.matches(path, detectedPackageManager))
|
||||
.map((detector) => detector.frameworkType);
|
||||
|
||||
if (!possibleFrameworks.length) {
|
||||
return "none";
|
||||
}
|
||||
|
||||
if (possibleFrameworks.length === 1) {
|
||||
return possibleFrameworks[0];
|
||||
}
|
||||
|
||||
info(
|
||||
`Detected multiple possible frameworks: ${possibleFrameworks
|
||||
.map((s) => `"${s}"`)
|
||||
.join(", ")}`,
|
||||
);
|
||||
|
||||
const question =
|
||||
"We detected multiple possible frameworks which one do you want to use?";
|
||||
|
||||
if (options.ci) {
|
||||
return possibleFrameworks[0];
|
||||
} else {
|
||||
const answer = await inquirer.prompt({
|
||||
type: "list",
|
||||
choices: possibleFrameworks,
|
||||
name: question,
|
||||
});
|
||||
return answer[question];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { info } from "../helpers/logger";
|
||||
import { LanguageType } from "../types/ProjectType";
|
||||
import { LanguageDetector } from "./detector";
|
||||
import inquirer from "inquirer";
|
||||
import JavascriptDetector from "./languages/javascript";
|
||||
import TypescriptDetector from "./languages/typescript";
|
||||
import PythonDetector from "./languages/python";
|
||||
import GoDetector from "./languages/go";
|
||||
|
||||
export default async function detect(
|
||||
path: string,
|
||||
options: any,
|
||||
): Promise<LanguageType> {
|
||||
const languageDetectors: LanguageDetector[] = [
|
||||
new JavascriptDetector(),
|
||||
new TypescriptDetector(),
|
||||
new PythonDetector(),
|
||||
new GoDetector(),
|
||||
];
|
||||
|
||||
const possibleLanguages = languageDetectors
|
||||
.filter((detector) => detector.matches(path))
|
||||
.map((detector) => detector.languageType);
|
||||
|
||||
if (!possibleLanguages.length) {
|
||||
return "none";
|
||||
}
|
||||
|
||||
if (possibleLanguages.length === 1) {
|
||||
return possibleLanguages[0];
|
||||
}
|
||||
|
||||
info(
|
||||
`Detected multiple possible languages: ${possibleLanguages
|
||||
.map((s) => `"${s}"`)
|
||||
.join(", ")}`,
|
||||
);
|
||||
|
||||
const question =
|
||||
"We detected multiple possible languages which one do you want to use?";
|
||||
|
||||
if (options.ci) {
|
||||
return possibleLanguages[0];
|
||||
} else {
|
||||
const answer = await inquirer.prompt({
|
||||
type: "list",
|
||||
choices: possibleLanguages,
|
||||
name: question,
|
||||
});
|
||||
return answer[question];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { info } from "../helpers/logger";
|
||||
import { LibraryType, PackageManagerType } from "../types/ProjectType";
|
||||
import { LibraryDetector } from "./detector";
|
||||
import inquirer from "inquirer";
|
||||
import ReactDetector from "./libraries/react";
|
||||
import ExpressDetector from "./libraries/express";
|
||||
import ReactNativeDetector from "./libraries/reactNative";
|
||||
import ViteDetector from "./libraries/vite";
|
||||
import Web3PyDetector from "./libraries/web3py";
|
||||
import PlayMakerDetector from "./libraries/playmaker";
|
||||
|
||||
export default async function detect(
|
||||
path: string,
|
||||
options: any,
|
||||
detectedPackageManager: PackageManagerType,
|
||||
): Promise<LibraryType> {
|
||||
// We could optimize further if we want, by only running the detectors that match the package manager.
|
||||
const libraryDetectors: LibraryDetector[] = [
|
||||
new ExpressDetector(),
|
||||
new ReactDetector(),
|
||||
new ReactNativeDetector(),
|
||||
new ViteDetector(),
|
||||
new Web3PyDetector(),
|
||||
new PlayMakerDetector(),
|
||||
];
|
||||
|
||||
const possibleLibraries = libraryDetectors
|
||||
.filter((detector) => detector.matches(path, detectedPackageManager))
|
||||
.map((detector) => detector.libraryType);
|
||||
|
||||
if (!possibleLibraries.length) {
|
||||
return "none";
|
||||
}
|
||||
|
||||
if (possibleLibraries.length === 1) {
|
||||
return possibleLibraries[0];
|
||||
}
|
||||
|
||||
info(
|
||||
`Detected multiple possible libraries: ${possibleLibraries
|
||||
.map((s) => `"${s}"`)
|
||||
.join(", ")}`,
|
||||
);
|
||||
|
||||
const question =
|
||||
"We detected multiple possible libraries which one do you want to use?";
|
||||
|
||||
if (options.ci) {
|
||||
return possibleLibraries[0];
|
||||
} else {
|
||||
const answer = await inquirer.prompt({
|
||||
type: "list",
|
||||
choices: possibleLibraries,
|
||||
name: question,
|
||||
});
|
||||
return answer[question];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import { info } from "../helpers/logger";
|
||||
import { PackageManagerType } from "../types/ProjectType";
|
||||
import { PackageManagerDetector } from "./detector";
|
||||
import inquirer from "inquirer";
|
||||
import NPMDetector from "./packageManagers/npm";
|
||||
import YarnDetector from "./packageManagers/yarn";
|
||||
import PnpmDetector from "./packageManagers/pnpm";
|
||||
import CondaDetector from "./packageManagers/conda";
|
||||
import PipDetector from "./packageManagers/pip";
|
||||
import PipEnvDetector from "./packageManagers/pipenv";
|
||||
import PoetryDetector from "./packageManagers/poetry";
|
||||
|
||||
export default async function detect(
|
||||
path: string,
|
||||
options: any,
|
||||
): Promise<PackageManagerType> {
|
||||
const packageManagerDetectors: PackageManagerDetector[] = [
|
||||
new NPMDetector(),
|
||||
new YarnDetector(),
|
||||
new PnpmDetector(),
|
||||
new CondaDetector(),
|
||||
new PipDetector(),
|
||||
new PipEnvDetector(),
|
||||
new PoetryDetector(),
|
||||
];
|
||||
|
||||
const possiblePackageManagers = packageManagerDetectors
|
||||
.filter((detector) => detector.matches(path))
|
||||
.map((detector) => detector.packageManagerType);
|
||||
|
||||
if (!possiblePackageManagers.length) {
|
||||
return "none";
|
||||
}
|
||||
|
||||
if (possiblePackageManagers.length === 1) {
|
||||
return possiblePackageManagers[0];
|
||||
}
|
||||
|
||||
info(
|
||||
`Detected multiple possible package managers: ${possiblePackageManagers
|
||||
.map((s) => `"${s}"`)
|
||||
.join(", ")}`,
|
||||
);
|
||||
|
||||
const question =
|
||||
"We detected multiple possible package managers, which one do you want to use?";
|
||||
|
||||
if (options.ci) {
|
||||
return possiblePackageManagers[0];
|
||||
} else {
|
||||
const answer = await inquirer.prompt({
|
||||
type: "list",
|
||||
choices: possiblePackageManagers,
|
||||
name: question,
|
||||
});
|
||||
return answer[question];
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,44 @@
|
||||
import { ProjectType } from "../types/ProjectType";
|
||||
import {
|
||||
ProjectType,
|
||||
LanguageType,
|
||||
PackageManagerType,
|
||||
AppType,
|
||||
FrameworkType,
|
||||
LibraryType,
|
||||
} from "../types/ProjectType";
|
||||
|
||||
export interface Detector {
|
||||
projectType: ProjectType;
|
||||
|
||||
matches(path: string): boolean;
|
||||
}
|
||||
|
||||
export interface PackageManagerDetector {
|
||||
packageManagerType: PackageManagerType;
|
||||
|
||||
matches(path: string): boolean;
|
||||
}
|
||||
|
||||
export interface FrameworkDetector {
|
||||
frameworkType: FrameworkType;
|
||||
|
||||
matches(path: string, PackageManager?: PackageManagerType): boolean;
|
||||
}
|
||||
|
||||
export interface LibraryDetector {
|
||||
libraryType: LibraryType;
|
||||
|
||||
matches(path: string, PackageManager?: PackageManagerType): boolean;
|
||||
}
|
||||
|
||||
export interface LanguageDetector {
|
||||
languageType: LanguageType;
|
||||
|
||||
matches(path: string): boolean;
|
||||
}
|
||||
|
||||
export interface AppTypeDetector {
|
||||
appType: AppType;
|
||||
|
||||
matches(path: string): boolean;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { FrameworkType, PackageManagerType } from "../../types/ProjectType";
|
||||
import { getDependenciesForPython } from "../../../lib/utils";
|
||||
|
||||
export default class BrownieDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "brownie";
|
||||
|
||||
public matches(path: string, packageManager: PackageManagerType): boolean {
|
||||
const { dependencies, devDependencies } = getDependenciesForPython(
|
||||
path,
|
||||
packageManager,
|
||||
);
|
||||
|
||||
const additionalFilesToCheck = [
|
||||
"/brownie-config.yaml",
|
||||
"/brownie-config.json",
|
||||
];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies.includes("brownie") ||
|
||||
devDependencies.includes("brownie") ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class CRADetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "cra";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
const craDependencyExists =
|
||||
dependencies["react-scripts"] ||
|
||||
devDependencies["react-scripts"] ||
|
||||
false;
|
||||
|
||||
return craDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { FrameworkType, PackageManagerType } from "../../types/ProjectType";
|
||||
import { getDependenciesForPython } from "../../../lib/utils";
|
||||
|
||||
export default class DjangoDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "django";
|
||||
|
||||
public matches(path: string, packageManager: PackageManagerType): boolean {
|
||||
const { dependencies, devDependencies } = getDependenciesForPython(
|
||||
path,
|
||||
packageManager,
|
||||
);
|
||||
|
||||
const additionalFilesToCheck = ["/manage.py"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies.includes("django") ||
|
||||
devDependencies.includes("django") ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { fileContainsImport, parseGoMod } from "../../../lib/utils";
|
||||
|
||||
export default class EchoDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "echo";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const goModFilePath = path + "/go.mod";
|
||||
const mainGoFilePath = path + "/main.go";
|
||||
let dependenciesExist = false;
|
||||
|
||||
if (!existsSync(goModFilePath) && !existsSync(mainGoFilePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (existsSync(goModFilePath)) {
|
||||
const goModFile = readFileSync(goModFilePath, "utf-8");
|
||||
const { dependencies } = parseGoMod(goModFile);
|
||||
const dependenciesToCheck = ["github.com/labstack/echo"];
|
||||
|
||||
dependenciesExist = dependenciesToCheck.some((dependency) =>
|
||||
dependencies.some((importstr) => importstr.name === dependency),
|
||||
);
|
||||
}
|
||||
|
||||
const mainGoFile = readFileSync(mainGoFilePath, "utf-8");
|
||||
const fileImportExists = fileContainsImport(
|
||||
mainGoFile,
|
||||
"github.com/labstack/echo",
|
||||
);
|
||||
|
||||
return dependenciesExist || fileImportExists || false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class ExpoDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "expo";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = ["/app.json", "/app.config.js", "/assets"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
const expoDependencyExists =
|
||||
dependencies["expo"] ||
|
||||
devDependencies["expo"] ||
|
||||
additionalFilesExist ||
|
||||
false;
|
||||
|
||||
return expoDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { FrameworkType, PackageManagerType } from "../../types/ProjectType";
|
||||
import { getDependenciesForPython } from "../../../lib/utils";
|
||||
|
||||
export default class FastAPIDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "fastapi";
|
||||
|
||||
public matches(path: string, packageManager: PackageManagerType): boolean {
|
||||
const { dependencies, devDependencies } = getDependenciesForPython(
|
||||
path,
|
||||
packageManager,
|
||||
);
|
||||
|
||||
const additionalFilesToCheck = ["/app.py", "/main.py"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies.includes("fastapi") ||
|
||||
devDependencies.includes("fastapi") ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class FastifyDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "fastify";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = [
|
||||
"/server.js",
|
||||
"/app.js",
|
||||
"/server.ts",
|
||||
"/app.ts",
|
||||
];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
const fastifyDependencyExists =
|
||||
dependencies["fastify"] ||
|
||||
devDependencies["fastify"] ||
|
||||
additionalFilesExist ||
|
||||
false;
|
||||
|
||||
return fastifyDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { fileContainsImport, parseGoMod } from "../../../lib/utils";
|
||||
|
||||
export default class FiberDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "fiber";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const goModFilePath = path + "/go.mod";
|
||||
const mainGoFilePath = path + "/main.go";
|
||||
let dependenciesExist = false;
|
||||
|
||||
if (!existsSync(goModFilePath) && !existsSync(mainGoFilePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (existsSync(goModFilePath)) {
|
||||
const goModFile = readFileSync(goModFilePath, "utf-8");
|
||||
const { dependencies } = parseGoMod(goModFile);
|
||||
const dependenciesToCheck = ["github.com/gofiber/fiber"];
|
||||
|
||||
dependenciesExist = dependenciesToCheck.some((dependency) =>
|
||||
dependencies.some((importstr) => importstr.name === dependency),
|
||||
);
|
||||
}
|
||||
|
||||
const mainGoFile = readFileSync(mainGoFilePath, "utf-8");
|
||||
const fileImportExists = fileContainsImport(
|
||||
mainGoFile,
|
||||
"github.com/gofiber/fiber",
|
||||
);
|
||||
|
||||
return dependenciesExist || fileImportExists || false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { FrameworkType, PackageManagerType } from "../../types/ProjectType";
|
||||
import { getDependenciesForPython } from "../../../lib/utils";
|
||||
|
||||
export default class FlaskDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "flask";
|
||||
|
||||
public matches(path: string, packageManager: PackageManagerType): boolean {
|
||||
const { dependencies, devDependencies } = getDependenciesForPython(
|
||||
path,
|
||||
packageManager,
|
||||
);
|
||||
|
||||
const additionalFilesToCheck = ["/app.py", "/application.py"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies.includes("flask") ||
|
||||
devDependencies.includes("flask") ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
|
||||
export default class FoundryDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "foundry";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const additionalFilesToCheck = ["/foundry.toml", "/lib/forge-std/"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return additionalFilesExist || false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class GatsbyDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "gatsby";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = ["/gatsby.config.js", "/gatsby-config.ts"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
const gatsbyDependencyExists =
|
||||
dependencies["gatsby"] ||
|
||||
devDependencies["gatsby"] ||
|
||||
additionalFilesExist ||
|
||||
false;
|
||||
|
||||
return gatsbyDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { fileContainsImport, parseGoMod } from "../../../lib/utils";
|
||||
|
||||
export default class GinDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "gin";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const goModFilePath = path + "/go.mod";
|
||||
const mainGoFilePath = path + "/main.go";
|
||||
let dependenciesExist = false;
|
||||
|
||||
if (!existsSync(goModFilePath) && !existsSync(mainGoFilePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (existsSync(goModFilePath)) {
|
||||
const goModFile = readFileSync(goModFilePath, "utf-8");
|
||||
const { dependencies } = parseGoMod(goModFile);
|
||||
const dependenciesToCheck = ["github.com/gin-gonic/gin"];
|
||||
|
||||
dependenciesExist = dependenciesToCheck.some((dependency) =>
|
||||
dependencies.some((importstr) => importstr.name === dependency),
|
||||
);
|
||||
}
|
||||
|
||||
const mainGoFile = readFileSync(mainGoFilePath, "utf-8");
|
||||
const fileImportExists = fileContainsImport(
|
||||
mainGoFile,
|
||||
"github.com/gin-gonic/gin",
|
||||
);
|
||||
|
||||
return dependenciesExist || fileImportExists || false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class HardhatDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "hardhat";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = ["/hardhat.config.js", "/contracts/"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
const hardhatDependencyExists =
|
||||
dependencies["hardhat"] ||
|
||||
devDependencies["hardhat"] ||
|
||||
additionalFilesExist ||
|
||||
false;
|
||||
|
||||
return hardhatDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class NextDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "next";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = ["/next.config.js", "/next-config.ts"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
const nextDependencyExists =
|
||||
dependencies["next"] ||
|
||||
devDependencies["next"] ||
|
||||
additionalFilesExist ||
|
||||
false;
|
||||
|
||||
return nextDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { FrameworkType, PackageManagerType } from "../../types/ProjectType";
|
||||
import { getDependenciesForPython } from "../../../lib/utils";
|
||||
|
||||
export default class PopulusDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "populus";
|
||||
|
||||
public matches(path: string, packageManager: PackageManagerType): boolean {
|
||||
const { dependencies, devDependencies } = getDependenciesForPython(
|
||||
path,
|
||||
packageManager,
|
||||
);
|
||||
|
||||
const additionalFilesToCheck = ["/populus.json", "/populus.yaml"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies.includes("populus") ||
|
||||
devDependencies.includes("populus") ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class ReactNativeCLIDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "react-native-cli";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = ["/android", "/ios"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies["react-native"] ||
|
||||
devDependencies["react-native"] ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class CRADetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "remix";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = ["/remix.config.js", "/remix-config.ts"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
const remixDependencies = Object.keys(dependencies)
|
||||
.concat(Object.keys(devDependencies))
|
||||
.filter((dep) => dep.startsWith("@remix-run/"));
|
||||
|
||||
return remixDependencies.length > 0 || additionalFilesExist || false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { fileContainsImport, parseGoMod } from "../../../lib/utils";
|
||||
|
||||
export default class RevelDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "revel";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const goModFilePath = path + "/go.mod";
|
||||
const mainGoFilePath = path + "/main.go";
|
||||
let dependenciesExist = false;
|
||||
|
||||
if (!existsSync(goModFilePath) && !existsSync(mainGoFilePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (existsSync(goModFilePath)) {
|
||||
const goModFile = readFileSync(goModFilePath, "utf-8");
|
||||
const { dependencies } = parseGoMod(goModFile);
|
||||
const dependenciesToCheck = ["github.com/revel/revel"];
|
||||
|
||||
dependenciesExist = dependenciesToCheck.some((dependency) =>
|
||||
dependencies.some((importstr) => importstr.name === dependency),
|
||||
);
|
||||
}
|
||||
|
||||
const mainGoFile = readFileSync(mainGoFilePath, "utf-8");
|
||||
const fileImportExists = fileContainsImport(
|
||||
mainGoFile,
|
||||
"github.com/revel/revel",
|
||||
);
|
||||
|
||||
return dependenciesExist || fileImportExists || false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class TruffleDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "truffle";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = [
|
||||
"/truffle.config.js",
|
||||
"/truffle.js",
|
||||
"/contracts/",
|
||||
];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies["truffle"] ||
|
||||
devDependencies["truffle"] ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class VueDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "vue";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = ["/vue.config.js"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies["vue"] ||
|
||||
devDependencies["vue"] ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { FrameworkDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
|
||||
export default class ZenjectDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "zenject";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const foundZenject = existsSync(path + "/Assets/Zenject");
|
||||
const foundZenjectDLL = existsSync(
|
||||
path + "/Assets/Zenject/OptionalExtras/Zenject.dll",
|
||||
);
|
||||
const foundScript = existsSync(path + "/Assets/Scripts/ProjectContext.cs");
|
||||
|
||||
return foundZenject || foundZenjectDLL || foundScript || false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { LanguageDetector } from "../detector";
|
||||
import { readdirSync } from "fs";
|
||||
import { LanguageType } from "../../types/ProjectType";
|
||||
|
||||
export default class GoDetector implements LanguageDetector {
|
||||
public languageType: LanguageType = "go";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
// Check if some of these files are written in Go.
|
||||
const goFileExtensionRegex = /\.go$/;
|
||||
const dirFiles = readdirSync(path);
|
||||
return dirFiles.some((file) => file.match(goFileExtensionRegex));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { LanguageDetector } from "../detector";
|
||||
import { readdirSync } from "fs";
|
||||
import { LanguageType } from "../../types/ProjectType";
|
||||
|
||||
export default class JavascriptDetector implements LanguageDetector {
|
||||
public languageType: LanguageType = "javascript";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
// Check if some of these files are written in Go.
|
||||
const javascriptFileExtensionRegex = /\.js$/;
|
||||
const dirFiles = readdirSync(path);
|
||||
return dirFiles.some((file) => file.match(javascriptFileExtensionRegex));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { LanguageDetector } from "../detector";
|
||||
import { readdirSync } from "fs";
|
||||
import { LanguageType } from "../../types/ProjectType";
|
||||
|
||||
export default class PythonDetector implements LanguageDetector {
|
||||
public languageType: LanguageType = "python";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
// Check if some of these files are written in Go.
|
||||
const pythonFileExtensionRegex = /\.py$/;
|
||||
const dirFiles = readdirSync(path);
|
||||
return dirFiles.some((file) => file.match(pythonFileExtensionRegex));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { LanguageDetector } from "../detector";
|
||||
import { readdirSync } from "fs";
|
||||
import { LanguageType } from "../../types/ProjectType";
|
||||
|
||||
export default class TypescriptDetector implements LanguageDetector {
|
||||
public languageType: LanguageType = "typescript";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
// Check if some of these files are written in Go.
|
||||
const typescriptFileExtensionRegex = /\.ts$/;
|
||||
const dirFiles = readdirSync(path);
|
||||
return dirFiles.some((file) => file.match(typescriptFileExtensionRegex));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { LibraryDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { LibraryType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class ExpressDetector implements LibraryDetector {
|
||||
public libraryType: LibraryType = "express";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
const expressDependencyExists =
|
||||
dependencies["express"] || devDependencies["express"] || false;
|
||||
|
||||
return expressDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { LibraryDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { LibraryType } from "../../types/ProjectType";
|
||||
|
||||
export default class PlayMakerDetector implements LibraryDetector {
|
||||
public libraryType: LibraryType = "playmaker";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const foundPlayMaker = existsSync(path + "/Assets/PlayMaker");
|
||||
const foundPlayMakerDLL = existsSync(path + "/Editor/PlayMaker.dll");
|
||||
|
||||
return foundPlayMaker || foundPlayMakerDLL || false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { LibraryDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { LibraryType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class ReactDetector implements LibraryDetector {
|
||||
public libraryType: LibraryType = "react";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
const reactDependencyExists =
|
||||
dependencies["react"] || devDependencies["react"] || false;
|
||||
|
||||
return reactDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { LibraryDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { LibraryType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class ReactNativeDetector implements LibraryDetector {
|
||||
public libraryType: LibraryType = "react-native";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
const reactNativeDependencyExists =
|
||||
dependencies["react-native"] || devDependencies["react-native"] || false;
|
||||
|
||||
return reactNativeDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { LibraryDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { LibraryType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
|
||||
export default class ViteDetector implements LibraryDetector {
|
||||
public libraryType: LibraryType = "vite";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
const viteDependencyExists =
|
||||
dependencies["vite"] || devDependencies["vite"] || false;
|
||||
|
||||
return viteDependencyExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { LibraryDetector } from "../detector";
|
||||
import { LibraryType, PackageManagerType } from "../../types/ProjectType";
|
||||
import { getDependenciesForPython } from "../../../lib/utils";
|
||||
|
||||
export default class Web3PyDetector implements LibraryDetector {
|
||||
public libraryType: LibraryType = "web3py";
|
||||
|
||||
public matches(path: string, packageManager: PackageManagerType): boolean {
|
||||
const { dependencies, devDependencies } = getDependenciesForPython(
|
||||
path,
|
||||
packageManager,
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies.includes("web3") || devDependencies.includes("web3") || false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { PackageManagerDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { PackageManagerType } from "../../types/ProjectType";
|
||||
|
||||
export default class CondaDetector implements PackageManagerDetector {
|
||||
public packageManagerType: PackageManagerType = "conda";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const files = [
|
||||
"/environment.yml",
|
||||
"/environment.yaml",
|
||||
"/conda-requirements.txt",
|
||||
"/.conda",
|
||||
"/.condarc",
|
||||
];
|
||||
|
||||
// Check if at least one of these files exists in the current path.
|
||||
return files.some((file) => existsSync(path + file));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PackageManagerDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { PackageManagerType } from "../../types/ProjectType";
|
||||
|
||||
export default class GoModulesDetector implements PackageManagerDetector {
|
||||
public packageManagerType: PackageManagerType = "go-modules";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
return existsSync(path + "/go.mod");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PackageManagerDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { PackageManagerType } from "../../types/ProjectType";
|
||||
|
||||
export default class NPMDetector implements PackageManagerDetector {
|
||||
public packageManagerType: PackageManagerType = "npm";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
return existsSync(path + "/package-lock.json");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PackageManagerDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { PackageManagerType } from "../../types/ProjectType";
|
||||
|
||||
export default class PipDetector implements PackageManagerDetector {
|
||||
public packageManagerType: PackageManagerType = "pip";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
return existsSync(path + "/requirements.txt");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { PackageManagerDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { PackageManagerType } from "../../types/ProjectType";
|
||||
|
||||
export default class PipEnvDetector implements PackageManagerDetector {
|
||||
public packageManagerType: PackageManagerType = "pipenv";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const files = ["/Pipfile", "/Pipfile.lock"];
|
||||
|
||||
// Check if at least one of these files exists in the current path.
|
||||
return files.some((file) => existsSync(path + file));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { PackageManagerDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { PackageManagerType } from "../../types/ProjectType";
|
||||
|
||||
export default class PnpmDetector implements PackageManagerDetector {
|
||||
public packageManagerType: PackageManagerType = "pnpm";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const files = ["/pnpm-lock.yaml", "/pnpm-workspace.yaml", "/.pnpm"];
|
||||
|
||||
// Check if at least one of these files exists in the current path.
|
||||
return files.some((file) => existsSync(path + file));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { PackageManagerDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { PackageManagerType } from "../../types/ProjectType";
|
||||
|
||||
export default class PoetryDetector implements PackageManagerDetector {
|
||||
public packageManagerType: PackageManagerType = "poetry";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const files = ["/pyproject.toml", "/poetry.lock"];
|
||||
|
||||
// Check if at least one of these files exists in the current path.
|
||||
return files.some((file) => existsSync(path + file));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PackageManagerDetector } from "../detector";
|
||||
import { existsSync } from "fs";
|
||||
import { PackageManagerType } from "../../types/ProjectType";
|
||||
|
||||
export default class YarnDetector implements PackageManagerDetector {
|
||||
public packageManagerType: PackageManagerType = "yarn";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
return existsSync(path + "/yarn.lock");
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,77 @@ export type ProjectType =
|
||||
| "spa-webapp"
|
||||
| "yarn"
|
||||
| "npm"
|
||||
| "none"
|
||||
| "pnpm";
|
||||
|
||||
export type PackageManagerType =
|
||||
| "yarn"
|
||||
| "npm"
|
||||
| "pnpm"
|
||||
| "pip"
|
||||
| "conda"
|
||||
| "pipenv"
|
||||
| "poetry"
|
||||
| "go-modules"
|
||||
| "none";
|
||||
export type LanguageType =
|
||||
| "javascript"
|
||||
| "typescript"
|
||||
| "python"
|
||||
| "go"
|
||||
| "c#"
|
||||
| "solidity"
|
||||
| "none";
|
||||
export type FrameworkType =
|
||||
| "next"
|
||||
| "gatsby"
|
||||
| "remix"
|
||||
| "cra"
|
||||
| "vue"
|
||||
| "expo"
|
||||
| "react-native-cli"
|
||||
| "express"
|
||||
| "hardhat"
|
||||
| "truffle"
|
||||
| "foundry"
|
||||
| "brownie"
|
||||
| "solc"
|
||||
| "django"
|
||||
| "flask"
|
||||
| "fastapi"
|
||||
| "populus"
|
||||
| "fastify"
|
||||
| "gin"
|
||||
| "echo"
|
||||
| "revel"
|
||||
| "fiber"
|
||||
| "zenject"
|
||||
| "none";
|
||||
export type LibraryType =
|
||||
| "react"
|
||||
| "react-native"
|
||||
| "vue"
|
||||
| "svelte"
|
||||
| "vite"
|
||||
| "express"
|
||||
| "web3py"
|
||||
| "playmaker"
|
||||
| "none";
|
||||
export type AppType = "app" | "contract" | "library" | "none";
|
||||
export type ContractLibrariesType =
|
||||
| "brownie"
|
||||
| "foundry"
|
||||
| "hardhat"
|
||||
| "truffle"
|
||||
| "solc"
|
||||
| "none";
|
||||
|
||||
|
||||
export const contractLibraries: readonly ContractLibrariesType[] = [
|
||||
"brownie",
|
||||
"foundry",
|
||||
"hardhat",
|
||||
"truffle",
|
||||
"solc",
|
||||
"none",
|
||||
] as const;
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
declare module 'sync-disk-cache';
|
||||
declare module "sync-disk-cache";
|
||||
declare module "solc";
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
import * as toml from "@iarna/toml";
|
||||
import * as yaml from "js-yaml";
|
||||
|
||||
import { PackageManagerType } from "../core/types/ProjectType";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
|
||||
export const parsePackageJson = (packageJson: Buffer) => {
|
||||
const packageJsonContent = JSON.parse(packageJson.toString());
|
||||
const dependencies = packageJsonContent.dependencies || {};
|
||||
const devDependencies = packageJsonContent.devDependencies || {};
|
||||
return { dependencies, devDependencies };
|
||||
};
|
||||
|
||||
export const parseRequirementsTxt = (requirementsTxt: Buffer) => {
|
||||
const requirementsTxtContent = requirementsTxt.toString();
|
||||
const dependencies = requirementsTxtContent.split("\n");
|
||||
return { dependencies };
|
||||
};
|
||||
|
||||
export const parsePipFile = (PipFile: string) => {
|
||||
const pipfile = toml.parse(PipFile);
|
||||
const dependencies = (pipfile.packages as string[]) || [];
|
||||
const devDependencies = (pipfile["dev-packages"] as string[]) || [];
|
||||
return {
|
||||
dependencies,
|
||||
devDependencies,
|
||||
};
|
||||
};
|
||||
|
||||
export const parsePyProjectToml = (pyProjectToml: string) => {
|
||||
const pyProjectFile = toml.parse(pyProjectToml) as any;
|
||||
const dependencies =
|
||||
(pyProjectFile["tool"]["poetry"]["dependencies"] as string[]) || [];
|
||||
const devDependencies =
|
||||
(pyProjectFile["tool"]["poetry"]["dev-dependencies"] as string[]) || [];
|
||||
return {
|
||||
dependencies,
|
||||
devDependencies,
|
||||
};
|
||||
};
|
||||
|
||||
export const parseCondaYml = (condaYml: string) => {
|
||||
const conda = yaml.load(condaYml) as any;
|
||||
const dependencies = (conda.dependencies as string[]) || [];
|
||||
return {
|
||||
dependencies,
|
||||
};
|
||||
};
|
||||
|
||||
export const parseGoMod = (goModContent: string) => {
|
||||
const dependencies: { name: string; version: string }[] = [];
|
||||
const lines: string[] = goModContent.split("\n");
|
||||
|
||||
lines.forEach((line) => {
|
||||
line = line.trim();
|
||||
|
||||
if (line.startsWith("require (")) {
|
||||
let i = lines.indexOf(line) + 1;
|
||||
while (i < lines.length && lines[i].trim() !== ")") {
|
||||
const dependencyLine = lines[i].trim();
|
||||
const [name, version] = dependencyLine.split(" ");
|
||||
dependencies.push({ name, version });
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
dependencies,
|
||||
};
|
||||
};
|
||||
|
||||
export const fileContainsImport = (file: string, importToCheck: string) => {
|
||||
const lines = file.split("\n");
|
||||
|
||||
lines.forEach(() => {
|
||||
if (lines.includes(importToCheck)) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const getDependenciesForPython = (
|
||||
path: string,
|
||||
packageManager: PackageManagerType,
|
||||
) => {
|
||||
let dependencies: string[] = [];
|
||||
let devDependencies: string[] = [];
|
||||
|
||||
switch (packageManager) {
|
||||
case "pip" || "pipenv":
|
||||
const foundPipFile = existsSync(path + "Pipfile");
|
||||
if (foundPipFile) {
|
||||
const pipFile = readFileSync(path + "Pipfile", "utf-8");
|
||||
const parsedPipFile = parsePipFile(pipFile);
|
||||
dependencies = parsedPipFile.dependencies;
|
||||
devDependencies = parsedPipFile.devDependencies;
|
||||
break;
|
||||
}
|
||||
const foundRequirementsTxt = existsSync(path + "/requirements.txt");
|
||||
if (!foundRequirementsTxt) {
|
||||
break;
|
||||
}
|
||||
const requirementsTxt = readFileSync(path + "/requirements.txt");
|
||||
dependencies = parseRequirementsTxt(requirementsTxt).dependencies;
|
||||
break;
|
||||
case "poetry":
|
||||
const foundPyProjectToml = existsSync(path + "/pyproject.toml");
|
||||
if (!foundPyProjectToml) {
|
||||
break;
|
||||
}
|
||||
const pyProjectFile = readFileSync(path + "/pyproject.toml", "utf-8");
|
||||
dependencies = parsePyProjectToml(pyProjectFile).dependencies;
|
||||
break;
|
||||
case "conda":
|
||||
const foundCondaYml = existsSync(path + "/environment.yml");
|
||||
if (!foundCondaYml) {
|
||||
break;
|
||||
}
|
||||
const condaYml = readFileSync(path + "/environment.yml", "utf-8");
|
||||
dependencies = parseCondaYml(condaYml).dependencies;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
dependencies,
|
||||
devDependencies,
|
||||
};
|
||||
};
|
||||
@@ -26,7 +26,7 @@
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ethers": "^5.7.0"
|
||||
"ethers": "^5"
|
||||
},
|
||||
"files": [
|
||||
"dist/",
|
||||
|
||||
@@ -1,5 +1,52 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 3.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#993](https://github.com/thirdweb-dev/js/pull/993) [`b1ede491`](https://github.com/thirdweb-dev/js/commit/b1ede491fbfbeca0ff3d6f5a6162546671bf8b99) Thanks [@0xfrosty](https://github.com/0xfrosty)! - Add React hook useBuyDirectListing() to buy a direct listing in a MarketplaceV3 contract
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1015](https://github.com/thirdweb-dev/js/pull/1015) [`39bd9630`](https://github.com/thirdweb-dev/js/commit/39bd963015ac00a1e4da2d0b4c9d85b334c7ad46) Thanks [@MananTank](https://github.com/MananTank)! - - add `selectUI` api in `WalletConfig` to allow rendering a custom UI for selecting a wallet
|
||||
|
||||
- Render an input for paper wallet and magic link using `selectUI` api
|
||||
- add prop `modalTitle` on `ConnectWallet` to configure a custom title for the modal
|
||||
- add props `selectionData`, `setSelectionData` and `supportedWallets` on `connectUI`
|
||||
|
||||
- [#996](https://github.com/thirdweb-dev/js/pull/996) [`c3645c45`](https://github.com/thirdweb-dev/js/commit/c3645c451b5e9a0fcf651fa07eb0e31ebf1882ca) Thanks [@MananTank](https://github.com/MananTank)! - - add `theme` in `ConfiguredWallet.connectUI`'s props - to use theme aware UI for wallets
|
||||
|
||||
- add `useWalletConfig` hook to get the `ConfiguredWallet` object for active wallet
|
||||
- add hooks `useSetConnectedWallet`, `useSetConnectionStatus`
|
||||
- rename `useActiveChain` to `useChain` - keep the `useActiveChain` also with deprecated tag
|
||||
- make `useSafe` hook await-able by returning the promise of connect() call
|
||||
- add hook `useSmartWallet`
|
||||
- allow rendering custom wallet details button via `<ConnectWallet detailsButton={} />` prop
|
||||
- Rename "Export" to "Backup" in local wallet UI
|
||||
|
||||
- [#1011](https://github.com/thirdweb-dev/js/pull/1011) [`470e0a14`](https://github.com/thirdweb-dev/js/commit/470e0a144db6aa03e7789e231bbdfae43144f0e0) Thanks [@MananTank](https://github.com/MananTank)! - rename ConfiguredWallet to WalletConfig
|
||||
|
||||
```diff
|
||||
- import { ConfiguredWallet } from '@thirdweb-dev/react';
|
||||
+ import { WalletConfig } from '@thirdweb-dev/react';
|
||||
```
|
||||
|
||||
- [#989](https://github.com/thirdweb-dev/js/pull/989) [`8db78299`](https://github.com/thirdweb-dev/js/commit/8db78299ea6cfb51d93b91bb1a351644a83c73d2) Thanks [@iketw](https://github.com/iketw)! - [React/ReactNative] Updated useThirdwebWallet to useWalletContext
|
||||
|
||||
- Updated dependencies [[`e9b69300`](https://github.com/thirdweb-dev/js/commit/e9b69300d15b233609f1ed897256ec9a1eef3e28), [`49ec2d17`](https://github.com/thirdweb-dev/js/commit/49ec2d171ecb1c9240398b7b486a452eb9429979), [`799d98e8`](https://github.com/thirdweb-dev/js/commit/799d98e86258677ab72931fa8397aee653fe8b34), [`c3645c45`](https://github.com/thirdweb-dev/js/commit/c3645c451b5e9a0fcf651fa07eb0e31ebf1882ca), [`470e0a14`](https://github.com/thirdweb-dev/js/commit/470e0a144db6aa03e7789e231bbdfae43144f0e0), [`738c0ec6`](https://github.com/thirdweb-dev/js/commit/738c0ec6c4190aa2252233c1382aed5d982cc7b8), [`d495a4b8`](https://github.com/thirdweb-dev/js/commit/d495a4b8a6e0599e5b4611620f3fded80a411173), [`482f6d1b`](https://github.com/thirdweb-dev/js/commit/482f6d1b58ac99b331fc750d3eeb6082556fd526), [`e4356e76`](https://github.com/thirdweb-dev/js/commit/e4356e76d1506624afe2eb6feeaf57dc376f372f), [`9886c858`](https://github.com/thirdweb-dev/js/commit/9886c858d9c8d0f677aba6572dbf5cc6c876edf2), [`8db78299`](https://github.com/thirdweb-dev/js/commit/8db78299ea6cfb51d93b91bb1a351644a83c73d2), [`4f843833`](https://github.com/thirdweb-dev/js/commit/4f8438335e3e3731b67ae271cb34c383832242a0)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 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/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 3.11.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "3.11.10",
|
||||
"version": "3.12.0",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -49,6 +49,7 @@ const MARKETPLACE_HOOKS = [
|
||||
"useCreateAuctionListing",
|
||||
"useMakeBid",
|
||||
"useBuyNow",
|
||||
"useBuyDirectListing",
|
||||
];
|
||||
|
||||
const DROP_HOOKS = [
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useThirdwebWallet } from "../providers/thirdweb-wallet-provider";
|
||||
import { useWalletContext } from "../providers/thirdweb-wallet-provider";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
* @returns the current active wallet instance
|
||||
*/
|
||||
export function useWallet() {
|
||||
const context = useThirdwebWallet();
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useWallet() hook must be used within a <ThirdwebProvider/>",
|
||||
@@ -13,12 +13,24 @@ export function useWallet() {
|
||||
return context.activeWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the current active wallet's configuration object
|
||||
*/
|
||||
export function useWalletConfig() {
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useWallet() hook must be used within a <ThirdwebProvider/>",
|
||||
);
|
||||
return context.activeWalletConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns `supportedWallets` configured in the `<ThirdwebProvider/>`
|
||||
*/
|
||||
export function useWallets() {
|
||||
const context = useThirdwebWallet();
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useWallets() hook must be used within a <ThirdwebProvider/>",
|
||||
@@ -31,7 +43,7 @@ export function useWallets() {
|
||||
* @returns a method to connect to a wallet class
|
||||
*/
|
||||
export function useConnect() {
|
||||
const context = useThirdwebWallet();
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useConnect() hook must be used within a <ThirdwebProvider/>",
|
||||
@@ -44,7 +56,7 @@ export function useConnect() {
|
||||
* @returns a method to disconnect from the current active wallet
|
||||
*/
|
||||
export function useDisconnect() {
|
||||
const context = useThirdwebWallet();
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useDisconnect() hook must be used within a <ThirdwebProvider/>",
|
||||
@@ -64,7 +76,7 @@ export function useDisconnect() {
|
||||
*
|
||||
*/
|
||||
export function useConnectionStatus() {
|
||||
const context = useThirdwebWallet();
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useConnectionStatus() must be used within a <ThirdwebProvider/>",
|
||||
@@ -74,19 +86,15 @@ export function useConnectionStatus() {
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns if the wallet is currently connecting
|
||||
*
|
||||
* @returns a method to create an instance of given wallet class
|
||||
*/
|
||||
export function useIsConnecting() {
|
||||
const context = useThirdwebWallet();
|
||||
export function useSetConnectionStatus() {
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useConnectionStatus() must be used within a <ThirdwebProvider/>",
|
||||
);
|
||||
return (
|
||||
context.connectionStatus === "connecting" ||
|
||||
context.connectionStatus === "unknown"
|
||||
"useSetConnectionStatus() must be used within a <ThirdwebProvider/>",
|
||||
);
|
||||
return context.setConnectionStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +102,7 @@ export function useIsConnecting() {
|
||||
* @returns a method to create an instance of given wallet class
|
||||
*/
|
||||
export function useCreateWalletInstance() {
|
||||
const context = useThirdwebWallet();
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useCreateWalletInstance() must be used within a <ThirdwebProvider/>",
|
||||
@@ -107,10 +115,23 @@ export function useCreateWalletInstance() {
|
||||
* @returns a method to connect the wallet to network/chain with given chainId
|
||||
*/
|
||||
export function useSwitchChain() {
|
||||
const context = useThirdwebWallet();
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useSwitchChain() must be used within a <ThirdwebProvider/>",
|
||||
);
|
||||
return context.switchChain;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns a method to set a connected wallet instance
|
||||
*/
|
||||
export function useSetConnectedWallet() {
|
||||
const context = useWalletContext();
|
||||
invariant(
|
||||
context,
|
||||
"useSwitchChain() must be used within a <ThirdwebProvider/>",
|
||||
);
|
||||
return context.setConnectedWallet;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ 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 { ConfiguredWallet } from "../types/wallet";
|
||||
import { WalletConfig } from "../types/wallet";
|
||||
import { ThirdwebThemeContext } from "./theme-context";
|
||||
import {
|
||||
ThirdwebWalletProvider,
|
||||
useThirdwebWallet,
|
||||
useWalletContext,
|
||||
} from "./thirdweb-wallet-provider";
|
||||
import { Chain, defaultChains } from "@thirdweb-dev/chains";
|
||||
import {
|
||||
@@ -40,7 +40,7 @@ export interface ThirdwebProviderCoreProps<TChains extends Chain[]>
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
supportedWallets: ConfiguredWallet[];
|
||||
supportedWallets: WalletConfig[];
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -172,7 +172,7 @@ const ThirdwebSDKProviderWrapper = <TChains extends Chain[]>({
|
||||
}: React.PropsWithChildren<
|
||||
Omit<ThirdwebSDKProviderProps<TChains>, "signer">
|
||||
>) => {
|
||||
const signer = useThirdwebWallet()?.signer;
|
||||
const signer = useWalletContext()?.signer;
|
||||
|
||||
return (
|
||||
<ThirdwebSDKProvider signer={signer} {...props}>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DAppMetaData } from "../types/dAppMeta";
|
||||
import type { ConfiguredWallet, WalletInstance } from "../types/wallet";
|
||||
import type { WalletConfig, WalletInstance } from "../types/wallet";
|
||||
import { ThirdwebThemeContext } from "./theme-context";
|
||||
import { Chain } from "@thirdweb-dev/chains";
|
||||
import {
|
||||
@@ -41,41 +41,60 @@ type WalletConnectParams<I extends WalletInstance> = Parameters<
|
||||
|
||||
type ConnectionStatus = "unknown" | "connected" | "disconnected" | "connecting";
|
||||
|
||||
type ConnectFnArgs<I extends WalletInstance> =
|
||||
type ConnectFnArgs<
|
||||
I extends WalletInstance,
|
||||
Config extends Record<string, any> | undefined,
|
||||
> =
|
||||
// if second argument is optional
|
||||
undefined extends WalletConnectParams<I>
|
||||
? [
|
||||
wallet: ConfiguredWallet<I>,
|
||||
wallet: WalletConfig<I, Config>,
|
||||
connectParams?: NonNullable<WalletConnectParams<I>>,
|
||||
]
|
||||
: // if second argument is required
|
||||
[
|
||||
wallet: ConfiguredWallet<I>,
|
||||
wallet: WalletConfig<I, Config>,
|
||||
connectParams: NonNullable<WalletConnectParams<I>>,
|
||||
];
|
||||
|
||||
// maps wallet instance to it's wallet config
|
||||
const walletInstanceToConfig: Map<
|
||||
WalletInstance,
|
||||
WalletConfig<any, any>
|
||||
> = new Map();
|
||||
|
||||
type ThirdwebWalletContextData = {
|
||||
wallets: ConfiguredWallet[];
|
||||
wallets: WalletConfig[];
|
||||
signer?: Signer;
|
||||
activeWallet?: WalletInstance;
|
||||
activeWalletConfig?: ConfiguredWallet;
|
||||
connect: <I extends WalletInstance>(
|
||||
...args: ConnectFnArgs<I>
|
||||
activeWalletConfig?: WalletConfig;
|
||||
connect: <
|
||||
I extends WalletInstance,
|
||||
Config extends Record<string, any> | undefined = undefined,
|
||||
>(
|
||||
...args: ConnectFnArgs<I, Config>
|
||||
) => Promise<void>;
|
||||
disconnect: () => Promise<void>;
|
||||
connectionStatus: ConnectionStatus;
|
||||
setConnectionStatus: (status: ConnectionStatus) => void;
|
||||
createWalletInstance: <I extends WalletInstance>(
|
||||
Wallet: ConfiguredWallet<I>,
|
||||
createWalletInstance: <
|
||||
I extends WalletInstance,
|
||||
Config extends Record<string, any> | undefined,
|
||||
>(
|
||||
Wallet: WalletConfig<I, Config>,
|
||||
) => I;
|
||||
createWalletStorage: CreateAsyncStorage;
|
||||
switchChain: (chain: number) => Promise<void>;
|
||||
chainToConnect?: Chain;
|
||||
activeChain: Chain;
|
||||
handleWalletConnect: (
|
||||
setConnectedWallet: (
|
||||
wallet: WalletInstance,
|
||||
params?: ConnectParams<Record<string, any>>,
|
||||
) => void;
|
||||
/**
|
||||
* Get wallet config object from wallet instance
|
||||
*/
|
||||
getWalletConfig: (walletInstance: WalletInstance) => WalletConfig | undefined;
|
||||
};
|
||||
|
||||
const ThirdwebWalletContext = createContext<
|
||||
@@ -85,7 +104,7 @@ const ThirdwebWalletContext = createContext<
|
||||
export function ThirdwebWalletProvider(
|
||||
props: PropsWithChildren<{
|
||||
activeChain: Chain;
|
||||
supportedWallets: ConfiguredWallet[];
|
||||
supportedWallets: WalletConfig[];
|
||||
shouldAutoConnect?: boolean;
|
||||
createWalletStorage: CreateAsyncStorage;
|
||||
dAppMeta?: DAppMetaData;
|
||||
@@ -101,8 +120,8 @@ export function ThirdwebWalletProvider(
|
||||
WalletInstance | undefined
|
||||
>();
|
||||
|
||||
const [activeWalletConfig, setActiveConfig] = useState<
|
||||
ConfiguredWallet | undefined
|
||||
const [activeWalletConfig, setActiveWalletConfig] = useState<
|
||||
WalletConfig | undefined
|
||||
>();
|
||||
|
||||
if (!lastConnectedWalletStorage) {
|
||||
@@ -130,8 +149,12 @@ export function ThirdwebWalletProvider(
|
||||
}, [props.chains, props.dAppMeta, props.activeChain, theme]);
|
||||
|
||||
const createWalletInstance = useCallback(
|
||||
<I extends WalletInstance>(wallet: ConfiguredWallet<I>): I => {
|
||||
return wallet.create(walletParams);
|
||||
<I extends WalletInstance, Config extends Record<string, any> | undefined>(
|
||||
walletConfig: WalletConfig<I, Config>,
|
||||
): I => {
|
||||
const walletInstance = walletConfig.create(walletParams);
|
||||
walletInstanceToConfig.set(walletInstance, walletConfig);
|
||||
return walletInstance;
|
||||
},
|
||||
[walletParams],
|
||||
);
|
||||
@@ -143,35 +166,20 @@ 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(
|
||||
const setConnectedWallet = useCallback(
|
||||
async (
|
||||
wallet: WalletInstance,
|
||||
connectParams?: ConnectParams<Record<string, any>>,
|
||||
isAutoConnect = false,
|
||||
) => {
|
||||
setActiveWallet(wallet);
|
||||
setActiveConfig(getWalletConfig(wallet));
|
||||
const walletConfig = walletInstanceToConfig.get(wallet);
|
||||
if (!walletConfig) {
|
||||
throw new Error(
|
||||
"Wallet config not found for given wallet instance. Do not create a wallet instance manually - use the useCreateWalletInstance() hook instead",
|
||||
);
|
||||
}
|
||||
setActiveWalletConfig(walletConfig);
|
||||
setConnectionStatus("connected");
|
||||
const _signer = await wallet.getSigner();
|
||||
setSigner(_signer);
|
||||
@@ -182,19 +190,21 @@ export function ThirdwebWalletProvider(
|
||||
}
|
||||
|
||||
// save to storage
|
||||
|
||||
const walletInfo: LastConnectedWalletInfo = {
|
||||
walletId: wallet.walletId,
|
||||
walletId: walletConfig.id,
|
||||
connectParams,
|
||||
};
|
||||
|
||||
// if personal wallet exists, we need to replace the connectParams.personalWallet to a stringifiable version
|
||||
const personalWallet = wallet.getPersonalWallet() as AbstractClientWallet;
|
||||
const personalWalletConfig = walletInstanceToConfig.get(personalWallet);
|
||||
|
||||
if (personalWallet) {
|
||||
if (personalWallet && personalWalletConfig) {
|
||||
walletInfo.connectParams = {
|
||||
...walletInfo.connectParams,
|
||||
personalWallet: {
|
||||
walletId: personalWallet.walletId,
|
||||
walletId: personalWalletConfig.id,
|
||||
connectParams: personalWallet.getConnectParams(),
|
||||
},
|
||||
};
|
||||
@@ -204,7 +214,7 @@ export function ThirdwebWalletProvider(
|
||||
saveLastConnectedWalletInfo(walletInfo);
|
||||
}
|
||||
},
|
||||
[getWalletConfig],
|
||||
[],
|
||||
);
|
||||
|
||||
const storeLastActiveChainId = useCallback(async (chainId: number) => {
|
||||
@@ -291,7 +301,7 @@ export function ThirdwebWalletProvider(
|
||||
|
||||
if (personalWalletInfo) {
|
||||
type Config = {
|
||||
personalWallets: ConfiguredWallet[];
|
||||
personalWallets: WalletConfig[];
|
||||
};
|
||||
|
||||
const personalWallets =
|
||||
@@ -334,7 +344,7 @@ export function ThirdwebWalletProvider(
|
||||
try {
|
||||
setConnectionStatus("connecting");
|
||||
await wallet.autoConnect(walletInfo.connectParams);
|
||||
handleWalletConnect(wallet, walletInfo.connectParams, true);
|
||||
setConnectedWallet(wallet, walletInfo.connectParams, true);
|
||||
} catch (e) {
|
||||
lastConnectedWalletStorage.removeItem(
|
||||
LAST_CONNECTED_WALLET_STORAGE_KEY,
|
||||
@@ -348,14 +358,19 @@ export function ThirdwebWalletProvider(
|
||||
}, [
|
||||
createWalletInstance,
|
||||
props.supportedWallets,
|
||||
handleWalletConnect,
|
||||
setConnectedWallet,
|
||||
props.shouldAutoConnect,
|
||||
activeWallet,
|
||||
connectionStatus,
|
||||
]);
|
||||
|
||||
const connectWallet = useCallback(
|
||||
async <I extends WalletInstance>(...args: ConnectFnArgs<I>) => {
|
||||
async <
|
||||
I extends WalletInstance,
|
||||
Config extends Record<string, any> | undefined = undefined,
|
||||
>(
|
||||
...args: ConnectFnArgs<I, Config>
|
||||
) => {
|
||||
const [WalletObj, connectParams] = args;
|
||||
|
||||
const _connectedParams = {
|
||||
@@ -367,14 +382,14 @@ export function ThirdwebWalletProvider(
|
||||
setConnectionStatus("connecting");
|
||||
try {
|
||||
await wallet.connect(_connectedParams);
|
||||
handleWalletConnect(wallet, _connectedParams);
|
||||
setConnectedWallet(wallet, _connectedParams);
|
||||
} catch (e: any) {
|
||||
console.error(`Error connecting to wallet: ${e}`);
|
||||
setConnectionStatus("disconnected");
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
[createWalletInstance, handleWalletConnect, chainToConnect],
|
||||
[createWalletInstance, setConnectedWallet, chainToConnect],
|
||||
);
|
||||
|
||||
const onWalletDisconnect = useCallback(async () => {
|
||||
@@ -384,7 +399,7 @@ export function ThirdwebWalletProvider(
|
||||
setConnectionStatus("disconnected");
|
||||
setSigner(undefined);
|
||||
setActiveWallet(undefined);
|
||||
setActiveConfig(undefined);
|
||||
setActiveWalletConfig(undefined);
|
||||
}, []);
|
||||
|
||||
const disconnectWallet = useCallback(async () => {
|
||||
@@ -443,9 +458,12 @@ export function ThirdwebWalletProvider(
|
||||
createWalletInstance: createWalletInstance,
|
||||
createWalletStorage: props.createWalletStorage,
|
||||
switchChain,
|
||||
handleWalletConnect,
|
||||
setConnectedWallet: setConnectedWallet,
|
||||
activeChain: props.activeChain,
|
||||
chainToConnect,
|
||||
getWalletConfig: (walletInstance: WalletInstance) => {
|
||||
return walletInstanceToConfig.get(walletInstance);
|
||||
},
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
@@ -453,11 +471,11 @@ export function ThirdwebWalletProvider(
|
||||
);
|
||||
}
|
||||
|
||||
export function useThirdwebWallet() {
|
||||
export function useWalletContext() {
|
||||
const ctx = useContext(ThirdwebWalletContext);
|
||||
if (!ctx) {
|
||||
throw new Error(
|
||||
`useThirdwebWallet() can only be used inside <ThirdwebProvider />`,
|
||||
`useWalletContext() can only be used inside <ThirdwebProvider />`,
|
||||
);
|
||||
}
|
||||
return ctx;
|
||||
|
||||
@@ -15,7 +15,7 @@ export type WalletOptions = {
|
||||
dappMetadata?: DAppMetaData;
|
||||
} & ExtraCoreWalletOptions;
|
||||
|
||||
export type WalletInstance = InstanceType<typeof AbstractClientWallet>;
|
||||
export type WalletInstance = AbstractClientWallet;
|
||||
|
||||
export type WalletClass<I extends WalletInstance = WalletInstance> = {
|
||||
id: string;
|
||||
@@ -23,14 +23,21 @@ export type WalletClass<I extends WalletInstance = WalletInstance> = {
|
||||
meta: (typeof AbstractClientWallet)["meta"];
|
||||
};
|
||||
|
||||
export type ConfiguredWallet<
|
||||
export type WalletConfig<
|
||||
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>;
|
||||
/**
|
||||
* UI for connecting wallet
|
||||
*/
|
||||
connectUI?: React.FC<ConnectUIProps<I, Config>>;
|
||||
/**
|
||||
* UI for selecting wallet - this UI is rendered in the wallet selection screen
|
||||
*/
|
||||
selectUI?: React.FC<SelectUIProps<I, Config>>;
|
||||
isInstalled?: () => boolean;
|
||||
} & (Config extends undefined
|
||||
? {}
|
||||
@@ -38,7 +45,10 @@ export type ConfiguredWallet<
|
||||
config: Config;
|
||||
});
|
||||
|
||||
export type ConnectUIProps = {
|
||||
export type ConnectUIProps<
|
||||
I extends WalletInstance = WalletInstance,
|
||||
Config extends Record<string, any> | undefined = undefined,
|
||||
> = {
|
||||
/**
|
||||
* 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
|
||||
@@ -61,4 +71,94 @@ export type ConnectUIProps = {
|
||||
* go back to the wallet selector screen in connect wallet modal
|
||||
*/
|
||||
goBack: () => void;
|
||||
|
||||
/**
|
||||
* theme of the connect wallet modal
|
||||
*/
|
||||
theme: "dark" | "light";
|
||||
|
||||
/**
|
||||
* `WalletConfig` object of your wallet
|
||||
*
|
||||
* you can use this to connect to your wallet
|
||||
*
|
||||
* ### 1. Using `useConnect` hook
|
||||
* ```ts
|
||||
* const connect = useConnect();
|
||||
*
|
||||
* // call this function to connect to your wallet
|
||||
* async function handleConnect() {
|
||||
* await connect(walletConfig, options);
|
||||
* }
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* ### 2. Manually creating wallet instance and connecting
|
||||
* ```ts
|
||||
* const createWalletInstance = useCreateWalletInstance();
|
||||
* const setConnectedWallet = useSetConnectedWallet();
|
||||
* const setConnectionStatus = useSetConnectionStatus();
|
||||
*
|
||||
* // call this function to connect to your wallet
|
||||
* async function handleConnect() {
|
||||
* // create instance
|
||||
* const walletInstance = createWalletInstance(walletConfig);
|
||||
* // connect wallet
|
||||
* setConnectionStatus('connecting);
|
||||
* try {
|
||||
* await walletInstance.connect(options);
|
||||
* // set connected wallet
|
||||
* setConnectedWallet(walletInstance);
|
||||
* } catch {
|
||||
* setConnectionStatus('disconnected');
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
walletConfig: WalletConfig<I, Config>;
|
||||
|
||||
/**
|
||||
* selectionData passed from `selectUI`'s `onSelect` function
|
||||
*/
|
||||
selectionData: any;
|
||||
|
||||
/**
|
||||
* set selectionData
|
||||
* @returns
|
||||
*/
|
||||
setSelectionData: (data: any) => void;
|
||||
|
||||
/**
|
||||
* List of all supported wallets including your wallet.
|
||||
*/
|
||||
supportedWallets: WalletConfig[];
|
||||
};
|
||||
|
||||
export type SelectUIProps<
|
||||
I extends WalletInstance = WalletInstance,
|
||||
Config extends Record<string, any> | undefined = undefined,
|
||||
> = {
|
||||
/**
|
||||
* Call this function to "select" your wallet and render the screen for connecting the wallet
|
||||
* @param selectionData - selectionData to be passed to `connectUI`'s `selectionData` prop
|
||||
* @returns
|
||||
*/
|
||||
onSelect: (selectionData: any) => void;
|
||||
|
||||
/**
|
||||
* `WalletConfig` object of your wallet
|
||||
*
|
||||
* you can use this get metadata of your wallet by doing `walletConfig.meta`
|
||||
*/
|
||||
walletConfig: WalletConfig<I, Config>;
|
||||
|
||||
/**
|
||||
* List of all supported wallets including your wallet.
|
||||
*
|
||||
* You can use this to conditionally render UI based on how many wallets are supported.
|
||||
* For example: You can render a larger UI if only one wallet (your wallet) is supported.
|
||||
*/
|
||||
supportedWallets: WalletConfig[];
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
import { useSDKChainId } from "../../providers/thirdweb-sdk-provider";
|
||||
import {
|
||||
AcceptDirectOffer,
|
||||
BuyFromListingParams,
|
||||
BuyNowParams,
|
||||
ExecuteAuctionSale,
|
||||
MakeBidParams,
|
||||
@@ -1380,6 +1381,71 @@ export function useBuyNow(contract: RequiredParam<Marketplace>) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Buy a direct listing
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* const Component = () => {
|
||||
* const { contract } = useContract("{{contract_address}}", "marketplace-v3");
|
||||
* const {
|
||||
* mutate: buyNow,
|
||||
* isLoading,
|
||||
* error,
|
||||
* } = useBuyDirectListing(contract);
|
||||
*
|
||||
* if (error) {
|
||||
* console.error("failed to buy direct listing", error);
|
||||
* }
|
||||
*
|
||||
* return (
|
||||
* <button
|
||||
* disabled={isLoading}
|
||||
* onClick={() => buyNow({listingId: 1, quantity: 1, buyer: "{{address}}"})}
|
||||
* >
|
||||
* Buy listing!
|
||||
* </button>
|
||||
* );
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a MarketplaceV3 contract
|
||||
* @returns a mutation object that can be used to buy out a direct listing
|
||||
* @see {@link https://portal.thirdweb.com/react/react.useBuyDirectListing?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useBuyDirectListing(contract: RequiredParam<MarketplaceV3>) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const walletAddress = useAddress();
|
||||
|
||||
return useMutation(
|
||||
async (data: BuyFromListingParams) => {
|
||||
invariant(walletAddress, "no wallet connected, cannot buy from listing");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract.directListings.buyFromListing,
|
||||
"contract does not support directListings.buyFromListing"
|
||||
);
|
||||
|
||||
return await contract.directListings.buyFromListing(
|
||||
data.listingId,
|
||||
data.quantity,
|
||||
data.buyer
|
||||
);
|
||||
},
|
||||
{
|
||||
onSettled: () =>
|
||||
invalidateContractAndBalances(
|
||||
queryClient,
|
||||
contractAddress,
|
||||
activeChainId,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
function isMarketplaceV1(
|
||||
contract: RequiredParam<Marketplace | MarketplaceV3>,
|
||||
): contract is Marketplace {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useThirdwebWallet } from "../../core/providers/thirdweb-wallet-provider";
|
||||
import { useWalletContext } from "../../core/providers/thirdweb-wallet-provider";
|
||||
|
||||
export function useSupportedWallet(id: string) {
|
||||
const context = useThirdwebWallet();
|
||||
const context = useWalletContext();
|
||||
const wallet = context?.wallets.find((_wallet) => _wallet.id === id);
|
||||
if (!wallet) {
|
||||
throw new Error(`Wallet with id "${id}" is not supported`);
|
||||
|
||||
@@ -103,16 +103,16 @@ export function useChainId(): number | undefined {
|
||||
* Hook for accessing the active Chain the current wallet is connected to
|
||||
*
|
||||
* ```javascript
|
||||
* import { useActiveChain } from "@thirdweb-dev/react-core"
|
||||
* import { useChain } from "@thirdweb-dev/react-core"
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* You can get the chain of the connected wallet by using the hook as follows:
|
||||
* ```javascript
|
||||
* import { useActiveChain } from "@thirdweb-dev/react-core"
|
||||
* import { useChain } from "@thirdweb-dev/react-core"
|
||||
*
|
||||
* const App = () => {
|
||||
* const chain = useActiveChain()
|
||||
* const chain = useChain()
|
||||
*
|
||||
* return <div>{chain.chainId}</div>
|
||||
* }
|
||||
@@ -120,7 +120,7 @@ export function useChainId(): number | undefined {
|
||||
* @see {@link https://portal.thirdweb.com/react/react.useActiveChain?utm_source=sdk | Documentation}
|
||||
* @public
|
||||
*/
|
||||
export function useActiveChain(): Chain | undefined {
|
||||
export function useChain(): Chain | undefined {
|
||||
const chainId = useChainId();
|
||||
|
||||
const chains = useSupportedChains();
|
||||
@@ -137,3 +137,14 @@ export function useActiveChain(): Chain | undefined {
|
||||
|
||||
return chain || unknownChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* This hook is renamed to `useChain`
|
||||
*
|
||||
* use the `useChain` hook instead
|
||||
*/
|
||||
export function useActiveChain() {
|
||||
return useChain();
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@ export {
|
||||
useDisconnect,
|
||||
useSwitchChain,
|
||||
useWallets,
|
||||
useIsConnecting,
|
||||
useWalletConfig,
|
||||
useSetConnectionStatus,
|
||||
useSetConnectedWallet,
|
||||
} from "../core/hooks/wallet-hooks";
|
||||
export { useNetwork } from "../core/hooks/useNetwork";
|
||||
export { useThirdwebWallet } from "../core/providers/thirdweb-wallet-provider";
|
||||
export { useWalletContext } from "../core/providers/thirdweb-wallet-provider";
|
||||
|
||||
// connected wallet hooks
|
||||
export {
|
||||
@@ -28,14 +30,16 @@ export {
|
||||
useAddress,
|
||||
useChainId,
|
||||
useActiveChain,
|
||||
useChain,
|
||||
} from "./hooks/wallet";
|
||||
|
||||
// Utilities and Others
|
||||
export { shouldNeverPersistQuery } from "../core/query-utils/query-key";
|
||||
export type { RequiredParam } from "../core/query-utils/required-param";
|
||||
export type {
|
||||
ConfiguredWallet,
|
||||
WalletConfig,
|
||||
ConnectUIProps,
|
||||
SelectUIProps,
|
||||
WalletClass,
|
||||
WalletInstance,
|
||||
ExtraCoreWalletOptions,
|
||||
@@ -149,6 +153,7 @@ export {
|
||||
useExecuteAuctionSale,
|
||||
useOffers,
|
||||
useBuyNow,
|
||||
useBuyDirectListing,
|
||||
} from "./hooks/async/marketplace";
|
||||
|
||||
// nft
|
||||
|
||||
@@ -268,6 +268,12 @@ export type BuyNowParams<TListingType = ListingType> =
|
||||
type: ListingType.Auction;
|
||||
};
|
||||
|
||||
export type BuyFromListingParams = {
|
||||
listingId: string;
|
||||
quantity: Amount;
|
||||
buyer: WalletAddress;
|
||||
};
|
||||
|
||||
// TOKEN DROP //
|
||||
|
||||
export type ClaimTokenParams = {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.2.12
|
||||
|
||||
## 0.2.11
|
||||
|
||||
## 0.2.10
|
||||
|
||||
## 0.2.9
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.2.10",
|
||||
"version": "0.2.12",
|
||||
"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,100 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.2.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#995](https://github.com/thirdweb-dev/js/pull/995) [`482f6d1b`](https://github.com/thirdweb-dev/js/commit/482f6d1b58ac99b331fc750d3eeb6082556fd526) Thanks [@iketw](https://github.com/iketw)! - [ReactNative] update export local wallet modal UI
|
||||
|
||||
- [#996](https://github.com/thirdweb-dev/js/pull/996) [`c3645c45`](https://github.com/thirdweb-dev/js/commit/c3645c451b5e9a0fcf651fa07eb0e31ebf1882ca) Thanks [@MananTank](https://github.com/MananTank)! - - add `theme` in `ConfiguredWallet.connectUI`'s props - to use theme aware UI for wallets
|
||||
|
||||
- add `useWalletConfig` hook to get the `ConfiguredWallet` object for active wallet
|
||||
- add hooks `useSetConnectedWallet`, `useSetConnectionStatus`
|
||||
- rename `useActiveChain` to `useChain` - keep the `useActiveChain` also with deprecated tag
|
||||
- make `useSafe` hook await-able by returning the promise of connect() call
|
||||
- add hook `useSmartWallet`
|
||||
- allow rendering custom wallet details button via `<ConnectWallet detailsButton={} />` prop
|
||||
- Rename "Export" to "Backup" in local wallet UI
|
||||
|
||||
- [#1011](https://github.com/thirdweb-dev/js/pull/1011) [`470e0a14`](https://github.com/thirdweb-dev/js/commit/470e0a144db6aa03e7789e231bbdfae43144f0e0) Thanks [@MananTank](https://github.com/MananTank)! - rename ConfiguredWallet to WalletConfig
|
||||
|
||||
```diff
|
||||
- import { ConfiguredWallet } from '@thirdweb-dev/react';
|
||||
+ import { WalletConfig } from '@thirdweb-dev/react';
|
||||
```
|
||||
|
||||
- [#1019](https://github.com/thirdweb-dev/js/pull/1019) [`8a0dd070`](https://github.com/thirdweb-dev/js/commit/8a0dd070d4f4cb4d30b313e72827abf6f91f3f17) Thanks [@iketw](https://github.com/iketw)! - ## [ReactNative] Adds modalTitle, buttonTitle and detailsButton props to the ConnectWallet component
|
||||
|
||||
You can now customize the following props:
|
||||
|
||||
1. `buttonTitle`
|
||||
|
||||
The title of the ConnectWallet button which defaults to: "Connect Wallet":
|
||||
|
||||
```javascript
|
||||
<ConnectWallet buttonTitle="Connect to claim" />
|
||||
```
|
||||
|
||||
2. `modalTitle`
|
||||
|
||||
The title of the ConnectWallet modal which defaults to: "Choose your wallet":
|
||||
|
||||
```javascript
|
||||
<ConnectWallet modalTitle="Select a wallet" />
|
||||
```
|
||||
|
||||
3. `detailsButton`
|
||||
|
||||
The button that shows the details of the connected wallet. By default it shows
|
||||
the chain icon, wallet balance, account address and wallet icon:
|
||||
|
||||
```javascript
|
||||
const customDetailsButton = (
|
||||
<View>
|
||||
<Text>Connected button details</Text>
|
||||
<Text>{shortenWalletAddress(address)}</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
<ConnectWallet detailsButton={customDetailsButton} />;
|
||||
```
|
||||
|
||||
### Web3Button
|
||||
|
||||
The `buttonTitle` and `modalTitle` props are also available in the `Web3Button` config since we show a `ConnectWallet` button
|
||||
if you don't have a connected wallet:
|
||||
|
||||
```javascript
|
||||
<Web3Button
|
||||
connectWalletProps={{
|
||||
buttonTitle: "Connect to claim",
|
||||
modalTitle: "Pick a wallet",
|
||||
}}
|
||||
contractAddress="contract-address"
|
||||
action={(contract) => contract?.erc1155.claim(0, 1)}
|
||||
>
|
||||
Claim Factory
|
||||
</Web3Button>
|
||||
```
|
||||
|
||||
- [#989](https://github.com/thirdweb-dev/js/pull/989) [`8db78299`](https://github.com/thirdweb-dev/js/commit/8db78299ea6cfb51d93b91bb1a351644a83c73d2) Thanks [@iketw](https://github.com/iketw)! - [React/ReactNative] Updated useThirdwebWallet to useWalletContext
|
||||
|
||||
- Updated dependencies [[`e9b69300`](https://github.com/thirdweb-dev/js/commit/e9b69300d15b233609f1ed897256ec9a1eef3e28), [`39bd9630`](https://github.com/thirdweb-dev/js/commit/39bd963015ac00a1e4da2d0b4c9d85b334c7ad46), [`49ec2d17`](https://github.com/thirdweb-dev/js/commit/49ec2d171ecb1c9240398b7b486a452eb9429979), [`799d98e8`](https://github.com/thirdweb-dev/js/commit/799d98e86258677ab72931fa8397aee653fe8b34), [`c3645c45`](https://github.com/thirdweb-dev/js/commit/c3645c451b5e9a0fcf651fa07eb0e31ebf1882ca), [`470e0a14`](https://github.com/thirdweb-dev/js/commit/470e0a144db6aa03e7789e231bbdfae43144f0e0), [`b1ede491`](https://github.com/thirdweb-dev/js/commit/b1ede491fbfbeca0ff3d6f5a6162546671bf8b99), [`738c0ec6`](https://github.com/thirdweb-dev/js/commit/738c0ec6c4190aa2252233c1382aed5d982cc7b8), [`d495a4b8`](https://github.com/thirdweb-dev/js/commit/d495a4b8a6e0599e5b4611620f3fded80a411173), [`482f6d1b`](https://github.com/thirdweb-dev/js/commit/482f6d1b58ac99b331fc750d3eeb6082556fd526), [`e4356e76`](https://github.com/thirdweb-dev/js/commit/e4356e76d1506624afe2eb6feeaf57dc376f372f), [`9886c858`](https://github.com/thirdweb-dev/js/commit/9886c858d9c8d0f677aba6572dbf5cc6c876edf2), [`8db78299`](https://github.com/thirdweb-dev/js/commit/8db78299ea6cfb51d93b91bb1a351644a83c73d2), [`4f843833`](https://github.com/thirdweb-dev/js/commit/4f8438335e3e3731b67ae271cb34c383832242a0)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 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/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 0.2.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.2.10",
|
||||
"version": "0.2.12",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -2,14 +2,33 @@ import { ThemeProvider, ThemeProviderProps } from "../styles/ThemeProvider";
|
||||
import { ConnectWalletDetails } from "./ConnectWalletDetails/ConnectWalletDetails";
|
||||
import { ConnectWalletFlow } from "./ConnectWalletFlow/ConnectWalletFlow";
|
||||
import { useAddress } from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useRef } from "react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { Animated } from "react-native";
|
||||
|
||||
export type ConnectWalletProps = {
|
||||
theme?: ThemeProviderProps["theme"];
|
||||
/**
|
||||
* Set a custom title for the button
|
||||
* @default "Connect Wallet"
|
||||
*/
|
||||
buttonTitle?: string;
|
||||
/**
|
||||
* Set a custom title for the Connect Wallet modal
|
||||
* @default "Choose your wallet"
|
||||
*/
|
||||
modalTitle?: string;
|
||||
/**
|
||||
* render a custom button to display the connected wallet details instead of the default button
|
||||
*/
|
||||
detailsButton?: React.ReactElement;
|
||||
};
|
||||
|
||||
export const ConnectWallet = ({ theme }: ConnectWalletProps) => {
|
||||
export const ConnectWallet = ({
|
||||
buttonTitle,
|
||||
detailsButton,
|
||||
modalTitle,
|
||||
theme,
|
||||
}: ConnectWalletProps) => {
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current;
|
||||
|
||||
const address = useAddress();
|
||||
@@ -26,9 +45,15 @@ export const ConnectWallet = ({ theme }: ConnectWalletProps) => {
|
||||
<ThemeProvider theme={theme}>
|
||||
<Animated.View style={{ opacity: fadeAnim }}>
|
||||
{address ? (
|
||||
<ConnectWalletDetails address={address} />
|
||||
<ConnectWalletDetails
|
||||
address={address}
|
||||
detailsButton={detailsButton}
|
||||
/>
|
||||
) : (
|
||||
<ConnectWalletFlow />
|
||||
<ConnectWalletFlow
|
||||
buttonTitle={buttonTitle}
|
||||
modalTitle={modalTitle}
|
||||
/>
|
||||
)}
|
||||
</Animated.View>
|
||||
</ThemeProvider>
|
||||
|
||||
+45
-18
@@ -17,14 +17,19 @@ import { Toast } from "../base/Toast";
|
||||
import { LocalWallet, SmartWallet, walletIds } from "@thirdweb-dev/wallets";
|
||||
import { SmartWalletAdditionalActions } from "./SmartWalletAdditionalActions";
|
||||
import { useSmartWallet } from "../../providers/context-provider";
|
||||
import RightArrowIcon from "../../assets/right-arrow";
|
||||
import { useTheme } from "@shopify/restyle";
|
||||
|
||||
export type ConnectWalletDetailsProps = {
|
||||
address: string;
|
||||
detailsButton?: React.ReactElement;
|
||||
};
|
||||
|
||||
export const ConnectWalletDetails = ({
|
||||
address,
|
||||
detailsButton,
|
||||
}: ConnectWalletDetailsProps) => {
|
||||
const theme = useTheme();
|
||||
const [isDetailsModalVisible, setIsDetailsModalVisible] = useState(false);
|
||||
const [isExportModalVisible, setIsExportModalVisible] = useState(false);
|
||||
const [isNetworkSelectorModalVisible, setIsNetworkSelectorModalVisible] =
|
||||
@@ -105,13 +110,21 @@ export const ConnectWalletDetails = ({
|
||||
backgroundColor="background"
|
||||
borderColor="border"
|
||||
mb="sm"
|
||||
justifyContent="space-between"
|
||||
style={styles.exportWallet}
|
||||
onPress={onExportLocalWalletPress}
|
||||
>
|
||||
<PocketWalletIcon size={16} />
|
||||
<View style={styles.exportWalletInfo}>
|
||||
<Text variant="bodySmall">Backup wallet</Text>
|
||||
</View>
|
||||
<>
|
||||
<PocketWalletIcon size={16} />
|
||||
<View style={styles.exportWalletInfo}>
|
||||
<Text variant="bodySmall">Backup wallet</Text>
|
||||
</View>
|
||||
</>
|
||||
<RightArrowIcon
|
||||
height={10}
|
||||
width={10}
|
||||
color={theme.colors.iconPrimary}
|
||||
/>
|
||||
</BaseButton>
|
||||
|
||||
{activeWallet?.walletId === LocalWallet.id ? (
|
||||
@@ -126,7 +139,12 @@ export const ConnectWalletDetails = ({
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [activeWallet?.walletId, onExportLocalWalletPress, smartWallet]);
|
||||
}, [
|
||||
activeWallet?.walletId,
|
||||
onExportLocalWalletPress,
|
||||
smartWallet,
|
||||
theme.colors.iconPrimary,
|
||||
]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -168,19 +186,28 @@ export const ConnectWalletDetails = ({
|
||||
style={styles.walletDetails}
|
||||
onPress={onPress}
|
||||
>
|
||||
<ChainIcon size={32} chainIconUrl={chain?.icon?.url} />
|
||||
<View style={styles.walletInfo}>
|
||||
<Text variant="bodySmall">
|
||||
{balanceQuery.data?.displayValue.slice(0, 5)}{" "}
|
||||
{balanceQuery.data?.symbol}
|
||||
</Text>
|
||||
{activeWallet?.walletId === LocalWallet.id ? (
|
||||
<Text variant="error">Guest</Text>
|
||||
) : (
|
||||
<Address variant="bodySmallSecondary" address={address} />
|
||||
)}
|
||||
</View>
|
||||
<WalletIcon size={32} iconUri={activeWallet?.getMeta().iconURL || ""} />
|
||||
{detailsButton ? (
|
||||
detailsButton
|
||||
) : (
|
||||
<>
|
||||
<ChainIcon size={32} chainIconUrl={chain?.icon?.url} />
|
||||
<View style={styles.walletInfo}>
|
||||
<Text variant="bodySmall">
|
||||
{balanceQuery.data?.displayValue.slice(0, 5)}{" "}
|
||||
{balanceQuery.data?.symbol}
|
||||
</Text>
|
||||
{activeWallet?.walletId === LocalWallet.id ? (
|
||||
<Text variant="error">Guest</Text>
|
||||
) : (
|
||||
<Address variant="bodySmallSecondary" address={address} />
|
||||
)}
|
||||
</View>
|
||||
<WalletIcon
|
||||
size={32}
|
||||
iconUri={activeWallet?.getMeta().iconURL || ""}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</BaseButton>
|
||||
</>
|
||||
);
|
||||
|
||||
+15
-13
@@ -14,9 +14,11 @@ import { ModalHeaderTextClose } from "../base/modal/ModalHeaderTextClose";
|
||||
import { useAddress, useWallet } from "@thirdweb-dev/react-core";
|
||||
import { PasswordInput } from "../PasswordInput";
|
||||
import * as FileSystem from "expo-file-system";
|
||||
import { LocalWallet } from "../../wallets/wallets/local-wallet";
|
||||
import { SmartWallet } from "@thirdweb-dev/wallets";
|
||||
import { usePersonalWalletAddress } from "../../wallets/hooks/usePersonalWalletAddress";
|
||||
import { shortenWalletAddress } from "../../utils/addresses";
|
||||
import { WalletIcon } from "../base/WalletIcon";
|
||||
import { LocalWallet } from "../../wallets/wallets/LocalWallet";
|
||||
|
||||
export type ExportLocalWalletModalProps = {
|
||||
isVisible: boolean;
|
||||
@@ -148,11 +150,14 @@ export const ExportLocalWalletModal = ({
|
||||
borderRadius="md"
|
||||
p="lg"
|
||||
>
|
||||
<ModalHeaderTextClose headerText={""} onClose={onCloseInternal} />
|
||||
<Text variant="header" textAlign="center">
|
||||
Export your Wallet
|
||||
<Box flexDirection="row" justifyContent="space-between" mb="sm">
|
||||
<WalletIcon size={32} iconUri={LocalWallet.meta.iconURL} />
|
||||
<ModalHeaderTextClose flex={1} onClose={onCloseInternal} />
|
||||
</Box>
|
||||
<Text variant="header" textAlign="left">
|
||||
Backup your Wallet
|
||||
</Text>
|
||||
<Text variant="subHeader" mt="md" textAlign="center">
|
||||
<Text variant="subHeader" mt="md" textAlign="left">
|
||||
{
|
||||
"This will download a JSON file containing your wallet information onto your device encrypted with the password."
|
||||
}
|
||||
@@ -161,7 +166,9 @@ export const ExportLocalWalletModal = ({
|
||||
Wallet Address
|
||||
</Text>
|
||||
<Text variant="bodySmallSecondary">
|
||||
{personalWalletAddress ? personalWalletAddress : address}
|
||||
{shortenWalletAddress(
|
||||
personalWalletAddress ? personalWalletAddress : address,
|
||||
)}
|
||||
</Text>
|
||||
<Text variant="bodySmall" textAlign="left" mt="lg" mb="xxs">
|
||||
Password
|
||||
@@ -170,12 +177,7 @@ export const ExportLocalWalletModal = ({
|
||||
<Text variant="bodySmall" color="red" mt="xs" textAlign="left">
|
||||
{error}
|
||||
</Text>
|
||||
<Box
|
||||
flexDirection="row"
|
||||
justifyContent="center"
|
||||
paddingHorizontal="md"
|
||||
mt="lg"
|
||||
>
|
||||
<Box flexDirection="row" justifyContent="flex-end" mt="lg">
|
||||
<BaseButton
|
||||
backgroundColor="white"
|
||||
style={styles.modalButton}
|
||||
@@ -185,7 +187,7 @@ export const ExportLocalWalletModal = ({
|
||||
<ActivityIndicator size="small" color="buttonTextColor" />
|
||||
) : (
|
||||
<Text variant="bodySmall" color="black">
|
||||
Export
|
||||
Backup
|
||||
</Text>
|
||||
)}
|
||||
</BaseButton>
|
||||
|
||||
+26
-15
@@ -2,12 +2,15 @@ import { StyleSheet, View } from "react-native";
|
||||
import PocketWalletIcon from "../../assets/wallet";
|
||||
import BaseButton from "../base/BaseButton";
|
||||
import { WalletIcon } from "../base/WalletIcon";
|
||||
import { AbstractClientWallet, SmartWallet } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
AbstractClientWallet,
|
||||
SmartWallet,
|
||||
walletIds,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { Address } from "../base/Address";
|
||||
import Text from "../base/Text";
|
||||
import { usePersonalWalletAddress } from "../../wallets/hooks/usePersonalWalletAddress";
|
||||
import { LocalWallet } from "../../wallets/wallets/local-wallet";
|
||||
import { useThirdwebWallet, useWallet } from "@thirdweb-dev/react-core";
|
||||
import { useWalletContext, useWallet } from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSmartWallet } from "../../providers/context-provider";
|
||||
import RightArrowIcon from "../../assets/right-arrow";
|
||||
@@ -19,7 +22,7 @@ export const SmartWalletAdditionalActions = ({
|
||||
onExportPress: () => void;
|
||||
}) => {
|
||||
const personalWalletAddress = usePersonalWalletAddress();
|
||||
const handleWalletConnect = useThirdwebWallet().handleWalletConnect;
|
||||
const { setConnectedWallet } = useWalletContext();
|
||||
const [smartWallet, setSmartWallet] = useSmartWallet();
|
||||
const [smartWalletAddress, setSmartWalletAddress] = useState<string>("");
|
||||
const [showSmartWallet, setShowSmartWallet] = useState(false);
|
||||
@@ -53,7 +56,7 @@ export const SmartWalletAdditionalActions = ({
|
||||
return;
|
||||
}
|
||||
|
||||
handleWalletConnect(wallet);
|
||||
setConnectedWallet(wallet);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -90,24 +93,32 @@ export const SmartWalletAdditionalActions = ({
|
||||
color={theme.colors.iconPrimary}
|
||||
/>
|
||||
</BaseButton>
|
||||
{wallet?.walletId === LocalWallet.id ||
|
||||
activeWallet?.walletId === LocalWallet.id ? (
|
||||
{wallet?.walletId === walletIds.localWallet ||
|
||||
activeWallet?.walletId === walletIds.localWallet ? (
|
||||
<>
|
||||
<BaseButton
|
||||
backgroundColor="background"
|
||||
borderColor="border"
|
||||
mb="sm"
|
||||
justifyContent="space-between"
|
||||
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>
|
||||
<>
|
||||
<PocketWalletIcon size={16} />
|
||||
<View style={styles.exportWalletInfo}>
|
||||
<Text variant="bodySmall">
|
||||
{wallet?.walletId === walletIds.localWallet
|
||||
? "Backup personal wallet"
|
||||
: "Backup wallet"}
|
||||
</Text>
|
||||
</View>
|
||||
</>
|
||||
<RightArrowIcon
|
||||
height={10}
|
||||
width={10}
|
||||
color={theme.colors.iconPrimary}
|
||||
/>
|
||||
</BaseButton>
|
||||
<Text variant="error">
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user