Compare commits

...
Author SHA1 Message Date
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>GitHub Action
031eccbab1 Version Packages (#2713)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <[email protected]>
2024-04-09 02:23:28 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
9e8cca2da5 chore(chains): update chains (#2739)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-09 02:03:38 -07:00
FirekeeperandGitHub 8d81b686f2 Unity 4.10.1 (#2733) 2024-04-09 08:57:23 +00:00
Jonas DanielsandGitHub d9cd6f5c2a implement additional extensions (#2735) 2024-04-09 08:51:13 +00:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2a5c7d0ebc chore(chains): update chains (#2734)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-09 01:03:26 -07:00
gregandGitHub 3847617f8e [SDK] fromGwei helper function (#2736) 2024-04-08 23:18:07 -07:00
Jonas DanielsandGitHub 1d4fdd6753 feat: Add chain Metadata type (#2731) 2024-04-08 16:42:03 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
c98112445c chore(chains): update chains (#2732)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-08 16:32:15 -07:00
f6a30c0371 feat: add phone login for embedded wallet (#2366)
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: Manan Tank <[email protected]>
2024-04-08 23:08:43 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b1013fc302 build(deps-dev): bump knip from 5.8.0 to 5.9.1 (#2720)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-08 15:30:24 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
f2b5d4ba56 chore(chains): update chains (#2730)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-08 15:30:03 -07:00
Joaquim VergesandGitHub 6961e09a4c [SDK] simulate inner transactions before bundling user ops (#2714) 2024-04-08 21:48:44 +00:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
49354c6cc3 chore(chains): update chains (#2727)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-08 14:07:17 -07:00
Jonas DanielsandGitHub 51502596d9 chore: remove unused dependency (#2726) 2024-04-08 20:54:19 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Jonas Daniels
df5eba9aff build(deps): bump octokit/request-action from 2.2.0 to 2.3.0 (#2715)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-08 13:25:53 -07:00
Jonas DanielsandGitHub 64c03ab378 chore: Update .gitignore and add VSCode configuration files (#2716) 2024-04-08 13:18:12 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
53e56f4bf8 chore(chains): update chains (#2708)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-08 13:05:45 -07:00
Jonas DanielsandGitHub 02583f857e fix(rpc): Fix issue with block number polling (#2712) 2024-04-08 19:45:47 +00:00
14cecc9c75 feat: expose useSendBatchTransaction for smart accounts (#2711)
Signed-off-by: Jonas Daniels <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-08 18:54:55 +00:00
Joaquim VergesandGitHub 30e6385dea chore: remove log (#2710) 2024-04-08 17:15:40 +02:00
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>GitHub Action
37c3224a78 Version Packages (#2705)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <[email protected]>
2024-04-07 16:30:37 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
ebdfb571c9 chore(chains): update chains (#2707)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-07 13:58:06 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Jonas Daniels
48c1d60382 chore(chains): update chains (#2702)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-07 19:26:20 +00:00
Jonas DanielsandGitHub 584d68e6f6 fix: update test command in package.json files (#2706) 2024-04-07 12:10:06 -07:00
Jonas DanielsandGitHub 703cb6ae3c chore: update dependencies (#2701) 2024-04-07 10:09:20 -07:00
7a9a086cdc Export ERC721 event: TokensLazyMintedEvent (#2704)
Signed-off-by: Jonas Daniels <[email protected]>
Co-authored-by: Kien Ngo <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-07 16:05:16 +00:00
599 changed files with 9882 additions and 6737 deletions
+7 -1
View File
@@ -53,6 +53,11 @@ jobs:
- name: Setup & Install
uses: ./.github/composite-actions/install
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: latest
- run: pnpm lint
test:
@@ -74,8 +79,9 @@ jobs:
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
directory: ./packages
directory: packages/
flags: packages
verbose: true
e2e:
timeout-minutes: 15
+2 -1
View File
@@ -73,8 +73,9 @@ jobs:
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
directory: ./legacy_packages
directory: legacy_packages/
flags: legacy_packages
verbose: true
e2e:
timeout-minutes: 15
+1 -1
View File
@@ -51,7 +51,7 @@ jobs:
steps:
- name: get pull request ref
id: get_pull_request_ref
uses: octokit/request-action@v2.2.0
uses: octokit/request-action@v2.3.0
with:
route: GET /repos/{owner}/{repository}/pulls/{issue_id}
owner: ${{ github.repository_owner }}
+4 -2
View File
@@ -16,8 +16,10 @@ public/dist
yalc.lock
build/
playwright-report/
.vscode/
.env/
# Artifacts
legacy_packages/cli/artifacts/
legacy_packages/cli/artifacts/
# codecov binary
codecov
+7
View File
@@ -0,0 +1,7 @@
{
"recommendations": ["biomejs.biome"],
"unwantedRecommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
+9
View File
@@ -0,0 +1,9 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "biomejs.biome",
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
},
"typescript.preferences.importModuleSpecifier": "relative"
}
+25
View File
@@ -0,0 +1,25 @@
{
"$schema": "https://biomejs.dev/schemas/1.6.4/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true,
"indentStyle": "space"
},
"files": {
"ignore": [
"legacy_packages/**",
"packages/thirdweb/src/crypto/aes/lib/md5.ts",
"packages/thirdweb/src/utils/promise/p-limit.ts",
"packages/thirdweb/src/utils/bytecode/cbor-decode.ts",
"packages/thirdweb/src/**/__generated__/**"
]
}
}
+30
View File
@@ -0,0 +1,30 @@
coverage:
status:
project:
default:
target: auto
patch:
packages:
target: auto
flags:
- packages
legacy_packages:
target: auto
flags:
- legacy_packages
github_checks:
annotations: true
flag_management:
default_rules:
carryforward: true
comment:
layout: "newheader, diff, flags, files"
require_changes: false # if true: only post the comment if coverage changes
require_base: false # [yes :: must have a base report to post]
require_head: true # [yes :: must have a head report to post]
show_carryforward_flags: true
hide_comment_details: true #collapse all the "detailed info" for the PR comment
+1 -1
View File
@@ -15,7 +15,7 @@
},
"devDependencies": {
"@swc/cli": "0.3.10",
"@swc/core": "^1.4.11",
"@swc/core": "^1.4.12",
"ora": "^6.3.1"
}
}
+1 -1
View File
@@ -15,6 +15,6 @@
},
"devDependencies": {
"ora": "^6.3.1",
"vite": "^5.2.7"
"vite": "^5.2.8"
}
}
+16
View File
@@ -1,5 +1,21 @@
# @thirdweb-dev/auth
## 4.1.58
### Patch Changes
- Updated dependencies [[`6961e09`](https://github.com/thirdweb-dev/js/commit/6961e09a4cec4c276b233285e721dc0505792be5), [`f6a30c0`](https://github.com/thirdweb-dev/js/commit/f6a30c037197391ef0a514570931775b18927f17), [`5150259`](https://github.com/thirdweb-dev/js/commit/51502596d9f165a5316ce08da8a04b3e5c5e4eba)]:
- @thirdweb-dev/wallets@2.5.0
## 4.1.57
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
- Updated dependencies [[`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f)]:
- @thirdweb-dev/wallets@2.4.35
## 4.1.56
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "4.1.56",
"version": "4.1.58",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
@@ -61,7 +61,7 @@
"lint": "eslint src/",
"fix": "eslint src/ --fix",
"clean": "rm -rf dist/ && rm -rf node_modules/",
"test": "vitest",
"test": "vitest run",
"push": "yalc push"
},
"preconstruct": {
@@ -85,14 +85,14 @@
"@microsoft/tsdoc": "^0.14.2",
"@preconstruct/cli": "2.7.0",
"@swc-node/register": "^1.9.0",
"@swc/core": "^1.4.11",
"@swc/core": "^1.4.12",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/cookie": "^0.6.0",
"@types/cookie-parser": "^1.4.7",
"@types/express": "^4.17.21",
"@types/uuid": "^9.0.8",
"cookie-parser": "^1.4.6",
"eslint": "^8.57.0",
"eslint": "8.57.0",
"eslint-config-thirdweb": "workspace:*",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-inclusive-language": "^2.2.1",
@@ -103,7 +103,7 @@
"fastify": "^4.26.2",
"next": "^13.5.6",
"next-auth": "^4.24.7",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"peerDependencies": {
"cookie-parser": "^1.4.6",
+14
View File
@@ -1,5 +1,19 @@
# @thirdweb-dev/chains
## 0.1.91
### Patch Changes
- [#2708](https://github.com/thirdweb-dev/js/pull/2708) [`53e56f4`](https://github.com/thirdweb-dev/js/commit/53e56f4bf8d3fbe7e2d5252b561bcef5927762e6) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
## 0.1.90
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
- [#2702](https://github.com/thirdweb-dev/js/pull/2702) [`48c1d60`](https://github.com/thirdweb-dev/js/commit/48c1d6038272284f8942e1fb3635283b48945a68) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
## 0.1.89
### Patch Changes
+4
View File
@@ -70,7 +70,11 @@ export default {
"https://mainnet.gateway.tenderly.co",
"wss://mainnet.gateway.tenderly.co",
"https://rpc.blocknative.com/boost",
"https://rpc.flashbots.net",
"https://rpc.flashbots.net/fast",
"https://rpc.mevblocker.io",
"https://rpc.mevblocker.io/fast",
"https://rpc.mevblocker.io/noreverts",
"https://rpc.mevblocker.io/fullprivacy",
"https://eth.drpc.org",
"wss://eth.drpc.org"
+40
View File
@@ -0,0 +1,40 @@
import type { Chain } from "../src/types";
export default {
"chain": "BSQ",
"chainId": 1113,
"explorers": [
{
"name": "B2 Hub Habitat Testnet Explorer",
"url": "https://habitat-hub-explorer.bsquared.network",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmPV6ASrQDEkEW3g3ni7p2rJMPeciRLpEpvrAc1QfzVkx9",
"width": 640,
"height": 640,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmPV6ASrQDEkEW3g3ni7p2rJMPeciRLpEpvrAc1QfzVkx9",
"width": 640,
"height": 640,
"format": "png"
},
"infoURL": "https://www.bsquared.network",
"name": "B2 Hub Habitat Testnet",
"nativeCurrency": {
"name": "BSquared Token",
"symbol": "BSQ",
"decimals": 18
},
"networkId": 1113,
"rpc": [
"https://1113.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://habitat-hub-rpc.bsquared.network"
],
"shortName": "B2Hub-testnet",
"slug": "b2-hub-habitat-testnet",
"testnet": true
} as const satisfies Chain;
+47
View File
@@ -0,0 +1,47 @@
import type { Chain } from "../src/types";
export default {
"chain": "Habitat",
"chainId": 1123,
"explorers": [
{
"name": "blockscout",
"url": "https://habitat-explorer.bsquared.network",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmPV6ASrQDEkEW3g3ni7p2rJMPeciRLpEpvrAc1QfzVkx9",
"width": 640,
"height": 640,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmPV6ASrQDEkEW3g3ni7p2rJMPeciRLpEpvrAc1QfzVkx9",
"width": 640,
"height": 640,
"format": "png"
},
"infoURL": "https://www.bsquared.network",
"name": "B2 Habitat Testnet",
"nativeCurrency": {
"name": "Bitcoin",
"symbol": "BTC",
"decimals": 18
},
"networkId": 1123,
"parent": {
"type": "L2",
"chain": "eip155-1113"
},
"rpc": [
"https://1123.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://b2habitat-testnet.alt.technology",
"https://habitat-rpc.bsquared.network",
"https://habitat-rpc-public.bsquared.network"
],
"shortName": "B2-testnet",
"slug": "b2-habitat-testnet",
"testnet": true,
"title": "B2 Habitat Testnet"
} as const satisfies Chain;
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 167009,
"explorers": [
{
"name": "blockscout",
"url": "https://blockscoutapi.hekla.taiko.xyz",
"standard": "EIP3091"
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmcHdmVr5VRUJq13jnM6tgah5Ge7hn3Dm14eY6vwivJ5ui",
"width": 288,
"height": 258,
"format": "png"
},
"infoURL": "https://taiko.xyz",
"name": "Taiko Hekla L2",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 167009,
"rpc": [
"https://167009.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.hekla.taiko.xyz",
"wss://ws.hekla.taiko.xyz"
],
"shortName": "tko-hekla",
"slug": "taiko-hekla-l2",
"status": "active",
"testnet": false
} as const satisfies Chain;
+49
View File
@@ -0,0 +1,49 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 1687,
"explorers": [
{
"name": "blockscout",
"url": "https://sepolia-testnet-explorer.mintchain.io",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmQsYisbKkCTKoKG2YSVs94UGuWWMiBspirH4Af4FyZeZz",
"width": 80,
"height": 80,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmQsYisbKkCTKoKG2YSVs94UGuWWMiBspirH4Af4FyZeZz",
"width": 80,
"height": 80,
"format": "png"
},
"infoURL": "https://www.mintchain.io",
"name": "Mint Sepolia Testnet",
"nativeCurrency": {
"name": "Sepolia Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 1687,
"parent": {
"type": "L2",
"chain": "eip155-1",
"bridges": [
{
"url": "https://sepolia-testnet-bridge.mintchain.io"
}
]
},
"rpc": [
"https://1687.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://sepolia-testnet-rpc.mintchain.io"
],
"shortName": "mintsepoliatest",
"slug": "mint-sepolia-testnet",
"testnet": true
} as const satisfies Chain;
+5 -4
View File
@@ -5,7 +5,7 @@ export default {
"explorers": [
{
"name": "Titan Explorer",
"url": "https://titan-testnet-explorer-light.tokenize-dev.com",
"url": "https://titan-testnet-explorer-light.titanlab.io/Titan%20Testnet",
"standard": "none",
"icon": {
"url": "ipfs://bafkreicyvc7t55zsejv6vwaxbmhvea5vdfkkbgqkmn65rhyyifpg3mq3ua",
@@ -22,7 +22,7 @@ export default {
"height": 512,
"format": "png"
},
"infoURL": "https://tokenize.exchange",
"infoURL": "https://titanlab.io",
"name": "Titan (TKX) Testnet",
"nativeCurrency": {
"name": "Titan tkx",
@@ -32,8 +32,9 @@ export default {
"networkId": 18889,
"rpc": [
"https://18889.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://titan-testnet-json-rpc-1.tokenize-dev.com",
"https://titan-testnet-json-rpc-2.tokenize-dev.com"
"https://titan-testnet-json-rpc.titanlab.io",
"https://titan-testnet-json-rpc-1.titanlab.io",
"https://titan-testnet-json-rpc-2.titanlab.io"
],
"shortName": "titan_tkx-testnet",
"slip44": 1,
+1 -1
View File
@@ -34,7 +34,7 @@ export default {
"wss://testnet-ws.bitlayer-rpc.com",
"https://rpc.ankr.com/bitlayer_testnet"
],
"shortName": "Bitlayer",
"shortName": "btrt",
"slip44": 1,
"slug": "bitlayer-testnet",
"testnet": true
+39
View File
@@ -0,0 +1,39 @@
import type { Chain } from "../src/types";
export default {
"chain": "Bitlayer",
"chainId": 200901,
"explorers": [
{
"name": "bitlayer mainnet scan",
"url": "https://www.btrscan.com",
"standard": "EIP3091"
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmdWZ1frB47fr3tw31xE68C2Vocaw5Ef53LQ5WDNdNnNyG",
"width": 4500,
"height": 4500,
"format": "jpg"
},
"infoURL": "https://docs.bitlayer.org/",
"name": "Bitlayer Mainnet",
"nativeCurrency": {
"name": "BTC",
"symbol": "BTC",
"decimals": 18
},
"networkId": 200901,
"rpc": [
"https://200901.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.bitlayer.org",
"https://rpc.bitlayer-rpc.com",
"https://rpc.ankr.com/bitlayer",
"wss://ws.bitlayer.org",
"wss://ws.bitlayer-rpc.com"
],
"shortName": "btr",
"slip44": 1,
"slug": "bitlayer",
"testnet": false
} as const satisfies Chain;
+6 -1
View File
@@ -39,9 +39,14 @@ export default {
},
"networkId": 2031,
"rpc": [
"wss://fullnode.parachain.centrifuge.io",
"https://2031.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://fullnode.centrifuge.io",
"wss://fullnode.centrifuge.io",
"https://centrifuge-parachain.api.onfinality.io/public",
"wss://centrifuge-parachain.api.onfinality.io/public-ws",
"https://centrifuge-rpc.dwellir.com",
"wss://centrifuge-rpc.dwellir.com",
"https://rpc-centrifuge.luckyfriday.io",
"wss://rpc-centrifuge.luckyfriday.io"
],
"shortName": "cfg",
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"chain": "OMNIA",
"chainId": 2342,
"explorers": [
{
"name": "OmniaVerse Explorer",
"url": "https://scan.omniaverse.io",
"standard": "EIP3091"
}
],
"faucets": [
"https://www.omniaverse.io"
],
"icon": {
"url": "ipfs://QmdNQMFxcjB9PAP1LZVqaQmyppV5QGTqXXmbBeQyaTUpMM",
"width": 192,
"height": 192,
"format": "png"
},
"infoURL": "https://www.omniaverse.io",
"name": "Omnia Chain",
"nativeCurrency": {
"name": "Omnia",
"symbol": "OMNIA",
"decimals": 18
},
"networkId": 2342,
"rpc": [
"https://2342.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.omniaverse.io"
],
"shortName": "omnia",
"slug": "omnia-chain",
"testnet": false
} as const satisfies Chain;
+42
View File
@@ -0,0 +1,42 @@
import type { Chain } from "../src/types";
export default {
"chain": "KOL",
"chainId": 2425,
"explorers": [
{
"name": "King Of Legends Devnet Explorer",
"url": "https://devnet.kingscan.org",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmTZFXhYJboYE9fbaeje12iTF3QPLn6xgyFgrDVe2isDBH",
"width": 400,
"height": 400,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmTZFXhYJboYE9fbaeje12iTF3QPLn6xgyFgrDVe2isDBH",
"width": 400,
"height": 400,
"format": "png"
},
"infoURL": "https://kingoflegends.net/",
"name": "King Of Legends Devnet",
"nativeCurrency": {
"name": "King Of Legends",
"symbol": "KOL",
"decimals": 18
},
"networkId": 2425,
"rpc": [
"https://2425.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-devnet.kinggamer.org/"
],
"shortName": "kol",
"slip44": 1,
"slug": "king-of-legends-devnet",
"testnet": false,
"title": "King Of Legends Devnet"
} as const satisfies Chain;
+6
View File
@@ -3,6 +3,11 @@ export default {
"chain": "FTH",
"chainId": 308,
"explorers": [
{
"name": "furthscan",
"url": "http://furthscan.com",
"standard": "EIP3091"
},
{
"name": "Furthscan Network Explorer",
"url": "http://furthscan.com/",
@@ -34,6 +39,7 @@ export default {
"redFlags": [],
"rpc": [
"https://308.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.furtheon.org/",
"https://rpc.furtheon.org"
],
"shortName": "FTH",
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"chain": "Sahara",
"chainId": 3132023,
"explorers": [],
"faucets": [],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"icon": {
"url": "ipfs://QmQXCm6w8xvWMkksTQYw3So14VCbwHP6chH41v6ysXdSwF",
"width": 608,
"height": 608,
"format": "svg"
},
"infoURL": "https://saharalabs.ai",
"name": "SaharaAI Network",
"nativeCurrency": {
"name": "SAHARA",
"symbol": "SAH",
"decimals": 18
},
"networkId": 3132023,
"rpc": [
"https://3132023.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet.saharalabs.ai"
],
"shortName": "sahara",
"slug": "saharaai-network",
"testnet": false
} as const satisfies Chain;
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"chain": "Sahara",
"chainId": 313313,
"explorers": [],
"faucets": [],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"icon": {
"url": "ipfs://QmQXCm6w8xvWMkksTQYw3So14VCbwHP6chH41v6ysXdSwF",
"width": 608,
"height": 608,
"format": "svg"
},
"infoURL": "https://saharalabs.ai",
"name": "SaharaAI Testnet",
"nativeCurrency": {
"name": "SAHARA",
"symbol": "SAH",
"decimals": 18
},
"networkId": 313313,
"rpc": [
"https://313313.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet.saharalabs.ai"
],
"shortName": "saharatest",
"slug": "saharaai-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 332323,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QI0408s3dev Testnet",
"nativeCurrency": {
"name": "QI0408s3dev Testnet Token",
"symbol": "REQ",
"decimals": 18
},
"networkId": 332323,
"redFlags": [],
"rpc": [
"https://332323.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QI0408s3dev Testnet",
"slug": "qi0408s3dev-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 33448,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QI0408s2 Testnet",
"nativeCurrency": {
"name": "QI0408s2 Testnet Token",
"symbol": "QCE",
"decimals": 18
},
"networkId": 33448,
"redFlags": [],
"rpc": [
"https://33448.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QI0408s2 Testnet",
"slug": "qi0408s2-testnet",
"testnet": true
} as const satisfies Chain;
+5 -5
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 33469,
"explorers": [
{
"name": "Zilliqa 2 EVM Devnet Explorer",
"url": "https://explorer.zq2-devnet.zilstg.dev",
"name": "Zilliqa-2 EVM Devnet Explorer",
"url": "https://explorer.zq2-devnet.zilliqa.com",
"standard": "EIP3091"
}
],
"faucets": [
"https://faucet.zq2-devnet.zilstg.dev"
"https://faucet.zq2-devnet.zilliqa.com"
],
"icon": {
"url": "ipfs://QmTREXNgGtUhSoxFsrkhTe5LUnDBTKL5byaX8kpET6UuKp",
@@ -19,7 +19,7 @@ export default {
"format": "png"
},
"infoURL": "https://www.zilliqa.com/",
"name": "Zilliqa 2 EVM Devnet",
"name": "Zilliqa-2 EVM Devnet",
"nativeCurrency": {
"name": "Zilliqa",
"symbol": "ZIL",
@@ -28,7 +28,7 @@ export default {
"networkId": 33469,
"rpc": [
"https://33469.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://api.zq2-devnet.zilstg.dev"
"https://api.zq2-devnet.zilliqa.com"
],
"shortName": "zq2-devnet",
"slug": "zilliqa-2-evm-devnet",
+6
View File
@@ -3,6 +3,11 @@ export default {
"chain": "XFI",
"chainId": 4157,
"explorers": [
{
"name": "CrossFi Testnet Scan",
"url": "https://scan.testnet.ms",
"standard": "EIP3091"
},
{
"name": "Scan Testnet",
"url": "https://scan.testnet.ms/",
@@ -22,6 +27,7 @@ export default {
"redFlags": [],
"rpc": [
"https://4157.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.testnet.ms/",
"https://rpc.testnet.ms"
],
"shortName": "XFI",
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 43125,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser3950 Testnet",
"nativeCurrency": {
"name": "QaUser3950 Testnet Token",
"symbol": "SZL",
"decimals": 18
},
"networkId": 43125,
"redFlags": [],
"rpc": [
"https://43125.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser3950 Testnet",
"slug": "qauser3950-testnet",
"testnet": true
} as const satisfies Chain;
+34
View File
@@ -0,0 +1,34 @@
import type { Chain } from "../src/types";
export default {
"chain": "BYC",
"chainId": 434,
"explorers": [
{
"name": "Boyaa explorer",
"url": "https://explorer.mainnet.boyaa.network",
"standard": "EIP3091"
}
],
"faucets": [],
"icon": {
"url": "ipfs://bafybeiapootrvggtigdlvgvk6srfseplpuowsqq3zpyup4j5yj5moxuala",
"width": 500,
"height": 500,
"format": "png"
},
"infoURL": "https://boyaa.network",
"name": "Boyaa Mainnet",
"nativeCurrency": {
"name": "Boyaa mainnet native coin",
"symbol": "BYC",
"decimals": 18
},
"networkId": 434,
"rpc": [
"https://434.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://evm-rpc.mainnet.boyaa.network"
],
"shortName": "BYC",
"slug": "boyaa",
"testnet": false
} as const satisfies Chain;
+3
View File
@@ -10,6 +10,7 @@ export default {
}
],
"faucets": [],
"features": [],
"infoURL": "https://ten.xyz",
"name": "Ten Testnet",
"nativeCurrency": {
@@ -27,8 +28,10 @@ export default {
}
]
},
"redFlags": [],
"rpc": [
"https://443.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet.ten.xyz/v1/",
"https://testnet.ten.xyz"
],
"shortName": "ten-testnet",
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 52146,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser4359 Testnet",
"nativeCurrency": {
"name": "QaUser4359 Testnet Token",
"symbol": "WBP",
"decimals": 18
},
"networkId": 52146,
"redFlags": [],
"rpc": [
"https://52146.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser4359 Testnet",
"slug": "qauser4359-testnet",
"testnet": true
} as const satisfies Chain;
-6
View File
@@ -12,12 +12,6 @@ export default {
"faucets": [
"https://t.me/vexfaucetbot"
],
"icon": {
"url": "ipfs://QmcZiEAGFYEEax1uxYnDUh8X5YBvZqMi9K92yZoq4o2zeM",
"width": 451,
"height": 446,
"format": "png"
},
"infoURL": "https://vexanium.com",
"name": "VEX EVM TESTNET",
"nativeCurrency": {
+48
View File
@@ -0,0 +1,48 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 59141,
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.sepolia.linea.build/",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmURjritnHL7a8TwZgsFwp3f272DJmG5paaPtWDZ98QZwH",
"width": 30,
"height": 30,
"format": "svg"
}
}
],
"faucets": [],
"features": [],
"icon": {
"url": "ipfs://QmURjritnHL7a8TwZgsFwp3f272DJmG5paaPtWDZ98QZwH",
"width": 30,
"height": 30,
"format": "svg"
},
"infoURL": "https://linea.build",
"name": "Linea Sepolia",
"nativeCurrency": {
"name": "Linea Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 59141,
"parent": {
"type": "L2",
"chain": "eip155-5",
"bridges": []
},
"redFlags": [],
"rpc": [
"https://59141.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.sepolia.linea.build"
],
"shortName": "linea-sepolia",
"slug": "linea-sepolia",
"testnet": true,
"title": "Linea Sepolia Testnet"
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 66042,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QI0408I1 Testnet",
"nativeCurrency": {
"name": "QI0408I1 Testnet Token",
"symbol": "YXE",
"decimals": 18
},
"networkId": 66042,
"redFlags": [],
"rpc": [
"https://66042.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QI0408I1 Testnet",
"slug": "qi0408i1-testnet",
"testnet": true
} as const satisfies Chain;
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"chain": "WON",
"chainId": 686868,
"explorers": [
{
"name": "Won Explorer",
"url": "https://scan.wonnetwork.org",
"standard": "EIP3091"
}
],
"faucets": [
"https://faucet.wondollars.org"
],
"icon": {
"url": "ipfs://QmQ6mjKWJQ5WmFiJzcqJnuHWZK53nQYJB1SnMQZEqgr74h",
"width": 250,
"height": 250,
"format": "png"
},
"infoURL": "https://wonnetwork.org",
"name": "Won Network",
"nativeCurrency": {
"name": "Won",
"symbol": "WON",
"decimals": 18
},
"networkId": 686868,
"rpc": [
"https://686868.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.wonnetwork.org"
],
"shortName": "WonChain",
"slug": "won-network",
"testnet": false
} as const satisfies Chain;
@@ -3,6 +3,11 @@ export default {
"chain": "ETH",
"chainId": 68840142,
"explorers": [
{
"name": "Frame Testnet Explorer",
"url": "https://explorer.testnet.frame.xyz",
"standard": "EIP3091"
},
{
"name": "Frame Testnet Explorer",
"url": "https://explorer.testnet.frame.xyz/",
@@ -10,6 +15,7 @@ export default {
}
],
"faucets": [
"https://faucet.triangleplatform.com/frame/testnet",
"https://faucet.triangleplatform.com/frame"
],
"features": [],
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 68976,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QI0408s1 Testnet",
"nativeCurrency": {
"name": "QI0408s1 Testnet Token",
"symbol": "ICV",
"decimals": 18
},
"networkId": 68976,
"redFlags": [],
"rpc": [
"https://68976.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QI0408s1 Testnet",
"slug": "qi0408s1-testnet",
"testnet": true
} as const satisfies Chain;
+3 -1
View File
@@ -39,7 +39,9 @@ export default {
"networkId": 7001,
"rpc": [
"https://7001.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.ankr.com/zetachain_evm_athens_testnet"
"https://zetachain-athens-evm.blockpi.network/v1/rpc/public",
"wss://zetachain-athens.blockpi.network/rpc/v1/public/websocket",
"https://zetachain-testnet-archive.allthatnode.com:8545"
],
"shortName": "zetachain-athens",
"slip44": 1,
+2 -1
View File
@@ -26,9 +26,10 @@ export default {
"networkId": 77001,
"rpc": [
"https://77001.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://public-node.api.boraportal.io/bora/mainnet"
"https://public-node.api.boraportal.com/bora/mainnet"
],
"shortName": "BORAchain",
"slip44": 8217,
"slug": "borachain",
"testnet": false
} as const satisfies Chain;
+1 -1
View File
@@ -39,7 +39,7 @@ export default {
"shortName": "maticmum",
"slip44": 1,
"slug": "mumbai",
"status": "active",
"status": "deprecated",
"testnet": true,
"title": "Polygon Testnet Mumbai"
} as const satisfies Chain;
+43
View File
@@ -0,0 +1,43 @@
import type { Chain } from "../src/types";
export default {
"chain": "BIZT Testnet",
"chainId": 808080,
"explorers": [
{
"name": "BIZ Smart Chain Testnet Explorer",
"url": "https://testnet.btscan.io",
"standard": "EIP3091"
}
],
"faucets": [],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"icon": {
"url": "ipfs://QmNnaDZRoMz9aoho35TGHBY5zD16P39cgPpw3z3jnkDHHB",
"width": 104,
"height": 104,
"format": "png"
},
"infoURL": "https://www.biztoken.io/",
"name": "BIZ Smart Chain Testnet",
"nativeCurrency": {
"name": "tBIZT",
"symbol": "tBIZT",
"decimals": 18
},
"networkId": 808080,
"rpc": [
"https://808080.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-testnet.bizex.io/"
],
"shortName": "bizt-testnet",
"slip44": 1,
"slug": "biz-smart-chain-testnet",
"testnet": true
} as const satisfies Chain;
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "PTCE",
"chainId": 889910245,
"explorers": [
{
"name": "PTCESCAN Testnet Explorer",
"url": "https://explorer-testnet.ptcscan.io",
"standard": "EIP3091"
}
],
"faucets": [
"https://faucet.ptcscan.io/"
],
"infoURL": "https://ptcscan.io",
"name": "PTCESCAN Testnet",
"nativeCurrency": {
"name": "PTCE",
"symbol": "PTCE",
"decimals": 18
},
"networkId": 889910245,
"rpc": [
"https://889910245.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-testnet.ptcscan.io"
],
"shortName": "PTCE",
"slug": "ptcescan-testnet",
"testnet": true,
"title": "PTCESCAN Testnet"
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 914031,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QR0408T1TS Testnet",
"nativeCurrency": {
"name": "QR0408T1TS Testnet Token",
"symbol": "HOK",
"decimals": 18
},
"networkId": 914031,
"redFlags": [],
"rpc": [
"https://914031.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/qr0408t1ts/testnet/rpc"
],
"shortName": "QR0408T1TS Testnet",
"slug": "qr0408t1ts-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 928010,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QR0408T2TS Testnet",
"nativeCurrency": {
"name": "QR0408T2TS Testnet Token",
"symbol": "XYZ",
"decimals": 18
},
"networkId": 928010,
"redFlags": [],
"rpc": [
"https://928010.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/qr0408t2ts/testnet/rpc"
],
"shortName": "QR0408T2TS Testnet",
"slug": "qr0408t2ts-testnet",
"testnet": true
} as const satisfies Chain;
+11
View File
@@ -3,6 +3,17 @@ export default {
"chain": "ETH",
"chainId": 94204209,
"explorers": [
{
"name": "blockscout",
"url": "https://polygon-blackberry.gelatoscout.com",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmYtUimyqHkkFxYdbXXRbUqNg2VLPUg6Uu2C2nmFWowiZM",
"width": 551,
"height": 540,
"format": "png"
}
},
{
"name": "blockscout",
"url": "https://polygon-blackberry.gelatoscout.com/",
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 987,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "Orange Testnet",
"nativeCurrency": {
"name": "Orange Testnet Token",
"symbol": "JUICE",
"decimals": 18
},
"networkId": 987,
"redFlags": [],
"rpc": [
"https://987.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/orangetest/testnet/rpc"
],
"shortName": "Orange Testnet",
"slug": "orange-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 99733,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser6779 Testnet",
"nativeCurrency": {
"name": "QaUser6779 Testnet Token",
"symbol": "WAG",
"decimals": 18
},
"networkId": 99733,
"redFlags": [],
"rpc": [
"https://99733.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser6779 Testnet",
"slug": "qauser6779-testnet",
"testnet": true
} as const satisfies Chain;
+22
View File
@@ -0,0 +1,22 @@
import type { Chain } from "../src/types";
export default {
"chain": "ZTC",
"chainId": 9998,
"explorers": [],
"faucets": [],
"infoURL": "https://ztc.best",
"name": "Ztc Mainnet",
"nativeCurrency": {
"name": "Ztcer",
"symbol": "ZTC",
"decimals": 5
},
"networkId": 9998,
"rpc": [
"https://9998.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://zitcoin.us"
],
"shortName": "ZTC",
"slug": "ztc",
"testnet": false
} as const satisfies Chain;
+5 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.89",
"version": "0.1.91",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"exports": {
@@ -12,11 +12,12 @@
},
"author": "thirdweb eng <[email protected]>",
"devDependencies": {
"@babel/runtime": "^7.24.1",
"eslint": "8.57.0",
"@babel/runtime": "^7.24.4",
"@preconstruct/cli": "2.7.0",
"@thirdweb-dev/tsconfig": "workspace:*",
"eslint-config-thirdweb": "workspace:*",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"preconstruct": {
"entrypoints": [
@@ -30,7 +31,7 @@
"db:sync": "bun scripts/sync-db.ts",
"build": "tsc && preconstruct build",
"push": "yalc push",
"test": "vitest"
"test": "vitest run"
},
"engines": {
"node": ">=18"
File diff suppressed because one or more lines are too long
+23
View File
@@ -1,5 +1,28 @@
# thirdweb
## 0.13.66
### Patch Changes
- Updated dependencies [[`6961e09`](https://github.com/thirdweb-dev/js/commit/6961e09a4cec4c276b233285e721dc0505792be5), [`f6a30c0`](https://github.com/thirdweb-dev/js/commit/f6a30c037197391ef0a514570931775b18927f17), [`53e56f4`](https://github.com/thirdweb-dev/js/commit/53e56f4bf8d3fbe7e2d5252b561bcef5927762e6), [`5150259`](https://github.com/thirdweb-dev/js/commit/51502596d9f165a5316ce08da8a04b3e5c5e4eba)]:
- @thirdweb-dev/wallets@2.5.0
- @thirdweb-dev/chains@0.1.91
- @thirdweb-dev/auth@4.1.58
- @thirdweb-dev/sdk@4.0.60
## 0.13.65
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
- Updated dependencies [[`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f), [`48c1d60`](https://github.com/thirdweb-dev/js/commit/48c1d6038272284f8942e1fb3635283b48945a68)]:
- @thirdweb-dev/storage@2.0.14
- @thirdweb-dev/wallets@2.4.35
- @thirdweb-dev/chains@0.1.90
- @thirdweb-dev/auth@4.1.57
- @thirdweb-dev/sdk@4.0.59
## 0.13.64
### Patch Changes
+5 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/cli",
"main": "dist/cli/index.js",
"version": "0.13.64",
"version": "0.13.66",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -9,15 +9,16 @@
"node": ">=18.0.0"
},
"devDependencies": {
"eslint": "8.57.0",
"@gmrchk/cli-testing-library": "^0.1.2",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/async-retry": "^1.4.8",
"@types/cross-spawn": "^6.0.6",
"@types/inquirer": "^8.2.10",
"@types/js-yaml": "^4.0.9",
"@types/node": "20.12.2",
"@types/node": "20.12.5",
"@types/prompts": "^2.4.9",
"@types/tar": "^6.1.11",
"@types/tar": "^6.1.12",
"@types/update-notifier": "^6.0.8",
"@types/validate-npm-package-name": "^4.0.2",
"chalk": "^5.3.0",
@@ -27,7 +28,7 @@
"hardhat": "^2.22.2",
"ora": "^6.3.1",
"tsup": "8.0.2",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"dependencies": {
"@iarna/toml": "^2.2.5",
@@ -1,5 +1,11 @@
# @thirdweb-dev/contracts-js
## 1.3.21
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
## 1.3.20
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/contracts-js",
"version": "1.3.20",
"version": "1.3.21",
"main": "dist/thirdweb-dev-contracts-js.cjs.js",
"module": "dist/thirdweb-dev-contracts-js.esm.js",
"exports": {
@@ -435,7 +435,7 @@
"eslint-config-thirdweb": "workspace:*",
"ethers": "^5.7.2",
"typechain": "^8.3.2",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"peerDependencies": {
"ethers": "^5"
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/crypto
## 0.2.5
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
## 0.2.4
### Patch Changes
+5 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/crypto",
"version": "0.2.4",
"version": "0.2.5",
"main": "dist/thirdweb-dev-crypto.cjs.js",
"module": "dist/thirdweb-dev-crypto.esm.js",
"exports": {
@@ -31,6 +31,7 @@
"js-sha3": "^0.9.3"
},
"devDependencies": {
"eslint": "8.57.0",
"@preconstruct/cli": "2.7.0",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/crypto-js": "^4.2.2",
@@ -39,8 +40,8 @@
"ethers": "^5.7.2",
"js-awe": "^1.0.65",
"tinybench": "^2.6.0",
"typescript": "5.4.3",
"viem": "2.9.6"
"typescript": "5.4.4",
"viem": "2.9.9"
},
"scripts": {
"format": "prettier --write 'src/**/*'",
@@ -49,7 +50,7 @@
"clean": "rm -rf dist/",
"build": "tsc && preconstruct build",
"push": "yalc push",
"test": "vitest",
"test": "vitest run",
"benchmark:aes-encrypt": "bun benchmark/aes-encrypt.ts",
"benchmark:aes-decrypt": "bun benchmark/aes-decrypt.ts",
"benchmark:sha256": "bun benchmark/sha256.ts",
@@ -1,5 +1,11 @@
# eslint-config-thirdweb
## 0.1.9
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
## 0.1.8
### Patch Changes
@@ -1,14 +1,14 @@
{
"name": "eslint-config-thirdweb",
"version": "0.1.8",
"version": "0.1.9",
"main": "index.js",
"license": "Apache-2.0",
"dependencies": {
"@typescript-eslint/eslint-plugin": "7.5.0",
"@typescript-eslint/parser": "7.4.0",
"@typescript-eslint/parser": "7.5.0",
"eslint-config-next": "13.4.12",
"eslint-config-prettier": "9.1.0",
"eslint-config-turbo": "1.13.1",
"eslint-config-turbo": "1.13.2",
"eslint-plugin-react": "7.34.1"
},
"publishConfig": {
+1 -3
View File
@@ -23,9 +23,7 @@
},
"author": "thirdweb eng <[email protected]>",
"sideEffects": false,
"files": [
"dist/"
],
"files": ["dist/"],
"scripts": {
"push": "yalc push"
}
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/merkletree
## 0.2.5
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
## 0.2.4
### Patch Changes
+4 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/merkletree",
"version": "0.2.4",
"version": "0.2.5",
"main": "dist/thirdweb-dev-merkletree.cjs.js",
"module": "dist/thirdweb-dev-merkletree.esm.js",
"exports": {
@@ -32,12 +32,13 @@
"treeify": "^1.1.0"
},
"devDependencies": {
"eslint": "8.57.0",
"@preconstruct/cli": "2.7.0",
"@thirdweb-dev/crypto": "workspace:*",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/treeify": "^1.0.3",
"eslint-config-thirdweb": "workspace:*",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"scripts": {
"format": "prettier --write 'src/**/*'",
@@ -46,7 +47,7 @@
"clean": "rm -rf dist/",
"build": "tsc && preconstruct build",
"push": "yalc push",
"test": "vitest"
"test": "vitest run"
},
"engines": {
"node": ">=18"
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/pay
## 0.1.7
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
## 0.1.6
### Patch Changes
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/pay",
"version": "0.1.6",
"version": "0.1.7",
"main": "dist/thirdweb-dev-pay.cjs.js",
"module": "dist/thirdweb-dev-pay.esm.js",
"exports": {
@@ -36,10 +36,11 @@
"@coinbase/cbpay-js": "^1.10.0"
},
"devDependencies": {
"eslint": "8.57.0",
"@preconstruct/cli": "2.7.0",
"@thirdweb-dev/tsconfig": "workspace:*",
"eslint-config-thirdweb": "workspace:*",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"scripts": {
"format": "prettier --write 'src/**/*'",
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/payments
## 1.0.4
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
## 1.0.3
### Patch Changes
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/payments",
"version": "1.0.3",
"version": "1.0.4",
"main": "dist/thirdweb-dev-payments.cjs.js",
"module": "dist/thirdweb-dev-payments.esm.js",
"types": "dist/thirdweb-dev-payments.cjs.d.ts",
@@ -41,10 +41,11 @@
"ethers": "^5.7.2"
},
"devDependencies": {
"eslint": "8.57.0",
"@preconstruct/cli": "2.7.0",
"@thirdweb-dev/tsconfig": "workspace:*",
"eslint-config-thirdweb": "workspace:*",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"scripts": {
"format": "prettier --write 'src/**/*'",
+23
View File
@@ -1,5 +1,28 @@
# @thirdweb-dev/react-core
## 4.5.0
### Patch Changes
- Updated dependencies [[`6961e09`](https://github.com/thirdweb-dev/js/commit/6961e09a4cec4c276b233285e721dc0505792be5), [`f6a30c0`](https://github.com/thirdweb-dev/js/commit/f6a30c037197391ef0a514570931775b18927f17), [`53e56f4`](https://github.com/thirdweb-dev/js/commit/53e56f4bf8d3fbe7e2d5252b561bcef5927762e6), [`5150259`](https://github.com/thirdweb-dev/js/commit/51502596d9f165a5316ce08da8a04b3e5c5e4eba)]:
- @thirdweb-dev/wallets@2.5.0
- @thirdweb-dev/chains@0.1.91
- @thirdweb-dev/auth@4.1.58
- @thirdweb-dev/sdk@4.0.60
## 4.4.33
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
- Updated dependencies [[`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f), [`48c1d60`](https://github.com/thirdweb-dev/js/commit/48c1d6038272284f8942e1fb3635283b48945a68)]:
- @thirdweb-dev/storage@2.0.14
- @thirdweb-dev/wallets@2.4.35
- @thirdweb-dev/chains@0.1.90
- @thirdweb-dev/auth@4.1.57
- @thirdweb-dev/sdk@4.0.59
## 4.4.32
### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "4.4.32",
"version": "4.5.0",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -58,7 +58,7 @@
"sideEffects:": false,
"devDependencies": {
"@babel/preset-react": "^7.24.1",
"@babel/runtime": "^7.24.1",
"@babel/runtime": "^7.24.4",
"@microsoft/api-documenter": "^7.24.1",
"@microsoft/api-extractor": "^7.43.0",
"@microsoft/tsdoc": "^0.14.2",
@@ -68,7 +68,7 @@
"@types/js-cookie": "^3.0.6",
"@types/mime": "3.0.0",
"@types/react": "18.2.17",
"eslint": "^8.57.0",
"eslint": "8.57.0",
"eslint-config-thirdweb": "workspace:*",
"eslint-plugin-better-tree-shaking": "0.0.4",
"eslint-plugin-import": "^2.29.1",
@@ -78,7 +78,7 @@
"ethers": "^5.7.2",
"react": "18.2.0",
"typedoc-gen": "workspace:*",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"dependencies": {
"@tanstack/react-query": "^4.36.1",
@@ -1,5 +1,13 @@
# @thirdweb-dev/react-native-compat
## 0.7.31
## 0.7.30
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
## 0.7.29
## 0.7.28
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/react-native-compat",
"description": "Shims for Thirdweb in React Native Projects",
"version": "0.7.29",
"version": "0.7.31",
"author": "thirdweb eng <[email protected]>",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native-compat",
"license": "Apache-2.0",
@@ -22,7 +22,7 @@
},
"dependencies": {
"@ethersproject/shims": "^5.7.0",
"@walletconnect/react-native-compat": "2.11.3",
"@walletconnect/react-native-compat": "2.12.1",
"base-64": "^1.0.0",
"big-integer": "^1.6.52",
"react-native-get-random-values": "^1.11.0",
@@ -35,12 +35,12 @@
},
"devDependencies": {
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/node": "20.12.2",
"@types/node": "20.12.5",
"babel-plugin-module-resolver": "^5.0.0",
"eslint-config-thirdweb": "workspace:*",
"ethers": "^5.7.2",
"react": "18.2.0",
"react-native": "^0.71.17",
"typescript": "5.4.3"
"typescript": "5.4.4"
}
}
+23
View File
@@ -1,5 +1,28 @@
# @thirdweb-dev/react-native
## 0.7.31
### Patch Changes
- Updated dependencies [[`6961e09`](https://github.com/thirdweb-dev/js/commit/6961e09a4cec4c276b233285e721dc0505792be5), [`f6a30c0`](https://github.com/thirdweb-dev/js/commit/f6a30c037197391ef0a514570931775b18927f17), [`53e56f4`](https://github.com/thirdweb-dev/js/commit/53e56f4bf8d3fbe7e2d5252b561bcef5927762e6), [`5150259`](https://github.com/thirdweb-dev/js/commit/51502596d9f165a5316ce08da8a04b3e5c5e4eba)]:
- @thirdweb-dev/wallets@2.5.0
- @thirdweb-dev/chains@0.1.91
- @thirdweb-dev/react-core@4.5.0
- @thirdweb-dev/sdk@4.0.60
## 0.7.30
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
- Updated dependencies [[`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f), [`48c1d60`](https://github.com/thirdweb-dev/js/commit/48c1d6038272284f8942e1fb3635283b48945a68)]:
- @thirdweb-dev/react-core@4.4.33
- @thirdweb-dev/storage@2.0.14
- @thirdweb-dev/wallets@2.4.35
- @thirdweb-dev/chains@0.1.90
- @thirdweb-dev/sdk@4.0.59
## 0.7.29
### Patch Changes
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-native",
"version": "0.7.29",
"version": "0.7.31",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -25,8 +25,8 @@
"android"
],
"dependencies": {
"@aws-sdk/client-lambda": "3.350.0",
"@aws-sdk/credential-providers": "3.350.0",
"@aws-sdk/client-lambda": "3.549.0",
"@aws-sdk/credential-providers": "3.549.0",
"@coinbase/wallet-mobile-sdk": "1.0.13",
"@paperxyz/embedded-wallet-service-sdk": "^1.2.5",
"@shopify/restyle": "^2.4.2",
@@ -55,7 +55,7 @@
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/react": "18.2.17",
"@types/react-native": "^0.71.13",
"eslint": "^8.57.0",
"eslint": "8.57.0",
"eslint-config-thirdweb": "workspace:*",
"eslint-plugin-i18next": "^6.0.3",
"eslint-plugin-import": "^2.29.1",
@@ -68,14 +68,14 @@
"react-native-camera": "^4.2.1",
"rimraf": "5.0.5",
"typedoc-gen": "workspace:*",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"optionalDependencies": {
"amazon-cognito-identity-js": "^6.3.12",
"react-native-aes-gcm-crypto": "^0.2.2",
"react-native-camera": "^4.2.1",
"react-native-inappbrowser-reborn": "^3.7.0",
"react-native-quick-base64": "^2.0.8",
"react-native-quick-base64": "^2.1.0",
"react-native-quick-crypto": "^0.6.1"
},
"peerDependencies": {
+48
View File
@@ -1,5 +1,53 @@
# @thirdweb-dev/react
## 4.5.0
### Minor Changes
- [#2366](https://github.com/thirdweb-dev/js/pull/2366) [`f6a30c0`](https://github.com/thirdweb-dev/js/commit/f6a30c037197391ef0a514570931775b18927f17) Thanks [@ElasticBottle](https://github.com/ElasticBottle)! - Add Login with SMS in EmbeddedWallet
Note that by having `phone` before `email` in the options array, the phone login option will be presented first.
Use `['email', 'phone']` to have the email option presented first.
```ts
<ThirdwebProvider
clientId={import.meta.env.VITE_TEMPLATE_CLIENT_ID}
activeChain={activeChain}
supportedWallets={[
embeddedWallet({
auth: {
options: ["phone", "email", "apple", "google"],
},
}),
...defaultWallets,
]}
>
<App />
</ThirdwebProvider>
```
### Patch Changes
- Updated dependencies [[`6961e09`](https://github.com/thirdweb-dev/js/commit/6961e09a4cec4c276b233285e721dc0505792be5), [`f6a30c0`](https://github.com/thirdweb-dev/js/commit/f6a30c037197391ef0a514570931775b18927f17), [`53e56f4`](https://github.com/thirdweb-dev/js/commit/53e56f4bf8d3fbe7e2d5252b561bcef5927762e6), [`5150259`](https://github.com/thirdweb-dev/js/commit/51502596d9f165a5316ce08da8a04b3e5c5e4eba)]:
- @thirdweb-dev/wallets@2.5.0
- @thirdweb-dev/chains@0.1.91
- @thirdweb-dev/react-core@4.5.0
- @thirdweb-dev/sdk@4.0.60
## 4.4.33
### Patch Changes
- [#2701](https://github.com/thirdweb-dev/js/pull/2701) [`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f) Thanks [@jnsdls](https://github.com/jnsdls)! - updated dependencies
- Updated dependencies [[`703cb6a`](https://github.com/thirdweb-dev/js/commit/703cb6ae3cc51fa4b0ba7c87f09f8e84dab8ed3f), [`48c1d60`](https://github.com/thirdweb-dev/js/commit/48c1d6038272284f8942e1fb3635283b48945a68)]:
- @thirdweb-dev/react-core@4.4.33
- @thirdweb-dev/payments@1.0.4
- @thirdweb-dev/wallets@2.4.35
- @thirdweb-dev/chains@0.1.90
- @thirdweb-dev/sdk@4.0.59
## 4.4.32
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "4.4.32",
"version": "4.5.0",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -72,7 +72,7 @@
},
"sideEffects:": false,
"devDependencies": {
"@babel/runtime": "^7.24.1",
"@babel/runtime": "^7.24.4",
"@microsoft/api-documenter": "^7.24.1",
"@microsoft/api-extractor": "^7.43.0",
"@microsoft/tsdoc": "^0.14.2",
@@ -82,9 +82,9 @@
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/qrcode": "^1.5.5",
"@types/react": "18.2.17",
"@types/react-dom": "^18.2.23",
"@types/react-dom": "^18.2.24",
"@types/uuid": "^9.0.8",
"eslint": "^8.57.0",
"eslint": "8.57.0",
"eslint-config-thirdweb": "workspace:*",
"eslint-plugin-better-tree-shaking": "0.0.4",
"eslint-plugin-import": "^2.29.1",
@@ -97,7 +97,7 @@
"react-dom": "^18.2.0",
"stream": "npm:stream-browserify@^3.0.0",
"typedoc-gen": "workspace:*",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"dependencies": {
"@emotion/css": "11.10.5",
@@ -1,4 +1,6 @@
import { UseQueryResult, useQuery } from "@tanstack/react-query";
import {
useAddress,
useCreateWalletInstance,
useSetConnectedWallet,
useSetConnectionStatus,
@@ -7,17 +9,12 @@ import {
useWallets,
} from "@thirdweb-dev/react-core";
import {
EmbeddedWallet,
walletIds,
type AuthParams,
EmbeddedWallet,
} from "@thirdweb-dev/wallets";
import { useCallback, useEffect } from "react";
import { useCallback } from "react";
import { embeddedWallet } from "../../../wallet/wallets/embeddedWallet/embeddedWallet";
import {
UseQueryResult,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
/**
* Hook to connect `EmbeddedWallet` which allows users to login via Email or social logins
@@ -194,14 +191,15 @@ export function useEmbeddedWalletUserEmail(): UseQueryResult<
string | undefined
> {
const wallet = useWallet();
const queryClient = useQueryClient();
const address = useAddress();
const emailQuery = useQuery<string | undefined, string>(
[wallet?.walletId, "embeddedWallet-email"],
[wallet?.walletId, address, "embeddedWallet-email"],
() => {
if (wallet && wallet.walletId === walletIds.embeddedWallet) {
return (wallet as EmbeddedWallet).getEmail();
return (wallet as EmbeddedWallet).getEmail() ?? "";
}
return "";
},
{
retry: false,
@@ -209,10 +207,49 @@ export function useEmbeddedWalletUserEmail(): UseQueryResult<
},
);
// Invalidate the query when the wallet changes
useEffect(() => {
queryClient.invalidateQueries([wallet?.walletId, "embeddedWallet-email"]);
}, [wallet, queryClient]);
return emailQuery;
}
/**
* Hook to get the user's phone number from connected `EmbeddedWallet`
*
* @example
* ```ts
* const phoneNumberQuery = useEmbeddedWalletUserPhoneNumber();
*
* if (phoneNumberQuery.isFetching) {
* return <div> Loading... </div>;
* }
*
* if (phoneNumberQuery.data) {
* return <div> Connected with {phoneNumberQuery.data} </div>;
* }
*
* return <div> Not connected </div>;
* ```
*
* @walletConnection
* @returns Hook's `data` property contains the `string` email if `EmbeddedWallet` is connected, otherwise `undefined`
*/
export function useEmbeddedWalletUserPhoneNumber(): UseQueryResult<
string | undefined
> {
const wallet = useWallet();
const address = useAddress();
const emailQuery = useQuery<string | undefined, string>(
[wallet?.walletId, address, "embeddedWallet-phone-number"],
() => {
if (wallet && wallet.walletId === walletIds.embeddedWallet) {
return (wallet as EmbeddedWallet).getPhoneNumber() ?? "";
}
return "";
},
{
retry: false,
enabled: wallet?.walletId === walletIds.embeddedWallet,
},
);
return emailQuery;
}
+9 -2
View File
@@ -1,5 +1,5 @@
import { ThirdwebLocale } from "./types";
import { DeepPartial, immutableOverride } from "../utils/applyOverrides";
import { ThirdwebLocale } from "./types";
// wallets that connect via extension and QR scan
function extensionAndQRScanScreens(walletName: string) {
@@ -210,6 +210,7 @@ export function enDefault(): ThirdwebLocale {
signInWithGoogle: "Sign in with Google",
signInWithFacebook: "Sign in with Facebook",
signInWithApple: "Sign in with Apple",
signInWithEmail: "Sign in with Email",
emailPlaceholder: "Enter your email address",
submitEmail: "Continue",
signIn: "Sign in",
@@ -217,13 +218,19 @@ export function enDefault(): ThirdwebLocale {
invalidEmail: "Invalid email address",
maxAccountsExceeded:
"Maximum number of accounts exceeded. Please notify the app developer.",
invalidPhone: "Invalid phone number",
invalidEmailOrPhone: "Invalid email address or phone number",
countryCodeMissing: "Phone number must start with a country code",
phonePlaceholder: "Enter phone number",
signInWithPhone: "Sign in with phone number",
phoneRequired: "phone number is required",
socialLoginScreen: {
title: "Sign in",
instruction: "Sign into your account in the pop-up",
failed: "Failed to sign in",
retry: "Retry",
},
emailLoginScreen: {
otpLoginScreen: {
title: "Sign in",
enterCodeSendTo: "Enter the verification code sent to",
newDeviceDetected: "New device detected",
+9 -1
View File
@@ -213,19 +213,27 @@ export function esDefault(): ThirdwebLocale {
signInWithGoogle: "Iniciar sesión con Google",
signInWithFacebook: "Iniciar sesión con Facebook",
signInWithApple: "Iniciar sesión con Apple",
signInWithEmail: "Iniciar sesión con correo electrónico",
emailPlaceholder: "Ingresa tu dirección de correo electrónico",
submitEmail: "Continuar",
signIn: "Iniciar sesión",
emailRequired: "Se requiere dirección de correo electrónico",
invalidEmail: "Dirección de correo electrónico inválida",
maxAccountsExceeded: "Número máximo de cuentas alcanzado",
invalidPhone: "Número de teléfono inválido",
invalidEmailOrPhone:
"Dirección de correo electrónico o número de teléfono inválido",
countryCodeMissing: "Phone number must start with a country code",
phonePlaceholder: "Ingresa tu número de teléfono",
signInWithPhone: "Iniciar sesión con número de teléfono",
phoneRequired: "Se requiere número de teléfono",
socialLoginScreen: {
title: "Iniciar sesión",
instruction: "Inicie sesión en su cuenta en la ventana abierta",
failed: "Error al iniciar sesión",
retry: "Reintentar",
},
emailLoginScreen: {
otpLoginScreen: {
title: "Iniciar sesión",
enterCodeSendTo: "Ingresa el código de verificación enviado a",
newDeviceDetected: "Nuevo dispositivo detectado",
+8 -1
View File
@@ -212,19 +212,26 @@ export function jaDefault(): ThirdwebLocale {
signInWithGoogle: "Googleでサインイン",
signInWithFacebook: "Facebookでサインイン",
signInWithApple: "Appleでサインイン",
signInWithEmail: "電子メールでサインインする",
emailPlaceholder: "メールアドレスを入力してください",
submitEmail: "続ける",
emailRequired: "メールアドレスが必要です",
invalidEmail: "無効なメールアドレス",
signIn: "サインイン",
maxAccountsExceeded: "アカウントの最大数を超えました",
invalidPhone: "無効な電話番号",
invalidEmailOrPhone: "無効なメールアドレスまたは電話番号",
countryCodeMissing: "Phone number must start with a country code",
phonePlaceholder: "電話番号を入力してください",
signInWithPhone: "電話番号でログイン",
phoneRequired: "電話番号が必要です",
socialLoginScreen: {
title: "サインイン",
instruction: "ポップアップウィンドウでアカウントにサインインします", // TODO: check if this is correct
failed: "サインインに失敗しました",
retry: "再試行",
},
emailLoginScreen: {
otpLoginScreen: {
title: "サインイン",
enterCodeSendTo: "送信された確認コードを入力してください",
newDeviceDetected: "新しいデバイスが検出されました",
+8 -1
View File
@@ -215,19 +215,26 @@ export function tlDefault(): ThirdwebLocale {
signInWithGoogle: "Mag-sign in gamit ang Google",
signInWithFacebook: "Mag-sign in gamit ang Facebook",
signInWithApple: "Mag-sign in gamit ang Apple",
signInWithEmail: "Mag-sign in gamit ang email",
emailPlaceholder: "Ilagay ang iyong email address",
submitEmail: "Magpatuloy",
signIn: "Mag-sign in",
emailRequired: "Kinakailangan ang email address",
invalidEmail: "Hindi wastong email address",
maxAccountsExceeded: "Naabot mo na ang maximum na bilang ng accounts",
invalidPhone: "Hindi wastong numero ng telepono",
invalidEmailOrPhone: "Hindi wastong email address o numero ng telepono",
countryCodeMissing: "Phone number must start with a country code",
phonePlaceholder: "Ilagay ang iyong numero ng telepono",
signInWithPhone: "Mag-login gamit ang numero ng telepono",
phoneRequired: "Kinakailangan ang numero ng telepono",
socialLoginScreen: {
title: "Mag-sign in",
instruction: "Mag-sign in sa iyong account sa pop-up",
failed: "Hindi nagawa ang pag-sign in",
retry: "Subukan muli",
},
emailLoginScreen: {
otpLoginScreen: {
title: "Mag-sign in",
enterCodeSendTo: "Ilagay ang verification code na ipinadala sa",
newDeviceDetected: "Natuklasan ang bagong device",
@@ -131,7 +131,7 @@ export type ThirdwebLocale = {
submitButton: string;
title: string;
};
emailLoginScreen: {
otpLoginScreen: {
enterCodeSendTo: string;
enterRecoveryCode: string;
failedToSendCode: string;
@@ -143,6 +143,7 @@ export type ThirdwebLocale = {
title: string;
verify: string;
};
signInWithEmail: string;
emailPlaceholder: string;
emailRequired: string;
enterPassword: {
@@ -153,6 +154,12 @@ export type ThirdwebLocale = {
wrongPassword: string;
};
invalidEmail: string;
invalidEmailOrPhone: string;
invalidPhone: string;
countryCodeMissing: string;
phonePlaceholder: string;
signInWithPhone: string;
phoneRequired: string;
signIn: string;
signInWithApple: string;
signInWithFacebook: string;
@@ -1,76 +1,79 @@
import styled from "@emotion/styled";
import {
ChevronRightIcon,
EnterIcon,
ExitIcon,
PaperPlaneIcon,
PinBottomIcon,
ShuffleIcon,
TextAlignJustifyIcon,
} from "@radix-ui/react-icons";
import { Localhost } from "@thirdweb-dev/chains";
import {
WalletInstance,
shortenString,
useAddress,
useBalance,
useChain,
useChainId,
useDisconnect,
useENS,
useSDK,
useSupportedChains,
useWallet,
useWalletConfig,
useWalletContext,
} from "@thirdweb-dev/react-core";
import {
MetaMaskWallet,
walletIds,
type EmbeddedWallet,
type SmartWallet,
} from "@thirdweb-dev/wallets";
import { useEffect, useState } from "react";
import { ChainIcon } from "../../components/ChainIcon";
import { CopyIcon } from "../../components/CopyIcon";
import { Img } from "../../components/Img";
import { Modal } from "../../components/Modal";
import { Skeleton } from "../../components/Skeleton";
import { Spacer } from "../../components/Spacer";
import { Container, Line } from "../../components/basic";
import { Button, IconButton } from "../../components/buttons";
import { Link, Text } from "../../components/text";
import {
Theme,
fontSize,
iconSize,
media,
radius,
spacing,
Theme,
} from "../../design-system";
import { useCustomTheme } from "../../design-system/CustomThemeProvider";
import { fadeInAnimation } from "../../design-system/animations";
import { StyledButton, StyledDiv } from "../../design-system/elements";
import {
useEmbeddedWalletUserEmail,
useEmbeddedWalletUserPhoneNumber,
} from "../../evm/hooks/wallets/useEmbeddedWallet";
import { useTWLocale } from "../../evm/providers/locale-provider";
import { isMobile } from "../../evm/utils/isMobile";
import { ExportLocalWallet } from "../wallets/localWallet/ExportLocalWallet";
import type { LocalWalletConfig } from "../wallets/localWallet/types";
import {
NetworkSelectorContent,
type NetworkSelectorProps,
} from "./NetworkSelector";
import styled from "@emotion/styled";
import {
ChevronRightIcon,
EnterIcon,
PaperPlaneIcon,
PinBottomIcon,
ShuffleIcon,
TextAlignJustifyIcon,
ExitIcon,
} from "@radix-ui/react-icons";
import { Localhost } from "@thirdweb-dev/chains";
import {
useChain,
useAddress,
useBalance,
useChainId,
useDisconnect,
useSDK,
useSupportedChains,
useWallet,
WalletInstance,
useENS,
} from "@thirdweb-dev/react-core";
import { useEffect, useState } from "react";
import {
MetaMaskWallet,
type SmartWallet,
walletIds,
type EmbeddedWallet,
} from "@thirdweb-dev/wallets";
import { Container, Line } from "../../components/basic";
import { FundsIcon } from "./icons/FundsIcon";
import { ExportLocalWallet } from "../wallets/localWallet/ExportLocalWallet";
import { useWalletContext } from "@thirdweb-dev/react-core";
import { useWalletConfig } from "@thirdweb-dev/react-core";
import type { LocalWalletConfig } from "../wallets/localWallet/types";
import { fadeInAnimation } from "../../design-system/animations";
import { Link, Text } from "../../components/text";
import { SendFunds } from "./SendFunds";
import { SupportedTokens } from "./defaultTokens";
import { ReceiveFunds } from "./ReceiveFunds";
import { SendFunds } from "./SendFunds";
import { onModalUnmount } from "./constants";
import { SupportedTokens } from "./defaultTokens";
import { FundsIcon } from "./icons/FundsIcon";
import { smartWalletIcon } from "./icons/dataUris";
import { useTWLocale } from "../../evm/providers/locale-provider";
import { shortenString } from "@thirdweb-dev/react-core";
import { StyledButton, StyledDiv } from "../../design-system/elements";
import { useCustomTheme } from "../../design-system/CustomThemeProvider";
import {
appleIconUri,
facebookIconUri,
googleIconUri,
} from "./icons/socialLogins";
import { useEmbeddedWalletUserEmail } from "../../evm/hooks/wallets/useEmbeddedWallet";
import { onModalUnmount } from "./constants";
const TW_CONNECTED_WALLET = "tw-connected-wallet";
@@ -354,7 +357,7 @@ export const ConnectedWalletDetails: React.FC<{
<Container px="lg">
<ConnectedToSmartWallet />
<EmbeddedWalletEmail />
<EmbeddedWalletDetails />
{/* Send and Receive */}
<Container
@@ -813,10 +816,11 @@ function ConnectedToSmartWallet() {
return null;
}
function EmbeddedWalletEmail() {
function EmbeddedWalletDetails() {
const emailQuery = useEmbeddedWalletUserEmail();
const phoneNumberQuery = useEmbeddedWalletUserPhoneNumber();
if (emailQuery.data) {
if (emailQuery.data || phoneNumberQuery.data) {
return (
<Container
flex="row"
@@ -825,7 +829,7 @@ function EmbeddedWalletEmail() {
paddingBottom: spacing.md,
}}
>
<Text size="sm">{emailQuery.data}</Text>
<Text size="sm">{emailQuery.data || phoneNumberQuery.data}</Text>
</Container>
);
}
@@ -0,0 +1,7 @@
// A super basic email validation function that is very forgiving to allow for a wide range emails
export function validateEmail(str: string) {
// <string> + @ + <string> + . + <string>
const emailRegex = /^\S+@\S+\.\S+$/;
return emailRegex.test(str.replace(/\+/g, ""));
}
@@ -1,8 +1,9 @@
import { useState } from "react";
import { Spacer } from "../../components/Spacer";
import { Button } from "../../components/buttons";
import { Text } from "../../components/text";
import { Input } from "../../components/formElements";
import { Text } from "../../components/text";
import { CountrySelector } from "./embeddedWallet/CountrySelector";
export function InputSelectionUI(props: {
onSelect: (data: string) => void;
@@ -12,7 +13,9 @@ export function InputSelectionUI(props: {
errorMessage?: (input: string) => string | undefined;
emptyErrorMessage?: string;
submitButtonText: string;
format?: "phone";
}) {
const [countryCodeInfo, setCountryCodeInfo] = useState("US +1");
const [input, setInput] = useState("");
const [error, setError] = useState<string | undefined>();
const [showError, setShowError] = useState(false);
@@ -23,7 +26,11 @@ export function InputSelectionUI(props: {
return;
}
props.onSelect(input);
props.onSelect(
props.format === "phone"
? `+${countryCodeInfo.split("+")[1]}${input}`
: input,
);
};
const renderingError =
@@ -31,15 +38,31 @@ export function InputSelectionUI(props: {
(!input && !!props.emptyErrorMessage && showError);
return (
<div>
<div
style={{
width: "100%",
}}
>
<div
style={{
position: "relative",
display: "flex",
flexDirection: "row",
gap: "12px",
}}
>
{props.format === "phone" && (
<CountrySelector
countryCode={countryCodeInfo}
setCountryCode={setCountryCodeInfo}
/>
)}
<Input
tabIndex={-1}
placeholder={props.placeholder}
style={{
flexGrow: 1,
}}
variant="outline"
type={props.type}
name={props.name}
@@ -0,0 +1,99 @@
import { useQuery } from "@tanstack/react-query";
import React, { useRef } from "react";
import { fontSize, spacing } from "../../../design-system";
import { useCustomTheme } from "../../../design-system/CustomThemeProvider";
import { StyledSelect } from "../../../design-system/elements";
export function CountrySelector({
countryCode,
setCountryCode,
}: {
countryCode: string;
setCountryCode: React.Dispatch<React.SetStateAction<string>>;
}) {
const selectRef = useRef<HTMLSelectElement>(null);
const { data: supportedCountries } = useQuery({
queryKey: ["supported-sms-countries"],
queryFn: async () => {
const { supportedSmsCountries } = await import(
"@thirdweb-dev/wallets/evm/connectors/embedded-wallet/implementations"
);
return supportedSmsCountries;
},
});
const supportedCountriesForSms = supportedCountries ?? [
{
countryIsoCode: "US",
countryName: "United States",
phoneNumberCode: 1,
},
];
return (
<>
<Select
ref={selectRef}
name="countries"
id="countries"
value={countryCode}
onChange={(e) => {
setCountryCode(e.target.value);
}}
>
<option
style={{
display: "none",
}}
value={countryCode}
>
{countryCode}
</option>
{supportedCountriesForSms.map((country) => {
return (
<option
key={country.countryIsoCode}
value={`${country.countryIsoCode} +${country.phoneNumberCode}`}
>
{country.countryName} +{country.phoneNumberCode}{" "}
</option>
);
})}
</Select>
</>
);
}
export const Select = /* @__PURE__ */ StyledSelect(() => {
const theme = useCustomTheme();
return {
fontSize: fontSize.sm,
display: "block",
padding: spacing.sm,
boxSizing: "border-box",
outline: "none",
border: "none",
borderRadius: "6px",
color: theme.colors.primaryText,
WebkitAppearance: "none",
appearance: "none",
cursor: "pointer",
background: "transparent",
"&::placeholder": {
color: theme.colors.secondaryText,
},
boxShadow: `0 0 0 1.5px ${theme.colors.borderColor}`,
"&:focus, &:hover": {
boxShadow: `0 0 0 2px ${theme.colors.accentText}`,
},
"&[disabled]": {
cursor: "not-allowed",
},
minWidth: "0px",
maxWidth: "90px",
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
};
});
@@ -4,23 +4,25 @@ import {
EmbeddedWallet,
EmbeddedWalletOauthStrategy,
} from "@thirdweb-dev/wallets";
import { useCallback, useContext, useState } from "react";
import { Img } from "../../../components/Img";
import { Spacer } from "../../../components/Spacer";
import { TextDivider } from "../../../components/TextDivider";
import { Container, ModalHeader } from "../../../components/basic";
import { Button } from "../../../components/buttons";
import { fontSize, iconSize, spacing } from "../../../design-system";
import { useTWLocale } from "../../../evm/providers/locale-provider";
import { openOauthSignInWindow } from "../../utils/openOauthSignInWindow";
import { InputSelectionUI } from "../InputSelectionUI";
import { socialIcons } from "./socialIcons";
import type { AuthOption, EmbeddedWalletLoginType } from "./types";
import { useCustomTheme } from "../../../design-system/CustomThemeProvider";
import { useScreenContext } from "../../ConnectWallet/Modal/screen";
import { PoweredByThirdweb } from "../../ConnectWallet/PoweredByTW";
import { useContext } from "react";
import { useTWLocale } from "../../../evm/providers/locale-provider";
import { ModalConfigCtx } from "../../../evm/providers/wallet-ui-states-provider";
import { TOS } from "../../ConnectWallet/Modal/TOS";
import { useScreenContext } from "../../ConnectWallet/Modal/screen";
import { PoweredByThirdweb } from "../../ConnectWallet/PoweredByTW";
import { openOauthSignInWindow } from "../../utils/openOauthSignInWindow";
import { validateEmail } from "../../utils/validateEmail";
import { InputSelectionUI } from "../InputSelectionUI";
import { LinkButton } from "./LinkButton";
import { socialIcons } from "./socialIcons";
import type { AuthOption, EmbeddedWalletLoginType } from "./types";
export const EmbeddedWalletFormUI = (props: {
onSelect: (loginType: EmbeddedWalletLoginType) => void;
@@ -45,10 +47,46 @@ export const EmbeddedWalletFormUI = (props: {
apple: locale.signInWithApple,
};
const enableEmailLogin = props.authOptions.includes("email");
const emailIndex = props.authOptions.indexOf("email");
const isEmailEnabled = emailIndex !== -1;
const phoneIndex = props.authOptions.indexOf("phone");
const isPhoneEnabled = phoneIndex !== -1;
const selectDefaultInputMode = () => {
if (isEmailEnabled && isPhoneEnabled) {
return emailIndex < phoneIndex ? "email" : "phone";
} else if (isEmailEnabled) {
return "email";
} else if (isPhoneEnabled) {
return "phone";
}
return "none";
};
const [inputMode, setInputMode] = useState<"email" | "phone" | "none">(
selectDefaultInputMode(),
);
const placeholder =
inputMode === "email" ? locale.emailPlaceholder : locale.phonePlaceholder;
const emptyErrorMessage =
inputMode === "email" ? locale.emailRequired : locale.phoneRequired;
let type = "text";
if (inputMode === "email") {
type = "email";
} else if (inputMode === "phone") {
type = "tel";
}
const switchInputModeText =
inputMode === "email" ? locale.signInWithPhone : locale.signInWithEmail;
const switchInputMode = useCallback(() => {
setInputMode((prev) => (prev === "email" ? "phone" : "email"));
}, []);
const allowSwitchInputMode = isEmailEnabled && isPhoneEnabled;
const socialLogins = props.authOptions.filter(
(x) => x !== "email",
(x) => x !== "email" && x !== "phone",
) as EmbeddedWalletOauthStrategy[];
const hasSocialLogins = socialLogins.length > 0;
@@ -83,7 +121,13 @@ export const EmbeddedWalletFormUI = (props: {
const showOnlyIcons = socialLogins.length > 1;
return (
<Container flex="column" gap="lg">
<Container
flex="column"
gap="lg"
style={{
position: "relative",
}}
>
{/* Social Login */}
{hasSocialLogins && (
<Container
@@ -120,29 +164,62 @@ export const EmbeddedWalletFormUI = (props: {
</Container>
)}
{props.modalSize === "wide" && hasSocialLogins && enableEmailLogin && (
{props.modalSize === "wide" && hasSocialLogins && isEmailEnabled && (
<TextDivider text={twLocale.connectWallet.or} />
)}
{/* Email Login */}
{enableEmailLogin && (
<InputSelectionUI
onSelect={(email) => props.onSelect({ email })}
placeholder={locale.emailPlaceholder}
name="email"
type="email"
errorMessage={(_input) => {
const input = _input.replace(/\+/g, "").toLowerCase();
const emailRegex =
/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,})$/g;
const isValidEmail = emailRegex.test(input);
if (!isValidEmail) {
return locale.invalidEmail;
}
}}
emptyErrorMessage={locale.emailRequired}
submitButtonText={locale.submitEmail}
/>
{inputMode !== "none" && (
<Container>
{inputMode === "email" ? (
<InputSelectionUI
type={type}
onSelect={(value) => {
props.onSelect({ email: value });
}}
placeholder={placeholder}
name="email"
errorMessage={(input) => {
const isValidEmail = validateEmail(input.toLowerCase());
if (!isValidEmail) {
return locale.invalidEmail;
}
}}
emptyErrorMessage={emptyErrorMessage}
submitButtonText={locale.submitEmail}
/>
) : (
<InputSelectionUI
format="phone"
type={type}
onSelect={(value) => {
// removes white spaces and special characters
props.onSelect({ phone: value.replace(/[-\(\) ]/g, "") });
}}
placeholder={placeholder}
name="phone"
errorMessage={(_input) => {
// removes white spaces and special characters
const input = _input.replace(/[-\(\) ]/g, "");
const isPhone = /^[0-9]+$/.test(input);
if (!isPhone && isPhoneEnabled) {
return locale.invalidPhone;
}
}}
emptyErrorMessage={emptyErrorMessage}
submitButtonText={locale.submitEmail}
/>
)}
{allowSwitchInputMode && (
<>
<Spacer y="md" />
<LinkButton onClick={switchInputMode} type="button">
{switchInputModeText}
</LinkButton>
</>
)}
</Container>
)}
</Container>
);
@@ -158,7 +235,7 @@ export const EmbeddedWalletFormUIScreen: React.FC<{
setConnectionStatus: ConnectUIProps<EmbeddedWallet>["setConnectionStatus"];
setConnectedWallet: ConnectUIProps<EmbeddedWallet>["setConnectedWallet"];
}> = (props) => {
const locale = useTWLocale().wallets.embeddedWallet.emailLoginScreen;
const locale = useTWLocale().wallets.embeddedWallet.otpLoginScreen;
const isCompact = props.modalSize === "compact";
const { initialScreen, screen } = useScreenContext();
const modalConfig = useContext(ModalConfigCtx);
@@ -1,5 +1,9 @@
import { ConnectUIProps } from "@thirdweb-dev/react-core";
import { EmbeddedWallet, SendEmailOtpReturnType } from "@thirdweb-dev/wallets";
import {
EmbeddedWallet,
SendEmailOtpReturnType,
type AuthResult,
} from "@thirdweb-dev/wallets";
import { useCallback, useEffect, useRef, useState } from "react";
import { FadeIn } from "../../../components/FadeIn";
import { OTPInput } from "../../../components/OTPInput";
@@ -8,12 +12,10 @@ import { Spinner } from "../../../components/Spinner";
import { Container, Line, ModalHeader } from "../../../components/basic";
import { Button } from "../../../components/buttons";
import { Text } from "../../../components/text";
import { fontSize } from "../../../design-system";
import { useTWLocale } from "../../../evm/providers/locale-provider";
import { LinkButton } from "./LinkButton";
import { CreatePassword } from "./USER_MANAGED/CreatePassword";
import { EnterPasswordOrRecovery } from "./USER_MANAGED/EnterPassword";
import { useTWLocale } from "../../../evm/providers/locale-provider";
import { StyledButton } from "../../../design-system/elements";
import { useCustomTheme } from "../../../design-system/CustomThemeProvider";
type EmbeddedWalletOTPLoginUIProps = ConnectUIProps<EmbeddedWallet>;
@@ -23,16 +25,20 @@ type VerificationStatus =
| "valid"
| "idle"
| "payment_required";
type EmailStatus = "sending" | SendEmailOtpReturnType | "error";
type AccountStatus = "sending" | SendEmailOtpReturnType | "error";
type ScreenToShow =
| "base"
| "create-password"
| "enter-password-or-recovery-code";
export const EmbeddedWalletOTPLoginUI: React.FC<
EmbeddedWalletOTPLoginUIProps
EmbeddedWalletOTPLoginUIProps & {
userInfo: { email: string } | { phone: string };
}
> = (props) => {
const email = props.selectionData;
const { userInfo } = props;
const isWideModal = props.modalSize === "wide";
const locale = useTWLocale().wallets.embeddedWallet;
@@ -42,35 +48,45 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
const [wallet, setWallet] = useState<EmbeddedWallet | null>(null);
const [verifyStatus, setVerifyStatus] = useState<VerificationStatus>("idle");
const [emailStatus, setEmailStatus] = useState<EmailStatus>("sending");
const [accountStatus, setAccountStatus] = useState<AccountStatus>("sending");
const [screen, setScreen] = useState<ScreenToShow>("base");
const sendEmail = useCallback(async () => {
const sendEmailOrSms = useCallback(async () => {
setOtpInput("");
setVerifyStatus("idle");
setEmailStatus("sending");
setAccountStatus("sending");
try {
const _wallet = createWalletInstance();
setWallet(_wallet);
const status = await _wallet.sendVerificationEmail({ email });
setEmailStatus(status);
if ("email" in userInfo) {
const status = await _wallet.sendVerificationEmail({
email: userInfo.email,
});
setAccountStatus(status);
} else {
const status = await _wallet.sendVerificationSms({
phoneNumber: userInfo.phone,
});
setAccountStatus(status);
}
} catch (e) {
console.error(e);
setVerifyStatus("idle");
setEmailStatus("error");
setAccountStatus("error");
}
}, [createWalletInstance, email]);
}, [createWalletInstance, userInfo]);
const verify = async (otp: string) => {
if (typeof emailStatus !== "object" || otp.length !== 6) {
if (typeof accountStatus !== "object" || otp.length !== 6) {
return;
}
setVerifyStatus("idle");
if (typeof emailStatus !== "object") {
if (typeof accountStatus !== "object") {
return;
}
@@ -83,20 +99,28 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
setConnectionStatus("connecting");
const needsRecoveryCode =
emailStatus.recoveryShareManagement === "USER_MANAGED" &&
(emailStatus.isNewUser || emailStatus.isNewDevice);
accountStatus.recoveryShareManagement === "USER_MANAGED" &&
(accountStatus.isNewUser || accountStatus.isNewDevice);
// USER_MANAGED
if (needsRecoveryCode) {
if (emailStatus.isNewUser) {
if (accountStatus.isNewUser) {
try {
// verifies otp for UI feedback
// TODO (ews) tweak the UI flow to avoid verifying otp twice - needs new endpoint or new UI
await wallet.authenticate({
strategy: "email_verification",
email,
verificationCode: otp,
});
if ("email" in userInfo) {
await wallet.authenticate({
strategy: "email_verification",
email: userInfo.email,
verificationCode: otp,
});
} else {
await wallet.authenticate({
strategy: "phone_number_verification",
phoneNumber: userInfo.phone,
verificationCode: otp,
});
}
} catch (e: any) {
if (e instanceof Error && e.message.includes("encryption key")) {
setScreen("create-password");
@@ -107,11 +131,19 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
} else {
try {
// verifies otp for UI feedback
await wallet.authenticate({
strategy: "email_verification",
email,
verificationCode: otp,
});
if ("email" in userInfo) {
await wallet.authenticate({
strategy: "email_verification",
email: userInfo.email,
verificationCode: otp,
});
} else {
await wallet.authenticate({
strategy: "phone_number_verification",
phoneNumber: userInfo.phone,
verificationCode: otp,
});
}
} catch (e: any) {
if (e instanceof Error && e.message.includes("encryption key")) {
setScreen("enter-password-or-recovery-code");
@@ -124,11 +156,21 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
// AWS_MANAGED
else {
const authResult = await wallet.authenticate({
strategy: "email_verification",
email,
verificationCode: otp,
});
let authResult: AuthResult;
if ("email" in userInfo) {
authResult = await wallet.authenticate({
strategy: "email_verification",
email: userInfo.email,
verificationCode: otp,
});
} else {
authResult = await wallet.authenticate({
strategy: "phone_number_verification",
phoneNumber: userInfo.phone,
verificationCode: otp,
});
}
if (!authResult) {
throw new Error("Failed to verify OTP");
}
@@ -155,26 +197,37 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
useEffect(() => {
if (!emailSentOnMount.current) {
emailSentOnMount.current = true;
sendEmail();
sendEmailOrSms();
}
}, [sendEmail]);
}, [sendEmailOrSms]);
if (screen === "create-password") {
return (
<CreatePassword
modalSize={props.modalSize}
email={email}
goBack={props.goBack}
onPassword={async (password) => {
if (!wallet || typeof emailStatus !== "object") {
if (!wallet || typeof accountStatus !== "object") {
return;
}
const authResult = await wallet.authenticate({
strategy: "email_verification",
email,
verificationCode: otpInput,
recoveryCode: password,
});
let authResult: AuthResult;
if ("email" in userInfo) {
authResult = await wallet.authenticate({
strategy: "email_verification",
email: userInfo.email,
verificationCode: otpInput,
recoveryCode: password,
});
} else {
authResult = await wallet.authenticate({
strategy: "phone_number_verification",
phoneNumber: userInfo.phone,
verificationCode: otpInput,
recoveryCode: password,
});
}
if (!authResult) {
throw new Error("Failed to verify recovery code");
}
@@ -193,17 +246,29 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
<EnterPasswordOrRecovery
modalSize={props.modalSize}
goBack={props.goBack}
email={email}
emailOrPhone={"email" in userInfo ? userInfo.email : userInfo.phone}
onVerify={async (passwordOrRecoveryCode) => {
if (!wallet || typeof emailStatus !== "object") {
if (!wallet || typeof accountStatus !== "object") {
return;
}
const authResult = await wallet.authenticate({
strategy: "email_verification",
email,
verificationCode: otpInput,
recoveryCode: passwordOrRecoveryCode,
});
let authResult: AuthResult;
if ("email" in userInfo) {
authResult = await wallet.authenticate({
strategy: "email_verification",
email: userInfo.email,
verificationCode: otpInput,
recoveryCode: passwordOrRecoveryCode,
});
} else {
authResult = await wallet.authenticate({
strategy: "phone_number_verification",
phoneNumber: userInfo.phone,
verificationCode: otpInput,
recoveryCode: passwordOrRecoveryCode,
});
}
if (!authResult) {
throw new Error("Failed to verify recovery code");
}
@@ -233,9 +298,11 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
>
<Container flex="column" center="x" px="lg">
{!isWideModal && <Spacer y="xl" />}
<Text>{locale.emailLoginScreen.enterCodeSendTo}</Text>
<Text>{locale.otpLoginScreen.enterCodeSendTo}</Text>
<Spacer y="sm" />
<Text color="primaryText">{email}</Text>
<Text color="primaryText">
{"email" in userInfo ? userInfo.email : userInfo.phone}
</Text>
<Spacer y="xl" />
</Container>
@@ -257,7 +324,7 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
<FadeIn>
<Spacer y="md" />
<Text size="sm" color="danger" center>
{locale.emailLoginScreen.invalidCode}
{locale.otpLoginScreen.invalidCode}
</Text>
</FadeIn>
)}
@@ -290,7 +357,7 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
width: "100%",
}}
>
{locale.emailLoginScreen.verify}
{locale.otpLoginScreen.verify}
</Button>
</Container>
)}
@@ -301,15 +368,15 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
{!isWideModal && <Line />}
<Container p={isWideModal ? undefined : "lg"}>
{emailStatus === "error" && (
{accountStatus === "error" && (
<>
<Text size="sm" center color="danger">
{locale.emailLoginScreen.failedToSendCode}
{locale.otpLoginScreen.failedToSendCode}
</Text>
</>
)}
{emailStatus === "sending" && (
{accountStatus === "sending" && (
<Container
flex="row"
center="both"
@@ -318,14 +385,14 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
textAlign: "center",
}}
>
<Text size="sm">{locale.emailLoginScreen.sendingCode}</Text>
<Text size="sm">{locale.otpLoginScreen.sendingCode}</Text>
<Spinner size="xs" color="secondaryText" />
</Container>
)}
{typeof emailStatus === "object" && (
<LinkButton onClick={sendEmail} type="button">
{locale.emailLoginScreen.resendCode}
{typeof accountStatus === "object" && (
<LinkButton onClick={sendEmailOrSms} type="button">
{locale.otpLoginScreen.resendCode}
</LinkButton>
)}
</Container>
@@ -337,19 +404,3 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
return null;
};
const LinkButton = /* @__PURE__ */ StyledButton(() => {
const theme = useCustomTheme();
return {
all: "unset",
color: theme.colors.accentText,
fontSize: fontSize.sm,
cursor: "pointer",
textAlign: "center",
fontWeight: 500,
width: "100%",
"&:hover": {
color: theme.colors.primaryText,
},
};
});
@@ -0,0 +1,19 @@
import { fontSize } from "../../../design-system";
import { useCustomTheme } from "../../../design-system/CustomThemeProvider";
import { StyledButton } from "../../../design-system/elements";
export const LinkButton = /* @__PURE__ */ StyledButton(() => {
const theme = useCustomTheme();
return {
all: "unset",
color: theme.colors.accentText,
fontSize: fontSize.sm,
cursor: "pointer",
textAlign: "center",
fontWeight: 500,
width: "100%",
"&:hover": {
color: theme.colors.primaryText,
},
};
});
@@ -24,7 +24,6 @@ import { useCustomTheme } from "../../../../design-system/CustomThemeProvider";
export function CreatePassword(props: {
goBack: () => void;
email: string;
onPassword: (password: string) => Promise<void>;
modalSize: "wide" | "compact";
}) {
@@ -11,7 +11,7 @@ import { useTWLocale } from "../../../../evm/providers/locale-provider";
export function EnterPasswordOrRecovery(props: {
goBack: () => void;
onVerify: (password: string) => void;
email: string;
emailOrPhone: string;
modalSize: "wide" | "compact";
}) {
const locale = useTWLocale().wallets.embeddedWallet.enterPassword;
@@ -55,7 +55,7 @@ export function EnterPasswordOrRecovery(props: {
<Text center>{locale.instruction}</Text>
<Spacer y="sm" />
<Text center color="primaryText">
{props.email}
{props.emailOrPhone}
</Text>
<Spacer y="xl" />
@@ -23,6 +23,7 @@ import {
} from "./types";
const DEFAULT_AUTH_OPTIONS: AuthOption[] = [
"phone",
"email",
"google",
"apple",
@@ -70,38 +71,50 @@ const DEFAULT_AUTH_OPTIONS: AuthOption[] = [
export const embeddedWallet = (
options?: EmbeddedWalletConfigOptions,
): WalletConfig<EmbeddedWallet> => {
const defaultConfig: EmbeddedWalletConfigOptions = {
auth: {
options: DEFAULT_AUTH_OPTIONS,
},
};
const authOptions = options?.auth?.options ?? DEFAULT_AUTH_OPTIONS;
const finalOptions: EmbeddedWalletConfigOptions = options
? { ...defaultConfig, ...options }
: defaultConfig;
const isEmailEnabled = authOptions.indexOf("email") !== -1;
const isPhoneEnabled = authOptions.indexOf("phone") !== -1;
const isSocialsEnabled = authOptions.some(
(x) => x !== "email" && x !== "phone",
);
const { auth } = finalOptions;
function getName() {
// only email
if (isEmailEnabled && !isPhoneEnabled && !isSocialsEnabled) {
return "Email";
}
let name = "Email & Socials";
// only phone
if (isPhoneEnabled && !isEmailEnabled && !isSocialsEnabled) {
return "Phone";
}
// if only email is enabled, show the name as "Email"
if (
finalOptions?.auth?.options.length === 1 &&
finalOptions.auth.options[0] === "email"
) {
name = "Email";
// only phone + email
if (isPhoneEnabled && isEmailEnabled && !isSocialsEnabled) {
return "Email & Phone";
}
// only phone + socials
if (isPhoneEnabled && isSocialsEnabled && !isEmailEnabled) {
return "Phone & Socials";
}
// only email + socials
if (isEmailEnabled && isSocialsEnabled && !isPhoneEnabled) {
return "Email & Socials";
}
return "Social Login";
}
// if email is not enabled, show the name as "Social Login"
if (finalOptions?.auth?.options.indexOf("email") === -1) {
name = "Social Login";
}
const name = getName();
return {
category: "socialLogin",
isHeadless: true,
id: EmbeddedWallet.id,
recommended: finalOptions?.recommended,
recommended: options?.recommended,
meta: {
...EmbeddedWallet.meta,
name,
@@ -110,25 +123,14 @@ export const embeddedWallet = (
create(walletOptions: WalletOptions) {
return new EmbeddedWallet({
...walletOptions,
...finalOptions,
clientId: walletOptions?.clientId ?? "",
});
},
selectUI(props) {
return (
<EmbeddedWalletSelectionUI
{...props}
authOptions={auth ? auth?.options : DEFAULT_AUTH_OPTIONS}
/>
);
return <EmbeddedWalletSelectionUI {...props} authOptions={authOptions} />;
},
connectUI(props) {
return (
<EmbeddedWalletConnectUI
{...props}
authOptions={auth ? auth?.options : DEFAULT_AUTH_OPTIONS}
/>
);
return <EmbeddedWalletConnectUI {...props} authOptions={authOptions} />;
},
};
};
@@ -198,7 +200,7 @@ const EmbeddedWalletConnectUI = (
return (
<EmbeddedWalletOTPLoginUI
{...props}
selectionData={loginType.email}
userInfo={loginType}
goBack={handleBack}
/>
);
@@ -3,7 +3,7 @@ import type {
EmbeddedWalletOauthStrategy,
} from "@thirdweb-dev/wallets";
export type AuthOption = EmbeddedWalletOauthStrategy | "email";
export type AuthOption = EmbeddedWalletOauthStrategy | "email" | "phone";
/**
* @wallet
@@ -35,4 +35,5 @@ export type EmbeddedWalletConfigOptions = Omit<
export type EmbeddedWalletLoginType =
| { email: string }
| { phone: string }
| EmbeddedWalletOauthStrategy;
@@ -38,6 +38,7 @@ import {
twitterIconUri,
} from "../../ConnectWallet/icons/socialLogins";
import { useCustomTheme } from "../../../design-system/CustomThemeProvider";
import { validateEmail } from "../../utils/validateEmail";
/**
* @wallet
@@ -353,9 +354,7 @@ const MagicUI: React.FC<{
const isPhone = Number.isInteger(Number(input[input.length - 1]));
if (isEmail && isEmailEnabled) {
const emailRegex =
/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,})$/g;
const isValidEmail = emailRegex.test(input.replace(/\+/g, ""));
const isValidEmail = validateEmail(input);
if (!isValidEmail) {
return locale.invalidEmail;
}
Binary file not shown.

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