Compare commits

..
Author SHA1 Message Date
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8febea4db0 Version Packages (#1041)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-21 13:45:57 -07:00
Joaquim VergesandGitHub 30e5593dd1 [Wallets] deploy smart wallet contract before signing messages (#1040) 2023-05-20 21:01:38 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
f253909710 Version Packages (#1032)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-19 14:39:22 -07:00
iketwandGitHub 99ffa8ce3b [RN] Single global modal (#1025) 2023-05-19 18:09:49 +00:00
Adam MajmudarandGitHub 61212d27d7 [React] Add ability to configure gatewayUrl on MediaRenderer (#1030) 2023-05-19 18:09:28 +00:00
FirekeeperandGitHub 58df84f8ba [unity-js-bridge] MagicLink bridge integration (#1038) 2023-05-19 17:49:18 +00:00
Joaquim VergesandGitHub b6f48e1088 [Wallets] Expose overrideable paymasterAPI in SmartWalletConfig (#1034) 2023-05-19 17:48:51 +00:00
Jonas DanielsandGitHub d51230441a [storage] - update ipfs gateway and add additional fallbacks (#1037) 2023-05-19 16:54:40 +00:00
MykandGitHub 01e83b6f13 update sepolia weth to an address that does not have a mint function (#1036) 2023-05-19 16:43:04 +00:00
Joaquim VergesandGitHub 907d97bede [Chains] Added faucet for optimism goerli (#1033) 2023-05-19 03:52:48 +00:00
Jonas DanielsandGitHub 3c8c5d56f2 Jd/add xrp ledger (#1031) 2023-05-19 03:19:26 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
7faab1c09b Version Packages (#994)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-18 11:15:53 -07:00
8bb0a6d874 fix: set ethers@^5 version in peerDeps of @thirdweb/contracts-js (#921)
Co-authored-by: Joaquim Verges <[email protected]>
2023-05-18 04:06:46 +00:00
b1ede491fb [REACT] Add React hook useBuyDirectListing() (#993)
Co-authored-by: Fran Ros <[email protected]>
Co-authored-by: Jarrod Watts <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2023-05-18 04:00:01 +00:00
f674da7b44 Add sepolia as a supported chain for WETH (#987)
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Jarrod Watts <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2023-05-18 03:49:27 +00:00
iketwandGitHub 748e3e7856 [RN] clear unusued fields (#1026) 2023-05-17 23:40:59 +00:00
738c0ec6c4 [wallets] Update paper sdk and add new supported chains (#1022)
Co-authored-by: Manan Tank <[email protected]>
2023-05-17 22:35:09 +00:00
Joaquim VergesandGitHub e4356e76d1 [SDK] Update error message when contracts ABIs cannot be resolved, with url to import contract (#1021) 2023-05-17 17:27:38 +00:00
iketwandGitHub 8a0dd070d4 [RN] Adds modalTitle, buttonTitle and detailsButton props to the ConnectWallet component (#1019) 2023-05-17 00:06:39 +00:00
Manan TankandGitHub 39bd963015 Render input for magic and paper wallet using selectUI API (#1015) 2023-05-16 22:41:48 +00:00
84fc3b6fab Add detect-project command to CLI (#926)
Co-authored-by: Jonas Daniels <[email protected]>
2023-05-16 20:05:59 +00:00
Adam MajmudarandGitHub 49ec2d171e [SDK] Add a prepareGaslessRequest function (#983) 2023-05-15 21:27:57 +00:00
Adam MajmudarandGitHub b92aabe450 [Auth] Expose request on user hook (#1013) 2023-05-15 21:21:40 +00:00
Manan TankandGitHub 470e0a144d [react-core] rename ConfiguredWallet -> WalletConfig (#1011) 2023-05-15 19:29:22 +00:00
Manan TankandGitHub b6bb73b34c [react, react-core] Various connect Wallet changes (#1006) 2023-05-15 18:20:45 +00:00
YashandGitHub 9886c858d9 [SDK] Add support for ZKSync Era Testnet (#988) 2023-05-12 22:24:31 +00:00
iketwandGitHub 25de32d45d [RN] Update wcv2 props (#1005) 2023-05-12 15:35:55 +00:00
Manan TankandGitHub d495a4b8a6 [react, wallets] Expose Web3Modal QRModalOptions in WalletConnect v2 (#1002) 2023-05-12 14:53:06 +00:00
Manan TankandGitHub 2b0fb9d22f [react] Fix flaky Coinbase QR code scan (#1001) 2023-05-11 15:12:39 +00:00
e9b69300d1 [SDK] Display plugins on router release page (#713)
Co-authored-by: Jonas Daniels <[email protected]>
2023-05-10 23:18:40 +00:00
Manan TankandGitHub 4f8438335e [react] Connect Wallet improvements (#998) 2023-05-10 22:42:45 +00:00
Manan TankandGitHub c3645c451b Various Connect Wallet changes (#996) 2023-05-10 18:49:58 +00:00
iketwandGitHub 482f6d1b58 [ReactNative] update export wallet modal UI (#995) 2023-05-10 18:05:05 +00:00
Joaquim VergesandGitHub 799d98e862 [SDK] switch type of abi in SmartContract to Abi (#997) 2023-05-10 17:51:01 +00:00
iketwandGitHub 8db78299ea [React/RN] rename useThirdwebWallet to useProviderContext (#989) 2023-05-10 11:44:04 +00:00
257 changed files with 6636 additions and 2142 deletions
+4 -1
View File
@@ -16,4 +16,7 @@ public/dist
yalc.lock
build/
playwright-report/
.vscode/
.vscode/
# Artifacts
packages/cli/artifacts/
+1 -1
View File
@@ -46,7 +46,7 @@
"eslint": "^8.37.0",
"mocha": "^10.2.0",
"prettier": "^2.8.7",
"turbo": "^1.8.8",
"turbo": "^1.9.8",
"yalc": "1.0.0-pre.53"
},
"manypkg": {
+23
View File
@@ -1,5 +1,28 @@
# @thirdweb-dev/auth
## 3.0.21
### Patch Changes
- Updated dependencies [[`30e5593d`](https://github.com/thirdweb-dev/js/commit/30e5593dd1ce9abd809ad216a1cfce77b897093c)]:
- @thirdweb-dev/wallets@0.2.22
## 3.0.20
### Patch Changes
- Updated dependencies [[`b6f48e10`](https://github.com/thirdweb-dev/js/commit/b6f48e1088b5d36a51103de4afda53179029faaf)]:
- @thirdweb-dev/wallets@0.2.21
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "3.0.18",
"version": "3.0.21",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
+1 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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;
}
+39
View File
@@ -1,5 +1,44 @@
# @thirdweb-dev/chains
## 0.1.18
### Patch Changes
- [#1040](https://github.com/thirdweb-dev/js/pull/1040) [`30e5593d`](https://github.com/thirdweb-dev/js/commit/30e5593dd1ce9abd809ad216a1cfce77b897093c) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Update chains
## 0.1.17
### Patch Changes
- [#1031](https://github.com/thirdweb-dev/js/pull/1031) [`3c8c5d56`](https://github.com/thirdweb-dev/js/commit/3c8c5d56f2a21c0918fede71061c6745f2956f83) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains
- [#1033](https://github.com/thirdweb-dev/js/pull/1033) [`907d97be`](https://github.com/thirdweb-dev/js/commit/907d97bedef7331148bdfe8b9bf1e19459282e4c) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Added faucet for optimism goerli
## 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
+18 -3
View File
@@ -10,9 +10,24 @@ export default {
},
"rpc": [
"https://fibonacci.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://node1.fibo-api.asia"
"https://node1.fibo-api.asia",
"https://node2.fibo-api.asia",
"https://node3.fibo-api.asia",
"https://node4.fibo-api.asia",
"https://node5.fibo-api.asia",
"https://node6.fibo-api.asia",
"https://node7.fibo-api.asia",
"https://node1.fibo-rpc.asia",
"https://node2.fibo-rpc.asia",
"https://node3.fibo-rpc.asia",
"https://node4.fibo-rpc.asia",
"https://node5.fibo-rpc.asia",
"https://node6.fibo-rpc.asia",
"https://node7.fibo-rpc.asia"
],
"faucets": [
"https://test.fibochain.org/faucets"
],
"faucets": [],
"nativeCurrency": {
"name": "FIBONACCI UTILITY TOKEN",
"symbol": "FIBO",
@@ -29,6 +44,6 @@ export default {
"standard": "EIP3091"
}
],
"testnet": false,
"testnet": true,
"slug": "fibonacci"
} as const satisfies Chain;
+34
View File
@@ -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;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"name": "XRP Ledger EVM Devnet Sidechain",
"chain": "XRPL",
"shortName": "XRPL-EVM-Devnet-Sidechain",
"chainId": 1440001,
"testnet": true,
"icon": {
"format": "png",
"url": "ipfs://bafkreidmgxjwjircegjkvysgz25b2ukw6h7axoirkxv6idupzzqsdrljgy",
"width": 780,
"height": 680
},
"rpc": [
"https://xrp-ledger-evm-devnet-sidechain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-evm-sidechain.xrpl.org"
],
"nativeCurrency": {
"decimals": 18,
"name": "XRP",
"symbol": "XRP"
},
"explorers": [
{
"url": "https://evm-sidechain.xrpl.org/",
"name": "XRP Ledger Explorer",
"standard": "EIP3091"
}
],
"slug": "xrp-ledger-evm-devnet-sidechain"
} as const satisfies Chain;
+34
View File
@@ -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;
+2 -2
View File
@@ -11,8 +11,8 @@ export default {
"rpc": [
"https://dogechain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.dogechain.dog",
"https://rpc-us.dogechain.dog",
"https://rpc01.dogechain.dog"
"https://rpc01-sg.dogechain.dog",
"https://rpc.ankr.com/dogechain"
],
"faucets": [],
"nativeCurrency": {
+21
View File
@@ -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;
+3 -3
View File
@@ -1,6 +1,6 @@
import type { Chain } from "../src/types";
export default {
"name": "Metaplayerone Network",
"name": "Metaplayerone Dubai Testnet",
"chain": "MP1 Dubai-Testnet",
"icon": {
"url": "ipfs://QmfJKxmubJrqYWDcR2PnPvmpukxPz4fYDu3hqTaSnpJDxC",
@@ -9,7 +9,7 @@ export default {
"format": "svg"
},
"rpc": [
"https://metaplayerone-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://metaplayerone-dubai-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-dubai.mp1network.com/"
],
"faucets": [],
@@ -36,5 +36,5 @@ export default {
}
],
"testnet": true,
"slug": "metaplayerone-network"
"slug": "metaplayerone-dubai-testnet"
} as const satisfies Chain;
+14 -2
View File
@@ -5,7 +5,7 @@ export default {
"chain": "Kanazawa",
"rpc": [
"https://kanazawa.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-kanazawa.meldlabs.dev/ext/bc/2Ci7VYrUd4fTBqGA5D2HA6UPHzQ4LQyr8rZQww9MGSv9rNkRzn/rpc"
"https://subnets.avax.network/meld/testnet/rpc"
],
"faucets": [],
"features": [],
@@ -24,7 +24,19 @@ export default {
"shortName": "kanazawa",
"chainId": 222000222,
"networkId": 222000222,
"explorers": [],
"explorers": [
{
"name": "explorer",
"url": "https://subnets-test.avax.network/meld",
"icon": {
"url": "ipfs://QmRhB4AbjDrhvwfSAQi2JvKirFiDWxzJvKEvG8S8AdDdED",
"width": 4000,
"height": 4000,
"format": "png"
},
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "kanazawa"
} as const satisfies Chain;
+42
View File
@@ -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;
+43
View File
@@ -0,0 +1,43 @@
import type { Chain } from "../src/types";
export default {
"name": "SOMA Network Mainnet",
"chain": "SOMA",
"rpc": [
"https://soma-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://data-mainnet-v1.somanetwork.io/"
],
"faucets": [
"https://airdrop.somanetwork.io"
],
"nativeCurrency": {
"name": "Soma Native Token",
"symbol": "SMA",
"decimals": 18
},
"infoURL": "https://somanetwork.io",
"shortName": "smam",
"chainId": 2332,
"networkId": 2332,
"icon": {
"url": "ipfs://QmadSU2tcyvuzssDYGJ4rVLag43QLnKwcBerZR2zKLVU2N",
"width": 500,
"height": 500,
"format": "png"
},
"status": "incubating",
"explorers": [
{
"name": "SOMA Explorer Mainnet",
"icon": {
"url": "ipfs://QmadSU2tcyvuzssDYGJ4rVLag43QLnKwcBerZR2zKLVU2N",
"width": 500,
"height": 500,
"format": "png"
},
"url": "https://somascan.io",
"standard": "none"
}
],
"testnet": false,
"slug": "soma-network"
} as const satisfies Chain;
+40
View File
@@ -0,0 +1,40 @@
import type { Chain } from "../src/types";
export default {
"name": "LaChain",
"chain": "LaChain",
"icon": {
"url": "ipfs://bafkreiecoqvit2mikpbpbtzy2zrn6e7fvqdegm72sdcathdwmgiyuzey7u",
"width": 104,
"height": 114,
"format": "png"
},
"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;
+36
View File
@@ -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;
+48
View File
@@ -0,0 +1,48 @@
import type { Chain } from "../src/types";
export default {
"name": "Neurochain Testnet",
"chain": "NCN",
"rpc": [
"https://neurochain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://nc-rpc-test1.neurochain.io"
],
"faucets": [],
"nativeCurrency": {
"name": "Neurochain",
"symbol": "tNCN",
"decimals": 18
},
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"infoURL": "https://www.neurochain.ai",
"shortName": "ncnt",
"chainId": 303,
"networkId": 303,
"icon": {
"url": "ipfs://Qmc9zDWXar67cMUodp28mbN5pnwbVibxGXhwa8YCDvxmTR",
"width": 62,
"height": 59,
"format": "svg"
},
"explorers": [
{
"name": "neuroscan",
"url": "https://testnet.ncnscan.com",
"icon": {
"url": "ipfs://Qmc9zDWXar67cMUodp28mbN5pnwbVibxGXhwa8YCDvxmTR",
"width": 62,
"height": 59,
"format": "svg"
},
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "neurochain-testnet"
} as const satisfies Chain;
+49
View File
@@ -0,0 +1,49 @@
import type { Chain } from "../src/types";
export default {
"name": "Neurochain Mainnet",
"chain": "NCN",
"rpc": [
"https://neurochain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://nc-rpc-prd1.neurochain.io",
"https://nc-rpc-prd2.neurochain.io"
],
"faucets": [],
"nativeCurrency": {
"name": "Neurochain",
"symbol": "NCN",
"decimals": 18
},
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"infoURL": "https://www.neurochain.ai",
"shortName": "ncn",
"chainId": 313,
"networkId": 313,
"icon": {
"url": "ipfs://Qmc9zDWXar67cMUodp28mbN5pnwbVibxGXhwa8YCDvxmTR",
"width": 62,
"height": 59,
"format": "svg"
},
"explorers": [
{
"name": "neuroscan",
"url": "https://ncnscan.com",
"icon": {
"url": "ipfs://Qmc9zDWXar67cMUodp28mbN5pnwbVibxGXhwa8YCDvxmTR",
"width": 62,
"height": 59,
"format": "svg"
},
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "neurochain"
} as const satisfies Chain;
+14 -2
View File
@@ -5,7 +5,7 @@ export default {
"chain": "MELD",
"rpc": [
"https://meld.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://network-rpc.meld.com"
"https://subnets.avax.network/meld/mainnet/rpc"
],
"faucets": [],
"features": [],
@@ -24,7 +24,19 @@ export default {
"shortName": "meld",
"chainId": 333000333,
"networkId": 333000333,
"explorers": [],
"explorers": [
{
"name": "explorer",
"url": "https://subnets.avax.network/meld",
"icon": {
"url": "ipfs://QmRhB4AbjDrhvwfSAQi2JvKirFiDWxzJvKEvG8S8AdDdED",
"width": 4000,
"height": 4000,
"format": "png"
},
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "meld"
} as const satisfies Chain;
+15 -3
View File
@@ -1,6 +1,6 @@
import type { Chain } from "../src/types";
export default {
"name": "PulseChain Mainnet",
"name": "PulseChain",
"shortName": "pls",
"chain": "PLS",
"chainId": 369,
@@ -8,10 +8,22 @@ export default {
"infoURL": "https://pulsechain.com/",
"rpc": [
"https://pulsechain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.mainnet.pulsechain.com/",
"wss://rpc.mainnet.pulsechain.com/"
"https://rpc.pulsechain.com/",
"wss://rpc.pulsechain.com/"
],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"faucets": [],
"ens": {
"registry": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
},
"status": "incubating",
"nativeCurrency": {
"name": "Pulse",
"symbol": "PLS",
+1
View File
@@ -4,6 +4,7 @@ export default {
"chain": "FTM",
"rpc": [
"https://fantom-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://fantom-testnet.publicnode.com",
"https://rpc.testnet.fantom.network"
],
"faucets": [
+45
View File
@@ -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;
+7
View File
@@ -18,6 +18,13 @@ export default {
"shortName": "TelosEVMTestnet",
"chainId": 41,
"networkId": 41,
"explorers": [
{
"name": "teloscan",
"url": "https://testnet.teloscan.io",
"standard": "EIP3091"
}
],
"testnet": true,
"icon": {
"url": "ipfs://QmdkgQDtDedsNNth3ZVgWfwRZPCePLA13MtLvV4CEYSuTR/TLOS.png",
+12 -6
View File
@@ -1,16 +1,22 @@
import type { Chain } from "../src/types";
export default {
"name": "LA Testnet",
"chain": "LATestnet",
"name": "LaTestnet",
"chain": "LaTestnet",
"icon": {
"url": "ipfs://bafkreiecoqvit2mikpbpbtzy2zrn6e7fvqdegm72sdcathdwmgiyuzey7u",
"width": 104,
"height": 114,
"format": "png"
},
"rpc": [
"https://la-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://latestnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.testnet.lachain.network"
],
"faucets": [
"https://faucet.lachain.network"
],
"nativeCurrency": {
"name": "Test La Coin",
"name": "Test LaCoin",
"symbol": "TLA",
"decimals": 18
},
@@ -25,11 +31,11 @@ export default {
"networkId": 418,
"explorers": [
{
"name": "LA Testnet Explorer",
"name": "LaTestnet Explorer",
"url": "https://testexplorer.lachain.network",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "la-testnet"
"slug": "latestnet"
} as const satisfies Chain;
+3 -1
View File
@@ -8,7 +8,9 @@ export default {
"https://optimism-goerli.infura.io/v3/${INFURA_API_KEY}",
"https://goerli.optimism.io/"
],
"faucets": [],
"faucets": [
"https://coinbase.com/faucets/optimism-goerli-faucet"
],
"nativeCurrency": {
"name": "Goerli Ether",
"symbol": "ETH",
+1 -1
View File
@@ -22,7 +22,7 @@ export default {
"decimals": 18
},
"infoURL": "https://fastex.com",
"shortName": "ftn",
"shortName": "fastexTestnet",
"chainId": 424242,
"networkId": 424242,
"explorers": [
+36
View File
@@ -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;
+2 -1
View File
@@ -11,7 +11,8 @@ export default {
"rpc": [
"https://avalanche-fuji.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://avalanche-fuji.infura.io/v3/${INFURA_API_KEY}",
"https://api.avax-test.network/ext/bc/C/rpc"
"https://api.avax-test.network/ext/bc/C/rpc",
"https://avalanche-fuji-c-chain.publicnode.com"
],
"faucets": [
"https://faucet.avax.network/",
+34
View File
@@ -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 -1
View File
@@ -8,7 +8,8 @@ export default {
"https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
"https://goerli.infura.io/v3/${INFURA_API_KEY}",
"wss://goerli.infura.io/v3/${INFURA_API_KEY}",
"https://rpc.goerli.mudit.blog/"
"https://rpc.goerli.mudit.blog/",
"https://ethereum-goerli.publicnode.com"
],
"faucets": [
"https://faucet.paradigm.xyz/",
+5 -2
View File
@@ -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"
}
],
+49
View File
@@ -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;
+44
View File
@@ -0,0 +1,44 @@
import type { Chain } from "../src/types";
export default {
"name": "Fastex Chain (Bahamut)",
"title": "Bahamut mainnet Sahara",
"chain": "Fastex Chain (Bahamut)",
"icon": {
"url": "ipfs://QmSemioP83RXnDWwTZbet8VpwJxcFRboX4B3pcdhLZGodP",
"width": 200,
"height": 200,
"format": "png"
},
"rpc": [
"https://fastex-chain-bahamut.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": "fastex-chain-bahamut"
} as const satisfies Chain;
+5
View File
@@ -22,6 +22,11 @@ export default {
"name": "Scroll Alpha Testnet Block Explorer",
"url": "https://blockscout.scroll.io",
"standard": "EIP3091"
},
{
"name": "Scroll Alpha Testnet Block Explorer",
"url": "https://scrollexplorer.unifra.io",
"standard": "EIP3091"
}
],
"parent": {
+42
View File
@@ -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;
+35
View File
@@ -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;
+2 -1
View File
@@ -15,7 +15,8 @@ export default {
"https://polygon-mumbai.infura.io/v3/${INFURA_API_KEY}",
"https://matic-mumbai.chainstacklabs.com",
"https://rpc-mumbai.maticvigil.com",
"https://matic-testnet-archive-rpc.bwarelabs.com"
"https://matic-testnet-archive-rpc.bwarelabs.com",
"https://polygon-mumbai-bor.publicnode.com"
],
"faucets": [
"https://faucet.polygon.technology/"
+22
View File
@@ -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;
+34
View File
@@ -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;
+48
View File
@@ -0,0 +1,48 @@
import type { Chain } from "../src/types";
export default {
"name": "SwissDLT",
"chain": "SDLT",
"rpc": [
"https://swissdlt.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.swissdlt.ch"
],
"faucets": [],
"nativeCurrency": {
"name": "BCTS",
"symbol": "BCTS",
"decimals": 18
},
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"infoURL": "https://bcts.ch",
"shortName": "sdlt",
"chainId": 94,
"networkId": 94,
"icon": {
"url": "ipfs://bafkreig7x5z4j6vh2r3pugmjnob3tmlksaekhqcgsorqzvs55o6v7ehqd4",
"width": 682,
"height": 512,
"format": "png"
},
"explorers": [
{
"name": "SwissDLT Explorer",
"url": "https://explorer.swissdlt.ch",
"icon": {
"url": "ipfs://bafkreig7x5z4j6vh2r3pugmjnob3tmlksaekhqcgsorqzvs55o6v7ehqd4",
"width": 682,
"height": 512,
"format": "png"
},
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "swissdlt"
} as const satisfies Chain;
+1
View File
@@ -4,6 +4,7 @@ export default {
"chain": "BSC",
"rpc": [
"https://binance-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://bsc-testnet.publicnode.com",
"https://data-seed-prebsc-2-s3.binance.org:8545",
"https://data-seed-prebsc-1-s3.binance.org:8545",
"https://data-seed-prebsc-2-s2.binance.org:8545",
+48
View File
@@ -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;
@@ -0,0 +1,30 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Omit<Chain, "slug">} */
export default {
name: "XRP Ledger EVM Devnet Sidechain",
chain: "XRPL",
shortName: "XRPL-EVM-Devnet-Sidechain",
chainId: 1440001,
testnet: true,
icon: {
format: "png",
url: "ipfs://bafkreidmgxjwjircegjkvysgz25b2ukw6h7axoirkxv6idupzzqsdrljgy",
width: 780,
height: 680,
},
rpc: ["https://rpc-evm-sidechain.xrpl.org"],
nativeCurrency: {
decimals: 18,
name: "XRP",
symbol: "XRP",
},
explorers: [
{
url: "https://evm-sidechain.xrpl.org/",
name: "XRP Ledger Explorer",
standard: "EIP3091",
},
],
};
+1
View File
@@ -13,4 +13,5 @@ export default {
"https://optimism-goerli.infura.io/v3/${INFURA_API_KEY}",
"https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
],
faucets: ["https://coinbase.com/faucets/optimism-goerli-faucet"],
};
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.15",
"version": "0.1.18",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"browser": {
File diff suppressed because one or more lines are too long
+31
View File
@@ -1,5 +1,36 @@
# thirdweb
## 0.10.18
### Patch Changes
- Updated dependencies [[`30e5593d`](https://github.com/thirdweb-dev/js/commit/30e5593dd1ce9abd809ad216a1cfce77b897093c)]:
- @thirdweb-dev/chains@0.1.18
- @thirdweb-dev/sdk@3.10.17
## 0.10.17
### Patch Changes
- [#1037](https://github.com/thirdweb-dev/js/pull/1037) [`d5123044`](https://github.com/thirdweb-dev/js/commit/d51230441a097734be092c42b45dea07629e65fa) Thanks [@jnsdls](https://github.com/jnsdls)! - update ipfs gateways - add more fallbacks
- Updated dependencies [[`d5123044`](https://github.com/thirdweb-dev/js/commit/d51230441a097734be092c42b45dea07629e65fa), [`3c8c5d56`](https://github.com/thirdweb-dev/js/commit/3c8c5d56f2a21c0918fede71061c6745f2956f83), [`907d97be`](https://github.com/thirdweb-dev/js/commit/907d97bedef7331148bdfe8b9bf1e19459282e4c)]:
- @thirdweb-dev/storage@1.1.3
- @thirdweb-dev/chains@0.1.17
- @thirdweb-dev/sdk@3.10.16
## 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
+4 -1
View File
@@ -1,7 +1,7 @@
{
"name": "thirdweb",
"main": "dist/cli/index.js",
"version": "0.10.15",
"version": "0.10.18",
"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",
+12
View File
@@ -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);
}
+182
View File
@@ -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,
};
}
-15
View File
@@ -1,18 +1,3 @@
/**
* @internal
*/
export const DEFAULT_IPFS_GATEWAY = "https://ipfs.thirdwebcdn.com/ipfs/";
/**
* @internal
*/
export const TW_IPFS_SERVER_URL = "https://upload.nftlabs.co";
/**
* @internal
*/
export const PINATA_IPFS_URL = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
/**
* @internal
*/
@@ -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];
}
}
+38 -1
View File
@@ -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;

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