Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cea8436c1 | ||
|
|
dac8fa7d98 | ||
|
|
7a6534d1a9 | ||
|
|
d5aee62bf4 | ||
|
|
0bfdedd4ba | ||
|
|
c5761b99e9 | ||
|
|
42d9ab68d9 | ||
|
|
fd0650dcac | ||
|
|
ddb3dabe69 | ||
|
|
b96a228273 | ||
|
|
781e26d896 | ||
|
|
f7392138ee | ||
|
|
5eb6fc1bf3 | ||
|
|
7dc685bbec | ||
|
|
4915ac50f8 | ||
|
|
d724ad85c5 | ||
|
|
1d32b299a0 | ||
|
|
cfa7ecbc9a | ||
|
|
8dd7540c45 | ||
|
|
07c7d97c28 | ||
|
|
47e931e0dd | ||
|
|
0407b2c2f3 | ||
|
|
55ffb176f2 | ||
|
|
a9093bcf28 | ||
|
|
db964131b4 | ||
|
|
4393b22805 | ||
|
|
b28c3a5a67 | ||
|
|
4068219145 |
@@ -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,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": {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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,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"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -10,4 +10,6 @@ export default {
|
||||
width: 512,
|
||||
format: "png",
|
||||
},
|
||||
rpc: ["https://base.rpc.thirdweb.com/${THIRDWEB_API_KEY}"],
|
||||
status: "active",
|
||||
};
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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
@@ -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,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",
|
||||
|
||||
@@ -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,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,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,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",
|
||||
|
||||
@@ -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,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",
|
||||
|
||||
@@ -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,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();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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,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 (
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-typescript",
|
||||
["@babel/preset-env", { "targets": "defaults, not ie 11" }]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# folders
|
||||
dist/
|
||||
|
||||
# files
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ["thirdweb"],
|
||||
};
|
||||
@@ -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
|
||||
@@ -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"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-service-utils-node.cjs.js",
|
||||
"module": "dist/thirdweb-dev-service-utils-node.esm.js"
|
||||
}
|
||||
@@ -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("");
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
@@ -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[];
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
// only exports the public service definitions
|
||||
export * from "./core/services";
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "@thirdweb-dev/tsconfig/sdk.json",
|
||||
"include": ["src", "types"],
|
||||
"exclude": ["dist", "build", "node_modules"]
|
||||
}
|
||||
@@ -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,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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
@@ -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,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({
|
||||
|
||||
@@ -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,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 = {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Generated
+945
-426
File diff suppressed because it is too large
Load Diff
@@ -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/**"],
|
||||
|
||||
Reference in New Issue
Block a user