Compare commits

...
Author SHA1 Message Date
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
5cea8436c1 Version Packages (#1341)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-07-17 15:10:05 +02:00
Joaquim VergesandGitHub dac8fa7d98 [SDK] Fix getOwned missing last owner for OpenEdition contracts (#1357) 2023-07-15 22:13:58 +00:00
Joaquim VergesandGitHub 7a6534d1a9 [React] Fix wrong enabled logic in useOwnedNFTs (#1356) 2023-07-15 05:02:06 +00:00
Tair AsimandGitHub d5aee62bf4 [service-utils] remove unused type (#1355) 2023-07-14 23:33:28 +00:00
Tair AsimandGitHub 0bfdedd4ba [service-utils] fix enforce auth param (#1354) 2023-07-14 23:18:10 +00:00
Joaquim VergesandGitHub c5761b99e9 [Wallets] Switch local wallet to seed based wallets (#1352) 2023-07-14 23:07:59 +00:00
Tair AsimandGitHub 42d9ab68d9 [service-utils] allow to skip auth for backwards compat (#1353) 2023-07-14 22:27:14 +00:00
farhanW3andGitHub fd0650dcac Farhan/service utils fix (#1351) 2023-07-14 20:52:30 +00:00
Tair AsimandGitHub ddb3dabe69 [service-utils] allow target addresses and api url stringy (#1349) 2023-07-14 19:17:28 +00:00
Manan TankandGitHub b96a228273 [wallets, react] Various improvements (#1350) 2023-07-14 18:26:26 +00:00
Tair AsimandGitHub 781e26d896 [service-utils] authorize bundle (#1347) 2023-07-14 16:47:22 +00:00
Tair AsimandGitHub f7392138ee [service-utils] api url fix (#1346) 2023-07-14 09:52:23 +00:00
Jonas DanielsandGitHub 5eb6fc1bf3 [service-utils] - rewrite (#1345) 2023-07-14 08:21:03 +00:00
Danny FridayandGitHub 7dc685bbec Add creatorWalletAddress to ApiKey type (#1343) 2023-07-14 04:11:26 +00:00
Jonas DanielsandGitHub 4915ac50f8 [service-utils] add relayer service definition (#1342) 2023-07-14 04:02:47 +00:00
Jonas DanielsandGitHub d724ad85c5 [service-utils] - fix use endpoint (#1340) 2023-07-14 00:27:25 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
1d32b299a0 Version Packages (#1337)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-07-13 16:02:54 -07:00
Tair AsimandGitHub cfa7ecbc9a service-utils: remove crypt + unfetch (#1339) 2023-07-13 22:20:42 +00:00
Jonas DanielsandGitHub 8dd7540c45 [storage] - remove HEAD request pre upload (#1338) 2023-07-13 21:57:30 +00:00
07c7d97c28 [service-utils] - initially add package (#1333)
Co-authored-by: Tair Asim <[email protected]>
2023-07-13 20:51:55 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
47e931e0dd Version Packages (#1336)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-07-13 09:25:13 -07:00
Jonas DanielsandGitHub 0407b2c2f3 [chains] update chains (#1335) 2023-07-13 16:01:04 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
55ffb176f2 Version Packages (#1331)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-07-12 19:28:04 -07:00
Adam MajmudarandGitHub a9093bcf28 Override binance chain slug (#1330) 2023-07-12 19:17:58 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
db964131b4 Version Packages (#1329)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-07-12 18:56:29 -07:00
Adam MajmudarandGitHub 4393b22805 Make base default chain (#1328) 2023-07-12 18:42:27 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
b28c3a5a67 Version Packages (#1327)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-07-12 18:29:43 -07:00
Adam MajmudarandGitHub 4068219145 [Chains] Add support for base (#1326) 2023-07-13 00:25:33 +00:00
86 changed files with 3297 additions and 713 deletions
+42
View File
@@ -1,5 +1,47 @@
# @thirdweb-dev/auth
## 3.2.16
### Patch Changes
- Updated dependencies [[`c5761b99`](https://github.com/thirdweb-dev/js/commit/c5761b99e9797772481506e90cbfa5c35a05bd1d), [`b96a2282`](https://github.com/thirdweb-dev/js/commit/b96a2282730582b684cc96802649a96851af5220)]:
- @thirdweb-dev/wallets@1.0.12
## 3.2.15
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@1.0.11
## 3.2.14
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@1.0.10
## 3.2.13
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@1.0.9
## 3.2.12
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@1.0.8
## 3.2.11
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@1.0.7
## 3.2.10
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "3.2.10",
"version": "3.2.16",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
+30
View File
@@ -1,5 +1,35 @@
# @thirdweb-dev/chains
## 0.1.34
### Patch Changes
- [#1338](https://github.com/thirdweb-dev/js/pull/1338) [`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains
## 0.1.33
### Patch Changes
- [#1335](https://github.com/thirdweb-dev/js/pull/1335) [`0407b2c2`](https://github.com/thirdweb-dev/js/commit/0407b2c2f39b5f3fa06e613e671623b5644b3a28) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains again
## 0.1.32
### Patch Changes
- [#1330](https://github.com/thirdweb-dev/js/pull/1330) [`a9093bcf`](https://github.com/thirdweb-dev/js/commit/a9093bcf287c01e3335fd780e2ccbfdb3380bf95) Thanks [@adam-maj](https://github.com/adam-maj)! - Override binance slug
## 0.1.31
### Patch Changes
- [#1328](https://github.com/thirdweb-dev/js/pull/1328) [`4393b228`](https://github.com/thirdweb-dev/js/commit/4393b2280505fd0b2284555d64eae6567e8401a5) Thanks [@adam-maj](https://github.com/adam-maj)! - Make base default chain
## 0.1.30
### Patch Changes
- [#1326](https://github.com/thirdweb-dev/js/pull/1326) [`40682191`](https://github.com/thirdweb-dev/js/commit/40682191450de08ad40b9d2957afced248657af2) Thanks [@adam-maj](https://github.com/adam-maj)! - Add base chain support
## 0.1.29
### Patch Changes
-38
View File
@@ -1,38 +0,0 @@
import type { Chain } from "../src/types";
export default {
"name": "ShimmerEVM Testnet",
"title": "ShimmerEVM Testnet",
"chain": "ShimmerEVM",
"icon": {
"url": "ipfs://bafkreibky2sy6qhi6arktayvologkrgu5kudpgdxfkx4uosbvmstz7v4di",
"width": 720,
"height": 720,
"format": "png"
},
"rpc": [
"https://shimmerevm-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://json-rpc.evm.testnet.shimmer.network"
],
"faucets": [
"https://evm-toolkit.evm.testnet.shimmer.network",
"https://evm-faucet.testnet.shimmer.network"
],
"nativeCurrency": {
"name": "SMR",
"symbol": "SMR",
"decimals": 18
},
"infoURL": "https://shimmer.network",
"shortName": "shimmerevm-testnet",
"chainId": 1071,
"networkId": 1071,
"explorers": [
{
"name": "explorer",
"url": "https://explorer.evm.testnet.shimmer.network",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "shimmerevm-testnet"
} as const satisfies Chain;
+34
View File
@@ -0,0 +1,34 @@
import type { Chain } from "../src/types";
export default {
"name": "MXC zkEVM Mainnet",
"chain": "MXC zkEVM",
"icon": {
"url": "ipfs://QmdGCthKA11K9kCZJdbTP5WPAyq1wiRZ3REn6KG58MrWaE",
"width": 159,
"height": 159,
"format": "png"
},
"rpc": [
"https://mxc-zkevm.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.mxc.com"
],
"faucets": [],
"nativeCurrency": {
"name": "MXC zkEVM Mainnet",
"symbol": "MXC",
"decimals": 18
},
"infoURL": "https://doc.mxc.com/docs/intro",
"shortName": "MXCzkEVM",
"chainId": 18686,
"networkId": 18686,
"explorers": [
{
"name": "MXC zkEVM Mainnet",
"url": "https://explorer.mxc.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "mxc-zkevm"
} as const satisfies Chain;
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"name": "Antofy Testnet",
"chain": "ABN",
"icon": {
"url": "ipfs://QmdTfku81ohnG9ECU1Xswmeumt678cBhwHWuFYZ7i1Qsto",
"width": 400,
"height": 400,
"format": "png"
},
"rpc": [
"https://antofy-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-rpc.antofy.io"
],
"faucets": [
"https://faucet.antofy.io"
],
"nativeCurrency": {
"name": "Antofy",
"symbol": "ABN",
"decimals": 18
},
"infoURL": "https://antofy.io",
"shortName": "ABNt",
"chainId": 23006,
"networkId": 23006,
"explorers": [
{
"name": "Antofy Testnet",
"url": "https://test.antofyscan.com",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "antofy-testnet"
} as const satisfies Chain;
+50
View File
@@ -0,0 +1,50 @@
import type { Chain } from "../src/types";
export default {
"name": "Kroma Sepolia",
"title": "Kroma Testnet Sepolia",
"chainId": 2358,
"shortName": "kroma-sepolia",
"chain": "ETH",
"networkId": 2358,
"nativeCurrency": {
"name": "Sepolia Ether",
"symbol": "ETH",
"decimals": 18
},
"rpc": [
"https://kroma-sepolia.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://api.sepolia.kroma.network"
],
"faucets": [],
"infoURL": "https://kroma.network",
"icon": {
"url": "ipfs://QmcYafk2je5rMqgnFPDZJTaLi6dgFgq96vmX2Li6DX441B",
"width": 320,
"height": 320,
"format": "svg"
},
"explorers": [
{
"name": "blockscout",
"url": "https://blockscout.sepolia.kroma.network",
"icon": {
"url": "ipfs://QmcYafk2je5rMqgnFPDZJTaLi6dgFgq96vmX2Li6DX441B",
"width": 320,
"height": 320,
"format": "svg"
},
"standard": "EIP3091"
}
],
"parent": {
"type": "L2",
"chain": "eip155-11155111",
"bridges": [
{
"url": "https://kroma.network/bridge"
}
]
},
"testnet": true,
"slug": "kroma-sepolia"
} as const satisfies Chain;
+1 -4
View File
@@ -2,10 +2,7 @@ import type { Chain } from "../src/types";
export default {
"name": "Neon EVM MainNet",
"chain": "Solana",
"rpc": [
"https://neon-evm.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet.neonevm.org"
],
"rpc": [],
"faucets": [],
"icon": {
"url": "ipfs://Qmcxevb3v8PEvnvfYgcG3bCBuPhe5YAdsHeaufDChSSR3Q",
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"name": "EgonCoin Mainnet",
"chain": "EGON",
"icon": {
"url": "ipfs://QmNZiMmzMQYjyGtNSghtzLg4UooYhDgMQsa677DAP5KsBg",
"width": 512,
"height": 512,
"format": "png"
},
"rpc": [
"https://egoncoin.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.egcscan.com"
],
"faucets": [
"https://faucet.egcscan.com"
],
"nativeCurrency": {
"name": "EgonCoin",
"symbol": "EGON",
"decimals": 18
},
"infoURL": "https://egcscan.com",
"shortName": "EGONm",
"chainId": 271,
"networkId": 271,
"explorers": [
{
"name": "EgonCoin Mainnet",
"url": "https://egcscan.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "egoncoin"
} as const satisfies Chain;
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"name": "EgonCoin Testnet",
"chain": "EGON",
"icon": {
"url": "ipfs://QmNZiMmzMQYjyGtNSghtzLg4UooYhDgMQsa677DAP5KsBg",
"width": 512,
"height": 512,
"format": "png"
},
"rpc": [
"https://egoncoin-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpctest.egcscan.com"
],
"faucets": [
"https://faucet.egcscan.com"
],
"nativeCurrency": {
"name": "EgonCoin",
"symbol": "EGON",
"decimals": 18
},
"infoURL": "https://egcscan.com",
"shortName": "EGONt",
"chainId": 271271,
"networkId": 271271,
"explorers": [
{
"name": "EgonCoin Testnet",
"url": "https://testnet.egcscan.com",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "egoncoin-testnet"
} as const satisfies Chain;
+6 -1
View File
@@ -4,7 +4,12 @@ export default {
"chain": "ETH",
"rpc": [
"https://boba-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet.boba.network/"
"https://mainnet.boba.network",
"https://replica.boba.network",
"http://boba-ethereum.gateway.tenderly.co",
"http://gateway.tenderly.co/public/boba-ethereum",
"wss://boba-ethereum.gateway.tenderly.co/",
"wss://gateway.tenderly.co/public/boba-ethereum"
],
"faucets": [],
"nativeCurrency": {
+4 -3
View File
@@ -4,7 +4,8 @@ export default {
"chain": "ETH",
"rpc": [
"https://boba-network-goerli-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://goerli.boba.network/"
"https://goerli.boba.network/",
"wss://wss.goerli.boba.network/"
],
"faucets": [],
"nativeCurrency": {
@@ -13,7 +14,7 @@ export default {
"decimals": 18
},
"infoURL": "https://boba.network",
"shortName": "Bobagoerli",
"shortName": "BobaGoerli",
"chainId": 2888,
"networkId": 2888,
"explorers": [
@@ -28,7 +29,7 @@ export default {
"chain": "eip155-5",
"bridges": [
{
"url": "https://gateway.goerli.boba.network"
"url": "https://gateway.boba.network"
}
]
},
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"name": "SenjePowers Mainnet",
"chain": "SPC",
"icon": {
"url": "ipfs://QmcpyTj4hUyHJZ2VmSdkXFpPpRcNKRP1VxMs7Cp1anymNy",
"width": 504,
"height": 495,
"format": "png"
},
"rpc": [
"https://senjepowers.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.senjepowersscan.com"
],
"faucets": [
"https://faucet.senjepowersscan.com"
],
"nativeCurrency": {
"name": "SenjePowers",
"symbol": "SPC",
"decimals": 18
},
"infoURL": "https://senjepowersscan.com",
"shortName": "SPCm",
"chainId": 3699,
"networkId": 3699,
"explorers": [
{
"name": "SenjePowers",
"url": "https://senjepowersscan.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "senjepowers"
} as const satisfies Chain;
+57
View File
@@ -0,0 +1,57 @@
import type { Chain } from "../src/types";
export default {
"name": "PGN (Public Goods Network)",
"chain": "ETH",
"rpc": [
"https://pgn-public-goods-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.publicgoods.network"
],
"faucets": [],
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"infoURL": "https://publicgoods.network/",
"shortName": "PGN",
"chainId": 424,
"networkId": 424,
"icon": {
"url": "ipfs://QmUVJ7MLCEAfq3pHVPFLscqRMiyAY5biVgTkeDQCmAhHNS",
"width": 574,
"height": 574,
"format": "svg"
},
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.publicgoods.network",
"icon": {
"url": "ipfs://bafybeifu5tpui7dk5cjoo54kde7pmuthvnl7sdykobuarsxgu7t2izurnq",
"width": 512,
"height": 512,
"format": "png"
},
"standard": "EIP3091"
}
],
"parent": {
"type": "L2",
"chain": "eip155-1",
"bridges": [
{
"url": "https://bridge.publicgoods.network"
}
]
},
"testnet": false,
"slug": "pgn-public-goods-network"
} as const satisfies Chain;
+10 -2
View File
@@ -6,8 +6,7 @@ export default {
"https://bobafuji-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet.avax.boba.network",
"wss://wss.testnet.avax.boba.network",
"https://replica.testnet.avax.boba.network",
"wss://replica-wss.testnet.avax.boba.network"
"https://replica.testnet.avax.boba.network"
],
"faucets": [],
"nativeCurrency": {
@@ -26,6 +25,15 @@ export default {
"standard": "none"
}
],
"parent": {
"type": "L2",
"chain": "eip155-5",
"bridges": [
{
"url": "https://gateway.boba.network"
}
]
},
"testnet": true,
"slug": "bobafuji-testnet"
} as const satisfies Chain;
+37
View File
@@ -0,0 +1,37 @@
import type { Chain } from "../src/types";
export default {
"name": "Toronet Testnet",
"chain": "Toronet",
"icon": {
"url": "ipfs://QmciSvgLatP6jhgdazuiyD3fSrhipfAN7wC943v1qxcrpv",
"width": 846,
"height": 733,
"format": "png"
},
"rpc": [
"https://toronet-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"http://testnet.toronet.org/rpc"
],
"faucets": [],
"nativeCurrency": {
"name": "Toro",
"symbol": "TORO",
"decimals": 18
},
"infoURL": "https://toronet.org",
"shortName": "ToronetTestnet",
"chainId": 54321,
"networkId": 54321,
"ens": {
"registry": "0x059C474f26D65B0458F9da10A649a7322aB02C09"
},
"explorers": [
{
"name": "toronet_explorer",
"url": "https://testnet.toronet.org",
"standard": "none"
}
],
"testnet": true,
"slug": "toronet-testnet"
} as const satisfies Chain;
+7 -7
View File
@@ -1,6 +1,6 @@
import type { Chain } from "../src/types";
export default {
"name": "Binance Smart Chain Mainnet",
"name": "BNB Smart Chain Mainnet",
"chain": "BSC",
"rpc": [
"https://binance.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
@@ -14,20 +14,20 @@ export default {
"https://bsc-dataseed3.defibit.io",
"https://bsc-dataseed2.defibit.io",
"https://bsc-dataseed1.defibit.io",
"https://bsc-dataseed4.binance.org",
"https://bsc-dataseed3.binance.org",
"https://bsc-dataseed2.binance.org",
"https://bsc-dataseed1.binance.org"
"https://bsc-dataseed4.bnbchain.org",
"https://bsc-dataseed3.bnbchain.org",
"https://bsc-dataseed2.bnbchain.org",
"https://bsc-dataseed1.bnbchain.org"
],
"faucets": [
"https://free-online-app.com/faucet-for-eth-evm-chains/"
],
"nativeCurrency": {
"name": "Binance Chain Native Token",
"name": "BNB Chain Native Token",
"symbol": "BNB",
"decimals": 18
},
"infoURL": "https://www.binance.org",
"infoURL": "https://www.bnbchain.org/en",
"shortName": "bnb",
"chainId": 56,
"networkId": 56,
+13 -2
View File
@@ -5,9 +5,11 @@ export default {
"rpc": [
"https://boba-bnb.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://bnb.boba.network",
"wss://wss.bnb.boba.network",
"http://boba-bnb.gateway.tenderly.co/",
"http://gateway.tenderly.co/public/boba-bnb",
"https://replica.bnb.boba.network",
"wss://replica-wss.bnb.boba.network"
"wss://boba-bnb.gateway.tenderly.co/",
"wss://gateway.tenderly.co/public/boba-bnb"
],
"faucets": [],
"nativeCurrency": {
@@ -26,6 +28,15 @@ export default {
"standard": "none"
}
],
"parent": {
"type": "L2",
"chain": "eip155-5",
"bridges": [
{
"url": "https://gateway.boba.network"
}
]
},
"testnet": false,
"slug": "boba-bnb"
} as const satisfies Chain;
+57
View File
@@ -0,0 +1,57 @@
import type { Chain } from "../src/types";
export default {
"name": "Sepolia PGN (Public Goods Network)",
"chain": "ETH",
"rpc": [
"https://sepolia-pgn-public-goods-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://sepolia.publicgoods.network"
],
"faucets": [],
"nativeCurrency": {
"name": "Sepolia Ether",
"symbol": "ETH",
"decimals": 18
},
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"infoURL": "https://publicgoods.network/",
"shortName": "sepPGN",
"chainId": 58008,
"networkId": 58008,
"icon": {
"url": "ipfs://QmUVJ7MLCEAfq3pHVPFLscqRMiyAY5biVgTkeDQCmAhHNS",
"width": 574,
"height": 574,
"format": "svg"
},
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.sepolia.publicgoods.network",
"icon": {
"url": "ipfs://bafybeifu5tpui7dk5cjoo54kde7pmuthvnl7sdykobuarsxgu7t2izurnq",
"width": 512,
"height": 512,
"format": "png"
},
"standard": "EIP3091"
}
],
"parent": {
"type": "L2",
"chain": "eip155-11155111",
"bridges": [
{
"url": "https://pgn-bridge.vercel.app/bridge"
}
]
},
"testnet": false,
"slug": "sepolia-pgn-public-goods-network"
} as const satisfies Chain;
+34
View File
@@ -0,0 +1,34 @@
import type { Chain } from "../src/types";
export default {
"name": "Bitrock Mainnet",
"chain": "Bitrock",
"icon": {
"url": "ipfs://QmfXZCAh3HWS2bJroUStN9TieL4QA9QArMotie3X4pwBfj",
"width": 72,
"height": 72,
"format": "svg"
},
"rpc": [
"https://bitrock.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://connect.bit-rock.io"
],
"faucets": [],
"nativeCurrency": {
"name": "BITROCK",
"symbol": "BROCK",
"decimals": 18
},
"infoURL": "https://bit-rock.io",
"shortName": "bitrock",
"chainId": 7171,
"networkId": 7171,
"explorers": [
{
"name": "Bitrock Explorer",
"url": "https://scan.bit-rock.io",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "bitrock"
} as const satisfies Chain;
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"name": "Bitrock Testnet",
"chain": "Bitrock",
"icon": {
"url": "ipfs://QmfXZCAh3HWS2bJroUStN9TieL4QA9QArMotie3X4pwBfj",
"width": 72,
"height": 72,
"format": "svg"
},
"rpc": [
"https://bitrock-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet.bit-rock.io"
],
"faucets": [
"https://faucet.bit-rock.io"
],
"nativeCurrency": {
"name": "BITROCK",
"symbol": "BROCK",
"decimals": 18
},
"infoURL": "https://bit-rock.io",
"shortName": "tbitrock",
"chainId": 7771,
"networkId": 7771,
"explorers": [
{
"name": "Bitrock Testnet Explorer",
"url": "https://testnetscan.bit-rock.io",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "bitrock-testnet"
} as const satisfies Chain;
+37
View File
@@ -0,0 +1,37 @@
import type { Chain } from "../src/types";
export default {
"name": "Toronet Mainnet",
"chain": "Toronet",
"icon": {
"url": "ipfs://QmciSvgLatP6jhgdazuiyD3fSrhipfAN7wC943v1qxcrpv",
"width": 846,
"height": 733,
"format": "png"
},
"rpc": [
"https://toronet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"http://toronet.org/rpc"
],
"faucets": [],
"nativeCurrency": {
"name": "Toro",
"symbol": "TORO",
"decimals": 18
},
"infoURL": "https://toronet.org",
"shortName": "Toronet",
"chainId": 77777,
"networkId": 77777,
"ens": {
"registry": "0x1f45a71f4aAD769E27c969c4359E0e250C67165c"
},
"explorers": [
{
"name": "toronet_explorer",
"url": "https://toronet.org/explorer",
"standard": "none"
}
],
"testnet": false,
"slug": "toronet"
} as const satisfies Chain;
+17 -2
View File
@@ -2,7 +2,10 @@ import type { Chain } from "../src/types";
export default {
"name": "Base",
"chain": "ETH",
"rpc": [],
"rpc": [
"https://base.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://developer-access-mainnet.base.org/"
],
"faucets": [],
"nativeCurrency": {
"name": "Ether",
@@ -13,13 +16,25 @@ export default {
"shortName": "base",
"chainId": 8453,
"networkId": 8453,
"status": "incubating",
"icon": {
"url": "ipfs://QmW5Vn15HeRkScMfPcW12ZdZcC2yUASpu6eCsECRdEmjjj/base-512.png",
"height": 512,
"width": 512,
"format": "png"
},
"explorers": [
{
"name": "basescout",
"url": "https://base.blockscout.com",
"standard": "none"
},
{
"name": "basescan",
"url": "https://basescan.org",
"standard": "none"
}
],
"status": "active",
"testnet": false,
"slug": "base"
} as const satisfies Chain;
+6 -6
View File
@@ -18,6 +18,12 @@ export default {
"shortName": "basegor",
"chainId": 84531,
"networkId": 84531,
"icon": {
"url": "ipfs://QmW5Vn15HeRkScMfPcW12ZdZcC2yUASpu6eCsECRdEmjjj/base-512.png",
"height": 512,
"width": 512,
"format": "png"
},
"explorers": [
{
"name": "basescout",
@@ -31,11 +37,5 @@ export default {
}
],
"testnet": true,
"icon": {
"url": "ipfs://QmW5Vn15HeRkScMfPcW12ZdZcC2yUASpu6eCsECRdEmjjj/base-512.png",
"height": 512,
"width": 512,
"format": "png"
},
"slug": "base-goerli"
} as const satisfies Chain;
+10 -10
View File
@@ -1,26 +1,26 @@
import type { Chain } from "../src/types";
export default {
"name": "Binance Smart Chain Testnet",
"name": "BNB Smart Chain Testnet",
"chain": "BSC",
"rpc": [
"https://binance-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://bsc-testnet.publicnode.com",
"https://data-seed-prebsc-2-s3.binance.org:8545",
"https://data-seed-prebsc-1-s3.binance.org:8545",
"https://data-seed-prebsc-2-s2.binance.org:8545",
"https://data-seed-prebsc-1-s2.binance.org:8545",
"https://data-seed-prebsc-2-s1.binance.org:8545",
"https://data-seed-prebsc-1-s1.binance.org:8545"
"https://data-seed-prebsc-2-s3.bnbchain.org:8545",
"https://data-seed-prebsc-1-s3.bnbchain.org:8545",
"https://data-seed-prebsc-2-s2.bnbchain.org:8545",
"https://data-seed-prebsc-1-s2.bnbchain.org:8545",
"https://data-seed-prebsc-2-s1.bnbchain.org:8545",
"https://data-seed-prebsc-1-s1.bnbchain.org:8545"
],
"faucets": [
"https://testnet.binance.org/faucet-smart"
"https://testnet.bnbchain.org/faucet-smart"
],
"nativeCurrency": {
"name": "Binance Chain Native Token",
"name": "BNB Chain Native Token",
"symbol": "tBNB",
"decimals": 18
},
"infoURL": "https://testnet.binance.org/",
"infoURL": "https://www.bnbchain.org/en",
"shortName": "bnbt",
"chainId": 97,
"networkId": 97,
+9
View File
@@ -26,6 +26,15 @@ export default {
"standard": "none"
}
],
"parent": {
"type": "L2",
"chain": "eip155-5",
"bridges": [
{
"url": "https://gateway.boba.network"
}
]
},
"testnet": true,
"slug": "boba-bnb-testnet"
} as const satisfies Chain;
+2
View File
@@ -10,4 +10,6 @@ export default {
width: 512,
format: "png",
},
rpc: ["https://base.rpc.thirdweb.com/${THIRDWEB_API_KEY}"],
status: "active",
};
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.29",
"version": "0.1.34",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"browser": {
+3 -3
View File
@@ -164,10 +164,10 @@ function findSlug(chain) {
if (slug === "arbitrum-one") {
slug = "arbitrum";
}
if (slug === "binance-smart-chain") {
if (slug === "bnb-smart-chain") {
slug = "binance";
}
if (slug === "binance-smart-chain-testnet") {
if (slug === "bnb-smart-chain-testnet") {
slug = "binance-testnet";
}
if (slug === "base-goerli-testnet") {
@@ -267,7 +267,7 @@ import type { Chain } from "./types";
${exports.join("\n")}
export * from "./types";
export * from "./utils";
export const defaultChains = [c1, c5, c84531, c137, c80001, c42161, c421613, c10, c420, c56, c97, c250, c4002, c43114, c43113, c1337];
export const defaultChains = [c1, c5, c8453, c84531, c137, c80001, c42161, c421613, c10, c420, c56, c97, c250, c4002, c43114, c43113, c1337];
export const allChains: Chain[] = [${exportNames.join(", ")}];
type ChainsById = {
File diff suppressed because one or more lines are too long
+48
View File
@@ -1,5 +1,53 @@
# thirdweb
## 0.10.37
### Patch Changes
- Updated dependencies [[`dac8fa7d`](https://github.com/thirdweb-dev/js/commit/dac8fa7d98b6952acf8d13e173099889c1d47da8)]:
- @thirdweb-dev/sdk@3.10.36
## 0.10.36
### Patch Changes
- Updated dependencies [[`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b), [`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b)]:
- @thirdweb-dev/storage@1.1.9
- @thirdweb-dev/chains@0.1.34
- @thirdweb-dev/sdk@3.10.35
## 0.10.35
### Patch Changes
- Updated dependencies [[`0407b2c2`](https://github.com/thirdweb-dev/js/commit/0407b2c2f39b5f3fa06e613e671623b5644b3a28)]:
- @thirdweb-dev/chains@0.1.33
- @thirdweb-dev/sdk@3.10.34
## 0.10.34
### Patch Changes
- Updated dependencies [[`a9093bcf`](https://github.com/thirdweb-dev/js/commit/a9093bcf287c01e3335fd780e2ccbfdb3380bf95)]:
- @thirdweb-dev/chains@0.1.32
- @thirdweb-dev/sdk@3.10.33
## 0.10.33
### Patch Changes
- Updated dependencies [[`4393b228`](https://github.com/thirdweb-dev/js/commit/4393b2280505fd0b2284555d64eae6567e8401a5)]:
- @thirdweb-dev/chains@0.1.31
- @thirdweb-dev/sdk@3.10.32
## 0.10.32
### Patch Changes
- Updated dependencies [[`40682191`](https://github.com/thirdweb-dev/js/commit/40682191450de08ad40b9d2957afced248657af2)]:
- @thirdweb-dev/chains@0.1.30
- @thirdweb-dev/sdk@3.10.31
## 0.10.31
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "thirdweb",
"main": "dist/cli/index.js",
"version": "0.10.31",
"version": "0.10.37",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
+56
View File
@@ -1,5 +1,61 @@
# @thirdweb-dev/react-core
## 3.14.16
### Patch Changes
- [#1356](https://github.com/thirdweb-dev/js/pull/1356) [`7a6534d1`](https://github.com/thirdweb-dev/js/commit/7a6534d1a98cab1eb47cf88d13e2b7ec04037e42) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix useOwnedNFT enabled state
- Updated dependencies [[`dac8fa7d`](https://github.com/thirdweb-dev/js/commit/dac8fa7d98b6952acf8d13e173099889c1d47da8), [`c5761b99`](https://github.com/thirdweb-dev/js/commit/c5761b99e9797772481506e90cbfa5c35a05bd1d), [`b96a2282`](https://github.com/thirdweb-dev/js/commit/b96a2282730582b684cc96802649a96851af5220)]:
- @thirdweb-dev/sdk@3.10.36
- @thirdweb-dev/wallets@1.0.12
## 3.14.15
### Patch Changes
- Updated dependencies [[`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b), [`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b)]:
- @thirdweb-dev/storage@1.1.9
- @thirdweb-dev/chains@0.1.34
- @thirdweb-dev/sdk@3.10.35
- @thirdweb-dev/wallets@1.0.11
## 3.14.14
### Patch Changes
- Updated dependencies [[`0407b2c2`](https://github.com/thirdweb-dev/js/commit/0407b2c2f39b5f3fa06e613e671623b5644b3a28)]:
- @thirdweb-dev/chains@0.1.33
- @thirdweb-dev/sdk@3.10.34
- @thirdweb-dev/wallets@1.0.10
## 3.14.13
### Patch Changes
- Updated dependencies [[`a9093bcf`](https://github.com/thirdweb-dev/js/commit/a9093bcf287c01e3335fd780e2ccbfdb3380bf95)]:
- @thirdweb-dev/chains@0.1.32
- @thirdweb-dev/sdk@3.10.33
- @thirdweb-dev/wallets@1.0.9
## 3.14.12
### Patch Changes
- Updated dependencies [[`4393b228`](https://github.com/thirdweb-dev/js/commit/4393b2280505fd0b2284555d64eae6567e8401a5)]:
- @thirdweb-dev/chains@0.1.31
- @thirdweb-dev/sdk@3.10.32
- @thirdweb-dev/wallets@1.0.8
## 3.14.11
### Patch Changes
- Updated dependencies [[`40682191`](https://github.com/thirdweb-dev/js/commit/40682191450de08ad40b9d2957afced248657af2)]:
- @thirdweb-dev/chains@0.1.30
- @thirdweb-dev/sdk@3.10.31
- @thirdweb-dev/wallets@1.0.7
## 3.14.10
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "3.14.10",
"version": "3.14.16",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -256,7 +256,7 @@ export function useOwnedNFTs<TContract extends NFTContract>(
invariant(false, "Unknown NFT type");
},
{
enabled: !!erc721 || (!!erc1155 && !!ownerWalletAddress),
enabled: (!!erc721 || !!erc1155) && !!ownerWalletAddress,
},
);
}
+12
View File
@@ -1,5 +1,17 @@
# @thirdweb-dev/react-native-compat
## 0.2.35
## 0.2.34
## 0.2.33
## 0.2.32
## 0.2.31
## 0.2.30
## 0.2.29
## 0.2.28
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/react-native-compat",
"description": "Shims for Thirdweb in React Native Projects",
"version": "0.2.29",
"version": "0.2.35",
"author": "thirdweb eng <[email protected]>",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
"license": "Apache-2.0",
+60
View File
@@ -1,5 +1,65 @@
# @thirdweb-dev/react-native
## 0.2.35
### Patch Changes
- Updated dependencies [[`7a6534d1`](https://github.com/thirdweb-dev/js/commit/7a6534d1a98cab1eb47cf88d13e2b7ec04037e42), [`dac8fa7d`](https://github.com/thirdweb-dev/js/commit/dac8fa7d98b6952acf8d13e173099889c1d47da8), [`c5761b99`](https://github.com/thirdweb-dev/js/commit/c5761b99e9797772481506e90cbfa5c35a05bd1d), [`b96a2282`](https://github.com/thirdweb-dev/js/commit/b96a2282730582b684cc96802649a96851af5220)]:
- @thirdweb-dev/react-core@3.14.16
- @thirdweb-dev/sdk@3.10.36
- @thirdweb-dev/wallets@1.0.12
## 0.2.34
### Patch Changes
- Updated dependencies [[`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b), [`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b)]:
- @thirdweb-dev/storage@1.1.9
- @thirdweb-dev/chains@0.1.34
- @thirdweb-dev/react-core@3.14.15
- @thirdweb-dev/sdk@3.10.35
- @thirdweb-dev/wallets@1.0.11
## 0.2.33
### Patch Changes
- Updated dependencies [[`0407b2c2`](https://github.com/thirdweb-dev/js/commit/0407b2c2f39b5f3fa06e613e671623b5644b3a28)]:
- @thirdweb-dev/chains@0.1.33
- @thirdweb-dev/react-core@3.14.14
- @thirdweb-dev/sdk@3.10.34
- @thirdweb-dev/wallets@1.0.10
## 0.2.32
### Patch Changes
- Updated dependencies [[`a9093bcf`](https://github.com/thirdweb-dev/js/commit/a9093bcf287c01e3335fd780e2ccbfdb3380bf95)]:
- @thirdweb-dev/chains@0.1.32
- @thirdweb-dev/react-core@3.14.13
- @thirdweb-dev/sdk@3.10.33
- @thirdweb-dev/wallets@1.0.9
## 0.2.31
### Patch Changes
- Updated dependencies [[`4393b228`](https://github.com/thirdweb-dev/js/commit/4393b2280505fd0b2284555d64eae6567e8401a5)]:
- @thirdweb-dev/chains@0.1.31
- @thirdweb-dev/react-core@3.14.12
- @thirdweb-dev/sdk@3.10.32
- @thirdweb-dev/wallets@1.0.8
## 0.2.30
### Patch Changes
- Updated dependencies [[`40682191`](https://github.com/thirdweb-dev/js/commit/40682191450de08ad40b9d2957afced248657af2)]:
- @thirdweb-dev/chains@0.1.30
- @thirdweb-dev/react-core@3.14.11
- @thirdweb-dev/sdk@3.10.31
- @thirdweb-dev/wallets@1.0.7
## 0.2.29
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-native",
"version": "0.2.29",
"version": "0.2.35",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
+61
View File
@@ -1,5 +1,66 @@
# @thirdweb-dev/react
## 3.14.16
### Patch Changes
- [#1350](https://github.com/thirdweb-dev/js/pull/1350) [`b96a2282`](https://github.com/thirdweb-dev/js/commit/b96a2282730582b684cc96802649a96851af5220) Thanks [@MananTank](https://github.com/MananTank)! - Disable autofocus for the Paper/Magic email/phone input in Connect Wallet Modal to avoid keyboard popup on mobile
- Updated dependencies [[`7a6534d1`](https://github.com/thirdweb-dev/js/commit/7a6534d1a98cab1eb47cf88d13e2b7ec04037e42), [`dac8fa7d`](https://github.com/thirdweb-dev/js/commit/dac8fa7d98b6952acf8d13e173099889c1d47da8), [`c5761b99`](https://github.com/thirdweb-dev/js/commit/c5761b99e9797772481506e90cbfa5c35a05bd1d), [`b96a2282`](https://github.com/thirdweb-dev/js/commit/b96a2282730582b684cc96802649a96851af5220)]:
- @thirdweb-dev/react-core@3.14.16
- @thirdweb-dev/sdk@3.10.36
- @thirdweb-dev/wallets@1.0.12
## 3.14.15
### Patch Changes
- Updated dependencies [[`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b)]:
- @thirdweb-dev/chains@0.1.34
- @thirdweb-dev/react-core@3.14.15
- @thirdweb-dev/sdk@3.10.35
- @thirdweb-dev/wallets@1.0.11
## 3.14.14
### Patch Changes
- Updated dependencies [[`0407b2c2`](https://github.com/thirdweb-dev/js/commit/0407b2c2f39b5f3fa06e613e671623b5644b3a28)]:
- @thirdweb-dev/chains@0.1.33
- @thirdweb-dev/react-core@3.14.14
- @thirdweb-dev/sdk@3.10.34
- @thirdweb-dev/wallets@1.0.10
## 3.14.13
### Patch Changes
- Updated dependencies [[`a9093bcf`](https://github.com/thirdweb-dev/js/commit/a9093bcf287c01e3335fd780e2ccbfdb3380bf95)]:
- @thirdweb-dev/chains@0.1.32
- @thirdweb-dev/react-core@3.14.13
- @thirdweb-dev/sdk@3.10.33
- @thirdweb-dev/wallets@1.0.9
## 3.14.12
### Patch Changes
- Updated dependencies [[`4393b228`](https://github.com/thirdweb-dev/js/commit/4393b2280505fd0b2284555d64eae6567e8401a5)]:
- @thirdweb-dev/chains@0.1.31
- @thirdweb-dev/react-core@3.14.12
- @thirdweb-dev/sdk@3.10.32
- @thirdweb-dev/wallets@1.0.8
## 3.14.11
### Patch Changes
- Updated dependencies [[`40682191`](https://github.com/thirdweb-dev/js/commit/40682191450de08ad40b9d2957afced248657af2)]:
- @thirdweb-dev/chains@0.1.30
- @thirdweb-dev/react-core@3.14.11
- @thirdweb-dev/sdk@3.10.31
- @thirdweb-dev/wallets@1.0.7
## 3.14.10
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "3.14.10",
"version": "3.14.16",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -43,6 +43,7 @@ export function InputSelectionUI(props: {
}}
>
<Input
tabIndex={-1}
placeholder={props.placeholder}
variant="secondary"
type={props.type}
@@ -1,5 +1,8 @@
import type { WalletOptions, WalletConfig } from "@thirdweb-dev/react-core";
import { MetaMaskWallet, assertWindowEthereum } from "@thirdweb-dev/wallets";
import {
MetaMaskWallet,
getInjectedMetamaskProvider,
} from "@thirdweb-dev/wallets";
import { MetamaskConnectUI } from "./MetamaskConnectUI";
type MetamaskWalletOptions = {
@@ -27,10 +30,7 @@ export const metamaskWallet = (
},
connectUI: MetamaskConnectUI,
isInstalled() {
if (assertWindowEthereum(globalThis.window)) {
return globalThis.window.ethereum.isMetaMask;
}
return false;
return !!getInjectedMetamaskProvider();
},
};
};
+42
View File
@@ -1,5 +1,47 @@
# @thirdweb-dev/sdk
## 3.10.36
### Patch Changes
- [#1357](https://github.com/thirdweb-dev/js/pull/1357) [`dac8fa7d`](https://github.com/thirdweb-dev/js/commit/dac8fa7d98b6952acf8d13e173099889c1d47da8) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix getOwned not showing last owned NFT for OpenEdition contracts
## 3.10.35
### Patch Changes
- Updated dependencies [[`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b), [`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b)]:
- @thirdweb-dev/storage@1.1.9
- @thirdweb-dev/chains@0.1.34
## 3.10.34
### Patch Changes
- Updated dependencies [[`0407b2c2`](https://github.com/thirdweb-dev/js/commit/0407b2c2f39b5f3fa06e613e671623b5644b3a28)]:
- @thirdweb-dev/chains@0.1.33
## 3.10.33
### Patch Changes
- Updated dependencies [[`a9093bcf`](https://github.com/thirdweb-dev/js/commit/a9093bcf287c01e3335fd780e2ccbfdb3380bf95)]:
- @thirdweb-dev/chains@0.1.32
## 3.10.32
### Patch Changes
- Updated dependencies [[`4393b228`](https://github.com/thirdweb-dev/js/commit/4393b2280505fd0b2284555d64eae6567e8401a5)]:
- @thirdweb-dev/chains@0.1.31
## 3.10.31
### Patch Changes
- Updated dependencies [[`40682191`](https://github.com/thirdweb-dev/js/commit/40682191450de08ad40b9d2957afced248657af2)]:
- @thirdweb-dev/chains@0.1.30
## 3.10.30
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/sdk",
"version": "3.10.30",
"version": "3.10.36",
"description": "The main thirdweb SDK.",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
"license": "Apache-2.0",
@@ -87,12 +87,18 @@ export class Erc721Supply implements DetectableFeature {
*/
public async allOwners() {
let totalCount: BigNumber;
let startTokenId = BigNumber.from(0);
if (hasFunction<OpenEditionERC721>("startTokenId", this.contractWrapper)) {
startTokenId = await this.contractWrapper.readContract.startTokenId();
}
try {
totalCount = await this.erc721.totalClaimedSupply();
} catch (e) {
totalCount = await this.totalCount();
}
totalCount = totalCount.add(startTokenId);
// TODO use multicall3 if available
// TODO can't call toNumber() here, this can be a very large number
return (
+6
View File
@@ -0,0 +1,6 @@
{
"presets": [
"@babel/preset-typescript",
["@babel/preset-env", { "targets": "defaults, not ie 11" }]
]
}
+4
View File
@@ -0,0 +1,4 @@
# folders
dist/
# files
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ["thirdweb"],
};
+39
View File
@@ -0,0 +1,39 @@
# @thirdweb-dev/service-utils
## 0.2.0
### Minor Changes
- [#1345](https://github.com/thirdweb-dev/js/pull/1345) [`5eb6fc1b`](https://github.com/thirdweb-dev/js/commit/5eb6fc1bf309a34167bf1f27fe5b09a3ae781219) Thanks [@jnsdls](https://github.com/jnsdls)! - expose separate entrypoints for cloudflare workers and node projects
### Patch Changes
- [#1342](https://github.com/thirdweb-dev/js/pull/1342) [`4915ac50`](https://github.com/thirdweb-dev/js/commit/4915ac50f8ffd90cd965636905f73d1c99cbda29) Thanks [@jnsdls](https://github.com/jnsdls)! - add relayer service definition
- [#1340](https://github.com/thirdweb-dev/js/pull/1340) [`d724ad85`](https://github.com/thirdweb-dev/js/commit/d724ad85c52f6da341a248fbe62d85a99c1b65d0) Thanks [@jnsdls](https://github.com/jnsdls)! - fix use endpoint
- [#1354](https://github.com/thirdweb-dev/js/pull/1354) [`0bfdedd4`](https://github.com/thirdweb-dev/js/commit/0bfdedd4ba6ce9b42f9636303027b4421eb68d65) Thanks [@assimovt](https://github.com/assimovt)! - Fix enforceAuth param
- [#1355](https://github.com/thirdweb-dev/js/pull/1355) [`d5aee62b`](https://github.com/thirdweb-dev/js/commit/d5aee62bf41e45b5fed3061d4338d4a279a27c38) Thanks [@assimovt](https://github.com/assimovt)! - Remove unused type
- [#1349](https://github.com/thirdweb-dev/js/pull/1349) [`ddb3dabe`](https://github.com/thirdweb-dev/js/commit/ddb3dabe694be96d2de4c01c53d8c6fc6b9e211d) Thanks [@assimovt](https://github.com/assimovt)! - Allow target addresses array and fix api url stringy
- [#1351](https://github.com/thirdweb-dev/js/pull/1351) [`fd0650dc`](https://github.com/thirdweb-dev/js/commit/fd0650dcacfa6bf4a3fa479934046957eef8cf94) Thanks [@farhanW3](https://github.com/farhanW3)! - Fixed Node Service Url formation
- [#1353](https://github.com/thirdweb-dev/js/pull/1353) [`42d9ab68`](https://github.com/thirdweb-dev/js/commit/42d9ab68d949bc6788f628042d916a1c5e660b16) Thanks [@assimovt](https://github.com/assimovt)! - Allow to skip auth for backwards compat
- [#1347](https://github.com/thirdweb-dev/js/pull/1347) [`781e26d8`](https://github.com/thirdweb-dev/js/commit/781e26d89632ef421bec2914d4e3abcc17d96816) Thanks [@assimovt](https://github.com/assimovt)! - Authorize service bundle
- [#1343](https://github.com/thirdweb-dev/js/pull/1343) [`7dc685bb`](https://github.com/thirdweb-dev/js/commit/7dc685bbece749030e85a9f6d5aafa48d3ab8a74) Thanks [@nessup](https://github.com/nessup)! - Add missing type to ApiKey
- [#1346](https://github.com/thirdweb-dev/js/pull/1346) [`f7392138`](https://github.com/thirdweb-dev/js/commit/f7392138eeda55a6557b26a6c957d5b6b90b645c) Thanks [@assimovt](https://github.com/assimovt)! - fix api url extraction from URL in fetchKeyMetadataFromApi
## 0.1.0
### Minor Changes
- [#1333](https://github.com/thirdweb-dev/js/pull/1333) [`07c7d97c`](https://github.com/thirdweb-dev/js/commit/07c7d97c288063f7a5a65819e37ebe3f51095faf) Thanks [@jnsdls](https://github.com/jnsdls)! - add package
### Patch Changes
- [#1339](https://github.com/thirdweb-dev/js/pull/1339) [`cfa7ecbc`](https://github.com/thirdweb-dev/js/commit/cfa7ecbc9ab8f1c5031f82d5c23a6ee0a800c9f4) Thanks [@assimovt](https://github.com/assimovt)! - Remove crypto and unfetch node dependencies
+1
View File
@@ -0,0 +1 @@
### todo
@@ -0,0 +1,4 @@
{
"main": "dist/thirdweb-dev-service-utils-cf-worker.cjs.js",
"module": "dist/thirdweb-dev-service-utils-cf-worker.esm.js"
}
+4
View File
@@ -0,0 +1,4 @@
{
"main": "dist/thirdweb-dev-service-utils-node.cjs.js",
"module": "dist/thirdweb-dev-service-utils-node.esm.js"
}
+65
View File
@@ -0,0 +1,65 @@
{
"name": "@thirdweb-dev/service-utils",
"version": "0.2.0",
"main": "dist/thirdweb-dev-service-utils.cjs.js",
"module": "dist/thirdweb-dev-service-utils.esm.js",
"exports": {
".": {
"module": "./dist/thirdweb-dev-service-utils.esm.js",
"default": "./dist/thirdweb-dev-service-utils.cjs.js"
},
"./node": {
"module": "./node/dist/thirdweb-dev-service-utils-node.esm.js",
"default": "./node/dist/thirdweb-dev-service-utils-node.cjs.js"
},
"./cf-worker": {
"module": "./cf-worker/dist/thirdweb-dev-service-utils-cf-worker.esm.js",
"default": "./cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.js"
},
"./package.json": "./package.json"
},
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/pay",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/thirdweb-dev/js/issues"
},
"author": "thirdweb eng <[email protected]>",
"files": [
"dist/",
"node/",
"cf-worker/"
],
"preconstruct": {
"entrypoints": [
"index.ts",
"cf-worker/index.ts",
"node/index.ts"
],
"exports": true
},
"sideEffects": false,
"devDependencies": {
"@cloudflare/workers-types": "^4.20230710.0",
"@preconstruct/cli": "^2.8.1",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/jest": "^29.5.2",
"@types/node": "^20.4.1",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.44.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-thirdweb": "workspace:*",
"jest": "^29.4.3",
"prettier": "^3.0.0",
"typescript": "^5.1.6"
},
"scripts": {
"format": "prettier --write 'src/**/*'",
"lint": "eslint src/",
"fix": "eslint src/ --fix",
"clean": "rm -rf dist/",
"build": "tsc && preconstruct build",
"push": "yalc push",
"test": "jest"
}
}
@@ -0,0 +1,151 @@
import type { ExecutionContext, KVNamespace } from "@cloudflare/workers-types";
import type { ApiKeyMetadata, CoreServiceConfig } from "../core/api";
import { authorize } from "../core/authorize";
import type { Request } from "@cloudflare/workers-types";
import type { AuthorizationInput } from "../core/authorize";
import type { AuthorizationResult } from "../core/authorize/types";
import type { CoreAuthInput } from "../core/types";
export * from "../core/services";
type WorkerServiceConfig = CoreServiceConfig & {
kvStore: KVNamespace;
ctx: ExecutionContext;
cacheTtlSeconds?: number;
};
const DEFAULT_CACHE_TTL_SECONDS = 60;
type AuthInput = CoreAuthInput & {
req: Request;
};
export async function authorizeWorker(
authInput: AuthInput,
serviceConfig: WorkerServiceConfig,
): Promise<AuthorizationResult> {
let authData;
try {
authData = await extractAuthorizationData(authInput);
} catch (e) {
if (e instanceof Error && e.message === "KEY_CONFLICT") {
return {
authorized: false,
status: 400,
errorMessage: "Please pass either a client id or a secret key.",
errorCode: "KEY_CONFLICT",
};
}
return {
authorized: false,
status: 500,
errorMessage: "Internal Server Error",
errorCode: "INTERNAL_SERVER_ERROR",
};
}
return await authorize(authData, serviceConfig, {
get: async (clientId: string) => serviceConfig.kvStore.get(clientId),
put: (clientId: string, apiKeyMeta: ApiKeyMetadata) =>
serviceConfig.ctx.waitUntil(
serviceConfig.kvStore.put(
clientId,
JSON.stringify({
updatedAt: Date.now(),
apiKeyMeta,
}),
{
expirationTtl:
serviceConfig.cacheTtlSeconds &&
serviceConfig.cacheTtlSeconds >= DEFAULT_CACHE_TTL_SECONDS
? serviceConfig.cacheTtlSeconds
: DEFAULT_CACHE_TTL_SECONDS,
},
),
),
cacheTtlSeconds: serviceConfig.cacheTtlSeconds ?? DEFAULT_CACHE_TTL_SECONDS,
});
}
async function extractAuthorizationData(
authInput: AuthInput,
): Promise<AuthorizationInput> {
const requestUrl = new URL(authInput.req.url);
const headers = authInput.req.headers;
const secretKey = headers.get("x-secret-key");
// prefer clientId that is explicitly passed in
let clientId = authInput.clientId ?? null;
if (!clientId) {
// next preference is clientId from header
clientId = headers.get("x-client-id");
}
// next preference is search param
if (!clientId) {
clientId = requestUrl.searchParams.get("clientId");
}
// bundle id from header is first preference
let bundleId = headers.get("x-bundle-id");
// next preference is search param
if (!bundleId) {
bundleId = requestUrl.searchParams.get("bundleId");
}
let origin = headers.get("origin");
// if origin header is not available we'll fall back to referrer;
if (!origin) {
origin = headers.get("referer");
}
// if we have an origin at this point, normalize it
if (origin) {
try {
origin = new URL(origin).hostname;
} catch (e) {
console.warn("failed to parse origin", origin, e);
}
}
// handle if we a secret key is passed in the headers
let secretKeyHash: string | null = null;
if (secretKey) {
// hash the secret key
secretKeyHash = await hashSecretKey(secretKey);
// derive the client id from the secret key hash
const derivedClientId = deriveClientIdFromSecretKeyHash(secretKeyHash);
// if we already have a client id passed in we need to make sure they match
if (clientId && clientId !== derivedClientId) {
throw new Error("KEY_CONFLICT");
}
// otherwise set the client id to the derived client id (client id based off of secret key)
clientId = derivedClientId;
}
return {
secretKey,
clientId,
origin,
bundleId,
secretKeyHash,
targetAddress: authInput.targetAddress,
};
}
export async function hashSecretKey(secretKey: string) {
return bufferToHex(
await crypto.subtle.digest("SHA-256", new TextEncoder().encode(secretKey)),
);
}
export function deriveClientIdFromSecretKeyHash(secretKeyHash: string) {
return secretKeyHash.slice(0, 32);
}
function bufferToHex(buffer: ArrayBuffer) {
return [...new Uint8Array(buffer)]
.map((x) => x.toString(16).padStart(2, "0"))
.join("");
}
+54
View File
@@ -0,0 +1,54 @@
import type { ServiceName } from "./services";
export type CoreServiceConfig = {
enforceAuth: boolean;
apiUrl: string;
serviceScope: ServiceName;
serviceApiKey: string;
serviceAction?: string;
};
export type ApiKeyMetadata = {
id: string;
key: string;
creatorWalletAddress: string;
secretHash: string;
walletAddresses: string[];
domains: string[];
bundleIds: string[];
services: {
name: string;
targetAddresses: string[];
actions: string[];
}[];
};
export type ApiResponse = {
data: ApiKeyMetadata | null;
error: {
code: string;
statusCode: number;
message: string;
};
};
export async function fetchKeyMetadataFromApi(
clientId: string,
config: CoreServiceConfig,
): Promise<ApiResponse> {
const { apiUrl, serviceScope, serviceApiKey } = config;
const url = `${apiUrl}/v1/keys/use?clientId=${clientId}&scope=${serviceScope}`;
const response = await fetch(url, {
method: "GET",
headers: {
"x-service-api-key": serviceApiKey,
"content-type": "application/json",
},
});
if (!response.ok) {
throw new Error(
`Error fetching key metadata from API: ${response.statusText}`,
);
}
return (await response.json()) as ApiResponse;
}
@@ -0,0 +1,42 @@
import { authorize } from ".";
import { CoreServiceConfig } from "../api";
const validServiceConfig: CoreServiceConfig = {
apiUrl: "https://api.example.com",
serviceScope: "storage",
serviceApiKey: "service key",
enforceAuth: false,
};
describe("authorizeClient", () => {
it("should skip authorization if auth not enforced and no credentials", async () => {
const result = (await authorize(
{
secretKey: null,
clientId: null,
origin: null,
bundleId: null,
secretKeyHash: null,
},
validServiceConfig,
)) as any;
expect(result.authorized).toBe(true);
expect(result.apiKeyMeta).toEqual(null);
});
it("should continue authorization if auth enforced", async () => {
const result = (await authorize(
{
secretKey: null,
clientId: null,
origin: null,
bundleId: null,
secretKeyHash: null,
},
{ ...validServiceConfig, enforceAuth: true },
)) as any;
expect(result.authorized).toBe(false);
});
});
@@ -0,0 +1,97 @@
import { ApiKeyMetadata } from "../api";
import { ClientAuthorizationPayload, authorizeClient } from "./client";
describe("authorizeClient", () => {
const validApiKeyMeta: ApiKeyMetadata = {
id: "1",
key: "your-api-key",
creatorWalletAddress: "creator-address",
secretHash: "secret-hash",
walletAddresses: [],
domains: ["example.com", "*.example.com"],
bundleIds: ["com.example.app"],
services: [],
};
const validAuthOptions: ClientAuthorizationPayload = {
secretKeyHash: "secret-hash",
bundleId: null,
origin: "example.com",
};
it("should authorize client with valid secret key", () => {
const result = authorizeClient(validAuthOptions, validApiKeyMeta) as any;
expect(result.authorized).toBe(true);
expect(result.apiKeyMeta).toEqual(validApiKeyMeta);
});
it("should authorize client with matching wildcard domain", () => {
const authOptionsWithWildcardDomain: ClientAuthorizationPayload = {
secretKeyHash: null,
bundleId: null,
origin: "sub.example.com",
};
const result = authorizeClient(
authOptionsWithWildcardDomain,
validApiKeyMeta,
) as any;
expect(result.authorized).toBe(true);
expect(result.apiKeyMeta).toEqual(validApiKeyMeta);
});
it("should not authorize client with non-matching bundle id", () => {
const authOptionsWithBundleId: ClientAuthorizationPayload = {
secretKeyHash: null,
bundleId: "com.foo.bar",
origin: null,
};
const result = authorizeClient(
authOptionsWithBundleId,
validApiKeyMeta,
) as any;
expect(result.authorized).toBe(false);
expect(result.errorMessage).toBe(
"The bundle is not authorized for this key.",
);
expect(result.errorCode).toBe("BUNDLE_UNAUTHORIZED");
expect(result.status).toBe(401);
});
it("should not authorize client with invalid secret key", () => {
const authOptionsWithInvalidSecret: ClientAuthorizationPayload = {
secretKeyHash: "invalid-secret-hash",
bundleId: null,
origin: null,
};
const result = authorizeClient(
authOptionsWithInvalidSecret,
validApiKeyMeta,
) as any;
expect(result.authorized).toBe(false);
expect(result.errorMessage).toBe("The secret is invalid.");
expect(result.errorCode).toBe("SECRET_INVALID");
expect(result.status).toBe(401);
});
it("should not authorize client with unauthorized origin", () => {
const authOptionsWithUnauthorizedOrigin: ClientAuthorizationPayload = {
secretKeyHash: null,
bundleId: null,
origin: "unauthorized.com",
};
const result = authorizeClient(
authOptionsWithUnauthorizedOrigin,
validApiKeyMeta,
) as any;
expect(result.authorized).toBe(false);
expect(result.errorMessage).toBe(
"The origin is not authorized for this key.",
);
expect(result.errorCode).toBe("ORIGIN_UNAUTHORIZED");
expect(result.status).toBe(401);
});
});
@@ -0,0 +1,98 @@
import type { ApiKeyMetadata } from "../api";
import type { AuthorizationResult } from "./types";
export type ClientAuthorizationPayload = {
secretKeyHash: string | null;
bundleId: string | null;
origin: string | null;
};
export function authorizeClient(
authOptions: ClientAuthorizationPayload,
apiKeyMeta: ApiKeyMetadata,
): AuthorizationResult {
const { origin, bundleId, secretKeyHash: providedSecretHash } = authOptions;
const { domains, bundleIds, secretHash } = apiKeyMeta;
if (providedSecretHash) {
if (secretHash !== providedSecretHash) {
return {
authorized: false,
errorMessage: "The secret is invalid.",
errorCode: "SECRET_INVALID",
status: 401,
};
}
return {
authorized: true,
apiKeyMeta,
};
}
// validate domains
if (origin) {
if (
// find matching domain, or if all domains allowed
domains.find((d) => {
if (d === "*") {
return true;
}
// If the allowedDomain has a wildcard,
// we'll check that the ending of our domain matches the wildcard
if (d.startsWith("*.")) {
const domainRoot = d.slice(2);
return origin.endsWith(domainRoot);
}
// If there's no wildcard, we'll check for an exact match
return d === origin;
})
) {
return {
authorized: true,
apiKeyMeta,
};
}
return {
authorized: false,
errorMessage: "The origin is not authorized for this key.",
errorCode: "ORIGIN_UNAUTHORIZED",
status: 401,
};
}
// validate bundleId
if (bundleId) {
if (
// find matching bundle id, or if all bundles allowed
bundleIds.find((b) => {
if (b === "*") {
return true;
}
return b === bundleId;
})
) {
return {
authorized: true,
apiKeyMeta,
};
}
return {
authorized: false,
errorMessage: "The bundle is not authorized for this key.",
errorCode: "BUNDLE_UNAUTHORIZED",
status: 401,
};
}
return {
authorized: false,
errorMessage: "The keys are invalid.",
errorCode: "UNAUTHORIZED",
status: 401,
};
}
@@ -0,0 +1,164 @@
import {
ApiKeyMetadata,
CoreServiceConfig,
fetchKeyMetadataFromApi,
} from "../api";
import { authorizeClient } from "./client";
import { authorizeService } from "./service";
import { AuthorizationResult } from "./types";
export type AuthorizationInput = {
secretKey: string | null;
clientId: string | null;
origin: string | null;
bundleId: string | null;
secretKeyHash: string | null;
targetAddress?: string | string[];
};
type CacheOptions = {
get: (clientId: string) => Promise<string | null>;
put: (clientId: string, data: ApiKeyMetadata) => Promise<void> | void;
cacheTtlSeconds: number;
};
type CacheWithPossibleTtl =
| {
apiKeyMeta: ApiKeyMetadata;
updatedAt: number;
}
| ApiKeyMetadata;
export async function authorize(
authData: AuthorizationInput,
serviceConfig: CoreServiceConfig,
cacheOptions?: CacheOptions,
): Promise<AuthorizationResult> {
const { clientId, targetAddress, secretKeyHash } = authData;
const { enforceAuth } = serviceConfig;
// BACKWARDS COMPAT: if auth not enforced and
// we don't have auth credentials bypass
if (!enforceAuth && !clientId && !secretKeyHash) {
return {
authorized: true,
apiKeyMeta: null,
};
}
// if we don't have a client id at this point we can't authorize
if (!clientId) {
return {
authorized: false,
status: 401,
errorMessage: "Missing clientId or secretKey.",
errorCode: "MISSING_KEY",
};
}
let apiKeyMeta: ApiKeyMetadata | null = null;
// if we have cache options we want to check the cache first
if (cacheOptions) {
try {
const cachedKey = await cacheOptions.get(clientId);
if (cachedKey) {
const parsed = JSON.parse(cachedKey) as CacheWithPossibleTtl;
if ("updatedAt" in parsed) {
// we want to compare the updatedAt time to the current time
// if the difference is greater than the cacheTtl we want to ignore the cached data
const now = Date.now();
const diff = now - parsed.updatedAt;
const cacheTtl = cacheOptions.cacheTtlSeconds * 1000;
// only if the diff is less than the cacheTtl do we want to use the cached key
if (diff < cacheTtl * 1000) {
apiKeyMeta = parsed.apiKeyMeta;
}
} else {
apiKeyMeta = parsed;
}
}
} catch (err) {
// ignore errors, proceed as if not in cache
}
}
// if we don't have a cached key, fetch from the API
if (!apiKeyMeta) {
try {
const { data, error } = await fetchKeyMetadataFromApi(
clientId,
serviceConfig,
);
if (error) {
return {
authorized: false,
errorCode: error.code,
errorMessage: error.message,
status: error.statusCode,
};
} else if (!data) {
return {
authorized: false,
errorCode: "NO_KEY",
errorMessage: "No error but also no key returned.",
status: 500,
};
}
// if we have a key for sure then assign it
apiKeyMeta = data;
// cache the retrieved key if we have cache options
if (cacheOptions) {
// we await this always because it can be a promise or not
await cacheOptions.put(clientId, data);
}
} catch (err) {
console.warn("failed to fetch key metadata from api", err);
return {
authorized: false,
status: 500,
errorMessage: "Failed to fetch key metadata.",
errorCode: "FAILED_TO_FETCH_KEY",
};
}
}
if (!apiKeyMeta) {
return {
authorized: false,
status: 401,
errorMessage: "Key is invalid.",
errorCode: "INVALID_KEY",
};
}
// now we can validate the key itself
const clientAuth = authorizeClient(authData, apiKeyMeta);
if (!clientAuth.authorized) {
return {
errorCode: clientAuth.errorCode,
authorized: false,
status: 401,
errorMessage: clientAuth.errorMessage,
};
}
// if we've made it this far we need to check service specific authorization
const serviceAuth = authorizeService(apiKeyMeta, serviceConfig, {
targetAddress,
});
if (!serviceAuth.authorized) {
return {
errorCode: serviceAuth.errorCode,
authorized: false,
status: 403,
errorMessage: serviceAuth.errorMessage,
};
}
// if we reach this point we are authorized!
return {
authorized: true,
apiKeyMeta,
};
}
@@ -0,0 +1,158 @@
import { ApiKeyMetadata, CoreServiceConfig } from "../api";
import { ServiceAuthorizationPayload, authorizeService } from "./service";
describe("authorizeService", () => {
const validApiKeyMeta: ApiKeyMetadata = {
id: "1",
key: "your-api-key",
creatorWalletAddress: "creator-address",
secretHash: "secret-hash",
walletAddresses: [],
domains: [],
bundleIds: [],
services: [
{
name: "storage",
targetAddresses: ["target1", "target2"],
actions: ["action1", "action2"],
},
{
name: "service2",
targetAddresses: ["target3"],
actions: ["action3"],
},
{
name: "bundler",
targetAddresses: ["*"],
actions: ["action3"],
},
],
};
const validServiceConfig: CoreServiceConfig = {
apiUrl: "https://api.example.com",
serviceScope: "storage",
serviceApiKey: "service-api-key",
serviceAction: "action1",
enforceAuth: true,
};
const validBundlerServiceConfig: CoreServiceConfig = {
apiUrl: "https://api.example.com",
serviceScope: "bundler",
serviceApiKey: "service-api-key",
enforceAuth: true,
};
it("should authorize service with valid service scope and action", () => {
const result = authorizeService(validApiKeyMeta, validServiceConfig) as any;
expect(result.authorized).toBe(true);
expect(result.apiKeyMeta).toEqual(validApiKeyMeta);
});
it("should authorize service with valid target address", () => {
const validAuthorizationPayload: ServiceAuthorizationPayload = {
targetAddress: "target2",
};
const result = authorizeService(
validApiKeyMeta,
validServiceConfig,
validAuthorizationPayload,
) as any;
expect(result.authorized).toBe(true);
expect(result.apiKeyMeta).toEqual(validApiKeyMeta);
});
it("should not authorize service with unauthorized service scope", () => {
const invalidServiceConfig: CoreServiceConfig = {
apiUrl: "https://api.example.com",
serviceScope: "rpc",
serviceApiKey: "service-api-key",
serviceAction: "action1",
enforceAuth: true,
};
const result = authorizeService(
validApiKeyMeta,
invalidServiceConfig,
) as any;
expect(result.authorized).toBe(false);
expect(result.errorMessage).toBe(
'The service "rpc" is not authorized for this key.',
);
expect(result.errorCode).toBe("SERVICE_UNAUTHORIZED");
expect(result.status).toBe(403);
});
it("should not authorize service with unauthorized service action", () => {
const invalidServiceConfig: CoreServiceConfig = {
apiUrl: "https://api.example.com",
serviceScope: "storage",
serviceApiKey: "service-api-key",
serviceAction: "unauthorized-action",
enforceAuth: true,
};
const result = authorizeService(
validApiKeyMeta,
invalidServiceConfig,
) as any;
expect(result.authorized).toBe(false);
expect(result.errorMessage).toBe(
'The service "storage" action "unauthorized-action" is not authorized for this key.',
);
expect(result.errorCode).toBe("SERVICE_ACTION_UNAUTHORIZED");
expect(result.status).toBe(403);
});
it("should not authorize service with unauthorized target address", () => {
const invalidAuthorizationPayload: ServiceAuthorizationPayload = {
targetAddress: "unauthorized-target",
};
const result = authorizeService(
validApiKeyMeta,
validServiceConfig,
invalidAuthorizationPayload,
) as any;
expect(result.authorized).toBe(false);
expect(result.errorMessage).toBe(
'The service "storage" target address is not authorized for this key.',
);
expect(result.errorCode).toBe("SERVICE_TARGET_ADDRESS_UNAUTHORIZED");
expect(result.status).toBe(403);
});
it("should not authorize service with unauthorized target addresses", () => {
const invalidAuthorizationPayload: ServiceAuthorizationPayload = {
targetAddress: ["target1", "target2", "target3"],
};
const result = authorizeService(
validApiKeyMeta,
validServiceConfig,
invalidAuthorizationPayload,
) as any;
expect(result.authorized).toBe(false);
expect(result.errorMessage).toBe(
'The service "storage" target address is not authorized for this key.',
);
expect(result.errorCode).toBe("SERVICE_TARGET_ADDRESS_UNAUTHORIZED");
expect(result.status).toBe(403);
});
it("should authorize bundler service with * target addresses", () => {
const authorizationPayload: ServiceAuthorizationPayload = {
targetAddress: ["target1", "target2"],
};
const result = authorizeService(
validApiKeyMeta,
validBundlerServiceConfig,
authorizationPayload,
) as any;
expect(result.authorized).toBe(true);
expect(result.apiKeyMeta).toEqual(validApiKeyMeta);
});
});
@@ -0,0 +1,66 @@
import { ApiKeyMetadata, CoreServiceConfig } from "../api";
import { AuthorizationResult } from "./types";
export type ServiceAuthorizationPayload = { targetAddress?: string | string[] };
export function authorizeService(
apiKeyMetadata: ApiKeyMetadata,
serviceConfig: CoreServiceConfig,
authorizationPayload?: ServiceAuthorizationPayload,
): AuthorizationResult {
const { services } = apiKeyMetadata;
// validate services
const service = services.find(
(srv) => srv.name === serviceConfig.serviceScope,
);
if (!service) {
return {
authorized: false,
errorMessage: `The service "${serviceConfig.serviceScope}" is not authorized for this key.`,
errorCode: "SERVICE_UNAUTHORIZED",
status: 403,
};
}
// validate service actions
if (serviceConfig.serviceAction) {
const isActionAllowed = service.actions.includes(
serviceConfig.serviceAction,
);
if (!isActionAllowed) {
return {
authorized: false,
errorMessage: `The service "${serviceConfig.serviceScope}" action "${serviceConfig.serviceAction}" is not authorized for this key.`,
errorCode: "SERVICE_ACTION_UNAUTHORIZED",
status: 403,
};
}
}
// validate service target addresses
// the service has to pass in the target address for this to be validated
if (authorizationPayload?.targetAddress) {
const checkedAddresses = Array.isArray(authorizationPayload.targetAddress)
? authorizationPayload.targetAddress
: [authorizationPayload.targetAddress];
const allAllowed = service.targetAddresses.includes("*");
if (
!allAllowed &&
checkedAddresses.some((ta) => !service.targetAddresses.includes(ta))
) {
return {
authorized: false,
errorMessage: `The service "${serviceConfig.serviceScope}" target address is not authorized for this key.`,
errorCode: "SERVICE_TARGET_ADDRESS_UNAUTHORIZED",
status: 403,
};
}
}
return {
authorized: true,
apiKeyMeta: apiKeyMetadata,
};
}
@@ -0,0 +1,13 @@
import { ApiKeyMetadata } from "../api";
export type AuthorizationResult =
| {
authorized: true;
apiKeyMeta: ApiKeyMetadata | null;
}
| {
authorized: false;
status: number;
errorMessage: string;
errorCode: string;
};
@@ -0,0 +1,61 @@
export const SERVICE_DEFINITIONS = {
storage: {
name: "storage",
title: "Storage",
description: "IPFS Upload and Download",
actions: [
{
name: "read",
title: "Download",
description: "Download a file from Storage",
},
{
name: "write",
title: "Upload",
description: "Upload a file to Storage",
},
],
},
rpc: {
name: "rpc",
title: "RPC",
description: "Accelerated RPC Edge",
// all actions allowed
actions: [],
},
bundler: {
name: "bundler",
title: "Smart Wallets",
description: "Bundler & Paymaster services",
// all actions allowed
actions: [],
},
relayer: {
name: "relayer",
title: "Gasless Relayer",
description: "Enable gasless transactions",
// all actions allowed
actions: [],
},
} as const;
export const SERVICE_NAMES = Object.keys(
SERVICE_DEFINITIONS,
) as (keyof typeof SERVICE_DEFINITIONS)[];
export const SERVICES = Object.values(SERVICE_DEFINITIONS);
export type ServiceName = (typeof SERVICE_NAMES)[number];
export type ServiceAction = {
name: string;
title: string;
description?: string;
};
export type Service =
(typeof SERVICE_DEFINITIONS)[keyof typeof SERVICE_DEFINITIONS];
export function getServiceByName(name: ServiceName) {
return SERVICE_DEFINITIONS[name];
}
+6
View File
@@ -0,0 +1,6 @@
export type CoreAuthInput = {
// for passing it from the subdomain or path or other service specific things
clientId?: string;
// for passing in the address target in RPC or bundler services
targetAddress?: string | string[];
};
+2
View File
@@ -0,0 +1,2 @@
// only exports the public service definitions
export * from "./core/services";
+137
View File
@@ -0,0 +1,137 @@
import type { IncomingHttpHeaders, IncomingMessage } from "node:http";
import { createHash } from "node:crypto";
import type { AuthorizationInput } from "../core/authorize";
import type { CoreServiceConfig } from "../core/api";
import { authorize } from "../core/authorize";
import type { AuthorizationResult } from "../core/authorize/types";
import type { CoreAuthInput } from "../core/types";
export * from "../core/services";
type NodeServiceConfig = CoreServiceConfig;
export type AuthInput = CoreAuthInput & {
req: IncomingMessage;
};
export async function authorizeNode(
authInput: AuthInput,
serviceConfig: NodeServiceConfig,
): Promise<AuthorizationResult> {
let authData;
try {
authData = extractAuthorizationData(authInput);
} catch (e) {
if (e instanceof Error && e.message === "KEY_CONFLICT") {
return {
authorized: false,
status: 400,
errorMessage: "Please pass either a client id or a secret key.",
errorCode: "KEY_CONFLICT",
};
}
return {
authorized: false,
status: 500,
errorMessage: "Internal Server Error",
errorCode: "INTERNAL_SERVER_ERROR",
};
}
return await authorize(authData, serviceConfig);
}
function getHeader(
headers: IncomingHttpHeaders,
headerName: string,
): string | null {
const header = headers[headerName];
if (Array.isArray(header)) {
return header[0];
}
return header ?? null;
}
export function extractAuthorizationData(
authInput: AuthInput,
): AuthorizationInput {
let requestUrl;
try {
requestUrl = new URL(
authInput.req.url || "",
`http://${authInput.req.headers.host}`,
);
} catch (error) {
console.log("** Node URL Error **", error);
throw error;
}
const headers = authInput.req.headers;
const secretKey = getHeader(headers, "x-secret-key");
// prefer clientId that is explicitly passed in
let clientId = authInput.clientId ?? null;
if (!clientId) {
// next preference is clientId from header
clientId = getHeader(headers, "x-client-id");
}
// next preference is search param
if (!clientId) {
clientId = requestUrl.searchParams.get("clientId");
}
// bundle id from header is first preference
let bundleId = getHeader(headers, "x-bundle-id");
// next preference is search param
if (!bundleId) {
bundleId = requestUrl.searchParams.get("bundleId");
}
let origin = getHeader(headers, "origin");
// if origin header is not available we'll fall back to referrer;
if (!origin) {
origin = getHeader(headers, "referer");
}
// if we have an origin at this point, normalize it
if (origin) {
try {
origin = new URL(origin).hostname;
} catch (e) {
console.warn("failed to parse origin", origin, e);
}
}
// handle if we a secret key is passed in the headers
let secretKeyHash: string | null = null;
if (secretKey) {
// hash the secret key
secretKeyHash = hashSecretKey(secretKey);
// derive the client id from the secret key hash
const derivedClientId = deriveClientIdFromSecretKeyHash(secretKeyHash);
// if we already have a client id passed in we need to make sure they match
if (clientId && clientId !== derivedClientId) {
throw new Error("KEY_CONFLICT");
}
// otherwise set the client id to the derived client id (client id based off of secret key)
clientId = derivedClientId;
}
return {
secretKeyHash,
secretKey,
clientId,
origin,
bundleId,
targetAddress: authInput.targetAddress,
};
}
export function hashSecretKey(secretKey: string) {
return createHash("sha256").update(secretKey).digest("hex");
}
export function deriveClientIdFromSecretKeyHash(secretKeyHash: string) {
return secretKeyHash.slice(0, 32);
}
+5
View File
@@ -0,0 +1,5 @@
{
"extends": "@thirdweb-dev/tsconfig/sdk.json",
"include": ["src", "types"],
"exclude": ["dist", "build", "node_modules"]
}
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/storage
## 1.1.9
### Patch Changes
- [#1338](https://github.com/thirdweb-dev/js/pull/1338) [`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b) Thanks [@jnsdls](https://github.com/jnsdls)! - no longer check if file exists on gateway before uploading, always upload
## 1.1.8
### Patch Changes
+1 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/storage",
"version": "1.1.8",
"version": "1.1.9",
"main": "dist/thirdweb-dev-storage.cjs.js",
"module": "dist/thirdweb-dev-storage.esm.js",
"browser": {
@@ -67,7 +67,6 @@
"cid-tool": "^3.0.0",
"cross-fetch": "^3.1.6",
"form-data": "^4.0.0",
"ipfs-unixfs-importer": "^7.0.1",
"uuid": "^9.0.0"
}
}
-79
View File
@@ -1,79 +0,0 @@
import { FileOrBufferOrString } from "../types";
import { DEFAULT_GATEWAY_URLS, getGatewayUrlForCid } from "./urls";
import { isBufferOrStringWithName } from "./utils";
import fetch from "cross-fetch";
import { importer } from "ipfs-unixfs-importer";
type CIDVersion = 0 | 1;
type ContentWithPath = {
path?: string;
content: Uint8Array;
};
export async function getCIDForUpload(
data: FileOrBufferOrString[],
fileNames: string[],
wrapWithDirectory = true,
cidVersion: CIDVersion = 0,
) {
const contentWithPath: ContentWithPath[] = await Promise.all(
data.map(async (file, i) => {
const path = fileNames[i];
let content: Uint8Array;
if (typeof file === "string") {
content = new TextEncoder().encode(file);
} else if (isBufferOrStringWithName(file)) {
if (typeof file.data === "string") {
content = new TextEncoder().encode(file.data);
} else {
content = file.data as Uint8Array;
}
} else if (Buffer.isBuffer(file)) {
content = file as Uint8Array;
} else {
const buffer = await file.arrayBuffer();
content = new Uint8Array(buffer);
}
return { path, content };
}),
);
return getCID(contentWithPath, wrapWithDirectory, cidVersion);
}
export async function getCID(
content: ContentWithPath[],
wrapWithDirectory = true,
cidVersion: CIDVersion = 0,
) {
const options = { onlyHash: true, wrapWithDirectory, cidVersion };
const dummyBlockstore = {
put: async () => {},
};
let lastCid;
for await (const { cid } of importer(
content as any,
dummyBlockstore as any,
options,
)) {
lastCid = cid;
}
return `${lastCid}`;
}
export async function isUploaded(cid: string) {
const url = getGatewayUrlForCid(DEFAULT_GATEWAY_URLS["ipfs://"][0], cid);
const res = await fetch(url, {
method: "HEAD",
headers: {
// tell the gateway to skip fetching from origin in order to fail fast on 404s and just re-upload in those cases
"x-skip-origin": "true",
},
});
return res.ok;
}
-1
View File
@@ -1,3 +1,2 @@
export * from "./urls";
export * from "./utils";
export * from "./cid";
@@ -1,4 +1,3 @@
import { getCIDForUpload, isUploaded } from "../../common";
import { PINATA_IPFS_URL, TW_IPFS_SERVER_URL } from "../../common/urls";
import {
isBrowser,
@@ -57,30 +56,6 @@ export class IpfsUploader implements IStorageUploader<IpfsUploadBatchOptions> {
const formData = new FormData();
const { form, fileNames } = this.buildFormData(formData, data, options);
try {
const cid = await getCIDForUpload(
data,
fileNames.map((name) => decodeURIComponent(name)),
!options?.uploadWithoutDirectory,
);
if ((await isUploaded(cid)) && !options?.alwaysUpload) {
if (options?.onProgress) {
options?.onProgress({
progress: 100,
total: 100,
});
}
if (options?.uploadWithoutDirectory) {
return [`ipfs://${cid}`];
} else {
return fileNames.map((name) => `ipfs://${cid}/${name}`);
}
}
} catch {
// no-op
}
if (isBrowser()) {
return this.uploadBatchBrowser(form, fileNames, options);
} else {
-30
View File
@@ -1,30 +0,0 @@
import { getCID } from "../src";
import { expect } from "chai";
import fs from "fs";
describe("CID", async () => {
it("Should correctly get CID of a string", async () => {
const cid = await getCID(
[{ content: new TextEncoder().encode("hello world") }],
false,
);
expect(cid).to.equal("Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD");
});
it("Should correctly get CID of a file", async () => {
const cid = await getCID(
[{ content: fs.readFileSync("test/files/0.jpg") }],
false,
);
expect(cid).to.equal("QmSBs7aGB52CF2kXdQaHS6kvQuFACufCbfMKjrB5gSytiT");
});
it("Should correctly upload directory", async () => {
const files = [
{ path: "0.jpg", content: fs.readFileSync("test/files/0.jpg") },
{ path: "1.jpg", content: fs.readFileSync("test/files/1.jpg") },
];
const cid = await getCID(files);
expect(cid).to.equal("QmYtBTkEnTGrzkns2L8R4rL3keowVg3nGcBhPbwrbAWTRP");
});
});
+60
View File
@@ -1,5 +1,65 @@
# @thirdweb-dev/unity-js-bridge
## 0.2.53
### Patch Changes
- Updated dependencies [[`dac8fa7d`](https://github.com/thirdweb-dev/js/commit/dac8fa7d98b6952acf8d13e173099889c1d47da8), [`c5761b99`](https://github.com/thirdweb-dev/js/commit/c5761b99e9797772481506e90cbfa5c35a05bd1d), [`b96a2282`](https://github.com/thirdweb-dev/js/commit/b96a2282730582b684cc96802649a96851af5220)]:
- @thirdweb-dev/sdk@3.10.36
- @thirdweb-dev/wallets@1.0.12
- @thirdweb-dev/auth@3.2.16
## 0.2.52
### Patch Changes
- Updated dependencies [[`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b), [`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b)]:
- @thirdweb-dev/storage@1.1.9
- @thirdweb-dev/chains@0.1.34
- @thirdweb-dev/sdk@3.10.35
- @thirdweb-dev/wallets@1.0.11
- @thirdweb-dev/auth@3.2.15
## 0.2.51
### Patch Changes
- Updated dependencies [[`0407b2c2`](https://github.com/thirdweb-dev/js/commit/0407b2c2f39b5f3fa06e613e671623b5644b3a28)]:
- @thirdweb-dev/chains@0.1.33
- @thirdweb-dev/sdk@3.10.34
- @thirdweb-dev/wallets@1.0.10
- @thirdweb-dev/auth@3.2.14
## 0.2.50
### Patch Changes
- Updated dependencies [[`a9093bcf`](https://github.com/thirdweb-dev/js/commit/a9093bcf287c01e3335fd780e2ccbfdb3380bf95)]:
- @thirdweb-dev/chains@0.1.32
- @thirdweb-dev/sdk@3.10.33
- @thirdweb-dev/wallets@1.0.9
- @thirdweb-dev/auth@3.2.13
## 0.2.49
### Patch Changes
- Updated dependencies [[`4393b228`](https://github.com/thirdweb-dev/js/commit/4393b2280505fd0b2284555d64eae6567e8401a5)]:
- @thirdweb-dev/chains@0.1.31
- @thirdweb-dev/sdk@3.10.32
- @thirdweb-dev/wallets@1.0.8
- @thirdweb-dev/auth@3.2.12
## 0.2.48
### Patch Changes
- Updated dependencies [[`40682191`](https://github.com/thirdweb-dev/js/commit/40682191450de08ad40b9d2957afced248657af2)]:
- @thirdweb-dev/chains@0.1.30
- @thirdweb-dev/sdk@3.10.31
- @thirdweb-dev/wallets@1.0.7
- @thirdweb-dev/auth@3.2.11
## 0.2.47
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/unity-js-bridge",
"version": "0.2.47",
"version": "0.2.53",
"main": "dist/thirdweb-unity-bridge.js",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
"license": "Apache-2.0",
@@ -17,6 +17,7 @@ esbuild.build({
splitting: false,
write: true,
sourcemap: false,
inject: [require.resolve("node-stdlib-browser/helpers/esbuild/shim")],
define: {
process: JSON.stringify({
+51
View File
@@ -1,5 +1,56 @@
# @thirdweb-dev/wallets
## 1.0.12
### Patch Changes
- [#1352](https://github.com/thirdweb-dev/js/pull/1352) [`c5761b99`](https://github.com/thirdweb-dev/js/commit/c5761b99e9797772481506e90cbfa5c35a05bd1d) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Switch to seed based local wallets for faster encryption
- [#1350](https://github.com/thirdweb-dev/js/pull/1350) [`b96a2282`](https://github.com/thirdweb-dev/js/commit/b96a2282730582b684cc96802649a96851af5220) Thanks [@MananTank](https://github.com/MananTank)! - Improved Injected Metamask detection - Do not consider Phantom provider as MetaMask
- Updated dependencies [[`dac8fa7d`](https://github.com/thirdweb-dev/js/commit/dac8fa7d98b6952acf8d13e173099889c1d47da8)]:
- @thirdweb-dev/sdk@3.10.36
## 1.0.11
### Patch Changes
- Updated dependencies [[`8dd7540c`](https://github.com/thirdweb-dev/js/commit/8dd7540c455aa70534f6d29986537592fd12169b)]:
- @thirdweb-dev/chains@0.1.34
- @thirdweb-dev/sdk@3.10.35
## 1.0.10
### Patch Changes
- Updated dependencies [[`0407b2c2`](https://github.com/thirdweb-dev/js/commit/0407b2c2f39b5f3fa06e613e671623b5644b3a28)]:
- @thirdweb-dev/chains@0.1.33
- @thirdweb-dev/sdk@3.10.34
## 1.0.9
### Patch Changes
- Updated dependencies [[`a9093bcf`](https://github.com/thirdweb-dev/js/commit/a9093bcf287c01e3335fd780e2ccbfdb3380bf95)]:
- @thirdweb-dev/chains@0.1.32
- @thirdweb-dev/sdk@3.10.33
## 1.0.8
### Patch Changes
- Updated dependencies [[`4393b228`](https://github.com/thirdweb-dev/js/commit/4393b2280505fd0b2284555d64eae6567e8401a5)]:
- @thirdweb-dev/chains@0.1.31
- @thirdweb-dev/sdk@3.10.32
## 1.0.7
### Patch Changes
- Updated dependencies [[`40682191`](https://github.com/thirdweb-dev/js/commit/40682191450de08ad40b9d2957afced248657af2)]:
- @thirdweb-dev/chains@0.1.30
- @thirdweb-dev/sdk@3.10.31
## 1.0.6
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/wallets",
"version": "1.0.6",
"version": "1.0.12",
"main": "dist/thirdweb-dev-wallets.cjs.js",
"module": "dist/thirdweb-dev-wallets.esm.js",
"types": "dist/thirdweb-dev-wallets.cjs.d.ts",
@@ -0,0 +1,67 @@
import { Ethereum } from "../injected/types";
import { assertWindowEthereum } from "../../utils/assertWindowEthereum";
export function getInjectedMetamaskProvider(): Ethereum | undefined {
if (typeof window === "undefined") {
return;
}
function getReady(ethereum?: Ethereum): Ethereum | undefined {
const isMetaMask = !!ethereum?.isMetaMask;
if (!isMetaMask) {
return;
}
// Brave tries to make itself look like MetaMask
// Could also try RPC `web3_clientVersion` if following is unreliable
if (ethereum.isBraveWallet && !ethereum._events && !ethereum._state) {
return;
}
if (ethereum.isPhantom) {
return;
}
if (ethereum.isAvalanche) {
return;
}
if (ethereum.isBitKeep) {
return;
}
if (ethereum.isMathWallet) {
return;
}
if (ethereum.isZerion) {
return;
}
if (ethereum.isKuCoinWallet) {
return;
}
if (ethereum.isPortal) {
return;
}
if (ethereum.isTokenPocket) {
return;
}
if (ethereum.isTokenary) {
return;
}
return ethereum;
}
if (assertWindowEthereum(globalThis.window)) {
if (globalThis.window.ethereum?.providers) {
return globalThis.window.ethereum.providers.find(getReady);
}
return getReady(globalThis.window.ethereum);
}
}
@@ -5,12 +5,11 @@ import {
RpcError,
UserRejectedRequestError,
} from "../../../lib/wagmi-core/errors";
import { assertWindowEthereum } from "../../utils/assertWindowEthereum";
import { walletIds } from "../../constants/walletIds";
import { InjectedConnector, InjectedConnectorOptions } from "../injected";
import { Ethereum } from "../injected/types";
import type { Chain } from "@thirdweb-dev/chains";
import { utils } from "ethers";
import { getInjectedMetamaskProvider } from "./getInjectedMetamaskProvider";
export type MetaMaskConnectorOptions = Pick<
InjectedConnectorOptions,
@@ -37,46 +36,7 @@ export class MetaMaskConnector extends InjectedConnector {
name: "MetaMask",
shimDisconnect: true,
shimChainChangedDisconnect: true,
getProvider() {
function getReady(ethereum?: Ethereum) {
const isMetaMask = !!ethereum?.isMetaMask;
if (!isMetaMask) {
return;
}
// Brave tries to make itself look like MetaMask
// Could also try RPC `web3_clientVersion` if following is unreliable
if (ethereum.isBraveWallet && !ethereum._events && !ethereum._state) {
return;
}
if (ethereum.isAvalanche) {
return;
}
if (ethereum.isKuCoinWallet) {
return;
}
if (ethereum.isPortal) {
return;
}
if (ethereum.isTokenPocket) {
return;
}
if (ethereum.isTokenary) {
return;
}
return ethereum;
}
if (typeof window === "undefined") {
return;
}
if (assertWindowEthereum(globalThis.window)) {
if (globalThis.window.ethereum?.providers) {
return globalThis.window.ethereum.providers.find(getReady);
}
return getReady(globalThis.window.ethereum);
}
},
getProvider: getInjectedMetamaskProvider,
};
const options = {
+1
View File
@@ -44,3 +44,4 @@ export type { Chain } from "@thirdweb-dev/chains";
// export the window ethereum util
export { assertWindowEthereum } from "./utils/assertWindowEthereum";
export { getInjectedMetamaskProvider } from "./connectors/metamask/getInjectedMetamaskProvider";
@@ -94,7 +94,8 @@ export class LocalWallet extends AbstractClientWallet<
if (this.ethersWallet) {
throw new Error("wallet is already initialized");
}
this.ethersWallet = Wallet.createRandom();
const random = utils.randomBytes(32);
this.ethersWallet = new Wallet(random);
return this.ethersWallet.address;
}
+2 -7
View File
@@ -1,11 +1,11 @@
import type { WalletConnectConnector as WalletConnectConnectorType } from "../connectors/wallet-connect";
import type { QRModalOptions } from "../connectors/wallet-connect/qrModalOptions";
import { Connector, WagmiAdapter } from "../interfaces/connector";
import { assertWindowEthereum } from "../utils/assertWindowEthereum";
import { AbstractClientWallet, WalletOptions } from "./base";
import type { MetaMaskConnector as MetamaskConnectorType } from "../connectors/metamask";
import { walletIds } from "../constants/walletIds";
import { TW_WC_PROJECT_ID } from "../constants/wc";
import { getInjectedMetamaskProvider } from "../connectors/metamask/getInjectedMetamaskProvider";
type MetamaskAdditionalOptions = {
/**
@@ -63,12 +63,7 @@ export class MetaMaskWallet extends AbstractClientWallet<MetamaskAdditionalOptio
constructor(options: MetamaskWalletOptions) {
super(MetaMaskWallet.id, options);
if (assertWindowEthereum(globalThis.window)) {
this.isInjected = !!globalThis.window.ethereum?.isMetaMask;
} else {
this.isInjected = false;
}
this.isInjected = !!getInjectedMetamaskProvider();
}
protected async getConnector(): Promise<Connector> {
+945 -426
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -60,6 +60,10 @@
"inputs": ["package.json"],
"dependsOn": ["^build"]
},
"@thirdweb-dev/service-utils#build": {
"outputs": ["dist/**", "cf-worker/**", "node/**"],
"dependsOn": ["^build"]
},
"test": {
"outputs": [],
"inputs": ["src/**", "test/**"],