Compare commits

...
Author SHA1 Message Date
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>GitHub Action
d33227ab2b Version Packages (#2282)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <[email protected]>
2024-02-09 17:37:26 -08:00
Joaquim VergesandGitHub 53786fc306 [SDK] memoize extensions (#2291) 2024-02-10 01:00:42 +00:00
Manan TankandGitHub f85806c067 Update EmbeddedWallet name in CW (#2290) 2024-02-09 22:40:40 +00:00
Manan TankandGitHub 0155adcea4 Show EmbeddedWallet UI as initial screen in CW (#2289) 2024-02-09 20:57:32 +00:00
Manan TankandGitHub 74d76ff580 Add "Powered By Thirdweb" Branding in CW (#2288) 2024-02-09 16:32:27 +00:00
farhanW3andGitHub 537e5e063d [Usage]: Usage Schema to have new field (#2287) 2024-02-09 00:47:33 +00:00
Isaac DubuqueandGitHub a86478bf24 add sdk support for engine relayer options (#2233) 2024-02-09 00:40:52 +00:00
Joaquim VergesandGitHub 09de55f13c [SDK] Export MerkleTree helper functions (#2286) 2024-02-08 22:43:13 +00:00
23d0e55308 chore(chains): update chains (#2280)
Co-authored-by: GitHub Action <[email protected]>
2024-02-08 09:44:22 -08:00
FirekeeperandGitHub 185093c185 Unity 4.6.2 (#2284) 2024-02-08 14:35:00 +00:00
farhanW3andGitHub 77400fcf21 Added new properties to usage (#2281) 2024-02-08 01:34:19 +00:00
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>GitHub Action
6a41fe9829 Version Packages (#2274)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <[email protected]>
2024-02-07 13:11:26 -08:00
0092e2a317 fix(auth): Next.js App Router handler return type (#2278)
Signed-off-by: Jonas Daniels <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2024-02-07 12:47:09 -08:00
87b9e6d42d chore(chains): update chains (#2279)
Co-authored-by: GitHub Action <[email protected]>
2024-02-07 10:29:29 -08:00
github-actions[bot]andGitHub 336dfd3b37 chore(chains): update chains (#2277) 2024-02-07 08:52:01 -08:00
957c75a36e chore(chains): update chains (#2276)
Co-authored-by: GitHub Action <[email protected]>
2024-02-06 22:27:49 -08:00
357886e31b chore(chains): update chains (#2258)
Co-authored-by: GitHub Action <[email protected]>
2024-02-06 15:46:46 -08:00
DustinandGitHub 330c270f3c Update .env.example (#2272) 2024-02-06 13:52:51 -08:00
Joaquim VergesandGitHub 9096bdc0f1 [ServiceUtils] Add latency prop to CF worker logs (#2273) 2024-02-06 21:44:43 +00:00
saminaandGitHub 62ef83c9e0 Update pull_request_template.md (#2267)
Signed-off-by: samina <[email protected]>
2024-02-06 18:15:54 +00:00
100 changed files with 1926 additions and 487 deletions
+2 -1
View File
@@ -3,4 +3,5 @@
# used for unit tests that hit real IPFS gateway
# get a secret key from https://thirdweb.com/create-api-key
TW_SECRET_KEY=""
# Learn more about API keys. https://portal.thirdweb.com/account/api-keys
TW_SECRET_KEY=""
+6
View File
@@ -11,3 +11,9 @@ Short description of the bug fixed or feature added
- [ ] Automated tests: link to unit test file
- [ ] Manual tests: step by step instructions on how to test
## Contributor NFT
Paste in your wallet address below and we will airdrop you a special NFT when your pull request is merged.
```Address: ```
+16
View File
@@ -1,5 +1,21 @@
# @thirdweb-dev/auth
## 4.1.32
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.4.10
## 4.1.31
### Patch Changes
- [#2278](https://github.com/thirdweb-dev/js/pull/2278) [`0092e2a3`](https://github.com/thirdweb-dev/js/commit/0092e2a3177364ad26af15ecafb4381591dc9be1) Thanks [@hsynlms](https://github.com/hsynlms)! - fix(auth): Next.js App Router handler return type
- Updated dependencies []:
- @thirdweb-dev/wallets@2.4.9
## 4.1.30
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "4.1.30",
"version": "4.1.32",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
+2 -7
View File
@@ -58,13 +58,8 @@ export function ThirdwebAuth<
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain),
};
async function ThirdwebAuthHandler(...args: [] | [NextRequest, ThirdwebNextContext]) {
if (args.length === 0) {
return async (req: NextRequest, ctx: ThirdwebNextContext): Promise<void | Response> =>
await ThirdwebAuthRouter(req, ctx, authCtx as ThirdwebAuthContext);
}
return ThirdwebAuthRouter(args[0], args[1], authCtx as ThirdwebAuthContext);
async function ThirdwebAuthHandler(req: NextRequest, ctx: ThirdwebNextContext) {
return await ThirdwebAuthRouter(req, ctx, authCtx as ThirdwebAuthContext);
}
return {
+12
View File
@@ -1,5 +1,17 @@
# @thirdweb-dev/chains
## 0.1.72
### Patch Changes
- [#2280](https://github.com/thirdweb-dev/js/pull/2280) [`23d0e553`](https://github.com/thirdweb-dev/js/commit/23d0e553088321edfe3971950c2e7f27209d9aaf) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
## 0.1.71
### Patch Changes
- [#2258](https://github.com/thirdweb-dev/js/pull/2258) [`357886e3`](https://github.com/thirdweb-dev/js/commit/357886e31b37aad950731ce8f013a101190ebd07) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
## 0.1.70
### Patch Changes
+1 -1
View File
@@ -31,5 +31,5 @@ export default {
"shortName": "Baobab",
"slip44": 1,
"slug": "klaytn-testnet-baobab",
"testnet": true
"testnet": false
} as const satisfies Chain;
+13 -2
View File
@@ -2,8 +2,20 @@ import type { Chain } from "../src/types";
export default {
"chain": "Dymension",
"chainId": 1100,
"explorers": [],
"explorers": [
{
"name": "dym.fyi",
"url": "https://dym.fyi",
"standard": "EIP3091"
}
],
"faucets": [],
"icon": {
"url": "ipfs://bafkreic4sjyqikz33xzpcctczvkiwfj44q5i3i7zslycnjiqmyx5ybc3fi",
"width": 1200,
"height": 1200,
"format": "png"
},
"infoURL": "https://dymension.xyz",
"name": "Dymension",
"nativeCurrency": {
@@ -19,6 +31,5 @@ export default {
],
"shortName": "dymension",
"slug": "dymension",
"status": "incubating",
"testnet": false
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 12001,
"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": "Mikias's Testnet",
"nativeCurrency": {
"name": "Mikias's Testnet Token",
"symbol": "XVL",
"decimals": 18
},
"networkId": 12001,
"redFlags": [],
"rpc": [
"https://mikias-s-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://12001.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-test.io/c3c8cc74-5101-4380-937f-4f534cad0128"
],
"shortName": "Mikias's Testnet",
"slug": "mikias-s-testnet",
"testnet": true
} as const satisfies Chain;
@@ -1,7 +1,7 @@
import type { Chain } from "../src/types";
export default {
"chain": "XRPL",
"chainId": 1440001,
"chainId": 1440002,
"explorers": [
{
"name": "XRP Ledger Explorer",
@@ -23,11 +23,11 @@ export default {
"symbol": "XRP",
"decimals": 18
},
"networkId": 1440001,
"networkId": 1440002,
"redFlags": [],
"rpc": [
"https://xrp-ledger-evm-devnet-sidechain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://1440001.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://1440002.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-evm-sidechain.xrpl.org"
],
"shortName": "XRPL-EVM-Devnet-Sidechain",
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 15056,
"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": "QI M 2402052",
"nativeCurrency": {
"name": "QI M 2402052 Token",
"symbol": "ACI",
"decimals": 18
},
"networkId": 15056,
"redFlags": [],
"rpc": [
"https://qi-m-2402052.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://15056.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/c908add6-74c5-4407-8091-18762786a0b9"
],
"shortName": "QI M 2402052",
"slug": "qi-m-2402052",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 15104,
"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": "QI M 2402054",
"nativeCurrency": {
"name": "QI M 2402054 Token",
"symbol": "ACI",
"decimals": 18
},
"networkId": 15104,
"redFlags": [],
"rpc": [
"https://qi-m-2402054.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://15104.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/c908add6-74c5-4407-8091-18762786a0b9"
],
"shortName": "QI M 2402054",
"slug": "qi-m-2402054",
"testnet": true
} as const satisfies Chain;
-36
View File
@@ -1,36 +0,0 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 167005,
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.test.taiko.xyz",
"standard": "EIP3091"
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmcHdmVr5VRUJq13jnM6tgah5Ge7hn3Dm14eY6vwivJ5ui",
"width": 288,
"height": 258,
"format": "png"
},
"infoURL": "https://taiko.xyz",
"name": "Taiko Grimsvotn L2",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 167005,
"rpc": [
"https://taiko-grimsvotn-l2.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://167005.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.test.taiko.xyz"
],
"shortName": "taiko-l2",
"slug": "taiko-grimsvotn-l2",
"status": "deprecated",
"testnet": true
} as const satisfies Chain;
-36
View File
@@ -1,36 +0,0 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 167006,
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.l3test.taiko.xyz",
"standard": "EIP3091"
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmcHdmVr5VRUJq13jnM6tgah5Ge7hn3Dm14eY6vwivJ5ui",
"width": 288,
"height": 258,
"format": "png"
},
"infoURL": "https://taiko.xyz",
"name": "Taiko Eldfell L3",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 167006,
"rpc": [
"https://taiko-eldfell-l3.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://167006.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.l3test.taiko.xyz"
],
"shortName": "taiko-l3",
"slug": "taiko-eldfell-l3",
"status": "deprecated",
"testnet": true
} as const satisfies Chain;
-36
View File
@@ -1,36 +0,0 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 167007,
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.jolnir.taiko.xyz",
"standard": "EIP3091"
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmcHdmVr5VRUJq13jnM6tgah5Ge7hn3Dm14eY6vwivJ5ui",
"width": 288,
"height": 258,
"format": "png"
},
"infoURL": "https://taiko.xyz",
"name": "Taiko Jolnir L2",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 167007,
"rpc": [
"https://taiko-jolnir-l2.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://167007.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.jolnir.taiko.xyz"
],
"shortName": "tko-jolnir",
"slug": "taiko-jolnir-l2",
"status": "deprecated",
"testnet": false
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 234560,
"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": "Project Orc",
"nativeCurrency": {
"name": "Project Orc Token",
"symbol": "STX",
"decimals": 18
},
"networkId": 234560,
"redFlags": [],
"rpc": [
"https://project-orc.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://234560.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/projectorc/testnet/rpc"
],
"shortName": "Project Orc",
"slug": "project-orc",
"testnet": true
} as const satisfies Chain;
+41
View File
@@ -0,0 +1,41 @@
import type { Chain } from "../src/types";
export default {
"chain": "Elizabeth",
"chainId": 2731,
"explorers": [
{
"name": "Time Network Explorer",
"url": "https://testnet-scanner.timenetwork.io",
"standard": "none",
"icon": {
"url": "ipfs://bafkreidoudwo453gr3hoxpreleguga73rm55yl6vuedxrfmhknljppqbiu",
"width": 512,
"height": 512,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://bafkreidoudwo453gr3hoxpreleguga73rm55yl6vuedxrfmhknljppqbiu",
"width": 512,
"height": 512,
"format": "png"
},
"infoURL": "https://whitepaper.anttime.net/overview/anttime",
"name": "Elizabeth Testnet",
"nativeCurrency": {
"name": "TIME",
"symbol": "TIME",
"decimals": 18
},
"networkId": 2731,
"rpc": [
"https://elizabeth-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://2731.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-rpc.timenetwork.io"
],
"shortName": "TIME",
"slug": "elizabeth-testnet",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 29442,
"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": "QI M 2402055",
"nativeCurrency": {
"name": "QI M 2402055 Token",
"symbol": "ACI",
"decimals": 18
},
"networkId": 29442,
"redFlags": [],
"rpc": [
"https://qi-m-2402055.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://29442.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/c908add6-74c5-4407-8091-18762786a0b9"
],
"shortName": "QI M 2402055",
"slug": "qi-m-2402055",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 30266,
"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": "Tnet02-06",
"nativeCurrency": {
"name": "Tnet02-06 Token",
"symbol": "LFC",
"decimals": 18
},
"networkId": 30266,
"redFlags": [],
"rpc": [
"https://tnet02-06.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://30266.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "Tnet02-06",
"slug": "tnet02-06",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 32277,
"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": "QI M 2402058",
"nativeCurrency": {
"name": "QI M 2402058 Token",
"symbol": "ACI",
"decimals": 18
},
"networkId": 32277,
"redFlags": [],
"rpc": [
"https://qi-m-2402058.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://32277.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/c908add6-74c5-4407-8091-18762786a0b9"
],
"shortName": "QI M 2402058",
"slug": "qi-m-2402058",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 37375,
"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": "QI M 2402057",
"nativeCurrency": {
"name": "QI M 2402057 Token",
"symbol": "ACI",
"decimals": 18
},
"networkId": 37375,
"redFlags": [],
"rpc": [
"https://qi-m-2402057.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://37375.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/c908add6-74c5-4407-8091-18762786a0b9"
],
"shortName": "QI M 2402057",
"slug": "qi-m-2402057",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 37767,
"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": "Tnet 01-15",
"nativeCurrency": {
"name": "Tnet 01-15 Token",
"symbol": "LFC",
"decimals": 18
},
"networkId": 37767,
"redFlags": [],
"rpc": [
"https://tnet-01-15.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://37767.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "Tnet 01-15",
"slug": "tnet-01-15",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 41077,
"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": "REALLY",
"nativeCurrency": {
"name": "REALLY Token",
"symbol": "FAN",
"decimals": 18
},
"networkId": 41077,
"redFlags": [],
"rpc": [
"https://really.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://41077.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/really/testnet/rpc"
],
"shortName": "REALLY",
"slug": "really",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 41425,
"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": "QR0205I1",
"nativeCurrency": {
"name": "QR0205I1 Token",
"symbol": "PVW",
"decimals": 18
},
"networkId": 41425,
"redFlags": [],
"rpc": [
"https://qr0205i1.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://41425.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/qr0205i1/testnet/rpc"
],
"shortName": "QR0205I1",
"slug": "qr0205i1",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 41604,
"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": "Testnet",
"nativeCurrency": {
"name": "Testnet Token",
"symbol": "LFC",
"decimals": 18
},
"networkId": 41604,
"redFlags": [],
"rpc": [
"https://testnet-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://41604.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "Testnet",
"slug": "testnet-testnet",
"testnet": true
} as const satisfies Chain;
+42
View File
@@ -0,0 +1,42 @@
import type { Chain } from "../src/types";
export default {
"chain": "Merlin",
"chainId": 4200,
"explorers": [
{
"name": "blockscout",
"url": "https://scan.merlinchain.io",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmULpMFUvKSmJT8sWXS3WDnTm4EacgRbsEynDenpxcfrAj",
"width": 400,
"height": 400,
"format": "jpg"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmULpMFUvKSmJT8sWXS3WDnTm4EacgRbsEynDenpxcfrAj",
"width": 400,
"height": 400,
"format": "jpg"
},
"infoURL": "https://merlinchain.io",
"name": "Merlin Mainnet",
"nativeCurrency": {
"name": "BTC",
"symbol": "BTC",
"decimals": 18
},
"networkId": 4200,
"rpc": [
"https://merlin.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://4200.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.merlinchain.io"
],
"shortName": "Merlin-Mainnet",
"slug": "merlin",
"testnet": false,
"title": "Merlin Mainnet"
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 48702,
"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": "Testnet",
"nativeCurrency": {
"name": "Testnet Token",
"symbol": "LUG",
"decimals": 18
},
"networkId": 48702,
"redFlags": [],
"rpc": [
"https://testnet-testnet-48702.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://48702.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "Testnet",
"slug": "testnet-testnet-48702",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Syndicate",
"chainId": 510,
"explorers": [],
"faucets": [],
"icon": {
"url": "ipfs://QmeSvQcD3XvLFAiMLoQSPbGK9JxVfbCWPBUTMLhhhzYPqX",
"width": 16000,
"height": 16000,
"format": "png"
},
"infoURL": "https://syndicate.io",
"name": "Syndicate Chain",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 510,
"rpc": [
"https://syndicate-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://510.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-mainnet.syndicate.io"
],
"shortName": "syndicate-chain-mainnet",
"slug": "syndicate-chain",
"status": "incubating",
"testnet": false,
"title": "Syndicate Chain"
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Syndicate",
"chainId": 5100,
"explorers": [],
"faucets": [],
"icon": {
"url": "ipfs://QmeSvQcD3XvLFAiMLoQSPbGK9JxVfbCWPBUTMLhhhzYPqX",
"width": 16000,
"height": 16000,
"format": "png"
},
"infoURL": "https://syndicate.io",
"name": "Syndicate Testnet",
"nativeCurrency": {
"name": "S-Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 5100,
"rpc": [
"https://syndicate-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://5100.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-testnet.syndicate.io"
],
"shortName": "syndicate-chain-testnet",
"slug": "syndicate-testnet",
"status": "incubating",
"testnet": true,
"title": "Syndicate Testnet"
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Syndicate Frame",
"chainId": 5101,
"explorers": [],
"faucets": [],
"icon": {
"url": "ipfs://QmeSvQcD3XvLFAiMLoQSPbGK9JxVfbCWPBUTMLhhhzYPqX",
"width": 16000,
"height": 16000,
"format": "png"
},
"infoURL": "https://syndicate.io",
"name": "Syndicate Frame Chain",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 5101,
"rpc": [
"https://syndicate-frame-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://5101.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-frame.syndicate.io"
],
"shortName": "syndicate-chain-frame",
"slug": "syndicate-frame-chain",
"status": "incubating",
"testnet": false,
"title": "Syndicate Frame Chain"
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 60834,
"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": "QI M 2402059",
"nativeCurrency": {
"name": "QI M 2402059 Token",
"symbol": "ACI",
"decimals": 18
},
"networkId": 60834,
"redFlags": [],
"rpc": [
"https://qi-m-2402059.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://60834.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/c908add6-74c5-4407-8091-18762786a0b9"
],
"shortName": "QI M 2402059",
"slug": "qi-m-2402059",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 63891,
"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": "Tnetv2",
"nativeCurrency": {
"name": "Tnetv2 Token",
"symbol": "LFC",
"decimals": 18
},
"networkId": 63891,
"redFlags": [],
"rpc": [
"https://tnetv2.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://63891.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "Tnetv2",
"slug": "tnetv2",
"testnet": true
} as const satisfies Chain;
+2 -8
View File
@@ -2,13 +2,7 @@ import type { Chain } from "../src/types";
export default {
"chain": "Xai Mainnet",
"chainId": 660279,
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.xai-chain.net/",
"standard": "EIP3091"
}
],
"explorers": [],
"faucets": [],
"features": [],
"icon": {
@@ -29,7 +23,7 @@ export default {
"rpc": [
"https://xai.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://660279.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://xai-chain.net/rpc"
"https://xai-chain.net/rpc/xai79df8614da076af58f199126a07db"
],
"shortName": "xai",
"slug": "xai",
+44
View File
@@ -0,0 +1,44 @@
import type { Chain } from "../src/types";
export default {
"chain": "Sei",
"chainId": 713715,
"explorers": [
{
"name": "Seistream",
"url": "https://seistream.app",
"standard": "none"
},
{
"name": "Seitrace",
"url": "https://seitrace.com",
"standard": "EIP3091"
}
],
"faucets": [
"https://sei-faucet.nima.enterprises",
"https://sei-evm.faucetme.pro"
],
"icon": {
"url": "ipfs://bafkreih3l3iisplmikofkbfyimqlox7nmixzlkzhjoewmpi4jbqitwryoa",
"width": 600,
"height": 600,
"format": "png"
},
"infoURL": "https://www.sei.io",
"name": "Sei Devnet",
"nativeCurrency": {
"name": "Sei",
"symbol": "SEI",
"decimals": 18
},
"networkId": 713715,
"rpc": [
"https://sei-devnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://713715.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://evm-rpc-arctic-1.sei-apis.com",
"https://evm-rpc.arctic-1.seinetwork.io"
],
"shortName": "sei-devnet",
"slug": "sei-devnet",
"testnet": false
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 74738,
"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": "Testnet",
"nativeCurrency": {
"name": "Testnet Token",
"symbol": "CWA",
"decimals": 18
},
"networkId": 74738,
"redFlags": [],
"rpc": [
"https://testnet-testnet-74738.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://74738.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "Testnet",
"slug": "testnet-testnet-74738",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 7640,
"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": "QI0205I1",
"nativeCurrency": {
"name": "QI0205I1 Token",
"symbol": "KOA",
"decimals": 18
},
"networkId": 7640,
"redFlags": [],
"rpc": [
"https://qi0205i1.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://7640.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QI0205I1",
"slug": "qi0205i1",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 7865,
"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": "ST 02-07",
"nativeCurrency": {
"name": "ST 02-07 Token",
"symbol": "TJO",
"decimals": 18
},
"networkId": 7865,
"redFlags": [],
"rpc": [
"https://st-02-07.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://7865.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "ST 02-07",
"slug": "st-02-07",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 87815,
"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": "QI M 2402056",
"nativeCurrency": {
"name": "QI M 2402056 Token",
"symbol": "ACI",
"decimals": 18
},
"networkId": 87815,
"redFlags": [],
"rpc": [
"https://qi-m-2402056.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://87815.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/c908add6-74c5-4407-8091-18762786a0b9"
],
"shortName": "QI M 2402056",
"slug": "qi-m-2402056",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 92780,
"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": "QI M 2402053",
"nativeCurrency": {
"name": "QI M 2402053 Token",
"symbol": "ACI",
"decimals": 18
},
"networkId": 92780,
"redFlags": [],
"rpc": [
"https://qi-m-2402053.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://92780.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/c908add6-74c5-4407-8091-18762786a0b9"
],
"shortName": "QI M 2402053",
"slug": "qi-m-2402053",
"testnet": true
} as const satisfies Chain;
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 951083,
"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": "QR0205Y1S",
"nativeCurrency": {
"name": "QR0205Y1S Token",
"symbol": "MYO",
"decimals": 18
},
"networkId": 951083,
"redFlags": [],
"rpc": [
"https://qr0205y1s.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://951083.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/qr0205y1s/testnet/rpc"
],
"shortName": "QR0205Y1S",
"slug": "qr0205y1s",
"testnet": true
} as const satisfies Chain;
+2 -2
View File
@@ -21,11 +21,11 @@ export default {
"networkId": 95395,
"redFlags": [],
"rpc": [
"https://testnet-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-testnet-95395.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://95395.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "Testnet",
"slug": "testnet-testnet",
"slug": "testnet-testnet-95395",
"testnet": true
} as const satisfies Chain;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.70",
"version": "0.1.72",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"exports": {
File diff suppressed because one or more lines are too long
+20
View File
@@ -1,5 +1,25 @@
# thirdweb
## 0.13.40
### Patch Changes
- Updated dependencies [[`09de55f1`](https://github.com/thirdweb-dev/js/commit/09de55f13cbd29b4e0eb57808e0d30f9c1b3ba94), [`53786fc3`](https://github.com/thirdweb-dev/js/commit/53786fc3068568758f033a1c63975c94a8e407f5), [`a86478bf`](https://github.com/thirdweb-dev/js/commit/a86478bf248786423d03f4a20d9dc7c02270c371), [`23d0e553`](https://github.com/thirdweb-dev/js/commit/23d0e553088321edfe3971950c2e7f27209d9aaf)]:
- @thirdweb-dev/sdk@4.0.35
- @thirdweb-dev/chains@0.1.72
- @thirdweb-dev/wallets@2.4.10
- @thirdweb-dev/auth@4.1.32
## 0.13.39
### Patch Changes
- Updated dependencies [[`0092e2a3`](https://github.com/thirdweb-dev/js/commit/0092e2a3177364ad26af15ecafb4381591dc9be1), [`357886e3`](https://github.com/thirdweb-dev/js/commit/357886e31b37aad950731ce8f013a101190ebd07)]:
- @thirdweb-dev/auth@4.1.31
- @thirdweb-dev/chains@0.1.71
- @thirdweb-dev/sdk@4.0.34
- @thirdweb-dev/wallets@2.4.9
## 0.13.38
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "thirdweb",
"main": "dist/cli/index.js",
"version": "0.13.38",
"version": "0.13.40",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
+20
View File
@@ -1,5 +1,25 @@
# @thirdweb-dev/react-core
## 4.4.8
### Patch Changes
- Updated dependencies [[`09de55f1`](https://github.com/thirdweb-dev/js/commit/09de55f13cbd29b4e0eb57808e0d30f9c1b3ba94), [`53786fc3`](https://github.com/thirdweb-dev/js/commit/53786fc3068568758f033a1c63975c94a8e407f5), [`a86478bf`](https://github.com/thirdweb-dev/js/commit/a86478bf248786423d03f4a20d9dc7c02270c371), [`23d0e553`](https://github.com/thirdweb-dev/js/commit/23d0e553088321edfe3971950c2e7f27209d9aaf)]:
- @thirdweb-dev/sdk@4.0.35
- @thirdweb-dev/chains@0.1.72
- @thirdweb-dev/wallets@2.4.10
- @thirdweb-dev/auth@4.1.32
## 4.4.7
### Patch Changes
- Updated dependencies [[`0092e2a3`](https://github.com/thirdweb-dev/js/commit/0092e2a3177364ad26af15ecafb4381591dc9be1), [`357886e3`](https://github.com/thirdweb-dev/js/commit/357886e31b37aad950731ce8f013a101190ebd07)]:
- @thirdweb-dev/auth@4.1.31
- @thirdweb-dev/chains@0.1.71
- @thirdweb-dev/sdk@4.0.34
- @thirdweb-dev/wallets@2.4.9
## 4.4.6
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "4.4.6",
"version": "4.4.8",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
Binary file not shown.
@@ -1,5 +1,9 @@
# @thirdweb-dev/react-native-compat
## 0.7.5
## 0.7.4
## 0.7.3
## 0.7.2
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/react-native-compat",
"description": "Shims for Thirdweb in React Native Projects",
"version": "0.7.3",
"version": "0.7.5",
"author": "thirdweb eng <[email protected]>",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
"license": "Apache-2.0",
+20
View File
@@ -1,5 +1,25 @@
# @thirdweb-dev/react-native
## 0.7.5
### Patch Changes
- Updated dependencies [[`09de55f1`](https://github.com/thirdweb-dev/js/commit/09de55f13cbd29b4e0eb57808e0d30f9c1b3ba94), [`53786fc3`](https://github.com/thirdweb-dev/js/commit/53786fc3068568758f033a1c63975c94a8e407f5), [`a86478bf`](https://github.com/thirdweb-dev/js/commit/a86478bf248786423d03f4a20d9dc7c02270c371), [`23d0e553`](https://github.com/thirdweb-dev/js/commit/23d0e553088321edfe3971950c2e7f27209d9aaf)]:
- @thirdweb-dev/sdk@4.0.35
- @thirdweb-dev/chains@0.1.72
- @thirdweb-dev/react-core@4.4.8
- @thirdweb-dev/wallets@2.4.10
## 0.7.4
### Patch Changes
- Updated dependencies [[`357886e3`](https://github.com/thirdweb-dev/js/commit/357886e31b37aad950731ce8f013a101190ebd07)]:
- @thirdweb-dev/chains@0.1.71
- @thirdweb-dev/react-core@4.4.7
- @thirdweb-dev/sdk@4.0.34
- @thirdweb-dev/wallets@2.4.9
## 0.7.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-native",
"version": "0.7.3",
"version": "0.7.5",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
Binary file not shown.
+32
View File
@@ -1,5 +1,37 @@
# @thirdweb-dev/react
## 4.4.8
### Patch Changes
- [#2289](https://github.com/thirdweb-dev/js/pull/2289) [`0155adce`](https://github.com/thirdweb-dev/js/commit/0155adcea4b5379be552962f219853c0a2b1c050) Thanks [@MananTank](https://github.com/MananTank)! - - Show EmbeddedWallet UI instead of the default welcomeScreen in the ConnectWallet wide modal. If a custom welcomeScreen is provided, it will be shown instead of the EmbeddedWallet UI. Same Is done for the deprecated PaperWallet as well
- Stop treating Magic Link as a Social Login and remove the custom Select UI for it
- highlight the wallet for which the Connect UI is shown in the ConnectWallet wide modal
-
- [#2290](https://github.com/thirdweb-dev/js/pull/2290) [`f85806c0`](https://github.com/thirdweb-dev/js/commit/f85806c0674921adc7007eec9f061070eefe1d84) Thanks [@MananTank](https://github.com/MananTank)! - Update EmbeddedWallet name in ConnectWallet UI
- [#2288](https://github.com/thirdweb-dev/js/pull/2288) [`74d76ff5`](https://github.com/thirdweb-dev/js/commit/74d76ff580d78a5b98a2d7180a58457231c1b95a) Thanks [@MananTank](https://github.com/MananTank)! - Add "Powered By Thirdweb" Branding at the bottom of `ConnectEmbed` and `ConnectWallet` Modal
A new prop `showThirdwebBranding` has been added to both `ConnectEmbed` and `ConnectWallet` components to hide this branding.
- Updated dependencies [[`09de55f1`](https://github.com/thirdweb-dev/js/commit/09de55f13cbd29b4e0eb57808e0d30f9c1b3ba94), [`53786fc3`](https://github.com/thirdweb-dev/js/commit/53786fc3068568758f033a1c63975c94a8e407f5), [`a86478bf`](https://github.com/thirdweb-dev/js/commit/a86478bf248786423d03f4a20d9dc7c02270c371), [`23d0e553`](https://github.com/thirdweb-dev/js/commit/23d0e553088321edfe3971950c2e7f27209d9aaf)]:
- @thirdweb-dev/sdk@4.0.35
- @thirdweb-dev/chains@0.1.72
- @thirdweb-dev/react-core@4.4.8
- @thirdweb-dev/wallets@2.4.10
## 4.4.7
### Patch Changes
- Updated dependencies [[`357886e3`](https://github.com/thirdweb-dev/js/commit/357886e31b37aad950731ce8f013a101190ebd07)]:
- @thirdweb-dev/chains@0.1.71
- @thirdweb-dev/react-core@4.4.7
- @thirdweb-dev/sdk@4.0.34
- @thirdweb-dev/wallets@2.4.9
## 4.4.6
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "4.4.6",
"version": "4.4.8",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -185,6 +185,11 @@ export interface Web3ButtonProps<TActionFn extends ActionFn> {
* Either provide a component to replace the default screen entirely or an object with title, subtitle and imgSrc to change the content of the default screen
*/
welcomeScreen?: WelcomeScreen;
/**
* By default the ConnectWallet Modal shows "Powered by Thirdweb" at the bottom. If you want to hide it, set it to `false`
*/
showThirdwebBranding?: boolean;
};
/**
@@ -22,6 +22,7 @@ export type ModalConfig = {
};
isEmbed?: boolean;
onConnect?: () => void;
showThirdwebBranding?: boolean;
};
const WalletModalOpen = /* @__PURE__ */ createContext(false);
@@ -56,6 +57,7 @@ export const WalletUIStatesProvider = (
onLogout?: () => void;
};
onConnect?: () => void;
showThirdwebBranding?: boolean;
}>,
) => {
const [isWalletModalOpen, setIsWalletModalOpen] = useState(false);
@@ -74,6 +76,7 @@ export const WalletUIStatesProvider = (
isEmbed: props.isEmbed,
auth: props.auth,
onConnect: props.onConnect,
showThirdwebBranding: props.showThirdwebBranding,
});
return (
@@ -233,6 +236,13 @@ export type ModalConfigOptions = {
* Note that this does not include the sign in, If you want to call a callback after user connects AND signs in with their wallet, use `auth.onLogin` instead
*/
onConnect?: () => void;
/**
* By default the ConnectWallet Modal shows "powered by thirdweb" branding at the bottom of the modal.
*
* If you want to hide the branding, set this to `false`
*/
showThirdwebBranding?: boolean;
};
/**
@@ -352,6 +352,18 @@ export type ConnectWalletProps = {
* ```
*/
detailsModalFooter?: (props: { close: () => void }) => JSX.Element;
/**
* By default ConnectWallet shows "Powered by Thirdweb" branding at the bottom of the ConnectWallet Modal.
*
* If you want to hide the branding, set this prop to `false`
*
* @example
* ```tsx
* <ConnectWallet showThirdwebBranding={false} />
*```
*/
showThirdwebBranding?: boolean;
};
const TW_CONNECT_WALLET = "tw-connect-wallet";
@@ -588,6 +600,16 @@ const TW_CONNECT_WALLET = "tw-connect-wallet";
* })
* />
* ```
*
*
* ### showThirdwebBranding
* By default ConnectWallet shows "Powered by Thirdweb" branding at the bottom of the ConnectWallet Modal.
*
* If you want to hide the branding, set this prop to `false`
*
* ```tsx
* <ConnectWallet showThirdwebBranding={false} />
*```
*/
export function ConnectWallet(props: ConnectWalletProps) {
const activeWallet = useWallet();
@@ -707,6 +729,7 @@ export function ConnectWallet(props: ConnectWalletProps) {
titleIconUrl: props.modalTitleIconUrl,
auth: props.auth,
onConnect: props.onConnect,
showThirdwebBranding: props.showThirdwebBranding,
});
setIsWalletModalOpen(true);
}}
@@ -8,7 +8,7 @@ import {
reservedScreens,
} from "../constants";
import { ConnectModalContent } from "./ConnectModal";
import { useScreen } from "./screen";
import { useSetupScreen } from "./screen";
import { DynamicHeight } from "../../../components/DynamicHeight";
import {
CustomThemeProvider,
@@ -19,7 +19,6 @@ import { useTWLocale } from "../../../evm/providers/locale-provider";
import { StyledDiv } from "../../../design-system/elements";
import { Theme, radius } from "../../../design-system";
import {
WalletConfig,
useConnectionStatus,
useThirdwebAuthContext,
useUser,
@@ -118,6 +117,18 @@ export type ConnectEmbedProps = {
*
*/
onConnect?: () => void;
/**
* By default, A "Powered by Thirdweb" branding is shown at the bottom of the embed.
*
* If you want to hide it, set this to `false`
*
* @example
* ```tsx
* <ConnectEmbed showThirdwebBranding={false} />
* ```
*/
showThirdwebBranding?: boolean;
};
/**
@@ -276,32 +287,42 @@ export function useShowConnectEmbed(loginOptional?: boolean) {
* />
* ```
*
* ### showThirdwebBranding
* By default ConnectWallet shows "Powered by Thirdweb" branding at the bottom of the ConnectWallet Modal.
*
* If you want to hide the branding, set this prop to `false`
*
* ```tsx
* <ConnectWallet showThirdwebBranding={false} />
*```
*
*/
export function ConnectEmbed(props: ConnectEmbedProps) {
const loginOptional = props.auth?.loginOptional;
const requiresSignIn = useSignInRequired(loginOptional);
const show = useShowConnectEmbed(loginOptional);
const { screen, setScreen, initialScreen } = useScreen();
// if showing main screen but signIn is required, switch to signIn screen
useEffect(() => {
if (requiresSignIn && screen === reservedScreens.main) {
setScreen(reservedScreens.signIn);
}
}, [requiresSignIn, screen, setScreen]);
const contextTheme = useCustomTheme();
const walletUIStatesProps = {
theme: props.theme || contextTheme || defaultTheme,
modalSize: "compact" as const,
title: undefined,
termsOfServiceUrl: props.termsOfServiceUrl,
privacyPolicyUrl: props.privacyPolicyUrl,
isEmbed: true,
auth: props.auth,
onConnect: props.onConnect,
showThirdwebBranding: props.showThirdwebBranding,
};
if (show) {
return (
<ConnectEmbedContent
{...props}
onClose={() => {
setScreen(initialScreen);
}}
screen={screen}
setScreen={setScreen}
initialScreen={initialScreen}
onConnect={props.onConnect}
/>
<WalletUIStatesProvider {...walletUIStatesProps}>
<CustomThemeProvider theme={walletUIStatesProps.theme}>
<ConnectEmbedContent {...props} onConnect={props.onConnect} />
<SyncedWalletUIStates {...walletUIStatesProps} />
</CustomThemeProvider>
</WalletUIStatesProvider>
);
}
@@ -310,17 +331,23 @@ export function ConnectEmbed(props: ConnectEmbedProps) {
const ConnectEmbedContent = (
props: Omit<ConnectEmbedProps, "onConnect"> & {
onClose: () => void;
screen: string | WalletConfig;
setScreen: (screen: string | WalletConfig) => void;
initialScreen: string | WalletConfig;
onConnect?: () => void;
loginOptional?: boolean;
},
) => {
const modalSize = "compact" as const;
const requiresSignIn = useSignInRequired(props.loginOptional);
const screenSetup = useSetupScreen();
const { screen, setScreen, initialScreen } = screenSetup;
// if showing main screen but signIn is required, switch to signIn screen
useEffect(() => {
if (requiresSignIn && screen === reservedScreens.main) {
setScreen(reservedScreens.signIn);
}
}, [requiresSignIn, screen, setScreen]);
const connectionStatus = useConnectionStatus();
const { isAutoConnecting } = useWalletContext();
const contextTheme = useCustomTheme();
let content = null;
@@ -340,11 +367,11 @@ const ConnectEmbedContent = (
} else {
content = (
<ConnectModalContent
initialScreen={props.initialScreen}
screen={props.screen}
setScreen={props.setScreen}
screenSetup={screenSetup}
isOpen={true}
onClose={props.onClose}
onClose={() => {
setScreen(initialScreen);
}}
onHide={() => {
// no op
}}
@@ -355,33 +382,17 @@ const ConnectEmbedContent = (
);
}
const walletUIStatesProps = {
theme: props.theme || contextTheme || defaultTheme,
modalSize: modalSize,
title: undefined,
termsOfServiceUrl: props.termsOfServiceUrl,
privacyPolicyUrl: props.privacyPolicyUrl,
isEmbed: true,
auth: props.auth,
onConnect: props.onConnect,
};
return (
<WalletUIStatesProvider {...walletUIStatesProps}>
<CustomThemeProvider theme={walletUIStatesProps.theme}>
<EmbedContainer
className={props.className}
style={{
height: "auto",
maxWidth: modalMaxWidthCompact,
...props.style,
}}
>
<DynamicHeight> {content} </DynamicHeight>
<SyncedWalletUIStates {...walletUIStatesProps} />
</EmbedContainer>
</CustomThemeProvider>
</WalletUIStatesProvider>
<EmbedContainer
className={props.className}
style={{
height: "auto",
maxWidth: modalMaxWidthCompact,
...props.style,
}}
>
<DynamicHeight> {content} </DynamicHeight>
</EmbedContainer>
);
};
@@ -402,6 +413,7 @@ export function SyncedWalletUIStates(
privacyPolicyUrl: props.privacyPolicyUrl,
welcomeScreen: props.welcomeScreen,
titleIconUrl: props.titleIconUrl,
showThirdwebBranding: props.showThirdwebBranding,
}));
}, [
props.title,
@@ -413,6 +425,7 @@ export function SyncedWalletUIStates(
props.titleIconUrl,
setModalConfig,
locale.connectWallet.defaultModalTitle,
props.showThirdwebBranding,
]);
return <WalletUIStatesProvider {...props} />;
@@ -26,7 +26,7 @@ import {
} from "../constants";
import { HeadlessConnectUI } from "../../wallets/headlessConnectUI";
import { Container, noScrollBar } from "../../../components/basic";
import { ScreenContext, useScreen } from "./screen";
import { ScreenSetup, ScreenSetupContext, useSetupScreen } from "./screen";
import { StartScreen } from "../screens/StartScreen";
import {
CustomThemeProvider,
@@ -36,15 +36,14 @@ import { SignatureScreen } from "../SignatureScreen";
import { StyledDiv } from "../../../design-system/elements";
export const ConnectModalContent = (props: {
screen: string | WalletConfig;
initialScreen: string | WalletConfig;
setScreen: (screen: string | WalletConfig) => void;
screenSetup: ScreenSetup;
onHide: () => void;
onShow: () => void;
isOpen: boolean;
onClose: () => void;
}) => {
const { screen, setScreen, initialScreen, onHide, onShow, onClose } = props;
const { onHide, onShow, onClose } = props;
const { screen, setScreen, initialScreen } = props.screenSetup;
const walletConfigs = useWallets();
const connectionStatus = useConnectionStatus();
@@ -173,7 +172,7 @@ export const ConnectModalContent = (props: {
);
return (
<ScreenContext.Provider value={screen}>
<ScreenSetupContext.Provider value={props.screenSetup}>
{isWideModal ? (
<div
style={{
@@ -205,14 +204,15 @@ export const ConnectModalContent = (props: {
{typeof screen !== "string" && getWalletUI(screen)}
</Container>
)}
</ScreenContext.Provider>
</ScreenSetupContext.Provider>
);
};
export const ConnectModal = () => {
const { theme, modalSize } = useContext(ModalConfigCtx);
const { screen, setScreen, initialScreen } = useScreen();
const screenSetup = useSetupScreen();
const { screen, setScreen, initialScreen } = screenSetup;
const isWalletModalOpen = useIsWalletModalOpen();
const setIsWalletModalOpen = useSetIsWalletModalOpen();
const [hideModal, setHideModal] = useState(false);
@@ -311,9 +311,7 @@ export const ConnectModal = () => {
}}
>
<ConnectModalContent
initialScreen={initialScreen}
screen={screen}
setScreen={setScreen}
screenSetup={screenSetup}
onHide={onHide}
onShow={onShow}
isOpen={isWalletModalOpen}
@@ -9,7 +9,7 @@ import {
modalMaxWidthWide,
} from "../constants";
import { ConnectModalContent } from "./ConnectModal";
import { useScreen } from "./screen";
import { useSetupScreen } from "./screen";
import { useWallets } from "@thirdweb-dev/react-core";
import { DynamicHeight } from "../../../components/DynamicHeight";
import {
@@ -27,56 +27,20 @@ import { canFitWideModal } from "../../../evm/utils/canFitWIdeModal";
export type ConnectModalInlineProps = {
className?: string;
theme?: "dark" | "light" | Theme;
/**
* Set a custom title for the modal
* @defaultValue "Connect"
*/
modalTitle?: string;
/**
* Replace the thirdweb icon next to modalTitle and set your own iconUrl
*
* Set to empty string to hide the icon
*/
modalTitleIconUrl?: string;
style?: React.CSSProperties;
/**
* Set the size of the modal - `compact` or `wide` on desktop
*
* Modal size is always `compact` on mobile
*
* @defaultValue "wide"
*/
modalSize?: "compact" | "wide";
/**
* If provided, Modal will show a Terms of Service message at the bottom with below link
*/
termsOfServiceUrl?: string;
/**
* If provided, Modal will show a Privacy Policy message at the bottom with below link
*/
privacyPolicyUrl?: string;
/**
* Customize the welcome screen
*
* Either provide a component to replace the default screen entirely
*
* or an object with title, subtitle and imgSrc to change the content of the default screen
*/
welcomeScreen?: WelcomeScreen;
showThirdwebBranding?: boolean;
};
/**
* @internal
*/
export const ConnectModalInline = (props: ConnectModalInlineProps) => {
const { screen, setScreen, initialScreen } = useScreen();
const walletConfigs = useWallets();
const modalSize =
!canFitWideModal() || walletConfigs.length === 1
@@ -84,12 +48,41 @@ export const ConnectModalInline = (props: ConnectModalInlineProps) => {
: props.modalSize;
const ctxTheme = useCustomTheme();
const walletUIStatesProps = {
theme: props.theme || ctxTheme,
modalSize: modalSize,
title: props.modalTitle,
termsOfServiceUrl: props.termsOfServiceUrl,
privacyPolicyUrl: props.privacyPolicyUrl,
welcomeScreen: props.welcomeScreen,
titleIconUrl: props.modalTitleIconUrl,
showThirdwebBranding: props.showThirdwebBranding,
};
return (
<WalletUIStatesProvider {...walletUIStatesProps}>
<CustomThemeProvider theme={walletUIStatesProps.theme}>
<ConnectModalInlineContent
className={props.className}
modalSize={modalSize}
/>
<SyncedWalletUIStates {...walletUIStatesProps} />
</CustomThemeProvider>
</WalletUIStatesProvider>
);
};
function ConnectModalInlineContent(props: {
className?: string;
modalSize?: "compact" | "wide";
style?: React.CSSProperties;
}) {
const screenSetup = useSetupScreen();
const content = (
<>
<ConnectModalContent
initialScreen={initialScreen}
screen={screen}
setScreen={setScreen}
screenSetup={screenSetup}
onHide={() => {
// no op
}}
@@ -117,41 +110,26 @@ export const ConnectModalInline = (props: ConnectModalInlineProps) => {
</>
);
const walletUIStatesProps = {
theme: props.theme || ctxTheme,
modalSize: modalSize,
title: props.modalTitle,
termsOfServiceUrl: props.termsOfServiceUrl,
privacyPolicyUrl: props.privacyPolicyUrl,
welcomeScreen: props.welcomeScreen,
titleIconUrl: props.modalTitleIconUrl,
};
return (
<WalletUIStatesProvider {...walletUIStatesProps}>
<CustomThemeProvider theme={walletUIStatesProps.theme}>
<ConnectModalInlineContainer
className={props.className}
style={{
height: modalSize === "compact" ? "auto" : wideModalMaxHeight,
maxWidth:
modalSize === "compact"
? modalMaxWidthCompact
: modalMaxWidthWide,
...props.style,
}}
>
{modalSize === "compact" ? (
<DynamicHeight> {content} </DynamicHeight>
) : (
content
)}
<SyncedWalletUIStates {...walletUIStatesProps} />
</ConnectModalInlineContainer>
</CustomThemeProvider>
</WalletUIStatesProvider>
<ConnectModalInlineContainer
className={props.className}
style={{
height: props.modalSize === "compact" ? "auto" : wideModalMaxHeight,
maxWidth:
props.modalSize === "compact"
? modalMaxWidthCompact
: modalMaxWidthWide,
...props.style,
}}
>
{props.modalSize === "compact" ? (
<DynamicHeight> {content} </DynamicHeight>
) : (
content
)}
</ConnectModalInlineContainer>
);
};
}
const ConnectModalInlineContainer = /* @__PURE__ */ StyledDiv(() => {
const theme = useCustomTheme();
@@ -1,19 +1,41 @@
import { WalletConfig, useWallet, useWallets } from "@thirdweb-dev/react-core";
import { createContext, useState, useContext, useEffect, useRef } from "react";
import { reservedScreens } from "../constants";
import { ModalConfigCtx } from "../../../evm/providers/wallet-ui-states-provider";
type Screen = string | WalletConfig;
export const ScreenContext = /* @__PURE__ */ createContext<Screen | undefined>(
undefined,
);
export type ScreenSetup = {
screen: Screen;
setScreen: (newSreen: Screen) => void;
initialScreen: Screen;
};
export function useScreen() {
export const ScreenSetupContext = /* @__PURE__ */ createContext<
ScreenSetup | undefined
>(undefined);
export function useSetupScreen(): ScreenSetup {
const walletConfigs = useWallets();
const initialScreen =
(walletConfigs.length === 1 && !walletConfigs[0]?.selectUI
? walletConfigs[0]
: reservedScreens.main) || reservedScreens.main;
const modalConfig = useContext(ModalConfigCtx);
let initialScreen: Screen = reservedScreens.main;
const socialLogin = walletConfigs.find((w) => w.category === "socialLogin");
if (
walletConfigs.length === 1 &&
walletConfigs[0] &&
!walletConfigs[0]?.selectUI
) {
initialScreen = walletConfigs[0];
} else if (
modalConfig.modalSize === "wide" &&
!modalConfig.welcomeScreen &&
socialLogin
) {
initialScreen = socialLogin;
}
const [screen, setScreen] = useState<string | WalletConfig>(initialScreen);
const prevInitialScreen = useRef(initialScreen);
@@ -42,11 +64,11 @@ export function useScreen() {
}
export function useScreenContext() {
const screen = useContext(ScreenContext);
if (!screen) {
const ctx = useContext(ScreenSetupContext);
if (!ctx) {
throw new Error(
"useScreenContext must be used within a <ScreenProvider />",
);
}
return screen;
return ctx;
}
@@ -0,0 +1,34 @@
import { Container } from "../../components/basic";
import { Link, Text } from "../../components/text";
import { ThirdwebTextIcon } from "./icons/ThirdwebTextIcon";
export function PoweredByThirdweb() {
return (
<Link
color="secondaryText"
hoverColor="primaryText"
target="_blank"
href="https://thirdweb.com/connect?utm_source=cw_text"
>
<Container
flex="row"
center="both"
style={{
color: "currentColor",
gap: 4,
}}
>
<Text
size="sm"
weight={600}
style={{
color: "currentColor",
}}
>
{"Powered by"}
</Text>
<ThirdwebTextIcon height={13} />
</Container>
</Link>
);
}
@@ -31,6 +31,8 @@ import { useTWLocale } from "../../evm/providers/locale-provider";
import { ChevronLeftIcon } from "@radix-ui/react-icons";
import { StyledButton, StyledUl } from "../../design-system/elements";
import { useCustomTheme } from "../../design-system/CustomThemeProvider";
import { PoweredByThirdweb } from "./PoweredByTW";
import { useScreenContext } from "./Modal/screen";
type WalletSelectUIProps = {
connect: (
@@ -429,7 +431,14 @@ export const WalletSelector: React.FC<{
{topSection}
</Container>
{bottomSection}
<div>
{bottomSection}
{isCompact && modalConfig.showThirdwebBranding !== false && (
<Container py="md">
<PoweredByThirdweb />
</Container>
)}
</div>
</Container>
);
};
@@ -499,12 +508,15 @@ export function WalletEntryButton(props: {
const { walletConfig, selectWallet } = props;
const isRecommended = walletConfig.recommended;
const locale = useTWLocale().connectWallet;
const { screen } = useScreenContext();
return (
<WalletButton
type="button"
onClick={() => {
selectWallet();
}}
data-active={screen === props.walletConfig}
>
<Img
src={walletConfig.meta.iconURL}
@@ -565,6 +577,9 @@ const WalletButton = /* @__PURE__ */ StyledButton(() => {
backgroundColor: theme.colors.walletSelectorButtonHoverBg,
transform: "scale(1.01)",
},
'&[data-active="true"]': {
backgroundColor: theme.colors.walletSelectorButtonHoverBg,
},
transition: "background-color 200ms ease, transform 200ms ease",
};
});
@@ -0,0 +1,31 @@
export const ThirdwebTextIcon = (props: { height: number }) => {
return (
<svg
width={(props.height * 74) / 11}
height={props.height}
viewBox="0 0 74 11"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M34.1489 0.373291C33.5297 0.373291 33.022 0.874761 33.022 1.51414C33.022 2.14097 33.5297 2.64244 34.1489 2.64244C34.7681 2.64244 35.2758 2.14097 35.2758 1.51414C35.2758 0.874761 34.7681 0.373291 34.1489 0.373291ZM35.1396 3.21913H33.1706V9.97644H35.1396V3.21913ZM21.6787 0.624035H23.5982V3.21914H25.0718V5.02444H23.5982V7.40642C23.5982 7.75745 23.8706 8.03326 24.205 8.03326H25.0594V9.95138H24.205C22.818 9.95138 21.6787 8.81054 21.6787 7.39389V5.0119H20.7871V3.20661H21.6787V0.624035ZM29.7652 3.0687C28.8736 3.0687 28.1677 3.44481 27.8953 4.03403V0.624035H25.9263V9.96392H27.8953V6.17782C27.8953 5.388 28.403 4.83639 29.1213 4.83639C29.8519 4.83639 30.2605 5.31278 30.2605 6.11514V9.97646H32.2295V5.8644C32.2295 4.10925 31.3379 3.0687 29.7652 3.0687ZM37.9507 3.2066V4.13432C38.2479 3.45734 38.9661 3.0687 39.8701 3.05616C40.0063 3.05616 40.1797 3.0687 40.3902 3.09377V4.97429C40.1921 4.93668 39.9692 4.9116 39.7339 4.9116C38.607 4.9116 37.9507 5.55098 37.9507 6.66675V9.96392H35.9817V3.2066H37.9507ZM45.9257 4.09672C45.7275 3.50749 44.9474 3.09378 43.9443 3.09378C43.0032 3.09378 42.2106 3.43227 41.5791 4.10926C40.9599 4.7737 40.6379 5.61367 40.6379 6.59154C40.6379 7.5694 40.9599 8.39683 41.5791 9.08635C42.2106 9.7508 43.0032 10.0893 43.9443 10.0893C44.9474 10.0893 45.7275 9.67558 45.9257 9.08635V9.97646H47.8946V0.624035H45.9257V4.09672ZM45.5294 7.79506C45.195 8.12102 44.7864 8.27146 44.3034 8.27146C43.8329 8.27146 43.4242 8.10848 43.1022 7.79506C42.7679 7.45657 42.6069 7.0554 42.6069 6.59154C42.6069 6.12767 42.7679 5.7265 43.1022 5.40054C43.4366 5.06205 43.8329 4.89907 44.3034 4.89907C44.7988 4.89907 45.2074 5.06205 45.5294 5.40054C45.8761 5.7265 46.0495 6.12767 46.0495 6.59154C46.0495 7.0554 45.8761 7.45657 45.5294 7.79506ZM53.5787 3.2442L55.3619 6.45361L56.5631 3.21913H58.4949L55.7458 10.3651L53.5787 6.47868L51.4115 10.3651L48.6748 3.21913H50.6066L51.7954 6.45361L53.5787 3.2442ZM61.7394 3.05616C60.7239 3.05616 59.8694 3.38212 59.2007 4.03403C58.5444 4.6734 58.2101 5.5259 58.2101 6.57899V6.64167C58.2101 7.69476 58.5444 8.54726 59.2007 9.18664C59.8818 9.81347 60.7487 10.1394 61.8384 10.1394C62.8539 10.1394 63.6836 9.93884 64.3151 9.52513V7.78252C63.6959 8.22131 62.9034 8.43443 61.9499 8.43443C60.9097 8.43443 60.2286 7.92042 60.1914 7.11807H65.0829C65.1077 6.91748 65.12 6.69182 65.12 6.46616C65.12 5.50083 64.7981 4.69848 64.1789 4.04657C63.5597 3.38212 62.73 3.05616 61.7394 3.05616ZM60.1914 5.82679C60.2038 5.51337 60.3648 5.25009 60.662 5.03697C60.9716 4.82385 61.3183 4.71101 61.7394 4.71101C62.5195 4.71101 63.1263 5.22502 63.1263 5.82679H60.1914ZM69.8135 3.09378C70.7546 3.09378 71.5472 3.43227 72.1663 4.10925C72.7979 4.78624 73.1199 5.60113 73.1199 6.579C73.1199 7.55686 72.7979 8.38429 72.1663 9.07381C71.5472 9.73826 70.7546 10.0768 69.8135 10.0768C68.8104 10.0768 68.0302 9.66304 67.8321 9.07381V9.96392H65.8631V0.624035H67.8321V4.09672C68.0302 3.50749 68.8104 3.09378 69.8135 3.09378ZM69.4543 8.27146C69.9249 8.27146 70.3212 8.12102 70.6555 7.79506C70.9899 7.45657 71.1509 7.05539 71.1509 6.59153C71.1509 6.12767 70.9899 5.7265 70.6555 5.40054C70.3336 5.06205 69.9249 4.89907 69.4543 4.89907C68.9714 4.89907 68.5627 5.06205 68.216 5.40054C67.8816 5.7265 67.7083 6.12767 67.7083 6.59153C67.7083 7.05539 67.8816 7.45657 68.216 7.79506C68.5503 8.10848 68.959 8.27146 69.4543 8.27146Z"
fill="currentColor"
/>
<g clip-path="url(#clip0_5017_2727)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M0.045011 0.900694C-0.126602 0.467742 0.193222 0 0.661257 0H3.56697C3.83999 0 4.08181 0.162357 4.18322 0.413623L6.49609 6.18115C6.55849 6.33578 6.55849 6.50973 6.49609 6.66822L5.04128 10.2903C4.81896 10.8431 4.03111 10.8431 3.80879 10.2903L0.045011 0.900694ZM5.65759 0.881366C5.50158 0.45228 5.8214 0 6.28164 0H8.81292C9.09374 0 9.34336 0.173954 9.43697 0.432951L11.5392 6.20048C11.5899 6.34351 11.5899 6.502 11.5392 6.6489L10.2755 10.1164C10.0649 10.6962 9.23805 10.6962 9.02744 10.1164L5.65759 0.881366ZM11.3404 0C10.8724 0 10.5525 0.467742 10.7241 0.900694L14.4879 10.2903C14.7102 10.8431 15.4981 10.8431 15.7204 10.2903L17.1752 6.66822C17.2376 6.50973 17.2376 6.33578 17.1752 6.18115L14.8623 0.413623C14.7609 0.162357 14.5191 0 14.2461 0H11.3404Z"
fill="currentColor"
/>
</g>
<defs>
<clipPath id="clip0_5017_2727">
<rect width="17.219" height="10.7049" fill="white" />
</clipPath>
</defs>
</svg>
);
};
@@ -10,12 +10,15 @@ import { Img } from "../../../components/Img";
import { useTWLocale } from "../../../evm/providers/locale-provider";
import { StyledDiv } from "../../../design-system/elements";
import { useCustomTheme } from "../../../design-system/CustomThemeProvider";
import { PoweredByThirdweb } from "../PoweredByTW";
import { spacing } from "../../../design-system";
export function StartScreen() {
const {
termsOfServiceUrl,
privacyPolicyUrl,
welcomeScreen: WelcomeScreen,
showThirdwebBranding,
} = useContext(ModalConfigCtx);
const locale = useTWLocale().connectWallet;
@@ -80,9 +83,9 @@ export function StartScreen() {
>
{subtitle}
</Text>
</Container>
<Container py="lg" flex="column" gap="lg">
<Spacer y="lg" />
<Link
target="_blank"
center
@@ -90,13 +93,27 @@ export function StartScreen() {
>
{locale.newToWallets}
</Link>
</Container>
{showTOS && (
<TOS
termsOfServiceUrl={termsOfServiceUrl}
privacyPolicyUrl={privacyPolicyUrl}
/>
)}
<Container py="lg" flex="column" gap="lg">
<div>
{showTOS && (
<TOS
termsOfServiceUrl={termsOfServiceUrl}
privacyPolicyUrl={privacyPolicyUrl}
/>
)}
{showThirdwebBranding !== false && (
<Container
style={{
paddingTop: spacing.xl,
}}
>
<PoweredByThirdweb />
</Container>
)}
</div>
</Container>
</Container>
);
@@ -16,6 +16,11 @@ 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 { ModalConfigCtx } from "../../../evm/providers/wallet-ui-states-provider";
import { TOS } from "../../ConnectWallet/Modal/TOS";
export const EmbeddedWalletFormUI = (props: {
onSelect: (loginType: EmbeddedWalletLoginType) => void;
@@ -155,6 +160,9 @@ export const EmbeddedWalletFormUIScreen: React.FC<{
}> = (props) => {
const locale = useTWLocale().wallets.embeddedWallet.emailLoginScreen;
const isCompact = props.modalSize === "compact";
const { initialScreen, screen } = useScreenContext();
const modalConfig = useContext(ModalConfigCtx);
return (
<Container
fullHeight
@@ -165,7 +173,14 @@ export const EmbeddedWalletFormUIScreen: React.FC<{
minHeight: "250px",
}}
>
<ModalHeader onBack={props.onBack} title={locale.title} />
<ModalHeader
onBack={
screen === props.walletConfig && initialScreen === props.walletConfig
? undefined
: props.onBack
}
title={locale.title}
/>
{isCompact ? <Spacer y="xl" /> : null}
<Container
@@ -184,6 +199,20 @@ export const EmbeddedWalletFormUIScreen: React.FC<{
setConnectedWallet={props.setConnectedWallet}
/>
</Container>
{isCompact &&
(modalConfig.showThirdwebBranding !== false ||
modalConfig.termsOfServiceUrl ||
modalConfig.privacyPolicyUrl) && <Spacer y="xl" />}
<Container flex="column" gap="lg">
<TOS
termsOfServiceUrl={modalConfig.termsOfServiceUrl}
privacyPolicyUrl={modalConfig.privacyPolicyUrl}
/>
{modalConfig.showThirdwebBranding !== false && <PoweredByThirdweb />}
</Container>
</Container>
);
};
@@ -82,6 +82,21 @@ export const embeddedWallet = (
const { auth } = finalOptions;
let name = "Email & Socials";
// if only email is enabled, show the name as "Email"
if (
finalOptions?.auth?.options.length === 1 &&
finalOptions.auth.options[0] === "email"
) {
name = "Email";
}
// if email is not enabled, show the name as "Social Login"
if (finalOptions?.auth?.options.indexOf("email") === -1) {
name = "Social Login";
}
return {
category: "socialLogin",
isHeadless: true,
@@ -89,7 +104,7 @@ export const embeddedWallet = (
recommended: finalOptions?.recommended,
meta: {
...EmbeddedWallet.meta,
name: "Email",
name,
iconURL: emailIcon,
},
create(walletOptions: WalletOptions) {
@@ -123,7 +138,7 @@ const EmbeddedWalletSelectionUI: React.FC<
authOptions: AuthOption[];
}
> = (props) => {
const screen = useScreenContext();
const { screen } = useScreenContext();
// show the icon + text if
// wide -
@@ -1,7 +1,6 @@
import { MagicLink, MagicLinkAdditionalOptions } from "@thirdweb-dev/wallets";
import {
ConnectUIProps,
SelectUIProps,
WalletOptions,
useWalletContext,
} from "@thirdweb-dev/react-core";
@@ -15,7 +14,6 @@ import { fontSize, iconSize, spacing } from "../../../design-system";
import { Button, IconButton } from "../../../components/buttons";
import { ToolTip } from "../../../components/Tooltip";
import styled from "@emotion/styled";
import { WalletEntryButton } from "../../ConnectWallet/WalletSelector";
import {
emailAndPhoneIcon,
emailIcon,
@@ -177,7 +175,6 @@ export function magicLink(
}
return {
category: "socialLogin",
id: MagicLink.id,
recommended: config?.recommended,
isHeadless: true,
@@ -215,57 +212,12 @@ export function magicLink(
return <MagicConnectingUI {...props} type={type} />;
},
// select UI only for auth
selectUI:
config.type === "connect"
? undefined
: (props) => {
return (
<MagicSelectUI
{...props}
emailLoginEnabled={emailLoginEnabled}
smsLoginEnabled={smsLoginEnabled}
oauthProviders={oauthProviders}
/>
);
},
isInstalled() {
return false;
},
};
}
const MagicSelectUI = (
props: SelectUIProps<MagicLink> & {
emailLoginEnabled: boolean;
smsLoginEnabled: boolean;
oauthProviders?: OauthProvider[];
},
) => {
const screen = useScreenContext();
if (
props.modalSize === "wide" ||
(screen !== reservedScreens.main && props.modalSize === "compact")
) {
return (
<WalletEntryButton
walletConfig={props.walletConfig}
selectWallet={() => props.onSelect(undefined)}
/>
);
}
return (
<MagicUI
{...props}
emailLogin={props.emailLoginEnabled}
smsLogin={props.smsLoginEnabled}
oauthProviders={props.oauthProviders}
/>
);
};
type OauthProvider = Exclude<
MagicLinkAdditionalOptions["oauthOptions"],
undefined
@@ -305,7 +257,7 @@ const MagicUI: React.FC<{
}
const showInputUI = isEmailEnabled || isSMSEnabled;
const screen = useScreenContext();
const { screen } = useScreenContext();
const showSeparator =
props.modalSize === "wide" ||
(screen !== reservedScreens.main && props.modalSize === "compact");
@@ -13,6 +13,11 @@ import { PaperLoginType } from "./types";
import { Img } from "../../../components/Img";
import { googleIconUri } from "../../ConnectWallet/icons/socialLogins";
import { useCustomTheme } from "../../../design-system/CustomThemeProvider";
import { useContext } from "react";
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";
export const PaperFormUI = (props: {
onSelect: (loginType: PaperLoginType) => void;
@@ -105,6 +110,8 @@ export const PaperFormUIScreen: React.FC<{
}> = (props) => {
const isCompact = props.modalSize === "compact";
const locale = useTWLocale().wallets.paperWallet;
const { initialScreen, screen } = useScreenContext();
const modalConfig = useContext(ModalConfigCtx);
return (
<Container
fullHeight
@@ -115,7 +122,14 @@ export const PaperFormUIScreen: React.FC<{
minHeight: "250px",
}}
>
<ModalHeader onBack={props.onBack} title={locale.signIn} />
<ModalHeader
onBack={
screen === props.walletConfig && initialScreen === props.walletConfig
? undefined
: props.onBack
}
title={locale.signIn}
/>
{isCompact ? <Spacer y="xl" /> : null}
<Container
@@ -133,6 +147,20 @@ export const PaperFormUIScreen: React.FC<{
createWalletInstance={props.createWalletInstance}
/>
</Container>
{isCompact &&
(modalConfig.showThirdwebBranding !== false ||
modalConfig.termsOfServiceUrl ||
modalConfig.privacyPolicyUrl) && <Spacer y="xl" />}
<Container flex="column" gap="lg">
<TOS
termsOfServiceUrl={modalConfig.termsOfServiceUrl}
privacyPolicyUrl={modalConfig.privacyPolicyUrl}
/>
{modalConfig.showThirdwebBranding !== false && <PoweredByThirdweb />}
</Container>
</Container>
);
};
@@ -99,7 +99,7 @@ const PaperSelectionUI: React.FC<
providers?: OAuthProvider[];
}
> = (props) => {
const screen = useScreenContext();
const { screen } = useScreenContext();
// show the icon + text if
// wide -
Binary file not shown.
+20
View File
@@ -1,5 +1,25 @@
# @thirdweb-dev/sdk
## 4.0.35
### Patch Changes
- [#2286](https://github.com/thirdweb-dev/js/pull/2286) [`09de55f1`](https://github.com/thirdweb-dev/js/commit/09de55f13cbd29b4e0eb57808e0d30f9c1b3ba94) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Expose utilities for creating merkle trees
- [#2291](https://github.com/thirdweb-dev/js/pull/2291) [`53786fc3`](https://github.com/thirdweb-dev/js/commit/53786fc3068568758f033a1c63975c94a8e407f5) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Perfomance improvements by memoizing extensions
- [#2233](https://github.com/thirdweb-dev/js/pull/2233) [`a86478bf`](https://github.com/thirdweb-dev/js/commit/a86478bf248786423d03f4a20d9dc7c02270c371) Thanks [@IDubuque](https://github.com/IDubuque)! - Added support for engine relayer with custom forwarder
- Updated dependencies [[`23d0e553`](https://github.com/thirdweb-dev/js/commit/23d0e553088321edfe3971950c2e7f27209d9aaf)]:
- @thirdweb-dev/chains@0.1.72
## 4.0.34
### Patch Changes
- Updated dependencies [[`357886e3`](https://github.com/thirdweb-dev/js/commit/357886e31b37aad950731ce8f013a101190ebd07)]:
- @thirdweb-dev/chains@0.1.71
## 4.0.33
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/sdk",
"version": "4.0.33",
"version": "4.0.35",
"description": "The main thirdweb SDK.",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
"license": "Apache-2.0",
@@ -1,6 +1,6 @@
import { FeatureName } from "../../constants/contract-features";
import { ContractWrapper } from "../../core/classes/internal/contract-wrapper";
import { AbiSchema } from "../../schema/contracts/custom";
import { AbiInput } from "../../schema/contracts/custom";
import { BaseContract } from "ethers";
import { isExtensionEnabled } from "./isFeatureEnabled";
@@ -14,5 +14,10 @@ export function detectContractFeature<T extends BaseContract>(
contractWrapper: ContractWrapper<BaseContract>,
featureName: FeatureName,
): contractWrapper is ContractWrapper<T> {
return isExtensionEnabled(AbiSchema.parse(contractWrapper.abi), featureName);
const b = isExtensionEnabled(
contractWrapper.abi as AbiInput,
featureName,
contractWrapper.extensions,
);
return b;
}
@@ -4,8 +4,12 @@ import {
SUPPORTED_FEATURES,
} from "../../constants/contract-features";
import { AbiInput } from "../../schema/contracts/custom";
import { createLruCache } from "../utils";
import { hasMatchingAbi, matchesAbiFromBytecode } from "./hasMatchingAbi";
const lruCache =
/* @__PURE__ */ createLruCache<Record<string, FeatureWithEnabled>>(10);
/**
* Processes ALL supported features and sets whether the passed in abi supports each individual feature
* @internal
@@ -16,12 +20,25 @@ import { hasMatchingAbi, matchesAbiFromBytecode } from "./hasMatchingAbi";
export function detectFeatures(
abi: AbiInput,
features: Record<string, Feature> = SUPPORTED_FEATURES,
): Record<string, FeatureWithEnabled> {
const cacheKey = JSON.stringify(abi);
if (lruCache.has(cacheKey)) {
return lruCache.get(cacheKey) as Record<string, FeatureWithEnabled>;
}
const results = detectFeaturesInternal(abi, features);
lruCache.put(cacheKey, results);
return results;
}
function detectFeaturesInternal(
abi: AbiInput,
features: Record<string, Feature>,
): Record<string, FeatureWithEnabled> {
const results: Record<string, FeatureWithEnabled> = {};
for (const featureKey in features) {
const feature = features[featureKey];
const enabled = matchesAbiInterface(abi, feature);
const childResults = detectFeatures(abi, feature.features);
const childResults = detectFeaturesInternal(abi, feature.features);
results[featureKey] = {
...feature,
features: childResults,
@@ -3,7 +3,6 @@ import {
FeatureWithEnabled,
} from "../../constants/contract-features";
import { AbiInput } from "../../schema/contracts/custom";
import { detectFeatures } from "./detectFeatures";
/**
* Checks whether the given ABI supports a given feature
@@ -15,8 +14,8 @@ import { detectFeatures } from "./detectFeatures";
export function isFeatureEnabled(
abi: AbiInput,
featureName: FeatureName,
features: Record<string, FeatureWithEnabled>,
): boolean {
const features = detectFeatures(abi);
return _featureEnabled(features, featureName);
}
@@ -26,8 +25,12 @@ export function isFeatureEnabled(
* @param abi - The abi to check
* @param featureName - The feature name to check
*/
export function isExtensionEnabled(abi: AbiInput, featureName: FeatureName) {
return isFeatureEnabled(abi, featureName);
export function isExtensionEnabled(
abi: AbiInput,
featureName: FeatureName,
features: Record<string, FeatureWithEnabled>,
) {
return isFeatureEnabled(abi, featureName, features);
}
/**
@@ -3,13 +3,14 @@ import {
getAllPluginsAbi,
} from "../../constants/thirdweb-features";
import { ContractWrapper } from "../../core/classes/internal/contract-wrapper";
import { Abi, AbiSchema } from "../../schema/contracts/custom";
import { Abi } from "../../schema/contracts/custom";
import { SDKOptions } from "../../schema/sdk-options";
import { isExtensionEnabled } from "../feature-detection/isFeatureEnabled";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { Contract, providers } from "ethers";
import { joinABIs } from "./joinABIs";
import { getPluginABI } from "./getPluginABI";
import { detectFeatures } from "../feature-detection/detectFeatures";
/**
* @internal
@@ -24,21 +25,21 @@ export async function getCompositeABI(
let pluginABIs: Abi[] = [];
try {
// TODO this should not be needed here, should only be done once in getContract()
const features = detectFeatures(abi);
// check if contract is plugin-pattern / dynamic
const isPluginRouter: boolean = isExtensionEnabled(
AbiSchema.parse(abi),
abi,
"PluginRouter",
features,
);
const isbaseRouter: boolean = isExtensionEnabled(
AbiSchema.parse(abi),
abi,
"DynamicContract",
features,
);
// check if the contract has fallback function - we'll further check for diamond pattern if needed
const isFallback: boolean = isExtensionEnabled(
AbiSchema.parse(abi),
"Fallback",
);
const isFallback: boolean = isExtensionEnabled(abi, "Fallback", features);
if (isbaseRouter) {
const contract = new ContractWrapper(
@@ -1,14 +0,0 @@
import { Abi, AbiSchema } from "../../schema/contracts/custom";
import { isFeatureEnabled } from "../feature-detection/isFeatureEnabled";
export function isRouterContract(abi: Abi) {
const isPluginRouter: boolean = isFeatureEnabled(
AbiSchema.parse(abi),
"PluginRouter",
);
const isBaseRouter: boolean = isFeatureEnabled(
AbiSchema.parse(abi),
"DynamicContract",
);
return isBaseRouter || isPluginRouter;
}
+69 -1
View File
@@ -8,8 +8,10 @@ import {
SnapshotFormatVersion,
} from "./sharded-merkle-tree";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { providers } from "ethers";
import { providers, utils } from "ethers";
import { parseSnapshotInputs } from "./parseSnapshotInputs";
import { MerkleTree } from "@thirdweb-dev/merkletree";
import { SnapshotEntry } from "../schema/contracts/common/snapshots";
/**
* Create a snapshot (merkle tree) from a list of addresses and uploads it to IPFS
@@ -47,3 +49,69 @@ export async function createSnapshot(
snapshotUri: tree.uri,
};
}
/**
* Create a MerkleTree based on an allow list of addresses and maxClaimable
* @param snapshotInput - the list of addresses and maxClaimable
* @param tokenDecimals - optional decimals for the token to claim (default 18)
* @param version - optional version of the snapshot format (default V1)
* @returns The generated MerkleTree
*/
export async function createMerkleTreeFromAllowList(
snapshotInput: SnapshotInput,
tokenDecimals: number = 18,
version: SnapshotFormatVersion = SnapshotFormatVersion.V1,
): Promise<MerkleTree> {
const input = await parseSnapshotInputs(snapshotInput);
const addresses = input.map((i) => i.address);
const hasDuplicates = new Set(addresses).size < addresses.length;
if (hasDuplicates) {
throw new DuplicateLeafsError();
}
const leaves = input.map((i) => {
return hashAllowListEntry(i, tokenDecimals, version);
});
const tree = new MerkleTree(leaves, utils.keccak256, {
sort: true,
});
return tree;
}
/**
* Get the proofs for a given entry of addresses
* @param merkleTree - the merkle tree to get the proof from
* @param snapshotEntry - the entry to get the proof for
* @param tokenDecimals - optional decimals for the token to claim (default 18)
* @param version - optional version of the snapshot format (default V1)
* @returns
*/
export async function getProofsForAllowListEntry(
merkleTree: MerkleTree,
snapshotEntry: SnapshotEntry,
tokenDecimals: number = 18,
version: SnapshotFormatVersion = SnapshotFormatVersion.V1,
) {
return merkleTree.getProof(
hashAllowListEntry(snapshotEntry, tokenDecimals, version),
);
}
/**
* Hash an allow list entry for use in a MerkleTree
* @param snapshotEntry - the entry to hash
* @param tokenDecimals - optional decimals for the token to claim (default 18)
* @param version - optional version of the snapshot format (default V1)
* @returns
*/
export function hashAllowListEntry(
snapshotEntry: SnapshotEntry,
tokenDecimals: number = 18,
version: SnapshotFormatVersion = SnapshotFormatVersion.V1,
) {
return ShardedMerkleTree.hashEntry(
snapshotEntry,
tokenDecimals,
tokenDecimals,
version,
);
}
@@ -48,6 +48,7 @@ import { Transaction } from "./transactions";
import { fetchAndCacheDeployMetadata } from "../../common/any-evm-utils/fetchAndCacheDeployMetadata";
import { fetchPublishedContractFromPolygon } from "../../common/any-evm-utils/fetchPublishedContractFromPolygon";
import { isFeatureEnabled } from "../../common/feature-detection/isFeatureEnabled";
import { detectFeatures } from "../../common/feature-detection/detectFeatures";
/**
* Handles publishing contracts (EXPERIMENTAL)
@@ -225,9 +226,8 @@ export class ContractPublisher extends RPCConnectionHandler {
address: AddressOrEns,
): Promise<ContractSource[]> {
const resolvedAddress = await resolveAddress(address);
const metadata = await this.fetchCompilerMetadataFromAddress(
resolvedAddress,
);
const metadata =
await this.fetchCompilerMetadataFromAddress(resolvedAddress);
return await fetchSourceFilesFromMetadata(metadata, this.storage);
}
@@ -395,19 +395,22 @@ export class ContractPublisher extends RPCConnectionHandler {
predeployMetadata.metadataUri,
this.storage,
);
const features = detectFeatures(compilerMetadata.abi);
const isPlugin = isFeatureEnabled(
AbiSchema.parse(compilerMetadata.abi),
compilerMetadata.abi,
"PluginRouter",
features,
);
const isDynamic = isFeatureEnabled(
AbiSchema.parse(compilerMetadata.abi),
compilerMetadata.abi,
"DynamicContract",
features,
);
extraMetadataCleaned.routerType = isPlugin
? "plugin"
: isDynamic
? "dynamic"
: "none";
? "dynamic"
: "none";
// For a dynamic contract Router, try to fetch plugin/extension metadata
if (isDynamic || isPlugin) {
@@ -455,9 +458,8 @@ export class ContractPublisher extends RPCConnectionHandler {
predeployMetadata.name,
);
if (latestContract && latestContract.metadataUri) {
const latestMetadata = await this.fetchPublishedContractInfo(
latestContract,
);
const latestMetadata =
await this.fetchPublishedContractInfo(latestContract);
const latestVersion = latestMetadata.publishedMetadata.version;
if (
@@ -44,6 +44,7 @@ import {
} from "../../types";
import { RPCConnectionHandler } from "./rpc-connection-handler";
import { isBrowser } from "../../../common/utils";
import { detectFeatures } from "../../../common/feature-detection/detectFeatures";
/**
* @internal
@@ -61,6 +62,8 @@ export class ContractWrapper<
public readContract;
public abi;
public address;
public functions;
public extensions;
constructor(
network: NetworkInput,
@@ -70,7 +73,7 @@ export class ContractWrapper<
storage: ThirdwebStorage,
) {
super(network, options);
this.abi = contractAbi;
this.abi = AbiSchema.parse(contractAbi);
this.address = contractAddress;
// set up the contract
this.writeContract = new Contract(
@@ -83,6 +86,8 @@ export class ContractWrapper<
this.getProvider(),
) as TContract;
this.storage = storage;
this.functions = extractFunctionsFromAbi(this.abi);
this.extensions = detectFeatures(this.abi);
}
public override updateSignerOrProvider(network: NetworkInput): void {
@@ -112,6 +117,8 @@ export class ContractWrapper<
) as TContract;
this.abi = AbiSchema.parse(updatedAbi);
this.functions = extractFunctionsFromAbi(this.abi);
this.extensions = detectFeatures(this.abi);
}
/**
@@ -215,10 +222,7 @@ export class ContractWrapper<
? Awaited<ReturnType<OverrideContract["functions"][FnName]>>[0]
: Awaited<ReturnType<OverrideContract["functions"][FnName]>>
> {
const functions = extractFunctionsFromAbi(AbiSchema.parse(this.abi)).filter(
(f) => f.name === functionName,
);
const functions = this.functions.filter((f) => f.name === functionName);
if (!functions.length) {
throw new Error(
`Function "${functionName.toString()}" not found in contract. Check your dashboard for the list of functions available`,
@@ -689,6 +693,11 @@ export class ContractWrapper<
}
private async enginePrepareRequest(transaction: GaslessTransaction) {
invariant(
this.options.gasless && "engine" in this.options.gasless,
"calling engine gasless transaction without openzeppelin config in the SDK options",
);
const signer = this.getSigner();
const provider = this.getProvider();
const storage = this.storage;
@@ -793,6 +802,7 @@ export class ContractWrapper<
};
} else {
const forwarderAddress =
this.options.gasless.engine.relayerForwarderAddress ||
CONTRACT_ADDRESSES[
transaction.chainId as keyof typeof CONTRACT_ADDRESSES
]?.openzeppelinForwarder ||
@@ -806,24 +816,51 @@ export class ContractWrapper<
transaction.from,
]);
const domain = {
name: "GSNv2 Forwarder",
version: "0.0.1",
chainId: transaction.chainId,
verifyingContract: forwarderAddress,
};
const types = {
ForwardRequest,
};
let domain;
let types;
let message: ForwardRequestMessage;
const message = {
from: transaction.from,
to: transaction.to,
value: BigNumber.from(0).toString(),
gas: BigNumber.from(transaction.gasLimit).toString(),
nonce: BigNumber.from(nonce).toString(),
data: transaction.data,
};
if (this.options.gasless.experimentalChainlessSupport) {
domain = {
name: "GSNv2 Forwarder",
version: "0.0.1",
verifyingContract: forwarderAddress,
};
types = {
ForwardRequest: ChainAwareForwardRequest,
};
message = {
from: transaction.from,
to: transaction.to,
value: BigNumber.from(0).toString(),
gas: BigNumber.from(transaction.gasLimit).toString(),
nonce: BigNumber.from(nonce).toString(),
data: transaction.data,
chainid: BigNumber.from(transaction.chainId).toString(),
};
} else {
domain = {
name: this.options.gasless.engine.domainName,
version: this.options.gasless.engine.domainVersion,
chainId: transaction.chainId,
verifyingContract: forwarderAddress,
};
types = {
ForwardRequest,
};
message = {
from: transaction.from,
to: transaction.to,
value: BigNumber.from(0).toString(),
gas: BigNumber.from(transaction.gasLimit).toString(),
nonce: BigNumber.from(nonce).toString(),
data: transaction.data,
};
}
const { signature: sig } = await signTypedDataInternal(
signer,
@@ -5,7 +5,6 @@ import {
getContractMetadataFromCache,
} from "../../common/metadata-resolver";
import { fetchSourceFilesFromMetadata } from "../../common/fetchSourceFilesFromMetadata";
import { isRouterContract } from "../../common/plugin/isRouterContract";
import { ContractSource } from "../../schema/contracts/custom";
import { SDKOptionsOutput } from "../../schema/sdk-options";
import type {
@@ -448,17 +447,6 @@ export class Transaction<
// First, if no gasLimit is passed, call estimate gas ourselves
if (!overrides.gasLimit) {
overrides.gasLimit = await this.estimateGasLimit();
try {
// for dynamic contracts, add 30% to the gas limit to account for multiple delegate calls
const abi = JSON.parse(
this.contract.interface.format("json") as string,
);
if (isRouterContract(abi)) {
overrides.gasLimit = overrides.gasLimit.mul(110).div(100);
}
} catch (err) {
console.warn("Error raising gas limit", err);
}
}
// Now there should be no gas estimate errors
@@ -917,6 +905,7 @@ export async function engineSendFunction(
signer,
provider,
storage,
gaslessOptions,
);
const res = await fetch(gaslessOptions.engine.relayerUrl, {
@@ -1020,7 +1009,13 @@ async function enginePrepareRequest(
signer: Signer,
provider: providers.Provider,
storage: ThirdwebStorage,
gaslessOptions?: SDKOptionsOutput["gasless"],
) {
invariant(
gaslessOptions && "engine" in gaslessOptions,
"calling engine gasless transaction without openzeppelin config in the SDK options",
);
try {
const metadata = await fetchContractMetadataFromAddress(
transaction.to,
@@ -1126,6 +1121,7 @@ async function enginePrepareRequest(
};
} else {
const forwarderAddress =
gaslessOptions.engine.relayerForwarderAddress ||
CONTRACT_ADDRESSES[transaction.chainId as keyof typeof CONTRACT_ADDRESSES]
?.openzeppelinForwarder ||
(await computeForwarderAddress(provider, storage));
@@ -1138,24 +1134,51 @@ async function enginePrepareRequest(
transaction.from,
]);
const domain = {
name: "GSNv2 Forwarder",
version: "0.0.1",
chainId: transaction.chainId,
verifyingContract: forwarderAddress,
};
const types = {
ForwardRequest,
};
let domain;
let types;
let message: ForwardRequestMessage;
const message = {
from: transaction.from,
to: transaction.to,
value: BigNumber.from(0).toString(),
gas: BigNumber.from(transaction.gasLimit).toString(),
nonce: BigNumber.from(nonce).toString(),
data: transaction.data,
};
if (gaslessOptions.experimentalChainlessSupport) {
domain = {
name: "GSNv2 Forwarder",
version: "0.0.1",
verifyingContract: forwarderAddress,
};
types = {
ForwardRequest: ChainAwareForwardRequest,
};
message = {
from: transaction.from,
to: transaction.to,
value: BigNumber.from(0).toString(),
gas: BigNumber.from(transaction.gasLimit).toString(),
nonce: BigNumber.from(nonce).toString(),
data: transaction.data,
chainid: BigNumber.from(transaction.chainId).toString(),
};
} else {
domain = {
name: gaslessOptions.engine.domainName,
version: gaslessOptions.engine.domainVersion,
chainId: transaction.chainId,
verifyingContract: forwarderAddress,
};
types = {
ForwardRequest,
};
message = {
from: transaction.from,
to: transaction.to,
value: BigNumber.from(0).toString(),
gas: BigNumber.from(transaction.gasLimit).toString(),
nonce: BigNumber.from(nonce).toString(),
data: transaction.data,
};
}
const { signature: sig } = await signTypedDataInternal(
signer,
@@ -55,7 +55,6 @@ export class StaticJsonRpcBatchProvider extends providers.StaticJsonRpcProvider
request: utils.deepCopy(request),
provider: this,
});
return utils.fetchJson(this.connection, JSON.stringify(request_)).then(
(result) => {
this.emit("debug", {
@@ -55,7 +55,11 @@ export const SDKOptionsSchema = /* @__PURE__ */ (() =>
.string()
.url()
.transform((url) => url.replace(/\/$/, "")),
relayerForwarderAddress: z.string().optional(),
domainName: z.string().default("GSNv2 Forwarder"),
domainVersion: z.string().default("0.0.1"),
}),
experimentalChainlessSupport: z.boolean().default(false),
}),
])
.optional(),
@@ -1,5 +1,10 @@
import { assert } from "chai";
import { AbiSchema, SmartContract, isExtensionEnabled } from "../../src/evm";
import {
AbiSchema,
SmartContract,
detectFeatures,
isExtensionEnabled,
} from "../../src/evm";
import { jsonProvider, sdk, signers } from "./before-setup";
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import {
@@ -34,7 +39,13 @@ describe("Base Router for Dynamic Contracts", async () => {
it("should detect base router in a dynamic contract", async () => {
const contract = await sdk.getContract(coreRouterAddress);
assert(isExtensionEnabled(contract.abi, "DynamicContract"));
assert(
isExtensionEnabled(
contract.abi,
"DynamicContract",
detectFeatures(contract.abi),
),
);
});
it("should add extensions", async () => {
@@ -118,7 +129,8 @@ describe("Base Router for Dynamic Contracts", async () => {
let extensions = await coreRouter.extensions.getAll();
assert(extensions.length === 1);
assert(extensions[0].metadata.name === "OffersLogic");
assert(isExtensionEnabled(coreRouter.abi, "Offers"));
const features = detectFeatures(coreRouter.abi);
assert(isExtensionEnabled(coreRouter.abi, "Offers", features));
// replace extension
const newAddress = await deployContractAndUploadMetadata(
@@ -175,7 +187,13 @@ describe("Base Router for Dynamic Contracts", async () => {
const oldURI = extensions[0].metadata.metadataURI;
assert(extensions.length === 1);
assert(extensions[0].metadata.name === "OffersLogic");
assert(isExtensionEnabled(coreRouter.abi, "Offers"));
assert(
isExtensionEnabled(
coreRouter.abi,
"Offers",
detectFeatures(coreRouter.abi),
),
);
// update extension
const newAddress = await deployContractAndUploadMetadata(
@@ -196,7 +214,13 @@ describe("Base Router for Dynamic Contracts", async () => {
assert(extensions[0].metadata.name === "OffersLogic");
assert(extensions[0].metadata.implementation === newAddress);
assert(extensions[0].metadata.metadataURI !== oldURI);
assert(isExtensionEnabled(coreRouter.abi, "Offers"));
assert(
isExtensionEnabled(
coreRouter.abi,
"Offers",
detectFeatures(coreRouter.abi),
),
);
});
it("should remove extensions", async () => {
@@ -229,7 +253,13 @@ describe("Base Router for Dynamic Contracts", async () => {
let extensions = await coreRouter.extensions.getAll();
assert(extensions.length === 1);
assert(extensions[0].metadata.name === "OffersLogic");
assert(isExtensionEnabled(coreRouter.abi, "Offers"));
assert(
isExtensionEnabled(
coreRouter.abi,
"Offers",
detectFeatures(coreRouter.abi),
),
);
// remove extension
await coreRouter.extensions.remove({
@@ -241,7 +271,13 @@ describe("Base Router for Dynamic Contracts", async () => {
assert(extensions.length === 0);
// call function on extension
assert(!isExtensionEnabled(coreRouter.abi, "Offers"));
assert(
!isExtensionEnabled(
coreRouter.abi,
"Offers",
detectFeatures(coreRouter.abi),
),
);
});
it("should get extension for function", async () => {
+25 -10
View File
@@ -11,6 +11,7 @@ import {
IERC1155__factory,
} from "@thirdweb-dev/contracts-js";
import {
detectFeatures,
getAllDetectedExtensionNames,
isExtensionEnabled,
matchesAbiFromBytecode,
@@ -75,26 +76,40 @@ describe("Feature Detection", async () => {
});
it("should extract features", async () => {
let features = detectFeatures(TokenERC721__factory.abi);
expect(
isExtensionEnabled(TokenERC721__factory.abi, "ERC721Enumerable"),
isExtensionEnabled(
TokenERC721__factory.abi,
"ERC721Enumerable",
features,
),
).to.eq(true);
expect(
isExtensionEnabled(TokenERC721__factory.abi, "ERC721Mintable"),
isExtensionEnabled(TokenERC721__factory.abi, "ERC721Mintable", features),
).to.eq(true);
expect(
isExtensionEnabled(TokenERC721__factory.abi, "ERC721BatchMintable"),
isExtensionEnabled(
TokenERC721__factory.abi,
"ERC721BatchMintable",
features,
),
).to.eq(true);
// Drop
features = detectFeatures(DropERC721__factory.abi);
expect(
isExtensionEnabled(DropERC721__factory.abi, "ERC721ClaimPhasesV2"),
isExtensionEnabled(
DropERC721__factory.abi,
"ERC721ClaimPhasesV2",
features,
),
).to.eq(true);
expect(isExtensionEnabled(DropERC721__factory.abi, "ERC721Supply")).to.eq(
true,
);
expect(isExtensionEnabled(DropERC721__factory.abi, "ERC721Mintable")).to.eq(
false,
);
expect(
isExtensionEnabled(DropERC721__factory.abi, "ERC721Supply", features),
).to.eq(true);
expect(
isExtensionEnabled(DropERC721__factory.abi, "ERC721Mintable", features),
).to.eq(false);
});
it("should extract all features", async () => {
Binary file not shown.
+16
View File
@@ -1,5 +1,21 @@
# @thirdweb-dev/service-utils
## 0.4.17
### Patch Changes
- [#2281](https://github.com/thirdweb-dev/js/pull/2281) [`77400fcf`](https://github.com/thirdweb-dev/js/commit/77400fcf212b7dba138e3422c05136d6043fe361) Thanks [@farhanW3](https://github.com/farhanW3)! - Added new properties to usage
- [#2287](https://github.com/thirdweb-dev/js/pull/2287) [`537e5e06`](https://github.com/thirdweb-dev/js/commit/537e5e063db282e8777e01bdd1e9afcdec7c9ef5) Thanks [@farhanW3](https://github.com/farhanW3)! - Added new field to capture response time
## 0.4.16
### Patch Changes
- [#2273](https://github.com/thirdweb-dev/js/pull/2273) [`9096bdc0`](https://github.com/thirdweb-dev/js/commit/9096bdc0f1c182a5dc47db7a613978917d1fa006) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add latency prop to logHttpRequest
- [#2273](https://github.com/thirdweb-dev/js/pull/2273) [`9096bdc0`](https://github.com/thirdweb-dev/js/commit/9096bdc0f1c182a5dc47db7a613978917d1fa006) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add latency prop to CF worker logs
## 0.4.15
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/service-utils",
"version": "0.4.15",
"version": "0.4.17",
"main": "dist/thirdweb-dev-service-utils.cjs.js",
"module": "dist/thirdweb-dev-service-utils.esm.js",
"exports": {
@@ -181,11 +181,13 @@ export async function logHttpRequest({
res,
isAuthed,
statusMessage,
latencyMs,
}: AuthInput & {
source: string;
res: Response;
isAuthed?: boolean;
statusMessage?: Error | string;
latencyMs?: number;
}) {
try {
const authorizationData = await extractAuthorizationData({ req, clientId });
@@ -204,6 +206,8 @@ export async function logHttpRequest({
sdkName: headers.get("x-sdk-name") ?? "unknown",
sdkVersion: headers.get("x-sdk-version") ?? "unknown",
platform: headers.get("x-sdk-platform") ?? "unknown",
os: headers.get("x-sdk-os") ?? "unknown",
latencyMs: latencyMs ?? null,
}),
);
console.log(`statusMessage=${statusMessage ?? res.statusText}`);
@@ -62,6 +62,9 @@ const usageEventSchema = z.object({
extension: z.string().optional(),
retryCount: z.number().int().nonnegative().optional(),
policyId: z.string().optional(),
msSinceQueue: z.number().nonnegative().optional(),
msSinceSend: z.number().nonnegative().optional(),
msTotalDuration: z.number().nonnegative().optional(),
});
export type UsageEvent = z.infer<typeof usageEventSchema>;
Binary file not shown.
+22
View File
@@ -1,5 +1,27 @@
# @thirdweb-dev/unity-js-bridge
## 0.3.16
### Patch Changes
- [#2284](https://github.com/thirdweb-dev/js/pull/2284) [`185093c1`](https://github.com/thirdweb-dev/js/commit/185093c18567619c837f70eb45df1e6ee3eef6ed) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - Unity 4.6.2
- Updated dependencies [[`09de55f1`](https://github.com/thirdweb-dev/js/commit/09de55f13cbd29b4e0eb57808e0d30f9c1b3ba94), [`53786fc3`](https://github.com/thirdweb-dev/js/commit/53786fc3068568758f033a1c63975c94a8e407f5), [`a86478bf`](https://github.com/thirdweb-dev/js/commit/a86478bf248786423d03f4a20d9dc7c02270c371), [`23d0e553`](https://github.com/thirdweb-dev/js/commit/23d0e553088321edfe3971950c2e7f27209d9aaf)]:
- @thirdweb-dev/sdk@4.0.35
- @thirdweb-dev/chains@0.1.72
- @thirdweb-dev/wallets@2.4.10
- @thirdweb-dev/auth@4.1.32
## 0.3.15
### Patch Changes
- Updated dependencies [[`0092e2a3`](https://github.com/thirdweb-dev/js/commit/0092e2a3177364ad26af15ecafb4381591dc9be1), [`357886e3`](https://github.com/thirdweb-dev/js/commit/357886e31b37aad950731ce8f013a101190ebd07)]:
- @thirdweb-dev/auth@4.1.31
- @thirdweb-dev/chains@0.1.71
- @thirdweb-dev/sdk@4.0.34
- @thirdweb-dev/wallets@2.4.9
## 0.3.14
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/unity-js-bridge",
"version": "0.3.14",
"version": "0.3.16",
"main": "dist/thirdweb-unity-bridge.js",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
"license": "Apache-2.0",
@@ -143,7 +143,7 @@ class ThirdwebBridge implements TWBridge {
}
(globalThis as any).X_SDK_NAME = "UnitySDK_WebGL";
(globalThis as any).X_SDK_PLATFORM = "unity";
(globalThis as any).X_SDK_VERSION = "4.6.1";
(globalThis as any).X_SDK_VERSION = "4.6.2";
(globalThis as any).X_SDK_OS = browser?.os ?? "unknown";
}
this.initializedChain = chain;
+16
View File
@@ -1,5 +1,21 @@
# @thirdweb-dev/wallets
## 2.4.10
### Patch Changes
- Updated dependencies [[`09de55f1`](https://github.com/thirdweb-dev/js/commit/09de55f13cbd29b4e0eb57808e0d30f9c1b3ba94), [`53786fc3`](https://github.com/thirdweb-dev/js/commit/53786fc3068568758f033a1c63975c94a8e407f5), [`a86478bf`](https://github.com/thirdweb-dev/js/commit/a86478bf248786423d03f4a20d9dc7c02270c371), [`23d0e553`](https://github.com/thirdweb-dev/js/commit/23d0e553088321edfe3971950c2e7f27209d9aaf)]:
- @thirdweb-dev/sdk@4.0.35
- @thirdweb-dev/chains@0.1.72
## 2.4.9
### Patch Changes
- Updated dependencies [[`357886e3`](https://github.com/thirdweb-dev/js/commit/357886e31b37aad950731ce8f013a101190ebd07)]:
- @thirdweb-dev/chains@0.1.71
- @thirdweb-dev/sdk@4.0.34
## 2.4.8
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/wallets",
"version": "2.4.8",
"version": "2.4.10",
"main": "dist/thirdweb-dev-wallets.cjs.js",
"module": "dist/thirdweb-dev-wallets.esm.js",
"browser": {
@@ -6,6 +6,8 @@ import { Buffer } from "buffer";
if (typeof window !== "undefined") {
// Coinbase SDK uses Buffer for rendering the QRCode which requires a global polyfill
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.Buffer = Buffer;
}
Binary file not shown.