Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4676e1b4e | ||
|
|
0135a7790c | ||
|
|
2d088d367c | ||
|
|
546353a479 | ||
|
|
9daf044926 | ||
|
|
7054f9f016 | ||
|
|
a3bb17cb33 | ||
|
|
d03645aefd | ||
|
|
53626f8100 | ||
|
|
8a389f1295 | ||
|
|
4e5eb13b82 | ||
|
|
2b11353909 | ||
|
|
5882091eab | ||
|
|
8fc5f204b0 | ||
|
|
c953571588 | ||
|
|
edcd22d612 | ||
|
|
0d5503aae9 | ||
|
|
998e521733 | ||
|
|
be606dd3c9 | ||
|
|
d794b8f9f4 | ||
|
|
21b29490d4 | ||
|
|
7b1d62b323 | ||
|
|
e78da6b36c | ||
|
|
ed711c8cb2 | ||
|
|
05a7495a13 |
+7
-7
@@ -34,19 +34,19 @@
|
||||
"packageManager": "[email protected]",
|
||||
"dependencies": {
|
||||
"@changesets/changelog-github": "^0.4.8",
|
||||
"@changesets/cli": "^2.26.1",
|
||||
"@changesets/get-dependents-graph": "^1.3.5",
|
||||
"@changesets/get-release-plan": "^3.0.16",
|
||||
"@changesets/cli": "^2.26.2",
|
||||
"@changesets/get-dependents-graph": "^1.3.6",
|
||||
"@changesets/get-release-plan": "^3.0.17",
|
||||
"@changesets/parse": "^0.3.16",
|
||||
"@manypkg/cli": "^0.20.0",
|
||||
"@manypkg/get-packages": "^1.1.3",
|
||||
"@playwright/test": "1.31.2",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
||||
"@types/node": "^18.15.11",
|
||||
"eslint": "^8.42.0",
|
||||
"@types/node": "^18.16.18",
|
||||
"eslint": "^8.43.0",
|
||||
"mocha": "^10.2.0",
|
||||
"prettier": "^2.8.7",
|
||||
"turbo": "^1.9.8",
|
||||
"prettier": "^2.8.8",
|
||||
"turbo": "^1.10.6",
|
||||
"yalc": "1.0.0-pre.53"
|
||||
},
|
||||
"manypkg": {
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 3.2.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
- Updated dependencies [[`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2)]:
|
||||
- @thirdweb-dev/wallets@1.0.4
|
||||
|
||||
## 3.2.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2b113539`](https://github.com/thirdweb-dev/js/commit/2b113539098384f910b3c4d54e1fde9d35a6f053), [`be606dd3`](https://github.com/thirdweb-dev/js/commit/be606dd3c93c1514834c1d970e864d7f949a07ab), [`998e5217`](https://github.com/thirdweb-dev/js/commit/998e521733efd6a67e42f9bf0beab5fbdccf08ae)]:
|
||||
- @thirdweb-dev/wallets@1.0.3
|
||||
|
||||
## 3.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ed711c8c`](https://github.com/thirdweb-dev/js/commit/ed711c8cb2ed6a0deb1b2a5eeec06df1d4edc5e8), [`05a7495a`](https://github.com/thirdweb-dev/js/commit/05a7495a132aabab5f48abbdb80a468ff6f65df8), [`e78da6b3`](https://github.com/thirdweb-dev/js/commit/e78da6b36cfa6d954234820563201bf760186ed1)]:
|
||||
- @thirdweb-dev/wallets@1.0.2
|
||||
|
||||
## 3.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+19
-19
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "3.2.5",
|
||||
"version": "3.2.8",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
@@ -80,29 +80,29 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.3",
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@babel/preset-typescript": "^7.22.5",
|
||||
"@microsoft/api-documenter": "^7.22.21",
|
||||
"@microsoft/api-extractor": "^7.36.0",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@preconstruct/cli": "^2.7.0",
|
||||
"@solana/web3.js": "^1.62.0",
|
||||
"@swc-node/register": "^1.5.1",
|
||||
"@swc/core": "^1.3.23",
|
||||
"@swc-node/register": "^1.6.6",
|
||||
"@swc/core": "^1.3.67",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@types/chai": "^4.3.3",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/cookie": "^0.5.1",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"chai": "^4.3.6",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-inclusive-language": "^2.2.0",
|
||||
@@ -111,10 +111,10 @@
|
||||
"ethers": "^5.7.2",
|
||||
"express": "^4.18.1",
|
||||
"mocha": "^10.2.0",
|
||||
"next": "^12.2.0",
|
||||
"next-auth": "^4.20.1",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.7.4"
|
||||
"next": "^12.3.4",
|
||||
"next-auth": "^4.22.1",
|
||||
"prettier": "^2.8.8",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@solana/web3.js": "^1.73.0",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
- [#1281](https://github.com/thirdweb-dev/js/pull/1281) [`a3bb17cb`](https://github.com/thirdweb-dev/js/commit/a3bb17cb33f033846fb3b4c8a0a4809ba76cab96) Thanks [@nkrishang](https://github.com/nkrishang)! - Handle ERC4337Signer correctly for signTypedData
|
||||
|
||||
## 0.1.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1276](https://github.com/thirdweb-dev/js/pull/1276) [`5882091e`](https://github.com/thirdweb-dev/js/commit/5882091eab65978009a5a5305701f121851b10ad) Thanks [@MananTank](https://github.com/MananTank)! - Do not change order or RPCs in `getChainRPCs` to Fix RPC override issue
|
||||
|
||||
## 0.1.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -10,9 +10,9 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://ethereum.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://mainnet.infura.io/v3/${INFURA_API_KEY}",
|
||||
"wss://mainnet.infura.io/ws/v3/${INFURA_API_KEY}",
|
||||
"https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://api.mycryptoapi.com/eth",
|
||||
"https://cloudflare-eth.com",
|
||||
"https://ethereum.publicnode.com"
|
||||
|
||||
@@ -4,8 +4,8 @@ export default {
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://optimism.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://optimism-mainnet.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://mainnet.optimism.io/"
|
||||
],
|
||||
"faucets": [],
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Metachain One Mainnet",
|
||||
"chain": "METAO",
|
||||
"icon": {
|
||||
"url": "ipfs://QmTmo2QAtX5PbhX96vewnvH4Vc5H83Ft2DJGi6tAqTcFij",
|
||||
"width": 1000,
|
||||
"height": 981,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://metachain-one.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.metachain.one",
|
||||
"https://rpc2.metachain.one"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Metao",
|
||||
"symbol": "METAO",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://metachain.one",
|
||||
"shortName": "metao",
|
||||
"chainId": 112358,
|
||||
"networkId": 112358,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://explorer.metachain.one",
|
||||
"icon": {
|
||||
"url": "ipfs://bafybeifu5tpui7dk5cjoo54kde7pmuthvnl7sdykobuarsxgu7t2izurnq",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "metachain-one"
|
||||
} as const satisfies Chain;
|
||||
@@ -10,8 +10,8 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://polygon.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://polygon-mainnet.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://polygon-rpc.com/",
|
||||
"https://rpc-mainnet.matic.network",
|
||||
"https://matic-mainnet.chainstacklabs.com",
|
||||
|
||||
@@ -4,8 +4,8 @@ export default {
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://optimism-goerli.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://optimism-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://goerli.optimism.io/"
|
||||
],
|
||||
"faucets": [
|
||||
|
||||
@@ -13,8 +13,8 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://arbitrum-goerli.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://arb-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://arbitrum-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://arb-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://goerli-rollup.arbitrum.io/rpc/"
|
||||
],
|
||||
"faucets": [],
|
||||
|
||||
@@ -5,9 +5,9 @@ export default {
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://goerli.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"wss://goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://rpc.goerli.mudit.blog/",
|
||||
"https://ethereum-goerli.publicnode.com"
|
||||
],
|
||||
|
||||
@@ -5,6 +5,7 @@ export default {
|
||||
"rpc": [
|
||||
"https://rollux.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.rollux.com",
|
||||
"https://rollux.public-rpc.com",
|
||||
"wss://rpc.rollux.com/wss",
|
||||
"https://rpc.ankr.com/rollux/${ANKR_API_KEY}"
|
||||
],
|
||||
|
||||
@@ -5,10 +5,10 @@ export default {
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://linea-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.goerli.linea.build",
|
||||
"wss://rpc.goerli.linea.build",
|
||||
"https://linea-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"wss://linea-goerli.infura.io/v3/${INFURA_API_KEY}"
|
||||
"wss://linea-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://rpc.goerli.linea.build",
|
||||
"wss://rpc.goerli.linea.build"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucetlink.to/goerli"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Cascadia Testnet",
|
||||
"chain": "Cascadia",
|
||||
"rpc": [
|
||||
"https://cascadia-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet.cascadia.foundation"
|
||||
],
|
||||
"faucets": [
|
||||
"https://www.cascadia.foundation/faucet"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "CC",
|
||||
"symbol": "tCC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.cascadia.foundation",
|
||||
"shortName": "cascadia",
|
||||
"chainId": 6102,
|
||||
"networkId": 6102,
|
||||
"icon": {
|
||||
"url": "ipfs://QmQtcwxNiJ9D1QDz4k6jZ7qacLcqMk6CeW85TTBWBvNp3z",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Cascadia EVM Explorer",
|
||||
"url": "https://explorer.cascadia.foundation",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmQtcwxNiJ9D1QDz4k6jZ7qacLcqMk6CeW85TTBWBvNp3z",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "png"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cascadia Cosmos Explorer",
|
||||
"url": "https://validator.cascadia.foundation",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmQtcwxNiJ9D1QDz4k6jZ7qacLcqMk6CeW85TTBWBvNp3z",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "cascadia-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -11,8 +11,8 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://mumbai.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://polygon-mumbai.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://polygon-mumbai.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://polygon-mumbai.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://matic-mumbai.chainstacklabs.com",
|
||||
"https://rpc-mumbai.maticvigil.com",
|
||||
"https://matic-testnet-archive-rpc.bwarelabs.com",
|
||||
|
||||
@@ -26,19 +26,8 @@ export default {
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Evmos EVM Explorer",
|
||||
"url": "https://evm.evmos.dev",
|
||||
"standard": "EIP3091",
|
||||
"icon": {
|
||||
"url": "ipfs://QmeZW6VKUFTbz7PPW8PmDR3ZHa6osYPLBFPnW8T5LSU49c",
|
||||
"width": 400,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Evmos Cosmos Explorer",
|
||||
"url": "https://explorer.evmos.dev",
|
||||
"name": "Evmos Explorer (Escan)",
|
||||
"url": "https://testnet.escan.live",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmeZW6VKUFTbz7PPW8PmDR3ZHa6osYPLBFPnW8T5LSU49c",
|
||||
|
||||
@@ -4,7 +4,6 @@ export default {
|
||||
"chain": "Evmos",
|
||||
"rpc": [
|
||||
"https://evmos.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://eth.bd.evmos.org:8545",
|
||||
"https://evmos-evm.publicnode.com"
|
||||
],
|
||||
"faucets": [],
|
||||
@@ -25,7 +24,7 @@ export default {
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Evmos EVM Explorer (Escan)",
|
||||
"name": "Evmos Explorer (Escan)",
|
||||
"url": "https://escan.live",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
@@ -34,17 +33,6 @@ export default {
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Evmos Cosmos Explorer (Mintscan)",
|
||||
"url": "https://www.mintscan.io/evmos",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmeZW6VKUFTbz7PPW8PmDR3ZHa6osYPLBFPnW8T5LSU49c",
|
||||
"width": 400,
|
||||
"height": 400,
|
||||
"format": "png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.25",
|
||||
"version": "0.1.27",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"browser": {
|
||||
@@ -23,18 +23,18 @@
|
||||
},
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.3",
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@babel/runtime": "^7.19.0",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@babel/preset-typescript": "^7.22.5",
|
||||
"@babel/runtime": "^7.22.5",
|
||||
"@preconstruct/cli": "^2.7.0",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"axios": "^1.3.4",
|
||||
"deepmerge": "^4.3.0",
|
||||
"axios": "^1.4.0",
|
||||
"deepmerge": "^4.3.1",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"jest": "^29.4.3",
|
||||
"plop": "^3.1.2",
|
||||
"typescript": "^4.7.4"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"preconstruct": {
|
||||
"entrypoints": [
|
||||
|
||||
@@ -80,6 +80,33 @@ chains = chains
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Sort RPCs in chain
|
||||
* @param {Chain} chain
|
||||
*/
|
||||
function sortRPCs(chain) {
|
||||
const thirdwebRPCs = [];
|
||||
const alchemyRPCs = [];
|
||||
const infuraRPCs = [];
|
||||
const otherRPCs = [];
|
||||
|
||||
chain.rpc.forEach((rpc) => {
|
||||
if (rpc.includes("${THIRDWEB_API_KEY}")) {
|
||||
thirdwebRPCs.push(rpc);
|
||||
} else if (rpc.includes("${ALCHEMY_API_KEY}")) {
|
||||
alchemyRPCs.push(rpc);
|
||||
} else if (rpc.includes("${INFURA_API_KEY}")) {
|
||||
infuraRPCs.push(rpc);
|
||||
} else {
|
||||
otherRPCs.push(rpc);
|
||||
}
|
||||
});
|
||||
|
||||
chain.rpc = [...thirdwebRPCs, ...infuraRPCs, ...alchemyRPCs, ...otherRPCs];
|
||||
}
|
||||
|
||||
chains.forEach(sortRPCs);
|
||||
|
||||
const imports = [];
|
||||
const exports = [];
|
||||
const exportNames = [];
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -28,59 +28,45 @@ export function getChainRPCs(
|
||||
...options,
|
||||
};
|
||||
|
||||
const modeChains = chain.rpc.filter((rpc) => {
|
||||
if (rpc.startsWith("http") && mode === "http") {
|
||||
return true;
|
||||
}
|
||||
if (rpc.startsWith("ws") && mode === "ws") {
|
||||
return true;
|
||||
const processedRPCs: string[] = [];
|
||||
|
||||
chain.rpc.forEach((rpc) => {
|
||||
// exclude RPC if mode mismatch
|
||||
if (mode === "http" && !rpc.startsWith("http")) {
|
||||
return;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (mode === "ws" && !rpc.startsWith("ws")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Replace API_KEY placeholder with value
|
||||
if (thirdwebApiKey && rpc.includes("${THIRDWEB_API_KEY}")) {
|
||||
processedRPCs.push(rpc.replace("${THIRDWEB_API_KEY}", thirdwebApiKey));
|
||||
} else if (infuraApiKey && rpc.includes("${INFURA_API_KEY}")) {
|
||||
processedRPCs.push(rpc.replace("${INFURA_API_KEY}", infuraApiKey));
|
||||
} else if (alchemyApiKey && rpc.includes("${ALCHEMY_API_KEY}")) {
|
||||
processedRPCs.push(rpc.replace("${ALCHEMY_API_KEY}", alchemyApiKey));
|
||||
}
|
||||
|
||||
// exclude RPCs with unknown placeholder
|
||||
else if (rpc.includes("${")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add as is
|
||||
else {
|
||||
processedRPCs.push(rpc);
|
||||
}
|
||||
});
|
||||
|
||||
const thirdwebRPC = modeChains
|
||||
.filter((rpc) => {
|
||||
return rpc.includes("${THIRDWEB_API_KEY}") && thirdwebApiKey;
|
||||
})
|
||||
.map((rpc) =>
|
||||
thirdwebApiKey ? rpc.replace("${THIRDWEB_API_KEY}", thirdwebApiKey) : rpc,
|
||||
);
|
||||
|
||||
const alchemyRPC = modeChains
|
||||
.filter((rpc) => {
|
||||
return rpc.includes("${ALCHEMY_API_KEY}") && alchemyApiKey;
|
||||
})
|
||||
.map((rpc) =>
|
||||
alchemyApiKey ? rpc.replace("${ALCHEMY_API_KEY}", alchemyApiKey) : rpc,
|
||||
);
|
||||
|
||||
const infuraRPC = modeChains
|
||||
.filter((rpc) => {
|
||||
return rpc.includes("${INFURA_API_KEY}") && infuraApiKey;
|
||||
})
|
||||
.map((rpc) =>
|
||||
infuraApiKey ? rpc.replace("${INFURA_API_KEY}", infuraApiKey) : rpc,
|
||||
);
|
||||
|
||||
const allOtherRpcs = modeChains.filter((rpc) => {
|
||||
return !rpc.includes("${");
|
||||
});
|
||||
|
||||
const orderedRPCs = [
|
||||
...thirdwebRPC,
|
||||
...infuraRPC,
|
||||
...alchemyRPC,
|
||||
...allOtherRpcs,
|
||||
];
|
||||
|
||||
if (orderedRPCs.length === 0) {
|
||||
if (processedRPCs.length === 0) {
|
||||
throw new Error(
|
||||
`No RPC available for chainId "${chain.chainId}" with mode ${mode}`,
|
||||
);
|
||||
}
|
||||
|
||||
return orderedRPCs;
|
||||
return processedRPCs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.10.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1280](https://github.com/thirdweb-dev/js/pull/1280) [`53626f81`](https://github.com/thirdweb-dev/js/commit/53626f8100f400c46333617b14bd9fc144a7e801) Thanks [@Marfuen](https://github.com/Marfuen)! - Don't rely on package.json to export app
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
- Updated dependencies [[`2d088d36`](https://github.com/thirdweb-dev/js/commit/2d088d367ca54233836dc69712fd411ab7924205), [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2), [`9daf0449`](https://github.com/thirdweb-dev/js/commit/9daf044926bf995ac8998929dbeca548c5eb8561), [`546353a4`](https://github.com/thirdweb-dev/js/commit/546353a479c11533818ef917c0f6b4d6f8f69872), [`a3bb17cb`](https://github.com/thirdweb-dev/js/commit/a3bb17cb33f033846fb3b4c8a0a4809ba76cab96), [`0135a779`](https://github.com/thirdweb-dev/js/commit/0135a7790cf2acde6b701cb41ea10dd311da5ec3)]:
|
||||
- @thirdweb-dev/storage@1.1.6
|
||||
- @thirdweb-dev/chains@0.1.27
|
||||
- @thirdweb-dev/sdk@3.10.28
|
||||
|
||||
## 0.10.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1274](https://github.com/thirdweb-dev/js/pull/1274) [`8fc5f204`](https://github.com/thirdweb-dev/js/commit/8fc5f204b00733089c02beee92c86b0f1fcac271) Thanks [@Marfuen](https://github.com/Marfuen)! - Added all detections for deploy command and some minor bug fixes
|
||||
|
||||
- Updated dependencies [[`2b113539`](https://github.com/thirdweb-dev/js/commit/2b113539098384f910b3c4d54e1fde9d35a6f053), [`c9535715`](https://github.com/thirdweb-dev/js/commit/c95357158819abd42d4b0900ecc2fa40fcb957f8), [`5882091e`](https://github.com/thirdweb-dev/js/commit/5882091eab65978009a5a5305701f121851b10ad)]:
|
||||
- @thirdweb-dev/sdk@3.10.27
|
||||
- @thirdweb-dev/chains@0.1.26
|
||||
|
||||
## 0.10.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -2,7 +2,7 @@ import { CREATE_MESSAGES } from "../constants/constants";
|
||||
import { prepareEnvironment } from "@gmrchk/cli-testing-library";
|
||||
|
||||
// this creates an app, can take some time that's fine
|
||||
jest.setTimeout(120_000);
|
||||
jest.setTimeout(240_000);
|
||||
|
||||
describe("npx thirdweb detect", () => {
|
||||
it("should detect ERC721Base extensions", async () => {
|
||||
|
||||
+15
-15
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.10.27",
|
||||
"version": "0.10.29",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -14,25 +14,25 @@
|
||||
"@types/async-retry": "^1.3.0",
|
||||
"@types/cross-spawn": "^6.0.2",
|
||||
"@types/inquirer": "^8.2.1",
|
||||
"@types/jest": "^29.2.1",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/js-yaml": "^4.0.5",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/prompts": "^2.0.14",
|
||||
"@types/node": "^18.16.18",
|
||||
"@types/prompts": "^2.4.4",
|
||||
"@types/rimraf": "^3.0.0",
|
||||
"@types/tar": "^6.1.2",
|
||||
"@types/update-notifier": "^6.0.1",
|
||||
"@types/tar": "^6.1.5",
|
||||
"@types/update-notifier": "^6.0.4",
|
||||
"@types/validate-npm-package-name": "^4.0.0",
|
||||
"chalk": "^5.2.0",
|
||||
"chalk": "^5.3.0",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"hardhat": "^2.9.3",
|
||||
"hardhat": "^2.16.1",
|
||||
"jest": "^29.4.3",
|
||||
"ora": "^6.1.2",
|
||||
"prettier": "^2.7.1",
|
||||
"ts-jest": "^29.0.3",
|
||||
"ora": "^6.3.1",
|
||||
"prettier": "^2.8.8",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node": "^10.7.0",
|
||||
"tsup": "^6.2.3",
|
||||
"typescript": "^4.7.4"
|
||||
"tsup": "^6.7.0",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iarna/toml": "^2.2.5",
|
||||
@@ -53,10 +53,10 @@
|
||||
"rimraf": "^3.0.2",
|
||||
"solc": "0.8.17",
|
||||
"sync-disk-cache": "^2.1.0",
|
||||
"tar": "^6.1.11",
|
||||
"tar": "^6.1.15",
|
||||
"update-notifier": "^6.0.2",
|
||||
"validate-npm-package-name": "^4.0.0",
|
||||
"yaml": "^2.1.1"
|
||||
"yaml": "^2.3.1"
|
||||
},
|
||||
"bin": {
|
||||
"thirdweb": "./dist/cli/index.js"
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
import inquirer from "inquirer";
|
||||
import { info } from "../helpers/logger";
|
||||
import { FrameworkType, PackageManagerType } from "../types/ProjectType";
|
||||
import inquirer from "inquirer";
|
||||
import NextDetector from "./frameworks/next";
|
||||
import CRADetector from "./frameworks/cra";
|
||||
import RemixDetector from "./frameworks/remix";
|
||||
import GatsbyDetector from "./frameworks/gatsby";
|
||||
import VueDetector from "./frameworks/vue";
|
||||
import ReactNativeCLIDetector from "./frameworks/reactNativeCli";
|
||||
import DjangoDetector from "./frameworks/django";
|
||||
import ExpoDetector from "./frameworks/expo";
|
||||
import FoundryDetector from "./frameworks/foundry";
|
||||
import HardhatDetector from "./frameworks/hardhat";
|
||||
import { FrameworkDetector } from "./detector";
|
||||
import TruffleDetector from "./frameworks/truffle";
|
||||
import BrownieDetector from "./frameworks/brownie";
|
||||
import FastAPIDetector from "./frameworks/fastAPI";
|
||||
import FlaskDetector from "./frameworks/flask";
|
||||
import PopulusDetector from "./frameworks/populus";
|
||||
import FastifyDetector from "./frameworks/fastify";
|
||||
import CRADetector from "./frameworks/cra";
|
||||
import DjangoDetector from "./frameworks/django";
|
||||
import EchoDetector from "./frameworks/echo";
|
||||
import ExpoDetector from "./frameworks/expo";
|
||||
import FastAPIDetector from "./frameworks/fastAPI";
|
||||
import FastifyDetector from "./frameworks/fastify";
|
||||
import FiberDetector from "./frameworks/fiber";
|
||||
import FlaskDetector from "./frameworks/flask";
|
||||
import FoundryDetector from "./frameworks/foundry";
|
||||
import GatsbyDetector from "./frameworks/gatsby";
|
||||
import GinDetector from "./frameworks/gin";
|
||||
import HardhatDetector from "./frameworks/hardhat";
|
||||
import NextDetector from "./frameworks/next";
|
||||
import PopulusDetector from "./frameworks/populus";
|
||||
import ReactNativeCLIDetector from "./frameworks/reactNativeCli";
|
||||
import RemixDetector from "./frameworks/remix";
|
||||
import RevelDetector from "./frameworks/revel";
|
||||
import TruffleDetector from "./frameworks/truffle";
|
||||
import ViteDetector from "./frameworks/vite";
|
||||
import VueDetector from "./frameworks/vue";
|
||||
import ZenjectDetector from "./frameworks/zenject";
|
||||
|
||||
export default async function detect(
|
||||
@@ -50,6 +51,7 @@ export default async function detect(
|
||||
new RevelDetector(),
|
||||
new TruffleDetector(),
|
||||
new VueDetector(),
|
||||
new ViteDetector(),
|
||||
new ZenjectDetector(),
|
||||
];
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import inquirer from "inquirer";
|
||||
import { info } from "../helpers/logger";
|
||||
import { LibraryType, PackageManagerType } from "../types/ProjectType";
|
||||
import { LibraryDetector } from "./detector";
|
||||
import inquirer from "inquirer";
|
||||
import ReactDetector from "./libraries/react";
|
||||
import ExpressDetector from "./libraries/express";
|
||||
import ReactNativeDetector from "./libraries/reactNative";
|
||||
import ViteDetector from "./libraries/vite";
|
||||
import Web3PyDetector from "./libraries/web3py";
|
||||
import PlayMakerDetector from "./libraries/playmaker";
|
||||
import ReactDetector from "./libraries/react";
|
||||
import ReactNativeDetector from "./libraries/reactNative";
|
||||
import Web3PyDetector from "./libraries/web3py";
|
||||
|
||||
export default async function detect(
|
||||
path: string,
|
||||
@@ -19,7 +18,6 @@ export default async function detect(
|
||||
new ExpressDetector(),
|
||||
new ReactDetector(),
|
||||
new ReactNativeDetector(),
|
||||
new ViteDetector(),
|
||||
new Web3PyDetector(),
|
||||
new PlayMakerDetector(),
|
||||
];
|
||||
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
import { LibraryDetector } from "../detector";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { LibraryType } from "../../types/ProjectType";
|
||||
import { parsePackageJson } from "../../../lib/utils";
|
||||
import { FrameworkType } from "../../types/ProjectType";
|
||||
import { FrameworkDetector } from "../detector";
|
||||
|
||||
export default class ViteDetector implements LibraryDetector {
|
||||
public libraryType: LibraryType = "vite";
|
||||
export default class ViteDetector implements FrameworkDetector {
|
||||
public frameworkType: FrameworkType = "vite";
|
||||
|
||||
public matches(path: string): boolean {
|
||||
const packageJsonPath = path + "/package.json";
|
||||
@@ -16,7 +16,7 @@ export default class ViteDetector implements LibraryDetector {
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
const viteDependencyExists =
|
||||
dependencies["vite"] || devDependencies["vite"] || false;
|
||||
!!dependencies["vite"] || !!devDependencies["vite"] || false;
|
||||
|
||||
return viteDependencyExists;
|
||||
}
|
||||
@@ -56,6 +56,7 @@ export type FrameworkType =
|
||||
| "revel"
|
||||
| "fiber"
|
||||
| "zenject"
|
||||
| "vite"
|
||||
| "none";
|
||||
export type LibraryType =
|
||||
| "react"
|
||||
|
||||
@@ -1,30 +1,57 @@
|
||||
import NPMDetector from "../core/detection/npm";
|
||||
import ViteDetector from "../core/detection/vite";
|
||||
import YarnDetector from "../core/detection/yarn";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import detectFramework from "../core/detection/detectFramework";
|
||||
import detectPackageManager from "../core/detection/detectPackageManager";
|
||||
import { logger } from "../core/helpers/logger";
|
||||
import { runCommand } from "../create/helpers/run-command";
|
||||
import { upload } from "../storage/command";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
|
||||
export async function deployApp(distPath = "dist", projectPath = ".") {
|
||||
const storage = new ThirdwebStorage();
|
||||
const supportedFrameworks = [new ViteDetector()];
|
||||
const detectedPackageManager = await detectPackageManager(projectPath, {});
|
||||
const detectedFramework = await detectFramework(projectPath, {}, detectedPackageManager);
|
||||
|
||||
const possibleProjects = supportedFrameworks
|
||||
.filter((detector) => detector.matches(projectPath))
|
||||
.map((detector) => detector.projectType);
|
||||
|
||||
const hasYarn = new YarnDetector().matches(".");
|
||||
const hasNPM = new NPMDetector().matches(".");
|
||||
|
||||
if (possibleProjects.length === 0) {
|
||||
if (detectedFramework === "none") {
|
||||
throw new Error("No supported project detected");
|
||||
}
|
||||
|
||||
switch (detectedFramework) {
|
||||
case "next":
|
||||
distPath = "out";
|
||||
break;
|
||||
case "cra":
|
||||
distPath = "build";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
logger.info(`Detected project type: ${detectedFramework}`);
|
||||
logger.info(`Detected package manager: ${detectedPackageManager}`);
|
||||
logger.info(`distPath: ${distPath}`);
|
||||
logger.info(`projectPath: ${projectPath}`);
|
||||
|
||||
try {
|
||||
if (hasYarn) {
|
||||
await runCommand("yarn", ["build"]);
|
||||
} else if (hasNPM) {
|
||||
await runCommand("npm", ["build"]);
|
||||
switch (detectedPackageManager) {
|
||||
case "yarn":
|
||||
await runCommand("yarn", ["build"], true);
|
||||
if (detectedFramework === "next") {
|
||||
await runCommand("yarn", ["next", "export"], true);
|
||||
}
|
||||
break;
|
||||
case "npm":
|
||||
await runCommand("npm", ["run", "build"], true);
|
||||
if (detectedFramework === "next") {
|
||||
await runCommand("npx", ["next", "export"], true);
|
||||
}
|
||||
break;
|
||||
case "pnpm":
|
||||
await runCommand("pnpm", ["build"], true);
|
||||
if (detectedFramework === "next") {
|
||||
await runCommand("pnpm", ["next", "export"], true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error("No supported package manager detected");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Can't build project");
|
||||
@@ -33,9 +60,9 @@ export async function deployApp(distPath = "dist", projectPath = ".") {
|
||||
|
||||
try {
|
||||
const uri = await upload(storage, distPath);
|
||||
return `https://thirdweb.com/app/deploy/${uri.replace("ipfs://", "")}`;
|
||||
return `${uri.replace("ipfs://", "https://ipfs-public.thirdwebcdn.com/ipfs/")}`;
|
||||
} catch (err) {
|
||||
console.error("Can't upload project");
|
||||
console.error("Can't upload project", err);
|
||||
return Promise.reject("Can't upload project");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { spinner } from "../core/helpers/logger";
|
||||
import { BufferOrStringWithName, ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { spinner } from "../core/helpers/logger";
|
||||
|
||||
function recurseFiles(
|
||||
uploadPath: string,
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/contracts-js
|
||||
|
||||
## 1.3.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
## 1.3.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/contracts-js",
|
||||
"version": "1.3.7",
|
||||
"version": "1.3.8",
|
||||
"main": "dist/thirdweb-dev-contracts-js.cjs.js",
|
||||
"module": "dist/thirdweb-dev-contracts-js.esm.js",
|
||||
"browser": {
|
||||
@@ -13,17 +13,17 @@
|
||||
"@thirdweb-dev/contracts": "3.5.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@babel/preset-typescript": "^7.22.5",
|
||||
"@ethersproject/abi": "^5.7.0",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@preconstruct/cli": "^2.7.0",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@typechain/ethers-v5": "10.0.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"ethers": "^5.7.2",
|
||||
"typechain": "^8.1.0",
|
||||
"typescript": "^4.7.4"
|
||||
"typechain": "^8.2.0",
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ethers": "^5"
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# eslint-config-thirdweb
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "eslint-config-thirdweb",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"main": "index.js",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"eslint-config-next": "13.2.4",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-turbo": "^0.0.8",
|
||||
"eslint-plugin-react": "^7.28.0"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/pay
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/pay",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"main": "dist/thirdweb-dev-pay.cjs.js",
|
||||
"module": "dist/thirdweb-dev-pay.esm.js",
|
||||
"exports": {
|
||||
@@ -33,13 +33,13 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"@coinbase/cbpay-js": "^1.6.0"
|
||||
"@coinbase/cbpay-js": "^1.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"typescript": "^4.7.4",
|
||||
"@preconstruct/cli": "^2.7.0",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"scripts": {
|
||||
"format": "prettier --write 'src/**/*'",
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 3.14.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
- Updated dependencies [[`2d088d36`](https://github.com/thirdweb-dev/js/commit/2d088d367ca54233836dc69712fd411ab7924205), [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2), [`9daf0449`](https://github.com/thirdweb-dev/js/commit/9daf044926bf995ac8998929dbeca548c5eb8561), [`546353a4`](https://github.com/thirdweb-dev/js/commit/546353a479c11533818ef917c0f6b4d6f8f69872), [`a3bb17cb`](https://github.com/thirdweb-dev/js/commit/a3bb17cb33f033846fb3b4c8a0a4809ba76cab96), [`0135a779`](https://github.com/thirdweb-dev/js/commit/0135a7790cf2acde6b701cb41ea10dd311da5ec3)]:
|
||||
- @thirdweb-dev/storage@1.1.6
|
||||
- @thirdweb-dev/wallets@1.0.4
|
||||
- @thirdweb-dev/chains@0.1.27
|
||||
- @thirdweb-dev/sdk@3.10.28
|
||||
|
||||
## 3.14.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1271](https://github.com/thirdweb-dev/js/pull/1271) [`c9535715`](https://github.com/thirdweb-dev/js/commit/c95357158819abd42d4b0900ecc2fa40fcb957f8) Thanks [@nkrishang](https://github.com/nkrishang)! - Rename smart wallets to account
|
||||
|
||||
- [#1273](https://github.com/thirdweb-dev/js/pull/1273) [`edcd22d6`](https://github.com/thirdweb-dev/js/commit/edcd22d61236edb2832f9b2f9796e891d58cb145) Thanks [@MananTank](https://github.com/MananTank)! - Add `autoConnectTimeout` to `ThirdwebProvider` to timeout wallet autoconnect
|
||||
|
||||
- Updated dependencies [[`2b113539`](https://github.com/thirdweb-dev/js/commit/2b113539098384f910b3c4d54e1fde9d35a6f053), [`c9535715`](https://github.com/thirdweb-dev/js/commit/c95357158819abd42d4b0900ecc2fa40fcb957f8), [`be606dd3`](https://github.com/thirdweb-dev/js/commit/be606dd3c93c1514834c1d970e864d7f949a07ab), [`5882091e`](https://github.com/thirdweb-dev/js/commit/5882091eab65978009a5a5305701f121851b10ad), [`998e5217`](https://github.com/thirdweb-dev/js/commit/998e521733efd6a67e42f9bf0beab5fbdccf08ae)]:
|
||||
- @thirdweb-dev/wallets@1.0.3
|
||||
- @thirdweb-dev/sdk@3.10.27
|
||||
- @thirdweb-dev/chains@0.1.26
|
||||
|
||||
## 3.14.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ed711c8c`](https://github.com/thirdweb-dev/js/commit/ed711c8cb2ed6a0deb1b2a5eeec06df1d4edc5e8), [`05a7495a`](https://github.com/thirdweb-dev/js/commit/05a7495a132aabab5f48abbdb80a468ff6f65df8), [`e78da6b3`](https://github.com/thirdweb-dev/js/commit/e78da6b36cfa6d954234820563201bf760186ed1)]:
|
||||
- @thirdweb-dev/wallets@1.0.2
|
||||
|
||||
## 3.14.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "3.14.5",
|
||||
"version": "3.14.8",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -66,26 +66,26 @@
|
||||
},
|
||||
"sideEffects:": false,
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.3",
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@babel/runtime": "^7.19.0",
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@babel/preset-react": "^7.22.5",
|
||||
"@babel/preset-typescript": "^7.22.5",
|
||||
"@babel/runtime": "^7.22.5",
|
||||
"@microsoft/api-documenter": "^7.22.21",
|
||||
"@microsoft/api-extractor": "^7.36.0",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@preconstruct/cli": "^2.7.0",
|
||||
"@solana/wallet-adapter-react": "^0.15.19",
|
||||
"@solana/web3.js": "^1.62.0",
|
||||
"@thirdweb-dev/auth": "workspace:*",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@types/js-cookie": "^3.0.3",
|
||||
"@types/mime": "3.0.0",
|
||||
"@types/react": "^18.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"@types/react": "^18.2.14",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"eslint-plugin-better-tree-shaking": "0.0.3",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
@@ -93,12 +93,12 @@
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-tsdoc": "^0.2.16",
|
||||
"ethers": "^5.7.2",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier": "^2.8.8",
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.7.4"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/react-query": "^4.0.10",
|
||||
"@tanstack/react-query": "^4.29.19",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/generated-abis": "workspace:^",
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
|
||||
@@ -61,6 +61,15 @@ export interface ThirdwebProviderCoreProps<TChains extends Chain[]>
|
||||
* Whether or not to automatically switch to wallet's network to active chain
|
||||
*/
|
||||
autoSwitch?: boolean;
|
||||
|
||||
/**
|
||||
* Timeout for auto-connecting wallet in milliseconds
|
||||
*
|
||||
* If wallet fails to connect in this time, it will stop trying to connect and user will have to manually connect
|
||||
*
|
||||
* @defaultValue 15000
|
||||
*/
|
||||
autoConnectTimeout?: number;
|
||||
}
|
||||
|
||||
export const ThirdwebProviderCore = <TChains extends Chain[]>({
|
||||
@@ -145,6 +154,7 @@ export const ThirdwebProviderCore = <TChains extends Chain[]>({
|
||||
dAppMeta={dAppMeta}
|
||||
activeChain={activeChainWithKey}
|
||||
autoSwitch={props.autoSwitch}
|
||||
autoConnectTimeout={props.autoConnectTimeout}
|
||||
>
|
||||
<ThirdwebSDKProviderWrapper
|
||||
queryClient={props.queryClient}
|
||||
|
||||
@@ -101,12 +101,15 @@ export function ThirdwebWalletProvider(
|
||||
dAppMeta?: DAppMetaData;
|
||||
chains: Chain[];
|
||||
autoSwitch?: boolean;
|
||||
autoConnectTimeout?: number;
|
||||
}>,
|
||||
) {
|
||||
const [signer, setSigner] = useState<Signer | undefined>(undefined);
|
||||
const [connectionStatus, setConnectionStatus] =
|
||||
useState<ConnectionStatus>("unknown");
|
||||
|
||||
const autoConnectTimeout = props.autoConnectTimeout || 15000;
|
||||
|
||||
const [activeWallet, setActiveWallet] = useState<
|
||||
WalletInstance | undefined
|
||||
>();
|
||||
@@ -311,8 +314,14 @@ export function ThirdwebWalletProvider(
|
||||
const personalWalletInstance = createWalletInstance(personalWalleObj);
|
||||
|
||||
try {
|
||||
await personalWalletInstance.autoConnect(
|
||||
personalWalletInfo.connectParams,
|
||||
await timeoutPromise(
|
||||
personalWalletInstance.autoConnect(
|
||||
personalWalletInfo.connectParams,
|
||||
),
|
||||
{
|
||||
ms: autoConnectTimeout,
|
||||
message: "Failed to Auto connect. Auto connect timed out.",
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -337,7 +346,10 @@ export function ThirdwebWalletProvider(
|
||||
|
||||
try {
|
||||
setConnectionStatus("connecting");
|
||||
await wallet.autoConnect(walletInfo.connectParams);
|
||||
await timeoutPromise(wallet.autoConnect(walletInfo.connectParams), {
|
||||
ms: autoConnectTimeout,
|
||||
message: "Failed to Auto connect. Auto connect timed out.",
|
||||
});
|
||||
setConnectedWallet(wallet, walletInfo.connectParams, true);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -356,6 +368,7 @@ export function ThirdwebWalletProvider(
|
||||
props.shouldAutoConnect,
|
||||
activeWallet,
|
||||
connectionStatus,
|
||||
autoConnectTimeout,
|
||||
]);
|
||||
|
||||
const connectWallet = useCallback(
|
||||
@@ -496,3 +509,32 @@ async function saveLastConnectedWalletInfo(
|
||||
console.error("Error saving the last connected wallet info", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Timeout a promise with a given Error message if the promise does not resolve in given time
|
||||
*
|
||||
* @param promise - Promise to track for timeout
|
||||
* @param option - timeout options
|
||||
* @returns
|
||||
*/
|
||||
function timeoutPromise<T>(
|
||||
promise: Promise<T>,
|
||||
option: { ms: number; message: string },
|
||||
) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
const timeoutId = setTimeout(() => {
|
||||
reject(new Error(option.message));
|
||||
}, option.ms);
|
||||
|
||||
promise.then(
|
||||
(res) => {
|
||||
clearTimeout(timeoutId);
|
||||
resolve(res);
|
||||
},
|
||||
(err) => {
|
||||
clearTimeout(timeoutId);
|
||||
reject(err);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
import {
|
||||
RequiredParam,
|
||||
requiredParamInvariant,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/thirdweb-sdk-provider";
|
||||
import { WalletAddress } from "../../types";
|
||||
import {
|
||||
cacheKeys,
|
||||
invalidateContractAndBalances,
|
||||
} from "../../utils/cache-keys";
|
||||
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
|
||||
import {
|
||||
useMutation,
|
||||
useQueryClient,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
import type { AccountEvent, SmartContract } from "@thirdweb-dev/sdk";
|
||||
import type { BytesLike } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/** **********************/
|
||||
/** READ HOOKS **/
|
||||
/** **********************/
|
||||
|
||||
/**
|
||||
* Get all accounts
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const { data: accounts, isLoading, error } = useAccounts(contract);
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a account factory contract
|
||||
* @returns a response object that includes an array of all accounts with their associated admin
|
||||
* @twfeature AccountFactory
|
||||
* @see {@link https://portal.thirdweb.com/react/react.useaccounts?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useAccounts(
|
||||
contract: RequiredParam<SmartContract>,
|
||||
): UseQueryResult<AccountEvent[]> {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.accountFactory.getAll(contractAddress),
|
||||
() => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract.accountFactory.getAllAccounts,
|
||||
"Contract instance does not support contract.accountFactory.getAllAccounts",
|
||||
);
|
||||
return contract.accountFactory.getAllAccounts();
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all accounts associated with the provided address
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const { data: accountsForAddress, isLoading, error } = useAccountsForAddress(contract, "{{account_address}}");
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a account factory contract
|
||||
* @returns a response object that includes an array of all accounts associated with the adress
|
||||
* @twfeature AccountFactory
|
||||
* @see {@link https://portal.thirdweb.com/react/react.useaccountsforaddress?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useAccountsForAddress(
|
||||
contract: RequiredParam<SmartContract>,
|
||||
address: RequiredParam<WalletAddress>,
|
||||
): UseQueryResult<string[]> {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.accountFactory.getAllForAddress(
|
||||
contractAddress,
|
||||
address,
|
||||
),
|
||||
() => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract.accountFactory.getAssociatedAccounts,
|
||||
"Contract instance does not support contract.accountFactory.getAssociatedAccounts",
|
||||
);
|
||||
return contract.accountFactory.getAssociatedAccounts(address || "");
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a account has been deployed for the given admin
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const { data: isAccountDeployed, isLoading, error } = useIsAccountDeployed(contract);
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a account factory contract
|
||||
* @returns a boolean indicating if a account has been deployed for the given admin
|
||||
* @twfeature AccountFactory
|
||||
* @see {@link https://portal.thirdweb.com/react/react.useisaccountdeployed?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useIsAccountDeployed(
|
||||
contract: RequiredParam<SmartContract>,
|
||||
admin: RequiredParam<WalletAddress>,
|
||||
extraData?: BytesLike,
|
||||
): UseQueryResult<boolean> {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.accountFactory.isAccountDeployed(contractAddress, admin),
|
||||
() => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract.accountFactory.isAccountDeployed,
|
||||
"Contract instance does not support contract.accountFactory.getAllAccounts",
|
||||
);
|
||||
invariant(admin, "No account address provided");
|
||||
return contract.accountFactory.isAccountDeployed(admin, extraData);
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
);
|
||||
}
|
||||
|
||||
/** **********************/
|
||||
/** WRITE HOOKS **/
|
||||
/** **********************/
|
||||
/**
|
||||
* Create a account
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* const Component = () => {
|
||||
* const { contract } = useContract("{{contract_address}}");
|
||||
* const {
|
||||
* mutate: createAccount,
|
||||
* isLoading,
|
||||
* error,
|
||||
* } = useCreateAccount(contract);
|
||||
*
|
||||
* if (error) {
|
||||
* console.error("failed to create account", error);
|
||||
* }
|
||||
*
|
||||
* return (
|
||||
* <button
|
||||
* disabled={isLoading}
|
||||
* onClick={() => createAccount("0x...")}
|
||||
* >
|
||||
* Create Account
|
||||
* </button>
|
||||
* );
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a account factory contract
|
||||
* @returns a mutation object that can be used to create a account
|
||||
* @twfeature AccountFactory
|
||||
* @see {@link https://portal.thirdweb.com/react/react.usecreateaccount?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useCreateAccount(contract: RequiredParam<SmartContract>) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation(
|
||||
async (admin: string, extraData?: BytesLike) => {
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
|
||||
return contract.accountFactory.createAccount(admin, extraData);
|
||||
},
|
||||
{
|
||||
onSettled: () =>
|
||||
invalidateContractAndBalances(
|
||||
queryClient,
|
||||
contractAddress,
|
||||
activeChainId,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
+23
-23
@@ -27,32 +27,32 @@ import invariant from "tiny-invariant";
|
||||
/** **********************/
|
||||
|
||||
/**
|
||||
* Get all wallets
|
||||
* Get all accounts
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const { data: smartWallets, isLoading, error } = useSmartWalletSigners(contract);
|
||||
* const { data: accounts, isLoading, error } = useAccountSigners(contract);
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a smart wallet
|
||||
* @returns a response object that includes an array of all signers of the provided smart wallet
|
||||
* @twfeature SmartWallet
|
||||
* @see {@link https://portal.thirdweb.com/react/react.usesmartwalletsigners?utm_source=sdk | Documentation}
|
||||
* @param contract - an instance of a account
|
||||
* @returns a response object that includes an array of all signers of the provided account
|
||||
* @twfeature Account
|
||||
* @see {@link https://portal.thirdweb.com/react/react.useaccountsigners?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useSmartWalletSigners(
|
||||
export function useAccountSigners(
|
||||
contract: RequiredParam<SmartContract>,
|
||||
): UseQueryResult<SignerWithRestrictions[]> {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.smartWallet.signers(contractAddress),
|
||||
cacheKeys.contract.account.signers(contractAddress),
|
||||
() => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract.smartWallet.getSignersWithRestrictions,
|
||||
"Contract instance does not support contract.smartWallet.getSignersWithRestrictions",
|
||||
contract.account.getSignersWithRestrictions,
|
||||
"Contract instance does not support contract.account.getSignersWithRestrictions",
|
||||
);
|
||||
return contract.smartWallet.getSignersWithRestrictions();
|
||||
return contract.account.getSignersWithRestrictions();
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
);
|
||||
@@ -62,40 +62,40 @@ export function useSmartWalletSigners(
|
||||
/** WRITE HOOKS **/
|
||||
/** **********************/
|
||||
/**
|
||||
* Set the wallet's entire snapshot of permissions
|
||||
* Set the account's entire snapshot of permissions
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* const Component = () => {
|
||||
* const { contract } = useContract("{{contract_address}}");
|
||||
* const {
|
||||
* mutate: setSmartWalletSigners,
|
||||
* mutate: setAccountSigners,
|
||||
* isLoading,
|
||||
* error,
|
||||
* } = useSetSmartWalletSigners(contract);
|
||||
* } = useSetAccountSigners(contract);
|
||||
*
|
||||
* if (error) {
|
||||
* console.error("failed to set smart wallet signers", error);
|
||||
* console.error("failed to set account signers", error);
|
||||
* }
|
||||
*
|
||||
* return (
|
||||
* <button
|
||||
* disabled={isLoading}
|
||||
* onClick={() => setSmartWalletSigners("0x...")}
|
||||
* onClick={() => setAccountSigners("0x...")}
|
||||
* >
|
||||
* Set Smart Wallet Signers
|
||||
* Set Account Signers
|
||||
* </button>
|
||||
* );
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a smart wallet contract
|
||||
* @returns a mutation object that can be used to set the smart wallet signers
|
||||
* @twfeature SmartWallet
|
||||
* @see {@link https://portal.thirdweb.com/react/react.usesetsmartwalletsigners?utm_source=sdk | Documentation}
|
||||
* @param contract - an instance of a account contract
|
||||
* @returns a mutation object that can be used to set the account signers
|
||||
* @twfeature Account
|
||||
* @see {@link https://portal.thirdweb.com/react/react.usesetaccountsigners?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useSetSmartWalletSigners(
|
||||
export function useSetAccountSigners(
|
||||
contract: RequiredParam<SmartContract>,
|
||||
): UseMutationResult<
|
||||
{ receipt: providers.TransactionReceipt },
|
||||
@@ -111,7 +111,7 @@ export function useSetSmartWalletSigners(
|
||||
async (permissionsSnapshot: SignerWithRestrictionsBatchInput) => {
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
|
||||
return contract.smartWallet.setAccess(permissionsSnapshot);
|
||||
return contract.account.setAccess(permissionsSnapshot);
|
||||
},
|
||||
{
|
||||
onSettled: () =>
|
||||
@@ -1,188 +0,0 @@
|
||||
import {
|
||||
RequiredParam,
|
||||
requiredParamInvariant,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/thirdweb-sdk-provider";
|
||||
import { WalletAddress } from "../../types";
|
||||
import {
|
||||
cacheKeys,
|
||||
invalidateContractAndBalances,
|
||||
} from "../../utils/cache-keys";
|
||||
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
|
||||
import {
|
||||
useMutation,
|
||||
useQueryClient,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
import type { AccountEvent, SmartContract } from "@thirdweb-dev/sdk";
|
||||
import type { BytesLike } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/** **********************/
|
||||
/** READ HOOKS **/
|
||||
/** **********************/
|
||||
|
||||
/**
|
||||
* Get all wallets
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const { data: smartWallets, isLoading, error } = useSmartWallets(contract);
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a smart wallet factory contract
|
||||
* @returns a response object that includes an array of all smart wallets with their associated admin
|
||||
* @twfeature SmartWalletFactory
|
||||
* @see {@link https://portal.thirdweb.com/react/react.usesmartwallets?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useSmartWallets(
|
||||
contract: RequiredParam<SmartContract>,
|
||||
): UseQueryResult<AccountEvent[]> {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.smartWalletFactory.getAll(contractAddress),
|
||||
() => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract.smartWalletFactory.getAllAccounts,
|
||||
"Contract instance does not support contract.smartWalletFactory.getAllAccounts",
|
||||
);
|
||||
return contract.smartWalletFactory.getAllAccounts();
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all wallets associated with the provided address
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const { data: smartWalletsForAddress, isLoading, error } = useSmartWalletsForAddress(contract, "{{wallet_address}}");
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a smart wallet factory contract
|
||||
* @returns a response object that includes an array of all smart wallets associated with the adress
|
||||
* @twfeature SmartWalletFactory
|
||||
* @see {@link https://portal.thirdweb.com/react/react.usesmartwalletsforaddress?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useSmartWalletsForAddress(
|
||||
contract: RequiredParam<SmartContract>,
|
||||
address: RequiredParam<WalletAddress>,
|
||||
): UseQueryResult<string[]> {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.smartWalletFactory.getAllForAddress(
|
||||
contractAddress,
|
||||
address,
|
||||
),
|
||||
() => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract.smartWalletFactory.getAssociatedWallets,
|
||||
"Contract instance does not support contract.smartWalletFactory.getAssociatedWallets",
|
||||
);
|
||||
return contract.smartWalletFactory.getAssociatedWallets(address || "");
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a smart wallet has been deployed for the given admin
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const { data: isSmartWalletDeployed, isLoading, error } = useIsSmartWalletDeployed(contract);
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a smart wallet factory contract
|
||||
* @returns a boolean indicating if a smart wallet has been deployed for the given admin
|
||||
* @twfeature SmartWalletFactory
|
||||
* @see {@link https://portal.thirdweb.com/react/react.useissmartwalletdeployed?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useIsSmartWalletDeployed(
|
||||
contract: RequiredParam<SmartContract>,
|
||||
admin: RequiredParam<WalletAddress>,
|
||||
extraData?: BytesLike,
|
||||
): UseQueryResult<boolean> {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.smartWalletFactory.isSmartWalletDeployed(
|
||||
contractAddress,
|
||||
admin,
|
||||
),
|
||||
() => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract.smartWalletFactory.isWalletDeployed,
|
||||
"Contract instance does not support contract.smartWalletFactory.getAllWallets",
|
||||
);
|
||||
invariant(admin, "No wallet address provided");
|
||||
return contract.smartWalletFactory.isWalletDeployed(admin, extraData);
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
);
|
||||
}
|
||||
|
||||
/** **********************/
|
||||
/** WRITE HOOKS **/
|
||||
/** **********************/
|
||||
/**
|
||||
* Create a smart wallet
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* const Component = () => {
|
||||
* const { contract } = useContract("{{contract_address}}");
|
||||
* const {
|
||||
* mutate: createSmartWallet,
|
||||
* isLoading,
|
||||
* error,
|
||||
* } = useCreateSmartWallet(contract);
|
||||
*
|
||||
* if (error) {
|
||||
* console.error("failed to create smart wallet", error);
|
||||
* }
|
||||
*
|
||||
* return (
|
||||
* <button
|
||||
* disabled={isLoading}
|
||||
* onClick={() => createSmartWallet("0x...")}
|
||||
* >
|
||||
* Create Smart Wallet
|
||||
* </button>
|
||||
* );
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a smart wallet factory contract
|
||||
* @returns a mutation object that can be used to create a smart wallet
|
||||
* @twfeature SmartWalletFactory
|
||||
* @see {@link https://portal.thirdweb.com/react/react.usecreatesmartwallet?utm_source=sdk | Documentation}
|
||||
* @beta
|
||||
*/
|
||||
export function useCreateSmartWallet(contract: RequiredParam<SmartContract>) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation(
|
||||
async (admin: string, extraData?: BytesLike) => {
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
|
||||
return contract.smartWalletFactory.createWallet(admin, extraData);
|
||||
},
|
||||
{
|
||||
onSettled: () =>
|
||||
invalidateContractAndBalances(
|
||||
queryClient,
|
||||
contractAddress,
|
||||
activeChainId,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -194,19 +194,16 @@ export {
|
||||
useBurnToken,
|
||||
} from "./hooks/async/token";
|
||||
|
||||
// smart wallet factory
|
||||
// account factory
|
||||
export {
|
||||
useIsSmartWalletDeployed,
|
||||
useSmartWallets,
|
||||
useCreateSmartWallet,
|
||||
useSmartWalletsForAddress,
|
||||
} from "./hooks/async/smart-wallet-factory";
|
||||
useIsAccountDeployed,
|
||||
useAccounts,
|
||||
useCreateAccount,
|
||||
useAccountsForAddress,
|
||||
} from "./hooks/async/account-factory";
|
||||
|
||||
// smart wallet
|
||||
export {
|
||||
useSmartWalletSigners,
|
||||
useSetSmartWalletSigners,
|
||||
} from "./hooks/async/smart-wallet";
|
||||
// account
|
||||
export { useAccountSigners, useSetAccountSigners } from "./hooks/async/account";
|
||||
|
||||
// thirdweb hooks (work as long as at least `<ThirdwebSdkProvider>` is used)
|
||||
|
||||
|
||||
@@ -118,18 +118,23 @@ export const cacheKeys = {
|
||||
overrides,
|
||||
]),
|
||||
|
||||
smartWalletFactory: {
|
||||
accountFactory: {
|
||||
getAll: (contractAddress: RequiredParam<ContractAddress>) =>
|
||||
createContractCacheKey(contractAddress, ["smartWalletFactory"]),
|
||||
isSmartWalletDeployed: (contractAdress: RequiredParam<ContractAddress>, admin: RequiredParam<string>) =>
|
||||
createContractCacheKey(contractAdress, ["isSmartWalletDeployed", admin]),
|
||||
getAllForAddress: (contractAdress: RequiredParam<ContractAddress>, address: RequiredParam<string>) =>
|
||||
createContractCacheKey(contractAddress, ["accountFactory"]),
|
||||
isAccountDeployed: (
|
||||
contractAdress: RequiredParam<ContractAddress>,
|
||||
admin: RequiredParam<string>,
|
||||
) => createContractCacheKey(contractAdress, ["isAccountDeployed", admin]),
|
||||
getAllForAddress: (
|
||||
contractAdress: RequiredParam<ContractAddress>,
|
||||
address: RequiredParam<string>,
|
||||
) =>
|
||||
createContractCacheKey(contractAdress, ["getAllForAddress", address]),
|
||||
},
|
||||
|
||||
smartWallet: {
|
||||
account: {
|
||||
signers: (contractAddress: RequiredParam<ContractAddress>) =>
|
||||
createContractCacheKey(contractAddress, ["smartWallet", "signers"]),
|
||||
createContractCacheKey(contractAddress, ["account", "signers"]),
|
||||
},
|
||||
|
||||
app: {
|
||||
@@ -198,12 +203,8 @@ export const cacheKeys = {
|
||||
},
|
||||
},
|
||||
sharedMetadata: {
|
||||
get: (
|
||||
contractAddress: RequiredParam<ContractAddress>,
|
||||
) =>
|
||||
createContractCacheKey(
|
||||
contractAddress
|
||||
),
|
||||
get: (contractAddress: RequiredParam<ContractAddress>) =>
|
||||
createContractCacheKey(contractAddress),
|
||||
},
|
||||
drop: {
|
||||
getAllUnclaimed: (
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.2.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
## 0.2.26
|
||||
|
||||
## 0.2.25
|
||||
|
||||
## 0.2.24
|
||||
|
||||
## 0.2.23
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.2.24",
|
||||
"version": "0.2.27",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
|
||||
"license": "Apache-2.0",
|
||||
@@ -22,10 +22,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ethersproject/shims": "^5.7.0",
|
||||
"@walletconnect/react-native-compat": "^2.3.3",
|
||||
"@walletconnect/react-native-compat": "^2.8.6",
|
||||
"base-64": "^1.0.0",
|
||||
"big-integer": "^1.6.51",
|
||||
"react-native-get-random-values": "^1.8.0"
|
||||
"react-native-get-random-values": "^1.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ethers": "^5.5.1",
|
||||
@@ -34,12 +34,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/node": "^18.16.18",
|
||||
"babel-plugin-module-resolver": "^5.0.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"ethers": "^5.7.2",
|
||||
"react": "^18.2.0",
|
||||
"react-native": "^0.71.0",
|
||||
"typescript": "^4.7.4"
|
||||
"react-native": "^0.71.11",
|
||||
"typescript": "^5.1.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.2.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
- Updated dependencies [[`2d088d36`](https://github.com/thirdweb-dev/js/commit/2d088d367ca54233836dc69712fd411ab7924205), [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2), [`9daf0449`](https://github.com/thirdweb-dev/js/commit/9daf044926bf995ac8998929dbeca548c5eb8561), [`546353a4`](https://github.com/thirdweb-dev/js/commit/546353a479c11533818ef917c0f6b4d6f8f69872), [`a3bb17cb`](https://github.com/thirdweb-dev/js/commit/a3bb17cb33f033846fb3b4c8a0a4809ba76cab96), [`0135a779`](https://github.com/thirdweb-dev/js/commit/0135a7790cf2acde6b701cb41ea10dd311da5ec3)]:
|
||||
- @thirdweb-dev/storage@1.1.6
|
||||
- @thirdweb-dev/react-core@3.14.8
|
||||
- @thirdweb-dev/wallets@1.0.4
|
||||
- @thirdweb-dev/chains@0.1.27
|
||||
- @thirdweb-dev/sdk@3.10.28
|
||||
|
||||
## 0.2.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1270](https://github.com/thirdweb-dev/js/pull/1270) [`0d5503aa`](https://github.com/thirdweb-dev/js/commit/0d5503aae90d9cd7a7adcabad19f7f45d9a37063) Thanks [@iketw](https://github.com/iketw)! - Only handle Coinbase callback URL if Coinbase is added as a supportedWallet
|
||||
|
||||
- [#1277](https://github.com/thirdweb-dev/js/pull/1277) [`2b113539`](https://github.com/thirdweb-dev/js/commit/2b113539098384f910b3c4d54e1fde9d35a6f053) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - remove ethers/lib/utils dependency
|
||||
|
||||
- Updated dependencies [[`2b113539`](https://github.com/thirdweb-dev/js/commit/2b113539098384f910b3c4d54e1fde9d35a6f053), [`c9535715`](https://github.com/thirdweb-dev/js/commit/c95357158819abd42d4b0900ecc2fa40fcb957f8), [`be606dd3`](https://github.com/thirdweb-dev/js/commit/be606dd3c93c1514834c1d970e864d7f949a07ab), [`edcd22d6`](https://github.com/thirdweb-dev/js/commit/edcd22d61236edb2832f9b2f9796e891d58cb145), [`5882091e`](https://github.com/thirdweb-dev/js/commit/5882091eab65978009a5a5305701f121851b10ad), [`998e5217`](https://github.com/thirdweb-dev/js/commit/998e521733efd6a67e42f9bf0beab5fbdccf08ae)]:
|
||||
- @thirdweb-dev/wallets@1.0.3
|
||||
- @thirdweb-dev/sdk@3.10.27
|
||||
- @thirdweb-dev/react-core@3.14.7
|
||||
- @thirdweb-dev/chains@0.1.26
|
||||
|
||||
## 0.2.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ed711c8c`](https://github.com/thirdweb-dev/js/commit/ed711c8cb2ed6a0deb1b2a5eeec06df1d4edc5e8), [`05a7495a`](https://github.com/thirdweb-dev/js/commit/05a7495a132aabab5f48abbdb80a468ff6f65df8), [`e78da6b3`](https://github.com/thirdweb-dev/js/commit/e78da6b36cfa6d954234820563201bf760186ed1)]:
|
||||
- @thirdweb-dev/wallets@1.0.2
|
||||
- @thirdweb-dev/react-core@3.14.6
|
||||
|
||||
## 0.2.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.2.24",
|
||||
"version": "0.2.27",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -26,9 +26,9 @@
|
||||
"dependencies": {
|
||||
"@coinbase/wallet-mobile-sdk": "1.0.6",
|
||||
"@magic-sdk/provider": "17.2.0",
|
||||
"@magic-sdk/react-native-bare": "^18.3.0",
|
||||
"@shopify/restyle": "^2.4.1",
|
||||
"@tanstack/react-query": "^4.0.10",
|
||||
"@magic-sdk/react-native-bare": "^18.5.0",
|
||||
"@shopify/restyle": "^2.4.2",
|
||||
"@tanstack/react-query": "^4.29.19",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/react-core": "workspace:*",
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
@@ -41,38 +41,38 @@
|
||||
"expo-secure-store": "^12.1.1",
|
||||
"react-native-mmkv": "2.5.1",
|
||||
"react-native-modal": "^13.0.1",
|
||||
"react-native-svg": "^13.8.0",
|
||||
"react-native-svg": "^13.9.0",
|
||||
"tiny-invariant": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.3",
|
||||
"@babel/preset-env": "^7.1.6",
|
||||
"@react-native-async-storage/async-storage": "*",
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@react-native-async-storage/async-storage": "^1.18.2",
|
||||
"@react-native-community/eslint-config": "^3.0.2",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@types/jest": "^29.2.1",
|
||||
"@types/react": "^18.0.5",
|
||||
"@types/react-native": "^0.71.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
||||
"@typescript-eslint/parser": "^5.56.0",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-native": "^0.71.8",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"babel-jest": "^29.2.1",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-inclusive-language": "^2.2.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"ethers": "^5.7.2",
|
||||
"expo": "^47.0.0",
|
||||
"expo": "^47.0.14",
|
||||
"jest": "^29.4.3",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier": "^2.8.8",
|
||||
"react": "^18.2.0",
|
||||
"react-native": "^0.71.0",
|
||||
"react-native": "^0.71.11",
|
||||
"react-native-camera": "^4.2.1",
|
||||
"react-native-device-info": "10.6.0",
|
||||
"react-native-safe-area-context": "4.5.3",
|
||||
"react-native-webview": "12.1.0",
|
||||
"typescript": "^4.7.4"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"react-native-camera": "^4.2.1",
|
||||
|
||||
@@ -65,7 +65,9 @@ export const ThirdwebProvider = <
|
||||
theme,
|
||||
...restProps
|
||||
}: PropsWithChildren<ThirdwebProviderProps<TChains>>) => {
|
||||
useCoinbaseWalletListener();
|
||||
useCoinbaseWalletListener(
|
||||
!!supportedWallets.find((w) => w.id === walletIds.coinbase),
|
||||
);
|
||||
|
||||
const hasMagicConfig = useMemo(
|
||||
() => !!supportedWallets.find((wc) => wc.id === walletIds.magicLink),
|
||||
|
||||
@@ -17,8 +17,7 @@ import {
|
||||
WagmiConnector,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import type { Address } from "abitype";
|
||||
import { providers } from "ethers";
|
||||
import { getAddress, hexValue } from "ethers/lib/utils.js";
|
||||
import { providers, utils } from "ethers";
|
||||
|
||||
export type CoinbaseWalletConnectorOptions = WalletMobileSDKProviderOptions &
|
||||
ConfigurationParams & {
|
||||
@@ -130,7 +129,7 @@ export class CoinbaseWalletConnector extends WagmiConnector<
|
||||
throw new Error("No accounts found");
|
||||
}
|
||||
// return checksum address
|
||||
return getAddress(accounts[0] as string);
|
||||
return utils.getAddress(accounts[0] as string);
|
||||
}
|
||||
|
||||
async getChainId() {
|
||||
@@ -193,7 +192,7 @@ export class CoinbaseWalletConnector extends WagmiConnector<
|
||||
|
||||
async switchChain(chainId: number): Promise<Chain> {
|
||||
const provider = await this.getProvider();
|
||||
const id = hexValue(chainId);
|
||||
const id = utils.hexValue(chainId);
|
||||
|
||||
try {
|
||||
await provider.request({
|
||||
@@ -279,7 +278,7 @@ export class CoinbaseWalletConnector extends WagmiConnector<
|
||||
if (accounts.length === 0) {
|
||||
this.emit("disconnect");
|
||||
} else {
|
||||
this.emit("change", { account: getAddress(accounts[0] as string) });
|
||||
this.emit("change", { account: utils.getAddress(accounts[0] as string) });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useCoinbaseWalletListener } from "./useCoinbaseWalletListener";
|
||||
*/
|
||||
export function useCoinbaseWallet(callbackURL: string) {
|
||||
const connect = useConnect();
|
||||
useCoinbaseWalletListener();
|
||||
useCoinbaseWalletListener(true);
|
||||
|
||||
return useCallback(
|
||||
async (connectOptions?: { chainId?: number; callbackURL: string }) => {
|
||||
|
||||
@@ -7,12 +7,16 @@ import { Linking } from "react-native";
|
||||
*
|
||||
* This hook sets up the UniversalLinks listener.
|
||||
*/
|
||||
export function useCoinbaseWalletListener() {
|
||||
export function useCoinbaseWalletListener(enable: boolean) {
|
||||
useEffect(() => {
|
||||
if (!enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sub = Linking.addEventListener("url", ({ url }) => {
|
||||
// @ts-ignore - Passing a URL object to handleResponse crashes the function
|
||||
handleResponse(url);
|
||||
});
|
||||
return () => sub?.remove();
|
||||
}, []);
|
||||
}, [enable]);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,43 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.14.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1282](https://github.com/thirdweb-dev/js/pull/1282) [`7054f9f0`](https://github.com/thirdweb-dev/js/commit/7054f9f01691e1c942ffbec3ee8042218aadd126) Thanks [@kien-ngo](https://github.com/kien-ngo)! - Fix issue #1201 - MediaRenderer HTML MimeType
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
- Updated dependencies [[`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2), [`a3bb17cb`](https://github.com/thirdweb-dev/js/commit/a3bb17cb33f033846fb3b4c8a0a4809ba76cab96)]:
|
||||
- @thirdweb-dev/react-core@3.14.8
|
||||
- @thirdweb-dev/wallets@1.0.4
|
||||
- @thirdweb-dev/chains@0.1.27
|
||||
- @thirdweb-dev/sdk@3.10.28
|
||||
|
||||
## 3.14.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1210](https://github.com/thirdweb-dev/js/pull/1210) [`d794b8f9`](https://github.com/thirdweb-dev/js/commit/d794b8f9f41dbd7e461ef07d0808c5b6d2f85515) Thanks [@konojunya](https://github.com/konojunya)! - Add zerion to useInstalledWallets
|
||||
|
||||
- [#1269](https://github.com/thirdweb-dev/js/pull/1269) [`998e5217`](https://github.com/thirdweb-dev/js/commit/998e521733efd6a67e42f9bf0beab5fbdccf08ae) Thanks [@MananTank](https://github.com/MananTank)! - - Expose `advancedOptions` and `styles` for paper wallet
|
||||
- Allow using "+" in paper email
|
||||
- Allow using "+" in magic email
|
||||
- Update Paper SDK version
|
||||
- Updated dependencies [[`2b113539`](https://github.com/thirdweb-dev/js/commit/2b113539098384f910b3c4d54e1fde9d35a6f053), [`c9535715`](https://github.com/thirdweb-dev/js/commit/c95357158819abd42d4b0900ecc2fa40fcb957f8), [`be606dd3`](https://github.com/thirdweb-dev/js/commit/be606dd3c93c1514834c1d970e864d7f949a07ab), [`edcd22d6`](https://github.com/thirdweb-dev/js/commit/edcd22d61236edb2832f9b2f9796e891d58cb145), [`5882091e`](https://github.com/thirdweb-dev/js/commit/5882091eab65978009a5a5305701f121851b10ad), [`998e5217`](https://github.com/thirdweb-dev/js/commit/998e521733efd6a67e42f9bf0beab5fbdccf08ae)]:
|
||||
- @thirdweb-dev/wallets@1.0.3
|
||||
- @thirdweb-dev/sdk@3.10.27
|
||||
- @thirdweb-dev/react-core@3.14.7
|
||||
- @thirdweb-dev/chains@0.1.26
|
||||
|
||||
## 3.14.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ed711c8c`](https://github.com/thirdweb-dev/js/commit/ed711c8cb2ed6a0deb1b2a5eeec06df1d4edc5e8), [`05a7495a`](https://github.com/thirdweb-dev/js/commit/05a7495a132aabab5f48abbdb80a468ff6f65df8), [`e78da6b3`](https://github.com/thirdweb-dev/js/commit/e78da6b36cfa6d954234820563201bf760186ed1)]:
|
||||
- @thirdweb-dev/wallets@1.0.2
|
||||
- @thirdweb-dev/react-core@3.14.6
|
||||
|
||||
## 3.14.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+28
-28
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.14.5",
|
||||
"version": "3.14.8",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -81,15 +81,15 @@
|
||||
},
|
||||
"sideEffects:": false,
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.3",
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@babel/runtime": "^7.19.0",
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@babel/preset-react": "^7.22.5",
|
||||
"@babel/preset-typescript": "^7.22.5",
|
||||
"@babel/runtime": "^7.22.5",
|
||||
"@microsoft/api-documenter": "^7.22.21",
|
||||
"@microsoft/api-extractor": "^7.36.0",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@preconstruct/cli": "^2.7.0",
|
||||
"@solana/wallet-adapter-base": "^0.9.17",
|
||||
"@solana/wallet-adapter-phantom": "^0.9.17",
|
||||
"@solana/wallet-adapter-react": "^0.15.19",
|
||||
@@ -99,13 +99,13 @@
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/react": "^18.0.5",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-dom": "^18.2.6",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"eslint-plugin-better-tree-shaking": "0.0.3",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
@@ -113,25 +113,25 @@
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-tsdoc": "^0.2.16",
|
||||
"ethers": "^5.7.2",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier": "^2.8.8",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"stream": "npm:stream-browserify@^3.0.0",
|
||||
"typescript": "^4.7.4"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.0",
|
||||
"@emotion/styled": "^11.10.0",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@google/model-viewer": "^2.1.1",
|
||||
"@radix-ui/colors": "^0.1.8",
|
||||
"@radix-ui/react-dialog": "^1.0.2",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.2",
|
||||
"@radix-ui/react-icons": "^1.1.1",
|
||||
"@radix-ui/react-popover": "^1.0.5",
|
||||
"@radix-ui/react-tabs": "^1.0.2",
|
||||
"@radix-ui/react-tooltip": "^1.0.4",
|
||||
"@radix-ui/colors": "^0.1.9",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.5",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-popover": "^1.0.6",
|
||||
"@radix-ui/react-tabs": "^1.0.4",
|
||||
"@radix-ui/react-tooltip": "^1.0.6",
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@tanstack/react-query": "^4.0.10",
|
||||
"@tanstack/react-query": "^4.29.19",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/react-core": "workspace:*",
|
||||
"@thirdweb-dev/wallets": "workspace:*",
|
||||
|
||||
@@ -431,7 +431,7 @@ export const MediaRenderer = /* @__PURE__ */ React.forwardRef<
|
||||
alt={alt}
|
||||
/>
|
||||
);
|
||||
} else if (videoOrImageSrc.mimeType === "text/html") {
|
||||
} else if (videoOrImageSrc.mimeType.startsWith("text/html")) {
|
||||
return (
|
||||
<IframePlayer
|
||||
style={mergedStyle}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { useConnect, useWallet } from "@thirdweb-dev/react-core";
|
||||
import { PaperWallet, walletIds } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
PaperWallet,
|
||||
walletIds,
|
||||
PaperWalletAdditionalOptions,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { useCallback, useEffect } from "react";
|
||||
import {
|
||||
useQuery,
|
||||
@@ -7,10 +11,12 @@ import {
|
||||
useQueryClient,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
type PaperConfig = Omit<PaperWalletAdditionalOptions, "chain" | "chains">;
|
||||
|
||||
export function usePaperWallet() {
|
||||
const connect = useConnect();
|
||||
return useCallback(
|
||||
async (options: { chainId?: number; clientId: string; email?: string }) => {
|
||||
async (options: { chainId?: number; email?: string } & PaperConfig) => {
|
||||
const { paperWallet } = await import(
|
||||
"../../../wallet/wallets/paperWallet"
|
||||
);
|
||||
|
||||
@@ -3,22 +3,23 @@ import { assertWindowEthereum } from "@thirdweb-dev/wallets";
|
||||
export function useInstalledWallets() {
|
||||
let isMetamaskInstalled = false;
|
||||
let isCoinbaseWalletInstalled = false;
|
||||
let isTrustWalletInstalled: boolean | undefined = false;
|
||||
let isZerionWalletInstalled = false;
|
||||
let isTrustWalletInstalled = false;
|
||||
|
||||
if (assertWindowEthereum(globalThis.window)) {
|
||||
isMetamaskInstalled = globalThis.window.ethereum?.isMetaMask;
|
||||
const window_: Window | undefined = globalThis?.window;
|
||||
if (assertWindowEthereum(window_)) {
|
||||
isMetamaskInstalled = !!window_.ethereum?.isMetaMask;
|
||||
isCoinbaseWalletInstalled =
|
||||
globalThis.window.ethereum?.isCoinbaseWallet ||
|
||||
globalThis.window.ethereum?.providers?.some((p) => p.isCoinbaseWallet) ||
|
||||
false;
|
||||
isTrustWalletInstalled = globalThis.window.ethereum?.isTrust;
|
||||
!!window_.ethereum?.isCoinbaseWallet ||
|
||||
!!window_.ethereum?.providers?.some((p) => p.isCoinbaseWallet);
|
||||
isZerionWalletInstalled = !!window_.ethereum?.isZerion;
|
||||
isTrustWalletInstalled = !!window_.ethereum?.isTrust;
|
||||
}
|
||||
|
||||
const installedWallets = {
|
||||
metamask: !!isMetamaskInstalled,
|
||||
coinbaseWallet: !!isCoinbaseWalletInstalled,
|
||||
trustWallet: !!isTrustWalletInstalled,
|
||||
return {
|
||||
metamask: isMetamaskInstalled,
|
||||
coinbaseWallet: isCoinbaseWalletInstalled,
|
||||
trustWallet: isTrustWalletInstalled,
|
||||
zerionWallet: isZerionWalletInstalled,
|
||||
};
|
||||
|
||||
return installedWallets;
|
||||
}
|
||||
|
||||
@@ -21,12 +21,11 @@ export const coinbaseWallet = (): WalletConfig<CoinbaseWallet> => {
|
||||
},
|
||||
connectUI: CoinbaseConnectUI,
|
||||
isInstalled() {
|
||||
if (assertWindowEthereum(globalThis.window)) {
|
||||
const window_: Window | undefined = globalThis?.window;
|
||||
if (assertWindowEthereum(window_)) {
|
||||
return (
|
||||
globalThis.window.ethereum?.isCoinbaseWallet ||
|
||||
globalThis.window.ethereum?.providers?.some(
|
||||
(p) => p.isCoinbaseWallet,
|
||||
) ||
|
||||
window_.ethereum?.isCoinbaseWallet ||
|
||||
window_.ethereum?.providers?.some((p) => p.isCoinbaseWallet) ||
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,10 +19,11 @@ export const frameWallet = (): WalletConfig<FrameWallet> => ({
|
||||
},
|
||||
connectUI: FrameConnectUI,
|
||||
isInstalled() {
|
||||
if (assertWindowEthereum(globalThis.window)) {
|
||||
const window_: Window | undefined = globalThis?.window;
|
||||
if (assertWindowEthereum(window_)) {
|
||||
return (
|
||||
globalThis.window.ethereum?.isFrame ||
|
||||
globalThis.window.ethereum?.providers?.some((p) => p.isFrame) ||
|
||||
window_.ethereum?.isFrame ||
|
||||
window_.ethereum?.providers?.some((p) => p.isFrame) ||
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ const MagicSelectionUI: React.FC<
|
||||
|
||||
if (isEmail && isEmailEnabled) {
|
||||
const emailRegex = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,})$/g;
|
||||
const isValidEmail = emailRegex.test(input);
|
||||
const isValidEmail = emailRegex.test(input.replace(/\+/g, ""));
|
||||
if (!isValidEmail) {
|
||||
return "Invalid email address";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { PaperWallet } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
PaperWallet,
|
||||
PaperWalletAdditionalOptions,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
WalletConfig,
|
||||
WalletOptions,
|
||||
@@ -11,7 +14,7 @@ import { Spinner } from "../../components/Spinner";
|
||||
import { Flex } from "../../components/basic";
|
||||
import { InputSelectionUI } from "./InputSelectionUI";
|
||||
|
||||
type PaperConfig = { clientId: string };
|
||||
type PaperConfig = Omit<PaperWalletAdditionalOptions, "chain" | "chains">;
|
||||
|
||||
export const paperWallet = (config: PaperConfig): WalletConfig<PaperWallet> => {
|
||||
return {
|
||||
@@ -32,7 +35,8 @@ const PaperSelectionUI: React.FC<SelectUIProps<PaperWallet>> = (props) => {
|
||||
placeholder="Enter your email address"
|
||||
name="email"
|
||||
type="email"
|
||||
errorMessage={(input) => {
|
||||
errorMessage={(_input) => {
|
||||
const input = _input.replace(/\+/g, "");
|
||||
const emailRegex = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,})$/g;
|
||||
const isValidEmail = emailRegex.test(input);
|
||||
if (!isValidEmail) {
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 3.10.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
- [#1281](https://github.com/thirdweb-dev/js/pull/1281) [`a3bb17cb`](https://github.com/thirdweb-dev/js/commit/a3bb17cb33f033846fb3b4c8a0a4809ba76cab96) Thanks [@nkrishang](https://github.com/nkrishang)! - Handle ERC4337Signer correctly for signTypedData
|
||||
|
||||
- Updated dependencies [[`2d088d36`](https://github.com/thirdweb-dev/js/commit/2d088d367ca54233836dc69712fd411ab7924205), [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2), [`9daf0449`](https://github.com/thirdweb-dev/js/commit/9daf044926bf995ac8998929dbeca548c5eb8561), [`546353a4`](https://github.com/thirdweb-dev/js/commit/546353a479c11533818ef917c0f6b4d6f8f69872), [`a3bb17cb`](https://github.com/thirdweb-dev/js/commit/a3bb17cb33f033846fb3b4c8a0a4809ba76cab96), [`0135a779`](https://github.com/thirdweb-dev/js/commit/0135a7790cf2acde6b701cb41ea10dd311da5ec3)]:
|
||||
- @thirdweb-dev/storage@1.1.6
|
||||
- @thirdweb-dev/contracts-js@1.3.8
|
||||
- @thirdweb-dev/chains@0.1.27
|
||||
|
||||
## 3.10.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1277](https://github.com/thirdweb-dev/js/pull/1277) [`2b113539`](https://github.com/thirdweb-dev/js/commit/2b113539098384f910b3c4d54e1fde9d35a6f053) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - remove ethers/lib/utils dependency
|
||||
|
||||
- [#1271](https://github.com/thirdweb-dev/js/pull/1271) [`c9535715`](https://github.com/thirdweb-dev/js/commit/c95357158819abd42d4b0900ecc2fa40fcb957f8) Thanks [@nkrishang](https://github.com/nkrishang)! - Rename smart wallets to account
|
||||
|
||||
- Updated dependencies [[`5882091e`](https://github.com/thirdweb-dev/js/commit/5882091eab65978009a5a5305701f121851b10ad)]:
|
||||
- @thirdweb-dev/chains@0.1.26
|
||||
|
||||
## 3.10.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+22
-22
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "3.10.26",
|
||||
"version": "3.10.28",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
@@ -97,35 +97,35 @@
|
||||
"push": "yalc push"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aws-sdk/client-secrets-manager": "^3.256.0",
|
||||
"@aws-sdk/client-secrets-manager": "^3.363.0",
|
||||
"@ethersproject/abstract-provider": "^5.7.0",
|
||||
"@metaplex-foundation/amman": "^0.12.1",
|
||||
"@metaplex-foundation/amman-client": "^0.2.4",
|
||||
"@metaplex-foundation/js": "^0.19.2",
|
||||
"@metaplex-foundation/mpl-token-metadata": "^2.11",
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@metaplex-foundation/mpl-token-metadata": "^2.12.0",
|
||||
"@microsoft/api-documenter": "^7.22.21",
|
||||
"@microsoft/api-extractor": "^7.36.0",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.5",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@nomiclabs/hardhat-ethers": "^2.2.3",
|
||||
"@preconstruct/cli": "^2.7.0",
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/spl-token": "^0.3.5",
|
||||
"@solana/web3.js": "^1.62.0",
|
||||
"@swc-node/register": "^1.5.1",
|
||||
"@swc/core": "^1.3.23",
|
||||
"@swc-node/register": "^1.6.6",
|
||||
"@swc/core": "^1.3.67",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@types/bn.js": "^5.1.1",
|
||||
"@types/chai": "^4.3.3",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/deep-equal-in-any-order": "^1.0.1",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"@types/node": "^18.16.18",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"chai": "^4.3.6",
|
||||
"deep-equal-in-any-order": "^1.1.18",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"eslint-plugin-better-tree-shaking": "0.0.3",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
@@ -134,11 +134,11 @@
|
||||
"eslint-plugin-tsdoc": "^0.2.16",
|
||||
"ethers": "^5.7.2",
|
||||
"ethers-aws-kms-signer": "^1.3.2",
|
||||
"hardhat": "^2.9.3",
|
||||
"hardhat": "^2.16.1",
|
||||
"mocha": "^10.2.0",
|
||||
"nyc": "^15.1.0",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.7.4",
|
||||
"prettier": "^2.8.8",
|
||||
"typescript": "^5.1.6",
|
||||
"zksync-web3": "^0.14.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -187,14 +187,14 @@
|
||||
"bn.js": "^5.2.1",
|
||||
"bs58": "^5.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"eventemitter3": "^5.0.0",
|
||||
"cross-fetch": "^3.1.6",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"merkletreejs": "^0.2.24",
|
||||
"tiny-invariant": "^1.2.0",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"uuid": "^9.0.0",
|
||||
"yaml": "^2.1.1",
|
||||
"yaml": "^2.3.1",
|
||||
"zod": "^3.20.2"
|
||||
},
|
||||
"bugs": {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { BigNumber, providers, constants } from "ethers";
|
||||
import { isAddress } from "ethers/lib/utils";
|
||||
import { BigNumber, providers, constants, utils } from "ethers";
|
||||
import { extractIPFSHashFromBytecode } from "./extractIPFSHashFromBytecode";
|
||||
import { extractMinimalProxyImplementationAddress } from "./extractMinimalProxyImplementationAddress";
|
||||
|
||||
@@ -49,7 +48,7 @@ export async function resolveContractUriFromAddress(
|
||||
);
|
||||
const implementationAddress = `0x${proxyStorage.slice(-40)}`;
|
||||
if (
|
||||
isAddress(implementationAddress) &&
|
||||
utils.isAddress(implementationAddress) &&
|
||||
implementationAddress !== constants.AddressZero
|
||||
) {
|
||||
return await resolveContractUriFromAddress(
|
||||
|
||||
@@ -31,11 +31,17 @@ export type EIP712Domain = EIP712StandardDomain | EIP712PolygonDomain;
|
||||
* @internal
|
||||
*/
|
||||
export async function signTypedDataInternal(
|
||||
signer: Signer,
|
||||
signerInput: Signer,
|
||||
domain: EIP712Domain,
|
||||
types: Record<string, Array<TypedDataField>>,
|
||||
message: Record<string, any>,
|
||||
) {
|
||||
// Handle ERC4337Signer
|
||||
let signer = signerInput;
|
||||
if ((signerInput as any).originalSigner) {
|
||||
signer = (signerInput as any).originalSigner;
|
||||
}
|
||||
|
||||
const provider = signer?.provider as providers.JsonRpcProvider;
|
||||
if (!provider) {
|
||||
throw new Error("missing provider");
|
||||
@@ -60,7 +66,7 @@ export async function signTypedDataInternal(
|
||||
message,
|
||||
);
|
||||
} catch (err: any) {
|
||||
if (err?.message?.includes("Method eth_signTypedData_v4 not supported")) {
|
||||
if (err?.message?.includes("eth_signTypedData_v4")) {
|
||||
signature = await provider.send("eth_signTypedData", [
|
||||
signerAddress,
|
||||
JSON.stringify(payload),
|
||||
|
||||
@@ -62,8 +62,8 @@ import {
|
||||
FEATURE_ENGLISH_AUCTIONS,
|
||||
FEATURE_OFFERS,
|
||||
FEATURE_EXTENSION_ROUTER,
|
||||
FEATURE_SMART_WALLET,
|
||||
FEATURE_SMART_WALLET_FACTORY,
|
||||
FEATURE_ACCOUNT,
|
||||
FEATURE_ACCOUNT_FACTORY,
|
||||
} from "./thirdweb-features";
|
||||
|
||||
/**
|
||||
@@ -127,8 +127,8 @@ export type Feature =
|
||||
| typeof FEATURE_DIRECT_LISTINGS
|
||||
| typeof FEATURE_ENGLISH_AUCTIONS
|
||||
| typeof FEATURE_OFFERS
|
||||
| typeof FEATURE_SMART_WALLET
|
||||
| typeof FEATURE_SMART_WALLET_FACTORY;
|
||||
| typeof FEATURE_ACCOUNT
|
||||
| typeof FEATURE_ACCOUNT_FACTORY;
|
||||
|
||||
export type Extension = Feature;
|
||||
|
||||
@@ -170,6 +170,6 @@ export const SUPPORTED_FEATURES: Record<string, Feature> = /* @__PURE__ */ {
|
||||
[FEATURE_DIRECT_LISTINGS.name]: FEATURE_DIRECT_LISTINGS,
|
||||
[FEATURE_ENGLISH_AUCTIONS.name]: FEATURE_ENGLISH_AUCTIONS,
|
||||
[FEATURE_OFFERS.name]: FEATURE_OFFERS,
|
||||
[FEATURE_SMART_WALLET_FACTORY.name]: FEATURE_SMART_WALLET_FACTORY,
|
||||
[FEATURE_SMART_WALLET.name]: FEATURE_SMART_WALLET,
|
||||
[FEATURE_ACCOUNT_FACTORY.name]: FEATURE_ACCOUNT_FACTORY,
|
||||
[FEATURE_ACCOUNT.name]: FEATURE_ACCOUNT,
|
||||
};
|
||||
|
||||
@@ -279,24 +279,24 @@ export const FEATURE_OFFERS = {
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
export const FEATURE_SMART_WALLET_FACTORY = {
|
||||
name: "SmartWalletFactory",
|
||||
namespace: "smartwallet.factory",
|
||||
export const FEATURE_ACCOUNT_FACTORY = {
|
||||
name: "AccountFactory",
|
||||
namespace: "accountFactory",
|
||||
docLinks: {
|
||||
// TODO
|
||||
sdk: "sdk.smartWalletFactory",
|
||||
contracts: "smartWalletFactory",
|
||||
sdk: "sdk.accountFactory",
|
||||
contracts: "",
|
||||
},
|
||||
abis: [IAccountFactory],
|
||||
features: {},
|
||||
} as const;
|
||||
|
||||
export const FEATURE_SMART_WALLET = {
|
||||
name: "SmartWallet",
|
||||
namespace: "smartwallet",
|
||||
export const FEATURE_ACCOUNT = {
|
||||
name: "Account",
|
||||
namespace: "account",
|
||||
docLinks: {
|
||||
// TODO
|
||||
sdk: "",
|
||||
sdk: "sdk.account",
|
||||
contracts: "",
|
||||
},
|
||||
abis: [IAccountCore],
|
||||
|
||||
@@ -259,7 +259,7 @@ export class Marketplace implements UpdateableNetwork {
|
||||
(l.type === ListingType.Auction &&
|
||||
BigNumber.from(l.endTimeInEpochSeconds).gt(now) &&
|
||||
BigNumber.from(l.startTimeInEpochSeconds).lte(now)) ||
|
||||
(l.type === ListingType.Direct && l.quantity > 0)
|
||||
(l.type === ListingType.Direct && BigNumber.from(l.quantity).gt(0))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ import {
|
||||
FEATURE_PLATFORM_FEE,
|
||||
FEATURE_PRIMARY_SALE,
|
||||
FEATURE_ROYALTY,
|
||||
FEATURE_SMART_WALLET_FACTORY,
|
||||
FEATURE_SMART_WALLET,
|
||||
FEATURE_ACCOUNT_FACTORY,
|
||||
FEATURE_ACCOUNT,
|
||||
} from "../constants/thirdweb-features";
|
||||
import { Transaction } from "../core/classes/transactions";
|
||||
import { ContractAppURI } from "../core/classes/contract-appuri";
|
||||
@@ -54,7 +54,7 @@ import type {
|
||||
EnglishAuctionsLogic,
|
||||
OffersLogic,
|
||||
IAccountFactory,
|
||||
IAccountCore
|
||||
IAccountCore,
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { BaseContract, CallOverrides } from "ethers";
|
||||
@@ -66,8 +66,8 @@ import { ContractOwner } from "../core/classes/contract-owner";
|
||||
import { MarketplaceV3DirectListings } from "../core/classes/marketplacev3-direct-listings";
|
||||
import { MarketplaceV3EnglishAuctions } from "../core/classes/marketplacev3-english-auction";
|
||||
import { MarketplaceV3Offers } from "../core/classes/marketplacev3-offers";
|
||||
import { SmartWalletFactory } from "../core/classes/smart-wallet-factory";
|
||||
import { SmartWallet } from "../core/classes/smart-wallet";
|
||||
import { AccountFactory } from "../core/classes/account-factory";
|
||||
import { Account } from "../core/classes/account";
|
||||
|
||||
/**
|
||||
* Custom contract dynamic class with feature detection
|
||||
@@ -299,46 +299,40 @@ export class SmartContract<
|
||||
}
|
||||
|
||||
/**
|
||||
* Smart Wallet Factory
|
||||
* Account Factory
|
||||
*
|
||||
* @remarks Create smart wallets and fetch data about them.
|
||||
* @remarks Create accounts and fetch data about them.
|
||||
* @example
|
||||
* ```javascript
|
||||
*
|
||||
* // Predict the address of the smart wallet that will be created for an admin.
|
||||
* const deterministicAddress = await contract.smartWalletFactory.predictWalletAddress(admin, extraData);
|
||||
* // Predict the address of the account that will be created for an admin.
|
||||
* const deterministicAddress = await contract.accountFactory.predictAccountAddress(admin, extraData);
|
||||
*
|
||||
* // Create smart wallets
|
||||
* const tx = await contract.smartWalletFactory.createWallet(admin, extraData);
|
||||
* // Create accounts
|
||||
* const tx = await contract.accountFactory.createAccount(admin, extraData);
|
||||
* // the same as `deterministicAddress`
|
||||
* const smartWalletAddress = tx.address;
|
||||
* const accountAddress = tx.address;
|
||||
*
|
||||
* // Get all smart wallets created by the factory
|
||||
* const allWallets = await contract.smartWalletFactory.getAllWallets();
|
||||
* // Get all accounts created by the factory
|
||||
* const allAccounts = await contract.accountFactory.getAllAccounts();
|
||||
*
|
||||
* // Get all smart wallets on which a signer has been given authority.
|
||||
* const associatedWallets = await contract.smartWalletFactory.getAssociatedWallets(signer);
|
||||
* // Get all accounts on which a signer has been given authority.
|
||||
* const associatedAccounts = await contract.accountFactory.getAssociatedAccounts(signer);
|
||||
*
|
||||
* // Get all signers who have been given authority on a smart wallet.
|
||||
* const associatedSigners = await contract.smartWalletFactory.getAssociatedSigners(smartWalletAddress);
|
||||
* // Get all signers who have been given authority on a account.
|
||||
* const associatedSigners = await contract.accountFactory.getAssociatedSigners(accountAddress);
|
||||
*
|
||||
* // Check whether a smart wallet has already been created for a given admin.
|
||||
* const isWalletDeployed = await contract.smartWalletFactory.isWalletDeployed(admin, extraData);
|
||||
* // Check whether a account has already been created for a given admin.
|
||||
* const isAccountDeployed = await contract.accountFactory.isAccountDeployed(admin, extraData);
|
||||
* ```
|
||||
*/
|
||||
get smartWalletFactory(): SmartWalletFactory<IAccountFactory> {
|
||||
return assertEnabled(
|
||||
this.detectSmartWalletFactory(),
|
||||
FEATURE_SMART_WALLET_FACTORY,
|
||||
);
|
||||
get accountFactory(): AccountFactory<IAccountFactory> {
|
||||
return assertEnabled(this.detectAccountFactory(), FEATURE_ACCOUNT_FACTORY);
|
||||
}
|
||||
|
||||
// TODO documentation
|
||||
get smartWallet(): SmartWallet<IAccountCore> {
|
||||
return assertEnabled(
|
||||
this.detectSmartWallet(),
|
||||
FEATURE_SMART_WALLET,
|
||||
)
|
||||
get account(): Account<IAccountCore> {
|
||||
return assertEnabled(this.detectAccount(), FEATURE_ACCOUNT);
|
||||
}
|
||||
|
||||
private _chainId: number;
|
||||
@@ -568,25 +562,28 @@ export class SmartContract<
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// ========== Smart account features ==========
|
||||
// ========== Account features ==========
|
||||
|
||||
private detectSmartWalletFactory() {
|
||||
private detectAccountFactory() {
|
||||
if (
|
||||
detectContractFeature<IAccountFactory>(
|
||||
this.contractWrapper,
|
||||
FEATURE_SMART_WALLET_FACTORY.name,
|
||||
FEATURE_ACCOUNT_FACTORY.name,
|
||||
)
|
||||
) {
|
||||
return new SmartWalletFactory(this.contractWrapper);
|
||||
return new AccountFactory(this.contractWrapper);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectSmartWallet() {
|
||||
private detectAccount() {
|
||||
if (
|
||||
detectContractFeature<IAccountCore>(this.contractWrapper, FEATURE_SMART_WALLET.name)
|
||||
detectContractFeature<IAccountCore>(
|
||||
this.contractWrapper,
|
||||
FEATURE_ACCOUNT.name,
|
||||
)
|
||||
) {
|
||||
return new SmartWallet(this.contractWrapper);
|
||||
return new Account(this.contractWrapper);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
+46
-46
@@ -1,6 +1,6 @@
|
||||
import type { IAccountFactory } from "@thirdweb-dev/contracts-js";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { FEATURE_SMART_WALLET_FACTORY } from "../../constants/thirdweb-features";
|
||||
import { FEATURE_ACCOUNT_FACTORY } from "../../constants/thirdweb-features";
|
||||
|
||||
import { ContractEvents } from "./contract-events";
|
||||
import { ContractWrapper } from "./contract-wrapper";
|
||||
@@ -9,13 +9,13 @@ import { Transaction } from "./transactions";
|
||||
import { TransactionResultWithAddress } from "../types";
|
||||
import { type BytesLike, utils } from "ethers";
|
||||
import { AccountCreatedEvent } from "@thirdweb-dev/contracts-js/dist/declarations/src/AccountFactory";
|
||||
import type { AccountEvent } from "../../types/smart-wallet";
|
||||
import type { AccountEvent } from "../../types/account";
|
||||
import { isContractDeployed } from "../../common/any-evm-utils/isContractDeployed";
|
||||
|
||||
export class SmartWalletFactory<TContract extends IAccountFactory>
|
||||
export class AccountFactory<TContract extends IAccountFactory>
|
||||
implements DetectableFeature
|
||||
{
|
||||
featureName = FEATURE_SMART_WALLET_FACTORY.name;
|
||||
featureName = FEATURE_ACCOUNT_FACTORY.name;
|
||||
private contractWrapper: ContractWrapper<IAccountFactory>;
|
||||
|
||||
// utilities
|
||||
@@ -36,19 +36,19 @@ export class SmartWalletFactory<TContract extends IAccountFactory>
|
||||
*******************************/
|
||||
|
||||
/**
|
||||
* Get the deterministic address of the smart wallet that will be created
|
||||
* Get the deterministic address of the account that will be created
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const walletAddress = await contract.smartWalletFactory.predictWalletAddress(admin);
|
||||
* const accountAddress = await contract.accountFactory.predictAccountAddress(admin);
|
||||
* ```
|
||||
* @param admin - The admin of the smart wallet.
|
||||
* @param extraData - (Optional) Extra data to be passed to the smart wallet on creation.
|
||||
* @returns the deterministic address of the smart wallet that will be created for the given admin.
|
||||
* @param admin - The admin of the account.
|
||||
* @param extraData - (Optional) Extra data to be passed to the account on creation.
|
||||
* @returns the deterministic address of the account that will be created for the given admin.
|
||||
*
|
||||
* @twfeature SmartWalletFactory
|
||||
* @twfeature AccountFactory
|
||||
*/
|
||||
public async predictWalletAddress(
|
||||
public async predictAccountAddress(
|
||||
admin: string,
|
||||
extraData?: BytesLike,
|
||||
): Promise<string> {
|
||||
@@ -60,48 +60,48 @@ export class SmartWalletFactory<TContract extends IAccountFactory>
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all signers who have authority on the given smart wallet
|
||||
* Get all signers who have authority on the given account
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const allSigners = await contract.smartWalletFactory.getAssociatedSigners(admin);
|
||||
* const allSigners = await contract.accountFactory.getAssociatedSigners(admin);
|
||||
* ```
|
||||
* @param wallet - The smart wallet address.
|
||||
* @returns all signers who have authority on the given smart wallet.
|
||||
* @param account - The account address.
|
||||
* @returns all signers who have authority on the given account.
|
||||
*
|
||||
* @twfeature SmartWalletFactory
|
||||
* @twfeature AccountFactory
|
||||
*/
|
||||
public async getAssociatedSigners(wallet: string): Promise<string[]> {
|
||||
return this.contractWrapper.readContract.getSignersOfAccount(wallet);
|
||||
public async getAssociatedSigners(account: string): Promise<string[]> {
|
||||
return this.contractWrapper.readContract.getSignersOfAccount(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all wallets on which the given signer has authority
|
||||
* Get all accounts on which the given signer has authority
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const allWallets = await contract.smartWalletFactory.getAssociatedWallets(admin);
|
||||
* const allAccounts = await contract.accountFactory.getAssociatedAccounts(admin);
|
||||
* ```
|
||||
* @param signer - The smart wallet address.
|
||||
* @returns all wallets on which the given signer has authority.
|
||||
* @param signer - The account address.
|
||||
* @returns all accounts on which the given signer has authority.
|
||||
*
|
||||
* @twfeature SmartWalletFactory
|
||||
* @twfeature AccountFactory
|
||||
*/
|
||||
public async getAssociatedWallets(signer: string): Promise<string[]> {
|
||||
public async getAssociatedAccounts(signer: string): Promise<string[]> {
|
||||
return this.contractWrapper.readContract.getAccountsOfSigner(signer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all wallets
|
||||
* Get all accounts
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const allWallets = await contract.smartWalletFactory.getAllWallets();
|
||||
* const allAccounts = await contract.accountFactory.getAllAccounts();
|
||||
* ```
|
||||
*
|
||||
* @returns all wallets created via the smart wallet factory.
|
||||
* @returns all accounts created via the account factory.
|
||||
*
|
||||
* @twfeature SmartWalletFactory
|
||||
* @twfeature AccountFactory
|
||||
*/
|
||||
public async getAllAccounts(): Promise<AccountEvent[]> {
|
||||
const allAccounts =
|
||||
@@ -122,17 +122,17 @@ export class SmartWalletFactory<TContract extends IAccountFactory>
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a smart wallet has been deployed for the given admin
|
||||
* Check if a account has been deployed for the given admin
|
||||
*
|
||||
* @param admin - The admin of the smart wallet.
|
||||
* @param extraData - (Optional) Extra data to be passed to the smart wallet on creation.
|
||||
* @returns whether the smart wallet has been deployed for the given admin.
|
||||
* @param admin - The admin of the account.
|
||||
* @param extraData - (Optional) Extra data to be passed to the account on creation.
|
||||
* @returns whether the account has been deployed for the given admin.
|
||||
*/
|
||||
public async isWalletDeployed(
|
||||
public async isAccountDeployed(
|
||||
admin: string,
|
||||
extraData?: BytesLike,
|
||||
): Promise<boolean> {
|
||||
const addr = await this.predictWalletAddress(admin, extraData);
|
||||
const addr = await this.predictAccountAddress(admin, extraData);
|
||||
return isContractDeployed(addr, this.contractWrapper.getProvider());
|
||||
}
|
||||
|
||||
@@ -141,29 +141,29 @@ export class SmartWalletFactory<TContract extends IAccountFactory>
|
||||
*******************************/
|
||||
|
||||
/**
|
||||
* Create a smart wallet
|
||||
* Create a account
|
||||
*
|
||||
* @remarks Create a smart wallet for an admin. The admin will have complete authority over the smart wallet.
|
||||
* @remarks Create a account for an admin. The admin will have complete authority over the account.
|
||||
*
|
||||
* @param admin - The admin of the smart wallet.
|
||||
* @param extraData - (Optional) Extra data to be passed to the smart wallet on creation.
|
||||
* @param admin - The admin of the account.
|
||||
* @param extraData - (Optional) Extra data to be passed to the account on creation.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWalletFactory.createWallet(admin, extraData);
|
||||
* const tx = await contract.accountFactory.createAccount(admin, extraData);
|
||||
* const receipt = tx.receipt();
|
||||
* const smartWalletAddress = tx.address;
|
||||
* const accountAddress = tx.address;
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWalletFactory
|
||||
* @twfeature AccountFactory
|
||||
*/
|
||||
createWallet = /* @__PURE__ */ buildTransactionFunction(
|
||||
createAccount = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (
|
||||
walletAdmin: string,
|
||||
accountAdmin: string,
|
||||
extraData?: BytesLike,
|
||||
): Promise<Transaction<TransactionResultWithAddress>> => {
|
||||
if (await this.isWalletDeployed(walletAdmin, extraData)) {
|
||||
throw new Error(`Wallet already deployed for admin: ${walletAdmin}`);
|
||||
if (await this.isAccountDeployed(accountAdmin, extraData)) {
|
||||
throw new Error(`Account already deployed for admin: ${accountAdmin}`);
|
||||
}
|
||||
|
||||
let data: BytesLike = utils.toUtf8Bytes("");
|
||||
@@ -174,7 +174,7 @@ export class SmartWalletFactory<TContract extends IAccountFactory>
|
||||
return Transaction.fromContractWrapper({
|
||||
contractWrapper: this.contractWrapper,
|
||||
method: "createAccount",
|
||||
args: [walletAdmin, data],
|
||||
args: [accountAdmin, data],
|
||||
parse: (receipt) => {
|
||||
const event = this.contractWrapper.parseLogs<AccountCreatedEvent>(
|
||||
"AccountCreated",
|
||||
+65
-65
@@ -1,6 +1,6 @@
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { ContractWrapper } from "./contract-wrapper";
|
||||
import { FEATURE_SMART_WALLET } from "../../constants/thirdweb-features";
|
||||
import { FEATURE_ACCOUNT } from "../../constants/thirdweb-features";
|
||||
import { utils, BigNumber } from "ethers";
|
||||
import { Transaction } from "./transactions";
|
||||
|
||||
@@ -27,10 +27,10 @@ import { AddressOrEns } from "../../schema";
|
||||
import { resolveAddress } from "../../common";
|
||||
import { Signer } from "ethers";
|
||||
|
||||
export class SmartWallet<TContract extends IAccountCore>
|
||||
export class Account<TContract extends IAccountCore>
|
||||
implements DetectableFeature
|
||||
{
|
||||
featureName = FEATURE_SMART_WALLET.name;
|
||||
featureName = FEATURE_ACCOUNT.name;
|
||||
private contractWrapper: ContractWrapper<IAccountCore>;
|
||||
|
||||
private emptyRole: string =
|
||||
@@ -87,7 +87,7 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and sign a payload to grant or revoke a signer's access to the smart wallet.
|
||||
* Generate and sign a payload to grant or revoke a signer's access to the account.
|
||||
*
|
||||
* @param signer - The address of the signer
|
||||
* @param roleAction - The address of the signer
|
||||
@@ -137,7 +137,7 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the factory contract which deployed the smart wallet
|
||||
* Get the factory contract which deployed the account
|
||||
*
|
||||
* @returns Returns the address of the factory
|
||||
*
|
||||
@@ -161,16 +161,16 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
********************************/
|
||||
|
||||
/**
|
||||
* Get whether a signer is an admin on the smart wallet.
|
||||
* Get whether a signer is an admin on the account.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const isAdmin = await contract.smartWallet.isAdmin(signer);
|
||||
* const isAdmin = await contract.account.isAdmin(signer);
|
||||
* ```
|
||||
* @param signer - The address of a signer of the smart wallet.
|
||||
* @returns whether a signer is an admin on the smart wallet.
|
||||
* @param signer - The address of a signer of the account.
|
||||
* @returns whether a signer is an admin on the account.
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
public async isAdmin(signerAddress: AddressOrEns): Promise<boolean> {
|
||||
const resolvedSignerAddress = await resolveAddress(signerAddress);
|
||||
@@ -180,16 +180,16 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the restrictions under which a given signer can use the smart wallet.
|
||||
* Get the restrictions under which a given signer can use the account.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const restrictionsForSigner = await contract.smartWallet.getAccessRestrictions(signer);
|
||||
* const restrictionsForSigner = await contract.account.getAccessRestrictions(signer);
|
||||
* ```
|
||||
* @param signer - The address of a signer of the smart wallet.
|
||||
* @returns the restrictions under which a given signer can use the smart wallet.
|
||||
* @param signer - The address of a signer of the account.
|
||||
* @returns the restrictions under which a given signer can use the account.
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
public async getAccessRestrictions(
|
||||
signerAddress: AddressOrEns,
|
||||
@@ -203,16 +203,16 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the deployer of the smart wallet
|
||||
* @remarks Get the address of the EIP-4337 factory contract which deployed the smart wallet
|
||||
* Get the deployer of the account
|
||||
* @remarks Get the address of the EIP-4337 factory contract which deployed the account
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const factoryAddress = await contract.smartWallet.getFactoryAddress();
|
||||
* const factoryAddress = await contract.account.getFactoryAddress();
|
||||
* ```
|
||||
* @returns the address of the factory which deployed the smart wallet.
|
||||
* @returns the address of the factory which deployed the account.
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
public async getFactoryAddress(): Promise<string> {
|
||||
return this.contractWrapper.readContract.factory();
|
||||
@@ -223,11 +223,11 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const allSigners = await contract.smartWallet.getSignersWithRestrictions();
|
||||
* const allSigners = await contract.account.getSignersWithRestrictions();
|
||||
* ```
|
||||
* @returns all signers (admin or non-admin) of the smart wallet, along with their access restrictions.
|
||||
* @returns all signers (admin or non-admin) of the account, along with their access restrictions.
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
public async getSignersWithRestrictions(): Promise<SignerWithRestrictions[]> {
|
||||
// Get all associated signers.
|
||||
@@ -250,19 +250,19 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
********************************/
|
||||
|
||||
/**
|
||||
* Grant an address admin access to the smart wallet
|
||||
* Grant an address admin access to the account
|
||||
*
|
||||
* @remarks Grants an address admin access to the smart wallet. The admin will have complete authority over the smart wallet.
|
||||
* @remarks Grants an address admin access to the account. The admin will have complete authority over the account.
|
||||
*
|
||||
* @param signer - The address to be granted admin access to the smart wallet.
|
||||
* @param signer - The address to be granted admin access to the account.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWallet.grantAdminAccess(signer);
|
||||
* const tx = await contract.account.grantAdminAccess(signer);
|
||||
* const receipt = tx.receipt();
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
grantAdminAccess = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (signerAddress: AddressOrEns): Promise<Transaction> => {
|
||||
@@ -276,19 +276,19 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
);
|
||||
|
||||
/**
|
||||
* Revoke an address' admin access to the smart wallet
|
||||
* Revoke an address' admin access to the account
|
||||
*
|
||||
* @remarks Revokes an address' admin access to the smart wallet.
|
||||
* @remarks Revokes an address' admin access to the account.
|
||||
*
|
||||
* @param signer - The address of an admin of the smart wallet.
|
||||
* @param signer - The address of an admin of the account.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWallet.revokeAdminAccess(signer);
|
||||
* const tx = await contract.account.revokeAdminAccess(signer);
|
||||
* const receipt = tx.receipt();
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
revokeAdminAccess = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (signerAddress: AddressOrEns): Promise<Transaction> => {
|
||||
@@ -302,20 +302,20 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
);
|
||||
|
||||
/**
|
||||
* Grant an address access to the smart wallet with restrictions
|
||||
* Grant an address access to the account with restrictions
|
||||
*
|
||||
* @remarks Grants an address access to the smart wallet with certain restrictions.
|
||||
* @remarks Grants an address access to the account with certain restrictions.
|
||||
*
|
||||
* @param signer - The address to be granted access to the smart wallet.
|
||||
* @param restrictions - The restrictions to be applied to the signer's use of the smart wallet.
|
||||
* @param signer - The address to be granted access to the account.
|
||||
* @param restrictions - The restrictions to be applied to the signer's use of the account.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWallet.grantAccess(signer, restrictions);
|
||||
* const tx = await contract.account.grantAccess(signer, restrictions);
|
||||
* const receipt = tx.receipt();
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
grantAccess = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (
|
||||
@@ -395,20 +395,20 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
);
|
||||
|
||||
/**
|
||||
* Approve an address as a call target for a given signer on the smart wallet
|
||||
* Approve an address as a call target for a given signer on the account
|
||||
*
|
||||
* @remarks Approves an address as a call target for a given signer on the smart wallet.
|
||||
* @remarks Approves an address as a call target for a given signer on the account.
|
||||
*
|
||||
* @param signer - A signer with restricted access to the smart wallet.
|
||||
* @param signer - A signer with restricted access to the account.
|
||||
* @param target - The address to approve as a call target for the signer.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWallet.approveTargetForSigner(signer, target);
|
||||
* const tx = await contract.account.approveTargetForSigner(signer, target);
|
||||
* const receipt = tx.receipt();
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
approveTargetForSigner = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (
|
||||
@@ -444,20 +444,20 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
);
|
||||
|
||||
/**
|
||||
* Disapprove an address as a call target for a given signer on the smart wallet
|
||||
* Disapprove an address as a call target for a given signer on the account
|
||||
*
|
||||
* @remarks Disapprove an address as a call target for a given signer on the smart wallet.
|
||||
* @remarks Disapprove an address as a call target for a given signer on the account.
|
||||
*
|
||||
* @param signer - A signer with restricted access to the smart wallet.
|
||||
* @param signer - A signer with restricted access to the account.
|
||||
* @param target - The address to disapprove as a call target for the signer.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWallet.disapproveTargetForSigner(signer, target);
|
||||
* const tx = await contract.account.disapproveTargetForSigner(signer, target);
|
||||
* const receipt = tx.receipt();
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
disapproveTargetForSigner = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (
|
||||
@@ -496,20 +496,20 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
);
|
||||
|
||||
/**
|
||||
* Update the restrictions of an address for using the smart wallet
|
||||
* Update the restrictions of an address for using the account
|
||||
*
|
||||
* @remarks Updates an address' access to the smart wallet.
|
||||
* @remarks Updates an address' access to the account.
|
||||
*
|
||||
* @param signer - The address whose access to the smart wallet is to be updated.
|
||||
* @param restrictions - The restrictions to be applied to the signer's use of the smart wallet.
|
||||
* @param signer - The address whose access to the account is to be updated.
|
||||
* @param restrictions - The restrictions to be applied to the signer's use of the account.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWallet.updateAccess(signer, restrictions);
|
||||
* const tx = await contract.account.updateAccess(signer, restrictions);
|
||||
* const receipt = tx.receipt();
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
updateAccess = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (
|
||||
@@ -550,19 +550,19 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
);
|
||||
|
||||
/**
|
||||
* Revoke a scoped access address to the smart wallet
|
||||
* Revoke a scoped access address to the account
|
||||
*
|
||||
* @remarks Revokes an address' access to the smart wallet.
|
||||
* @remarks Revokes an address' access to the account.
|
||||
*
|
||||
* @param signer - The address whose access to the smart wallet is to be revoked.
|
||||
* @param signer - The address whose access to the account is to be revoked.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWallet.revokeAccess(signer);
|
||||
* const tx = await contract.account.revokeAccess(signer);
|
||||
* const receipt = tx.receipt();
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
revokeAccess = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (signerAddress: AddressOrEns): Promise<Transaction> => {
|
||||
@@ -600,19 +600,19 @@ export class SmartWallet<TContract extends IAccountCore>
|
||||
);
|
||||
|
||||
/**
|
||||
* Set the wallet's entire snapshot of permissions
|
||||
* Set the account's entire snapshot of permissions
|
||||
*
|
||||
* @remarks Sets the wallet's entire snapshot of permissions.
|
||||
* @remarks Sets the account's entire snapshot of permissions.
|
||||
*
|
||||
* @param permissionsSnapshot - the snapshot to set as the wallet's entire permission snapshot.
|
||||
* @param permissionsSnapshot - the snapshot to set as the account's entire permission snapshot.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const tx = await contract.smartWallet.setAccess(permissionsSnapshot);
|
||||
* const tx = await contract.account.setAccess(permissionsSnapshot);
|
||||
* const receipt = tx.receipt();
|
||||
* ```
|
||||
*
|
||||
* @twfeature SmartWallet
|
||||
* @twfeature Account
|
||||
*/
|
||||
setAccess = /* @__PURE__ */ buildTransactionFunction(
|
||||
async (
|
||||
@@ -1,8 +1,7 @@
|
||||
import { EventType } from "../../constants/events";
|
||||
import type { ContractEvent, EventQueryOptions } from "../../types/events";
|
||||
import { ContractWrapper } from "./contract-wrapper";
|
||||
import type { BaseContract, Event, providers } from "ethers";
|
||||
import type { EventFragment } from "ethers/lib/utils.js";
|
||||
import type { BaseContract, Event, providers, utils } from "ethers";
|
||||
import type { EventEmitter } from "eventemitter3";
|
||||
|
||||
/**
|
||||
@@ -325,7 +324,7 @@ export class ContractEvents<TContract extends BaseContract> {
|
||||
}
|
||||
|
||||
private toContractEvent<TEvent extends Record<string, any>>(
|
||||
event: EventFragment,
|
||||
event: utils.EventFragment,
|
||||
args: ReadonlyArray<any>,
|
||||
rawLog: providers.Log,
|
||||
): ContractEvent<TEvent> {
|
||||
|
||||
@@ -44,7 +44,6 @@ import {
|
||||
type Signer,
|
||||
constants,
|
||||
} from "ethers";
|
||||
import { ConnectionInfo } from "ethers/lib/utils.js";
|
||||
import invariant from "tiny-invariant";
|
||||
import { CONTRACT_ADDRESSES } from "../../constants/addresses/CONTRACT_ADDRESSES";
|
||||
import { getContractAddressByChainId } from "../../constants/addresses/getContractAddressByChainId";
|
||||
@@ -471,7 +470,7 @@ export class ContractWrapper<
|
||||
callOverrides: CallOverrides,
|
||||
) {
|
||||
const provider = this.getProvider() as providers.Provider & {
|
||||
connection?: ConnectionInfo;
|
||||
connection?: utils.ConnectionInfo;
|
||||
};
|
||||
|
||||
// Get metadata for transaction to populate into error
|
||||
|
||||
@@ -50,5 +50,5 @@ export * from "./contract-published-metadata";
|
||||
export * from "./contract-owner";
|
||||
export * from "./transactions";
|
||||
export * from "./contract-appuri";
|
||||
export * from "./smart-wallet";
|
||||
export * from "./smart-wallet-factory";
|
||||
export * from "./account";
|
||||
export * from "./account-factory";
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
DirectListingInputParams,
|
||||
DirectListingInputParamsSchema,
|
||||
} from "../../schema/marketplacev3/direct-listings";
|
||||
import type { MarketplaceFilter } from "../../types/marketplace";
|
||||
import type { MarketplaceFilterWithoutOfferor } from "../../types/marketplace";
|
||||
import type { DirectListingV3 } from "../../types/marketplacev3";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { TransactionResultWithId } from "../types";
|
||||
@@ -116,7 +116,7 @@ export class MarketplaceV3DirectListings<TContract extends DirectListingsLogic>
|
||||
* @returns the Direct listing object array
|
||||
* @twfeature DirectListings
|
||||
*/
|
||||
public async getAll(filter?: MarketplaceFilter): Promise<DirectListingV3[]> {
|
||||
public async getAll(filter?: MarketplaceFilterWithoutOfferor): Promise<DirectListingV3[]> {
|
||||
const totalListings = await this.getTotalCount();
|
||||
|
||||
let start = BigNumber.from(filter?.start || 0).toNumber();
|
||||
@@ -156,7 +156,7 @@ export class MarketplaceV3DirectListings<TContract extends DirectListingsLogic>
|
||||
* @twfeature DirectListings
|
||||
*/
|
||||
public async getAllValid(
|
||||
filter?: MarketplaceFilter,
|
||||
filter?: MarketplaceFilterWithoutOfferor,
|
||||
): Promise<DirectListingV3[]> {
|
||||
const totalListings = await this.getTotalCount();
|
||||
|
||||
@@ -955,7 +955,7 @@ export class MarketplaceV3DirectListings<TContract extends DirectListingsLogic>
|
||||
|
||||
private async applyFilter(
|
||||
listings: IDirectListings.ListingStructOutput[],
|
||||
filter?: MarketplaceFilter,
|
||||
filter?: MarketplaceFilterWithoutOfferor,
|
||||
) {
|
||||
let rawListings = [...listings];
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
EnglishAuctionInputParams,
|
||||
EnglishAuctionInputParamsSchema,
|
||||
} from "../../schema/marketplacev3/english-auctions";
|
||||
import type { MarketplaceFilter } from "../../types/marketplace";
|
||||
import type { MarketplaceFilterWithoutOfferor } from "../../types/marketplace";
|
||||
import { CurrencyValue, Price } from "../../types/currency";
|
||||
import { EnglishAuction, Bid } from "../../types/marketplacev3";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
@@ -104,7 +104,7 @@ export class MarketplaceV3EnglishAuctions<
|
||||
* @returns the Auction object array
|
||||
* @twfeature EnglishAuctions
|
||||
*/
|
||||
public async getAll(filter?: MarketplaceFilter): Promise<EnglishAuction[]> {
|
||||
public async getAll(filter?: MarketplaceFilterWithoutOfferor): Promise<EnglishAuction[]> {
|
||||
const totalAuctions = await this.getTotalCount();
|
||||
|
||||
let start = BigNumber.from(filter?.start || 0).toNumber();
|
||||
@@ -142,7 +142,7 @@ export class MarketplaceV3EnglishAuctions<
|
||||
* @twfeature EnglishAuctions
|
||||
*/
|
||||
public async getAllValid(
|
||||
filter?: MarketplaceFilter,
|
||||
filter?: MarketplaceFilterWithoutOfferor,
|
||||
): Promise<EnglishAuction[]> {
|
||||
const totalAuctions = await this.getTotalCount();
|
||||
|
||||
@@ -885,7 +885,7 @@ export class MarketplaceV3EnglishAuctions<
|
||||
|
||||
private async applyFilter(
|
||||
auctions: IEnglishAuctions.AuctionStructOutput[],
|
||||
filter?: MarketplaceFilter,
|
||||
filter?: MarketplaceFilterWithoutOfferor,
|
||||
) {
|
||||
let rawAuctions = [...auctions];
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
OfferInputParams,
|
||||
OfferInputParamsSchema,
|
||||
} from "../../schema/marketplacev3/offer";
|
||||
import type { MarketplaceFilter } from "../../types/marketplace";
|
||||
import type { MarketplaceFilterWithoutSeller } from "../../types/marketplace";
|
||||
import { OfferV3 } from "../../types/marketplacev3";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { TransactionResultWithId } from "../types";
|
||||
@@ -96,7 +96,7 @@ export class MarketplaceV3Offers<TContract extends OffersLogic>
|
||||
* @returns the Offer object array
|
||||
* @twfeature Offers
|
||||
*/
|
||||
public async getAll(filter?: MarketplaceFilter): Promise<OfferV3[]> {
|
||||
public async getAll(filter?: MarketplaceFilterWithoutSeller): Promise<OfferV3[]> {
|
||||
const totalOffers = await this.getTotalCount();
|
||||
|
||||
let start = BigNumber.from(filter?.start || 0).toNumber();
|
||||
@@ -133,7 +133,7 @@ export class MarketplaceV3Offers<TContract extends OffersLogic>
|
||||
* @returns the Offer object array
|
||||
* @twfeature Offers
|
||||
*/
|
||||
public async getAllValid(filter?: MarketplaceFilter): Promise<OfferV3[]> {
|
||||
public async getAllValid(filter?: MarketplaceFilterWithoutSeller): Promise<OfferV3[]> {
|
||||
const totalOffers = await this.getTotalCount();
|
||||
|
||||
let start = BigNumber.from(filter?.start || 0).toNumber();
|
||||
@@ -457,7 +457,7 @@ export class MarketplaceV3Offers<TContract extends OffersLogic>
|
||||
|
||||
private async applyFilter(
|
||||
offers: IOffers.OfferStructOutput[],
|
||||
filter?: MarketplaceFilter,
|
||||
filter?: MarketplaceFilterWithoutSeller,
|
||||
) {
|
||||
let rawOffers = [...offers];
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@ import {
|
||||
constants,
|
||||
} from "ethers";
|
||||
import { BigNumber } from "ethers";
|
||||
import { FormatTypes } from "ethers/lib/utils.js";
|
||||
import type { ConnectionInfo } from "ethers/lib/utils.js";
|
||||
import invariant from "tiny-invariant";
|
||||
import EventEmitter from "eventemitter3";
|
||||
import type { DeployEvents } from "../../types/deploy";
|
||||
@@ -494,7 +492,7 @@ export class Transaction<
|
||||
try {
|
||||
// for dynamic contracts, add 30% to the gas limit to account for multiple delegate calls
|
||||
const abi = JSON.parse(
|
||||
this.contract.interface.format(FormatTypes.json) as string,
|
||||
this.contract.interface.format("json") as string,
|
||||
);
|
||||
if (isRouterContract(abi)) {
|
||||
overrides.gasLimit = overrides.gasLimit.mul(110).div(100);
|
||||
@@ -663,7 +661,7 @@ export class Transaction<
|
||||
*/
|
||||
private async transactionError(error: any) {
|
||||
const provider = this.provider as providers.Provider & {
|
||||
connection?: ConnectionInfo;
|
||||
connection?: utils.ConnectionInfo;
|
||||
};
|
||||
|
||||
// Get metadata for transaction to populate into error
|
||||
@@ -849,7 +847,7 @@ export class DeployTransaction extends TransactionContext {
|
||||
*/
|
||||
private async deployError(error: any) {
|
||||
const provider = this.provider as providers.Provider & {
|
||||
connection?: ConnectionInfo;
|
||||
connection?: utils.ConnectionInfo;
|
||||
};
|
||||
|
||||
// Get metadata for transaction to populate into error
|
||||
|
||||
@@ -12,4 +12,4 @@ export * from "./multiwrap";
|
||||
export * from "./registry";
|
||||
export * from "./transactions";
|
||||
export * from "./contract";
|
||||
export * from "./smart-wallet";
|
||||
export * from "./account";
|
||||
|
||||
@@ -11,3 +11,13 @@ export interface MarketplaceFilter extends QueryAllParams {
|
||||
tokenId?: BigNumberish;
|
||||
offeror?: AddressOrEns;
|
||||
}
|
||||
|
||||
/**
|
||||
* English auctions and Direct Listings V3 cannot be retrieved by offeror.
|
||||
*/
|
||||
export interface MarketplaceFilterWithoutOfferor extends Omit<MarketplaceFilter, 'offeror'> {}
|
||||
|
||||
/**
|
||||
* Offers V3 cannot be retrieved by seller.
|
||||
*/
|
||||
export interface MarketplaceFilterWithoutSeller extends Omit<MarketplaceFilter, 'seller'> {}
|
||||
@@ -1,7 +1,4 @@
|
||||
import { Keypair } from "@solana/web3.js";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import yaml from "yaml";
|
||||
|
||||
/**
|
||||
@@ -9,14 +6,14 @@ import yaml from "yaml";
|
||||
*/
|
||||
function getConfig(): any {
|
||||
// Path to Solana CLI config file
|
||||
const CONFIG_FILE_PATH = path.resolve(
|
||||
os.homedir(),
|
||||
const CONFIG_FILE_PATH = require("path").resolve(
|
||||
require("os").homedir(),
|
||||
".config",
|
||||
"solana",
|
||||
"cli",
|
||||
"config.yml",
|
||||
);
|
||||
const configYml = fs.readFileSync(CONFIG_FILE_PATH, {
|
||||
const configYml = require("fs").readFileSync(CONFIG_FILE_PATH, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
return yaml.parse(configYml);
|
||||
@@ -62,7 +59,9 @@ export function getPayer(): Keypair {
|
||||
* Create a Keypair from a secret key stored in file as bytes' array
|
||||
*/
|
||||
export function createKeypairFromFile(filePath: string): Keypair {
|
||||
const secretKeyString = fs.readFileSync(filePath, { encoding: "utf8" });
|
||||
const secretKeyString = require("fs").readFileSync(filePath, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
const secretKey = Uint8Array.from(JSON.parse(secretKeyString));
|
||||
return Keypair.fromSecretKey(secretKey);
|
||||
}
|
||||
|
||||
+147
-165
@@ -4,8 +4,8 @@ import { assert, expect } from "chai";
|
||||
import {
|
||||
SignerWithRestrictions,
|
||||
AccessRestrictions,
|
||||
SmartWallet,
|
||||
SmartWalletFactory,
|
||||
Account,
|
||||
AccountFactory,
|
||||
SignerWithRestrictionsInput,
|
||||
SignerWithRestrictionsBatchInput,
|
||||
} from "../../src/evm";
|
||||
@@ -23,9 +23,9 @@ import { IAccountCore, IAccountFactory } from "@thirdweb-dev/contracts-js";
|
||||
|
||||
global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
|
||||
/* @__PURE__ */ describe("Smart wallets with wallet factory", function () {
|
||||
let smartWalletFactory: SmartWalletFactory<IAccountFactory>;
|
||||
let smartWallet: SmartWallet<IAccountCore>;
|
||||
/* @__PURE__ */ describe("Accounts with account factory", function () {
|
||||
let accountFactory: AccountFactory<IAccountFactory>;
|
||||
let account: Account<IAccountCore>;
|
||||
|
||||
let adminWallet: SignerWithAddress;
|
||||
|
||||
@@ -66,64 +66,63 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
adminWallet,
|
||||
[entrypoint.address],
|
||||
);
|
||||
smartWalletFactory = (await sdk.getContract(factoryAddress))
|
||||
.smartWalletFactory;
|
||||
accountFactory = (await sdk.getContract(factoryAddress)).accountFactory;
|
||||
});
|
||||
|
||||
describe("Test: SmartWalletFactory actions", () => {
|
||||
it("Should create a new wallet for the admin", async () => {
|
||||
// Check before creating a smart wallet for `adminWallet`
|
||||
const isDeployed = await smartWalletFactory.isWalletDeployed(
|
||||
describe("Test: AccountFactory actions", () => {
|
||||
it("Should create a new account for the admin", async () => {
|
||||
// Check before creating a account for `adminWallet`
|
||||
const isDeployed = await accountFactory.isAccountDeployed(
|
||||
adminWallet.address,
|
||||
);
|
||||
assert.isFalse(
|
||||
isDeployed,
|
||||
"Smart wallet is should not be deployed for admin.",
|
||||
"Account is should not be deployed for admin.",
|
||||
);
|
||||
|
||||
const predictedAccountAddress: string =
|
||||
await smartWalletFactory.predictWalletAddress(adminWallet.address);
|
||||
await accountFactory.predictAccountAddress(adminWallet.address);
|
||||
|
||||
const allWalletsBefore = (await smartWalletFactory.getAllAccounts()).map(
|
||||
(wallet) => wallet.account,
|
||||
const allAccountsBefore = (await accountFactory.getAllAccounts()).map(
|
||||
(wallet) => account.account,
|
||||
);
|
||||
assert.isFalse(
|
||||
allWalletsBefore.includes(predictedAccountAddress),
|
||||
allAccountsBefore.includes(predictedAccountAddress),
|
||||
"Account should not be deployed for admin already.",
|
||||
);
|
||||
|
||||
assert.isTrue(
|
||||
(await smartWalletFactory.getAssociatedSigners(predictedAccountAddress))
|
||||
(await accountFactory.getAssociatedSigners(predictedAccountAddress))
|
||||
.length === 0,
|
||||
"Wallet should have no associated signers.",
|
||||
);
|
||||
assert.isTrue(
|
||||
(await smartWalletFactory.getAssociatedWallets(adminWallet.address))
|
||||
(await accountFactory.getAssociatedAccounts(adminWallet.address))
|
||||
.length === 0,
|
||||
"Signer should have no associated wallets.",
|
||||
"Signer should have no associated accounts.",
|
||||
);
|
||||
|
||||
// Create smart wallet for `adminWallet`
|
||||
const tx = await smartWalletFactory.createWallet(adminWallet.address);
|
||||
// Create account for `adminWallet`
|
||||
const tx = await accountFactory.createAccount(adminWallet.address);
|
||||
|
||||
// Checks after creating a smart wallet for `adminWallet`
|
||||
// Checks after creating a account for `adminWallet`
|
||||
assert.strictEqual(
|
||||
utils.getAddress(tx.address),
|
||||
utils.getAddress(predictedAccountAddress),
|
||||
"Smart wallet address should match predicted address.",
|
||||
"Account address should match predicted address.",
|
||||
);
|
||||
assert.isTrue(
|
||||
await smartWalletFactory.isWalletDeployed(adminWallet.address),
|
||||
"Smart wallet is should be deployed for admin.",
|
||||
await accountFactory.isAccountDeployed(adminWallet.address),
|
||||
"Account is should be deployed for admin.",
|
||||
);
|
||||
|
||||
const allWalletsAfter = await smartWalletFactory.getAllAccounts();
|
||||
const allAccountsAfter = await accountFactory.getAllAccounts();
|
||||
assert.isTrue(
|
||||
allWalletsAfter.length === 1,
|
||||
"Only one wallet should be created on the factory.",
|
||||
allAccountsAfter.length === 1,
|
||||
"Only one account should be created on the factory.",
|
||||
);
|
||||
|
||||
const { account, admin } = allWalletsAfter.filter(
|
||||
const { account, admin } = allAccountsAfter.filter(
|
||||
(wallet) =>
|
||||
utils.getAddress(wallet.account) ===
|
||||
utils.getAddress(predictedAccountAddress),
|
||||
@@ -136,165 +135,161 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
assert.strictEqual(
|
||||
utils.getAddress(admin),
|
||||
utils.getAddress(adminWallet.address),
|
||||
"Correct admin for smart wallet.",
|
||||
"Correct admin for account.",
|
||||
);
|
||||
|
||||
const associatedWallets = await smartWalletFactory.getAssociatedWallets(
|
||||
const associatedAccounts = await accountFactory.getAssociatedAccounts(
|
||||
admin,
|
||||
);
|
||||
const associatedSigner = await smartWalletFactory.getAssociatedSigners(
|
||||
const associatedSigner = await accountFactory.getAssociatedSigners(
|
||||
account,
|
||||
);
|
||||
|
||||
assert.isTrue(
|
||||
associatedWallets.length === 1,
|
||||
associatedAccounts.length === 1,
|
||||
"Wallet should have only the admin as an associated signer.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
utils.getAddress(account),
|
||||
utils.getAddress(associatedWallets[0]),
|
||||
utils.getAddress(associatedAccounts[0]),
|
||||
"Wallet should have only the admin as an associated signer.",
|
||||
);
|
||||
assert.isTrue(
|
||||
associatedSigner.length === 1,
|
||||
"Signer should have only the created wallet as an associated wallet.",
|
||||
"Signer should have only the created account as an associated account.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
utils.getAddress(admin),
|
||||
utils.getAddress(associatedSigner[0]),
|
||||
"Signer should have only the created wallet as an associated wallet.",
|
||||
"Signer should have only the created account as an associated account.",
|
||||
);
|
||||
});
|
||||
|
||||
it("Should throw if creating wallet for an admin who already has one", async () => {
|
||||
// Create a wallet for admin
|
||||
await smartWalletFactory.createWallet(adminWallet.address);
|
||||
it("Should throw if creating account for an admin who already has one", async () => {
|
||||
// Create a account for admin
|
||||
await accountFactory.createAccount(adminWallet.address);
|
||||
|
||||
// Try creating another wallet for the same admin
|
||||
// Try creating another account for the same admin
|
||||
try {
|
||||
await smartWalletFactory.createWallet(adminWallet.address);
|
||||
await accountFactory.createAccount(adminWallet.address);
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.equal(
|
||||
`Wallet already deployed for admin: ${adminWallet.address}`,
|
||||
`Account already deployed for admin: ${adminWallet.address}`,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("Test: SmartWallet actions", () => {
|
||||
describe("Test: Account actions", () => {
|
||||
beforeEach(async () => {
|
||||
// Create a wallet for admin
|
||||
const tx = await smartWalletFactory.createWallet(adminWallet.address);
|
||||
const smartWalletAddress = tx.address;
|
||||
// Create a account for admin
|
||||
const tx = await accountFactory.createAccount(adminWallet.address);
|
||||
const accountAddress = tx.address;
|
||||
|
||||
sdk.updateSignerOrProvider(adminWallet);
|
||||
await mockUploadContractMetadata(
|
||||
"smart-wallet",
|
||||
smartWalletAddress,
|
||||
accountAddress,
|
||||
IAccountCoreAbi,
|
||||
);
|
||||
|
||||
smartWallet = (await sdk.getContract(smartWalletAddress)).smartWallet;
|
||||
account = (await sdk.getContract(accountAddress)).account;
|
||||
});
|
||||
|
||||
it("Should be able to add another admin to the wallet.", async () => {
|
||||
it("Should be able to add another admin to the account.", async () => {
|
||||
assert.isFalse(
|
||||
await smartWallet.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the smart wallet.",
|
||||
await account.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the account.",
|
||||
);
|
||||
|
||||
await smartWallet.grantAdminAccess(signer1Wallet.address);
|
||||
await account.grantAdminAccess(signer1Wallet.address);
|
||||
|
||||
assert.isTrue(
|
||||
await smartWallet.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should be an admin on the smart wallet.",
|
||||
await account.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should be an admin on the account.",
|
||||
);
|
||||
|
||||
const isAdmin = (
|
||||
(await smartWallet.getSignersWithRestrictions()).find(
|
||||
(await account.getSignersWithRestrictions()).find(
|
||||
(result) =>
|
||||
utils.getAddress(result.signer) ===
|
||||
utils.getAddress(signer1Wallet.address),
|
||||
) as SignerWithRestrictions
|
||||
).isAdmin;
|
||||
assert.isTrue(isAdmin, "New signer1 should be an admin on the wallet.");
|
||||
assert.isTrue(isAdmin, "New signer1 should be an admin on the account.");
|
||||
|
||||
assert.isTrue(
|
||||
(
|
||||
await smartWalletFactory.getAssociatedSigners(
|
||||
smartWallet.getAddress(),
|
||||
)
|
||||
await accountFactory.getAssociatedSigners(account.getAddress())
|
||||
).includes(signer1Wallet.address),
|
||||
"New signer1 is an associated signer of the wallet.",
|
||||
"New signer1 is an associated signer of the account.",
|
||||
);
|
||||
assert.isTrue(
|
||||
(
|
||||
await smartWalletFactory.getAssociatedWallets(signer1Wallet.address)
|
||||
).includes(smartWallet.getAddress()),
|
||||
"Wallet is an associated wallet of the signer.",
|
||||
await accountFactory.getAssociatedAccounts(signer1Wallet.address)
|
||||
).includes(account.getAddress()),
|
||||
"Wallet is an associated account of the signer.",
|
||||
);
|
||||
});
|
||||
|
||||
it("Should be able to remove an admin from the wallet.", async () => {
|
||||
await smartWallet.grantAdminAccess(signer1Wallet.address);
|
||||
it("Should be able to remove an admin from the account.", async () => {
|
||||
await account.grantAdminAccess(signer1Wallet.address);
|
||||
assert.isTrue(
|
||||
await smartWallet.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should be an admin on the smart wallet.",
|
||||
await account.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should be an admin on the account.",
|
||||
);
|
||||
|
||||
await smartWallet.revokeAdminAccess(signer1Wallet.address);
|
||||
await account.revokeAdminAccess(signer1Wallet.address);
|
||||
|
||||
assert.isFalse(
|
||||
await smartWallet.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the smart wallet.",
|
||||
await account.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the account.",
|
||||
);
|
||||
|
||||
assert.isFalse(
|
||||
(await smartWallet.getSignersWithRestrictions())
|
||||
(await account.getSignersWithRestrictions())
|
||||
.map((result) => utils.getAddress(result.signer))
|
||||
.includes(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the wallet.",
|
||||
"New signer1 should not be an admin on the account.",
|
||||
);
|
||||
|
||||
assert.isFalse(
|
||||
(
|
||||
await smartWalletFactory.getAssociatedSigners(
|
||||
smartWallet.getAddress(),
|
||||
)
|
||||
await accountFactory.getAssociatedSigners(account.getAddress())
|
||||
).includes(signer1Wallet.address),
|
||||
"New signer1 is not an associated signer of the wallet.",
|
||||
"New signer1 is not an associated signer of the account.",
|
||||
);
|
||||
assert.isFalse(
|
||||
(
|
||||
await smartWalletFactory.getAssociatedWallets(signer1Wallet.address)
|
||||
).includes(smartWallet.getAddress()),
|
||||
"Wallet is not an associated wallet of the signer.",
|
||||
await accountFactory.getAssociatedAccounts(signer1Wallet.address)
|
||||
).includes(account.getAddress()),
|
||||
"Wallet is not an associated account of the signer.",
|
||||
);
|
||||
});
|
||||
|
||||
it("Should be able to grant restricted access to a new signer.", async () => {
|
||||
const signersWithRestrictions =
|
||||
await smartWallet.getSignersWithRestrictions();
|
||||
await account.getSignersWithRestrictions();
|
||||
assert.isFalse(
|
||||
signersWithRestrictions
|
||||
.map((result) => utils.getAddress(result.signer))
|
||||
.includes(signer1Wallet.address),
|
||||
"New signer should not already have access to the wallet.",
|
||||
"New signer should not already have access to the account.",
|
||||
);
|
||||
|
||||
// Grant access
|
||||
await smartWallet.grantAccess(signer1Wallet.address, {
|
||||
await account.grantAccess(signer1Wallet.address, {
|
||||
nativeTokenLimitPerTransaction: "1",
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
|
||||
assert.isFalse(
|
||||
await smartWallet.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the smart wallet.",
|
||||
await account.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the account.",
|
||||
);
|
||||
const newSignerWithRestrictions =
|
||||
await smartWallet.getSignersWithRestrictions();
|
||||
await account.getSignersWithRestrictions();
|
||||
const restrictions = newSignerWithRestrictions.find(
|
||||
(result) =>
|
||||
utils.getAddress(result.signer) ===
|
||||
@@ -304,7 +299,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
newSignerWithRestrictions
|
||||
.map((result) => utils.getAddress(result.signer))
|
||||
.includes(signer1Wallet.address),
|
||||
"New signer1 should be a signer on the wallet.",
|
||||
"New signer1 should be a signer on the account.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.nativeTokenLimitPerTransaction.toString(),
|
||||
@@ -324,30 +319,28 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
|
||||
assert.isTrue(
|
||||
(
|
||||
await smartWalletFactory.getAssociatedSigners(
|
||||
smartWallet.getAddress(),
|
||||
)
|
||||
await accountFactory.getAssociatedSigners(account.getAddress())
|
||||
).includes(signer1Wallet.address),
|
||||
"New signer1 is an associated signer of the wallet.",
|
||||
"New signer1 is an associated signer of the account.",
|
||||
);
|
||||
assert.isTrue(
|
||||
(
|
||||
await smartWalletFactory.getAssociatedWallets(signer1Wallet.address)
|
||||
).includes(smartWallet.getAddress()),
|
||||
"Wallet is an associated wallet of the signer.",
|
||||
await accountFactory.getAssociatedAccounts(signer1Wallet.address)
|
||||
).includes(account.getAddress()),
|
||||
"Wallet is an associated account of the signer.",
|
||||
);
|
||||
});
|
||||
|
||||
it("Should not be able to grant restricted access to a signer who already has access.", async () => {
|
||||
// Grant access to signer1
|
||||
await smartWallet.grantAccess(signer1Wallet.address, {
|
||||
await account.grantAccess(signer1Wallet.address, {
|
||||
nativeTokenLimitPerTransaction: "1",
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
|
||||
// Try granting access to signer1 again
|
||||
try {
|
||||
await smartWallet.grantAccess(signer1Wallet.address, {
|
||||
await account.grantAccess(signer1Wallet.address, {
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
expect.fail();
|
||||
@@ -358,57 +351,55 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
|
||||
it("Should be able to revoke restricted access from an authorized signer.", async () => {
|
||||
// Grant access to signer1
|
||||
await smartWallet.grantAccess(signer1Wallet.address, {
|
||||
await account.grantAccess(signer1Wallet.address, {
|
||||
nativeTokenLimitPerTransaction: "1",
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
|
||||
// Revoke access
|
||||
await smartWallet.revokeAccess(signer1Wallet.address);
|
||||
await account.revokeAccess(signer1Wallet.address);
|
||||
|
||||
const signersWithRestrictions =
|
||||
await smartWallet.getSignersWithRestrictions();
|
||||
await account.getSignersWithRestrictions();
|
||||
assert.isFalse(
|
||||
signersWithRestrictions
|
||||
.map((result) => utils.getAddress(result.signer))
|
||||
.includes(signer1Wallet.address),
|
||||
"New signer should not have access to the wallet.",
|
||||
"New signer should not have access to the account.",
|
||||
);
|
||||
|
||||
assert.isFalse(
|
||||
await smartWallet.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the smart wallet.",
|
||||
await account.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the account.",
|
||||
);
|
||||
|
||||
assert.isFalse(
|
||||
(
|
||||
await smartWalletFactory.getAssociatedSigners(
|
||||
smartWallet.getAddress(),
|
||||
)
|
||||
await accountFactory.getAssociatedSigners(account.getAddress())
|
||||
).includes(signer1Wallet.address),
|
||||
"New signer1 is not an associated signer of the wallet.",
|
||||
"New signer1 is not an associated signer of the account.",
|
||||
);
|
||||
assert.isFalse(
|
||||
(
|
||||
await smartWalletFactory.getAssociatedWallets(signer1Wallet.address)
|
||||
).includes(smartWallet.getAddress()),
|
||||
"Wallet is not an associated wallet of the signer.",
|
||||
await accountFactory.getAssociatedAccounts(signer1Wallet.address)
|
||||
).includes(account.getAddress()),
|
||||
"Wallet is not an associated account of the signer.",
|
||||
);
|
||||
});
|
||||
|
||||
it("Should not be able to revoke restricted access from a signer who doesn't have access.", async () => {
|
||||
const signersWithRestrictions =
|
||||
await smartWallet.getSignersWithRestrictions();
|
||||
await account.getSignersWithRestrictions();
|
||||
assert.isFalse(
|
||||
signersWithRestrictions
|
||||
.map((result) => utils.getAddress(result.signer))
|
||||
.includes(signer1Wallet.address),
|
||||
"New signer should not already have access to the wallet.",
|
||||
"New signer should not already have access to the account.",
|
||||
);
|
||||
|
||||
// Try revoking access from signer1
|
||||
try {
|
||||
await smartWallet.revokeAccess(signer1Wallet.address);
|
||||
await account.revokeAccess(signer1Wallet.address);
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.equal(`Signer does not have any access`);
|
||||
@@ -417,18 +408,17 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
|
||||
it("Should be able to update access of an authorized signer.", async () => {
|
||||
// Grant access
|
||||
await smartWallet.grantAccess(signer1Wallet.address, {
|
||||
await account.grantAccess(signer1Wallet.address, {
|
||||
nativeTokenLimitPerTransaction: "1",
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
|
||||
assert.isFalse(
|
||||
await smartWallet.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the smart wallet.",
|
||||
await account.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the account.",
|
||||
);
|
||||
|
||||
const signerWithRestrictions =
|
||||
await smartWallet.getSignersWithRestrictions();
|
||||
const signerWithRestrictions = await account.getSignersWithRestrictions();
|
||||
const restrictions = signerWithRestrictions.find(
|
||||
(result) =>
|
||||
utils.getAddress(result.signer) ===
|
||||
@@ -438,7 +428,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
signerWithRestrictions
|
||||
.map((result) => utils.getAddress(result.signer))
|
||||
.includes(signer1Wallet.address),
|
||||
"New signer1 should be a signer on the wallet.",
|
||||
"New signer1 should be a signer on the account.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.nativeTokenLimitPerTransaction.toString(),
|
||||
@@ -457,18 +447,18 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
);
|
||||
|
||||
// Update access
|
||||
await smartWallet.updateAccess(signer1Wallet.address, {
|
||||
await account.updateAccess(signer1Wallet.address, {
|
||||
nativeTokenLimitPerTransaction: "3",
|
||||
approvedCallTargets: [signer2Wallet.address],
|
||||
});
|
||||
|
||||
assert.isFalse(
|
||||
await smartWallet.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the smart wallet.",
|
||||
await account.isAdmin(signer1Wallet.address),
|
||||
"New signer1 should not be an admin on the account.",
|
||||
);
|
||||
|
||||
const newSignerWithRestrictions =
|
||||
await smartWallet.getSignersWithRestrictions();
|
||||
await account.getSignersWithRestrictions();
|
||||
const newRestrictions = newSignerWithRestrictions.find(
|
||||
(result) =>
|
||||
utils.getAddress(result.signer) ===
|
||||
@@ -478,7 +468,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
newSignerWithRestrictions
|
||||
.map((result) => utils.getAddress(result.signer))
|
||||
.includes(signer1Wallet.address),
|
||||
"New signer1 should be a signer on the wallet.",
|
||||
"New signer1 should be a signer on the account.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
newRestrictions.nativeTokenLimitPerTransaction.toString(),
|
||||
@@ -499,17 +489,17 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
|
||||
it("Should not be able to update access of a signer who doesn't have access.", async () => {
|
||||
const signersWithRestrictions =
|
||||
await smartWallet.getSignersWithRestrictions();
|
||||
await account.getSignersWithRestrictions();
|
||||
assert.isFalse(
|
||||
signersWithRestrictions
|
||||
.map((result) => utils.getAddress(result.signer))
|
||||
.includes(signer1Wallet.address),
|
||||
"New signer should not already have access to the wallet.",
|
||||
"New signer should not already have access to the account.",
|
||||
);
|
||||
|
||||
// Try updating access of signer1
|
||||
try {
|
||||
await smartWallet.updateAccess(signer1Wallet.address, {
|
||||
await account.updateAccess(signer1Wallet.address, {
|
||||
approvedCallTargets: [signer2Wallet.address],
|
||||
});
|
||||
expect.fail();
|
||||
@@ -520,14 +510,12 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
|
||||
it("Should be able to append an approved target for an authorized signer.", async () => {
|
||||
// Grant access
|
||||
await smartWallet.grantAccess(signer1Wallet.address, {
|
||||
await account.grantAccess(signer1Wallet.address, {
|
||||
nativeTokenLimitPerTransaction: "1",
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
|
||||
const restrictions = (
|
||||
await smartWallet.getSignersWithRestrictions()
|
||||
).find(
|
||||
const restrictions = (await account.getSignersWithRestrictions()).find(
|
||||
(result) =>
|
||||
utils.getAddress(result.signer) ===
|
||||
utils.getAddress(signer1Wallet.address),
|
||||
@@ -544,14 +532,12 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
);
|
||||
|
||||
// Append approved target
|
||||
await smartWallet.approveTargetForSigner(
|
||||
await account.approveTargetForSigner(
|
||||
signer1Wallet.address,
|
||||
signer2Wallet.address,
|
||||
);
|
||||
|
||||
const newRestrictions = (
|
||||
await smartWallet.getSignersWithRestrictions()
|
||||
).find(
|
||||
const newRestrictions = (await account.getSignersWithRestrictions()).find(
|
||||
(result) =>
|
||||
utils.getAddress(result.signer) ===
|
||||
utils.getAddress(signer1Wallet.address),
|
||||
@@ -575,14 +561,12 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
|
||||
it("Should be able to remove an approved target for an authorized signer.", async () => {
|
||||
// Grant access
|
||||
await smartWallet.grantAccess(signer1Wallet.address, {
|
||||
await account.grantAccess(signer1Wallet.address, {
|
||||
nativeTokenLimitPerTransaction: "1",
|
||||
approvedCallTargets: [adminWallet.address, signer2Wallet.address],
|
||||
});
|
||||
|
||||
const restrictions = (
|
||||
await smartWallet.getSignersWithRestrictions()
|
||||
).find(
|
||||
const restrictions = (await account.getSignersWithRestrictions()).find(
|
||||
(result) =>
|
||||
utils.getAddress(result.signer) ===
|
||||
utils.getAddress(signer1Wallet.address),
|
||||
@@ -604,14 +588,12 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
);
|
||||
|
||||
// Remove approved target
|
||||
await smartWallet.disapproveTargetForSigner(
|
||||
await account.disapproveTargetForSigner(
|
||||
signer1Wallet.address,
|
||||
signer2Wallet.address,
|
||||
);
|
||||
|
||||
const newRestrictions = (
|
||||
await smartWallet.getSignersWithRestrictions()
|
||||
).find(
|
||||
const newRestrictions = (await account.getSignersWithRestrictions()).find(
|
||||
(result) =>
|
||||
utils.getAddress(result.signer) ===
|
||||
utils.getAddress(signer1Wallet.address),
|
||||
@@ -628,7 +610,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
);
|
||||
});
|
||||
|
||||
it("Should be able to set access for the smart wallet in a batch.", async () => {
|
||||
it("Should be able to set access for the account in a batch.", async () => {
|
||||
/**
|
||||
* All cases to test
|
||||
*
|
||||
@@ -661,7 +643,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
signersWithRestrictions.push(restrictionsSigner3);
|
||||
|
||||
// Removing existing admin
|
||||
await smartWallet.grantAdminAccess(signer4Wallet.address);
|
||||
await account.grantAdminAccess(signer4Wallet.address);
|
||||
|
||||
const restrictionsSigner4: SignerWithRestrictionsInput = {
|
||||
signer: signer4Wallet.address,
|
||||
@@ -679,7 +661,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
signersWithRestrictions.push(restrictionsSigner5);
|
||||
|
||||
// Removing an existing scoped signer
|
||||
await smartWallet.grantAccess(signer6Wallet.address, {
|
||||
await account.grantAccess(signer6Wallet.address, {
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
|
||||
@@ -692,7 +674,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
|
||||
// Updating the restrictions of an existing scoped signer
|
||||
|
||||
await smartWallet.grantAccess(signer7Wallet.address, {
|
||||
await account.grantAccess(signer7Wallet.address, {
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
|
||||
@@ -704,7 +686,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
signersWithRestrictions.push(restrictionsSigner7);
|
||||
|
||||
// Existing admin -> new scoped signer (demote)
|
||||
await smartWallet.grantAdminAccess(signer8Wallet.address);
|
||||
await account.grantAdminAccess(signer8Wallet.address);
|
||||
|
||||
const restrictionsSigner8: SignerWithRestrictionsInput = {
|
||||
signer: signer8Wallet.address,
|
||||
@@ -714,7 +696,7 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
signersWithRestrictions.push(restrictionsSigner8);
|
||||
|
||||
// Existing scoped signer -> new admin (promote)
|
||||
await smartWallet.grantAccess(signer9Wallet.address, {
|
||||
await account.grantAccess(signer9Wallet.address, {
|
||||
approvedCallTargets: [adminWallet.address],
|
||||
});
|
||||
|
||||
@@ -726,11 +708,11 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
signersWithRestrictions.push(restrictionsSigner9);
|
||||
|
||||
// Set access in batch
|
||||
await smartWallet.setAccess(signersWithRestrictions);
|
||||
await account.setAccess(signersWithRestrictions);
|
||||
|
||||
// Now checking if permissions are set correctly
|
||||
const signersWithRestrictionsAfter =
|
||||
await smartWallet.getSignersWithRestrictions();
|
||||
await account.getSignersWithRestrictions();
|
||||
|
||||
for (const restrictions of signersWithRestrictionsAfter) {
|
||||
switch (restrictions.signer) {
|
||||
@@ -738,96 +720,96 @@ global.fetch = /* @__PURE__ */ require("cross-fetch");
|
||||
case adminWallet.address:
|
||||
assert.isTrue(
|
||||
restrictions.isAdmin,
|
||||
"Admin wallet should be an admin.",
|
||||
"Admin account should be an admin.",
|
||||
);
|
||||
break;
|
||||
// `signer3Wallet` should be an admin
|
||||
case signer3Wallet.address:
|
||||
assert.isTrue(
|
||||
restrictions.isAdmin,
|
||||
"Signer3 wallet should be an admin.",
|
||||
"Signer3 account should be an admin.",
|
||||
);
|
||||
break;
|
||||
// `signer4Wallet` should not be admin or scoped signer
|
||||
case signer4Wallet.address:
|
||||
assert.isFalse(
|
||||
restrictions.isAdmin,
|
||||
"Signer4 wallet should not be an admin.",
|
||||
"Signer4 account should not be an admin.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.restrictions.approvedCallTargets.length,
|
||||
0,
|
||||
"Signer4 wallet should not have any approved call targets.",
|
||||
"Signer4 account should not have any approved call targets.",
|
||||
);
|
||||
break;
|
||||
// `signer5Wallet` should be a scoped signer
|
||||
case signer5Wallet.address:
|
||||
assert.isFalse(
|
||||
restrictions.isAdmin,
|
||||
"Signer5 wallet should not be an admin.",
|
||||
"Signer5 account should not be an admin.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.restrictions.approvedCallTargets.length,
|
||||
1,
|
||||
"Signer5 wallet should have one approved call target.",
|
||||
"Signer5 account should have one approved call target.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.restrictions.approvedCallTargets[0],
|
||||
adminWallet.address,
|
||||
"Signer5 wallet should have the expected approved call targets.",
|
||||
"Signer5 account should have the expected approved call targets.",
|
||||
);
|
||||
break;
|
||||
// `signer6Wallet` should not be admin or scoped signer
|
||||
case signer6Wallet.address:
|
||||
assert.isFalse(
|
||||
restrictions.isAdmin,
|
||||
"Signer6 wallet should not be an admin.",
|
||||
"Signer6 account should not be an admin.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.restrictions.approvedCallTargets.length,
|
||||
0,
|
||||
"Signer6 wallet should not have any approved call targets.",
|
||||
"Signer6 account should not have any approved call targets.",
|
||||
);
|
||||
break;
|
||||
// `signer7Wallet` should be a scoped signer with its updated restrictions
|
||||
case signer7Wallet.address:
|
||||
assert.isFalse(
|
||||
restrictions.isAdmin,
|
||||
"Signer7 wallet should not be an admin.",
|
||||
"Signer7 account should not be an admin.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.restrictions.approvedCallTargets.length,
|
||||
1,
|
||||
"Signer7 wallet should have one approved call target.",
|
||||
"Signer7 account should have one approved call target.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.restrictions.approvedCallTargets[0],
|
||||
signer1Wallet.address,
|
||||
"Signer7 wallet should have the expected approved call targets.",
|
||||
"Signer7 account should have the expected approved call targets.",
|
||||
);
|
||||
break;
|
||||
// `signer8Wallet` should be a scoped signer
|
||||
case signer8Wallet.address:
|
||||
assert.isFalse(
|
||||
restrictions.isAdmin,
|
||||
"Signer8 wallet should not be an admin.",
|
||||
"Signer8 account should not be an admin.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.restrictions.approvedCallTargets.length,
|
||||
1,
|
||||
"Signer8 wallet should have one approved call target.",
|
||||
"Signer8 account should have one approved call target.",
|
||||
);
|
||||
assert.strictEqual(
|
||||
restrictions.restrictions.approvedCallTargets[0],
|
||||
adminWallet.address,
|
||||
"Signer8 wallet should have the expected approved call targets.",
|
||||
"Signer8 account should have the expected approved call targets.",
|
||||
);
|
||||
break;
|
||||
// `signer9Wallet` should be an admin
|
||||
case signer9Wallet.address:
|
||||
assert.isTrue(
|
||||
restrictions.isAdmin,
|
||||
"Signer9 wallet should be an admin.",
|
||||
"Signer9 account should be an admin.",
|
||||
);
|
||||
break;
|
||||
default:
|
||||
@@ -82,6 +82,7 @@ let signers: SignerWithAddress[];
|
||||
let storage: ThirdwebStorage;
|
||||
let implementations: { [key in ContractType]?: string };
|
||||
let mock_weth_address: string;
|
||||
let thirdwebFactory: TWFactory;
|
||||
|
||||
const fastForwardTime = async (timeInSeconds: number): Promise<void> => {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
@@ -133,6 +134,7 @@ export const mochaHooks = {
|
||||
.connect(signer)
|
||||
.deploy(trustedForwarderAddress, registry.address)) as TWFactory;
|
||||
|
||||
thirdwebFactory = await thirdwebFactoryDeployer.deployed();
|
||||
const deployTxFactory = thirdwebFactoryDeployer.deployTransaction;
|
||||
await deployTxFactory.wait();
|
||||
const thirdwebRegistryAddress = await thirdwebFactoryDeployer.registry();
|
||||
@@ -391,4 +393,5 @@ export {
|
||||
storage,
|
||||
implementations,
|
||||
hardhatEthers,
|
||||
thirdwebFactory,
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import { expect } from "chai";
|
||||
import { Wallet } from "ethers";
|
||||
|
||||
describe("Error Handling", async () => {
|
||||
test.skip("should throw proper error on account with no balance", async () => {
|
||||
it("should throw proper error on account with no balance", async () => {
|
||||
const newSdk = ThirdwebSDK.fromSigner(
|
||||
Wallet.createRandom().connect(sdk.getProvider()),
|
||||
);
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,85 @@
|
||||
// from SplitWallet published at: ipfs://Qmc5cQotuEnCo71ZztJk69wc8kuKbGmuCARL2FyAojoi9r/
|
||||
|
||||
const abi = [
|
||||
{
|
||||
inputs: [],
|
||||
stateMutability: "nonpayable",
|
||||
type: "constructor",
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "Unauthorized",
|
||||
type: "error",
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: true,
|
||||
internalType: "address",
|
||||
name: "split",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
internalType: "uint256",
|
||||
name: "amount",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
name: "ReceiveETH",
|
||||
type: "event",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "contract ERC20",
|
||||
name: "token",
|
||||
type: "address",
|
||||
},
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "amount",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
name: "sendERC20ToMain",
|
||||
outputs: [],
|
||||
stateMutability: "payable",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [
|
||||
{
|
||||
internalType: "uint256",
|
||||
name: "amount",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
name: "sendETHToMain",
|
||||
outputs: [],
|
||||
stateMutability: "payable",
|
||||
type: "function",
|
||||
},
|
||||
{
|
||||
inputs: [],
|
||||
name: "splitMain",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "contract ISplitMain",
|
||||
name: "",
|
||||
type: "address",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
type: "function",
|
||||
},
|
||||
];
|
||||
|
||||
const bytecode =
|
||||
"0x60a060405234801561001057600080fd5b5033606081901b60805261035461004c60003960008181604b0152818160bc015281816101080152818161013c015261018601526103546000f3fe6080604052600436106100345760003560e01c80630e769b2b146100395780637c1f3ffe14610089578063ab0ebff41461009e575b600080fd5b34801561004557600080fd5b5061006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200160405180910390f35b61009c6100973660046102d0565b6100b1565b005b61009c6100ac366004610306565b610131565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146100f9576040516282b42960e81b815260040160405180910390fd5b61012d6001600160a01b0383167f0000000000000000000000000000000000000000000000000000000000000000836101af565b5050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610179576040516282b42960e81b815260040160405180910390fd5b6101ac6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001682610233565b50565b600060405163a9059cbb60e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506101ea81610289565b61022d5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064015b60405180910390fd5b50505050565b600080600080600085875af19050806102845760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401610224565b505050565b60003d8261029b57806000803e806000fd5b80602081146102b35780156102c457600092506102c9565b816000803e600051151592506102c9565b600192505b5050919050565b600080604083850312156102e2578182fd5b82356001600160a01b03811681146102f8578283fd5b946020939093013593505050565b600060208284031215610317578081fd5b503591905056fea26469706673582212208e095a368bcb2efb2a8afd9b560ad94441e926086a4bc92edf16c33900df798e64736f6c63430008040033";
|
||||
|
||||
const deployedBytecode =
|
||||
"0x6080604052600436106100345760003560e01c80630e769b2b146100395780637c1f3ffe14610089578063ab0ebff41461009e575b600080fd5b34801561004557600080fd5b5061006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200160405180910390f35b61009c6100973660046102d0565b6100b1565b005b61009c6100ac366004610306565b610131565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146100f9576040516282b42960e81b815260040160405180910390fd5b61012d6001600160a01b0383167f0000000000000000000000000000000000000000000000000000000000000000836101af565b5050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610179576040516282b42960e81b815260040160405180910390fd5b6101ac6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001682610233565b50565b600060405163a9059cbb60e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506101ea81610289565b61022d5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064015b60405180910390fd5b50505050565b600080600080600085875af19050806102845760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b6044820152606401610224565b505050565b60003d8261029b57806000803e806000fd5b80602081146102b35780156102c457600092506102c9565b816000803e600051151592506102c9565b600192505b5050919050565b600080604083850312156102e2578182fd5b82356001600160a01b03811681146102f8578283fd5b946020939093013593505050565b600060208284031215610317578081fd5b503591905056fea26469706673582212208e095a368bcb2efb2a8afd9b560ad94441e926086a4bc92edf16c33900df798e64736f6c63430008040033";
|
||||
|
||||
export { abi, bytecode, deployedBytecode };
|
||||
File diff suppressed because one or more lines are too long
@@ -20,5 +20,13 @@ export async function mockUploadWithCID(
|
||||
file: FileOrBufferOrString,
|
||||
options?: IpfsUploadBatchOptions | undefined,
|
||||
) {
|
||||
storage[cid] = file;
|
||||
const [cidMain, id] = cid.split("/");
|
||||
|
||||
if (id) {
|
||||
storage[cidMain] = {
|
||||
[id]: file,
|
||||
};
|
||||
} else {
|
||||
storage[cid] = file;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
|
||||
import { jsonProvider, sdk, signers, thirdwebFactory } from "./before-setup";
|
||||
import { expect, assert } from "chai";
|
||||
import {
|
||||
Forwarder__factory,
|
||||
DropERC721__factory,
|
||||
ERC721Base__factory,
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import {
|
||||
bytecode as SplitMainBytecode,
|
||||
deployedBytecode as SplitMainDeployedBytecode,
|
||||
abi as SplitMainAbi,
|
||||
} from "./metadata/SplitMain";
|
||||
import {
|
||||
bytecode as SplitWalletBytecode,
|
||||
deployedBytecode as SplitWalletDeployedBytecode,
|
||||
abi as SplitWalletAbi,
|
||||
} from "./metadata/SplitWallet";
|
||||
import {
|
||||
bytecode as TWCloneFactoryBytecode,
|
||||
abi as TWCloneFactoryAbi,
|
||||
} from "./metadata/TWCloneFactory";
|
||||
import { mockUploadMetadataWithBytecode } from "./utils";
|
||||
|
||||
const extendedMetadataMock = {
|
||||
name: "",
|
||||
metadataUri: "",
|
||||
bytecodeUri: "",
|
||||
analytics: {},
|
||||
version: "1.0.0",
|
||||
displayName: "",
|
||||
description: "",
|
||||
changelog: "",
|
||||
isDeployableViaFactory: false,
|
||||
isDeployableViaProxy: false,
|
||||
factoryDeploymentData: {
|
||||
implementationAddresses: {},
|
||||
implementationInitializerFunction: "initialize",
|
||||
factoryAddresses: {},
|
||||
},
|
||||
constructorParams: {},
|
||||
publisher: "",
|
||||
customFactoryInput: {
|
||||
factoryFunction: "",
|
||||
customFactoryAddresses: [],
|
||||
},
|
||||
};
|
||||
|
||||
describe("New Publish Flow", async () => {
|
||||
let adminWallet: SignerWithAddress,
|
||||
samWallet: SignerWithAddress,
|
||||
bobWallet: SignerWithAddress,
|
||||
w4: SignerWithAddress;
|
||||
|
||||
beforeEach(async () => {
|
||||
await jsonProvider.send("hardhat_reset", []);
|
||||
[adminWallet, samWallet, bobWallet, , , , , w4] = signers;
|
||||
});
|
||||
before("Mock upload infra contracts", async () => {
|
||||
// mock upload Forwarder
|
||||
await mockUploadMetadataWithBytecode(
|
||||
"Forwarder",
|
||||
Forwarder__factory.abi,
|
||||
Forwarder__factory.bytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
deployType: "standard",
|
||||
networksForDeployment: {
|
||||
allNetworks: true,
|
||||
networksEnabled: [],
|
||||
},
|
||||
},
|
||||
"ipfs://Qmcu8FaqerUvQYb4qPg7PwkXa6dRtEe45LedLJPN42Jwqe/0",
|
||||
// ^ we use actual publish uri as mock uri here, because this contract's uri is fetched from publisher by contractName
|
||||
);
|
||||
|
||||
// mock upload TWCloneFactory
|
||||
await mockUploadMetadataWithBytecode(
|
||||
"Forwarder",
|
||||
TWCloneFactoryAbi,
|
||||
TWCloneFactoryBytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
deployType: "standard",
|
||||
networksForDeployment: {
|
||||
allNetworks: true,
|
||||
networksEnabled: [],
|
||||
},
|
||||
},
|
||||
"ipfs://QmYfw13Zykqf9jAmJobNgYrEpatEF9waWcQPUHvJ7sctRb/0",
|
||||
// ^ we use actual publish uri as mock uri here, because this contract's uri is fetched from publisher by contractName
|
||||
);
|
||||
});
|
||||
|
||||
describe("Deploy newly published contract", async () => {
|
||||
it("should deploy regular contract", async () => {
|
||||
// mock publish as a standard-deploy contract
|
||||
const mockPublishUri = await mockUploadMetadataWithBytecode(
|
||||
"ERC721Base",
|
||||
ERC721Base__factory.abi,
|
||||
ERC721Base__factory.bytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
deployType: "standard",
|
||||
networksForDeployment: {
|
||||
allNetworks: true,
|
||||
networksEnabled: [],
|
||||
},
|
||||
publisher: await adminWallet.getAddress(),
|
||||
},
|
||||
);
|
||||
|
||||
// deploy with mock uri
|
||||
const admin = await adminWallet.getAddress();
|
||||
const contractAddress = await sdk.deployer.deployContractFromUri(
|
||||
mockPublishUri,
|
||||
["Direct Deploy ERC721Base", "DDE", admin, 5],
|
||||
);
|
||||
const contract = await sdk.getContract(contractAddress);
|
||||
|
||||
const name = await contract.call("name");
|
||||
const owner = await contract.call("owner");
|
||||
|
||||
expect(name).to.equal("Direct Deploy ERC721Base");
|
||||
expect(owner).to.equal(admin);
|
||||
});
|
||||
|
||||
it("should deploy with custom factory", async () => {
|
||||
// mock publish SplitMain as a standard-deploy contract
|
||||
const splitMainMockUri = await mockUploadMetadataWithBytecode(
|
||||
"SplitMain",
|
||||
SplitMainAbi,
|
||||
SplitMainBytecode,
|
||||
SplitMainDeployedBytecode,
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
deployType: "standard",
|
||||
networksForDeployment: {
|
||||
allNetworks: true,
|
||||
networksEnabled: [],
|
||||
},
|
||||
publisher: await adminWallet.getAddress(),
|
||||
},
|
||||
);
|
||||
|
||||
// deploy custom-factory `SplitMain`, with mock uri
|
||||
const splitMainAddress = await sdk.deployer.deployContractFromUri(
|
||||
splitMainMockUri,
|
||||
[],
|
||||
);
|
||||
|
||||
// mock publish SplitWallet as a custom-factory-deploy contract
|
||||
const splitWalletMockUri = await mockUploadMetadataWithBytecode(
|
||||
"SplitWallet",
|
||||
SplitWalletAbi,
|
||||
SplitWalletBytecode,
|
||||
SplitWalletDeployedBytecode,
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
deployType: "customFactory",
|
||||
factoryDeploymentData: {
|
||||
...extendedMetadataMock.factoryDeploymentData,
|
||||
customFactoryInput: {
|
||||
factoryFunction: "createSplit",
|
||||
params: [],
|
||||
customFactoryAddresses: {
|
||||
"31337": splitMainAddress,
|
||||
},
|
||||
},
|
||||
},
|
||||
networksForDeployment: {
|
||||
allNetworks: true,
|
||||
networksEnabled: [],
|
||||
},
|
||||
publisher: await adminWallet.getAddress(),
|
||||
},
|
||||
);
|
||||
|
||||
// deploy contract via custom-factory, with mock uri
|
||||
const splitWalletAddress = await sdk.deployer.deployContractFromUri(
|
||||
splitWalletMockUri,
|
||||
[
|
||||
[await bobWallet.getAddress(), await adminWallet.getAddress()],
|
||||
[500000, 500000],
|
||||
0,
|
||||
await adminWallet.getAddress(),
|
||||
],
|
||||
);
|
||||
|
||||
const splitContract = await sdk.getContract(splitWalletAddress);
|
||||
const deployingAddress = await splitContract.call("splitMain");
|
||||
|
||||
expect(deployingAddress).to.equal(splitMainAddress);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Deploy re-published contract", async () => {
|
||||
it("should deploy with auto factory", async () => {
|
||||
const mockPublisher = process.env.contractPublisherAddress;
|
||||
process.env.contractPublisherAddress =
|
||||
"0x664244560eBa21Bf82d7150C791bE1AbcD5B4cd7";
|
||||
const adminAddress = await adminWallet.getAddress();
|
||||
|
||||
// mock publish as a autoFactory-deploy contract
|
||||
const mockPublishUri = await mockUploadMetadataWithBytecode(
|
||||
"DropERC721",
|
||||
DropERC721__factory.abi,
|
||||
DropERC721__factory.bytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
deployType: "autoFactory",
|
||||
networksForDeployment: {
|
||||
allNetworks: true,
|
||||
networksEnabled: [],
|
||||
},
|
||||
publisher: adminAddress,
|
||||
},
|
||||
);
|
||||
|
||||
// deploy via autoFactory, with mock uri
|
||||
const contractAddress = await sdk.deployer.deployContractFromUri(
|
||||
mockPublishUri,
|
||||
[
|
||||
adminAddress,
|
||||
"DropERC721 Minimal Proxy",
|
||||
"DME",
|
||||
"",
|
||||
[],
|
||||
adminAddress,
|
||||
adminAddress,
|
||||
5,
|
||||
5,
|
||||
adminAddress,
|
||||
],
|
||||
);
|
||||
const contract = await sdk.getContract(contractAddress);
|
||||
|
||||
const name = await contract.call("name");
|
||||
const owner = await contract.call("owner");
|
||||
const code = await sdk.getProvider().getCode(contractAddress);
|
||||
|
||||
expect(name).to.equal("DropERC721 Minimal Proxy");
|
||||
expect(owner).to.equal(adminAddress);
|
||||
assert(code.startsWith("0x363d3d373d3d3d363d73"));
|
||||
|
||||
process.env.contractPublisherAddress = mockPublisher;
|
||||
});
|
||||
});
|
||||
|
||||
describe("Deploy old contract without re-publishing", async () => {
|
||||
it("should deploy regular contract", async () => {
|
||||
// mock publish as old style -- omit deployType, networksForDeployment etc
|
||||
const mockPublishUri = await mockUploadMetadataWithBytecode(
|
||||
"ERC721Base",
|
||||
ERC721Base__factory.abi,
|
||||
ERC721Base__factory.bytecode,
|
||||
"",
|
||||
extendedMetadataMock,
|
||||
);
|
||||
|
||||
// deploy with mock uri
|
||||
const admin = await adminWallet.getAddress();
|
||||
const contractAddress = await sdk.deployer.deployContractFromUri(
|
||||
mockPublishUri,
|
||||
["Direct Deploy ERC721Base", "DDE", admin, 5],
|
||||
);
|
||||
const contract = await sdk.getContract(contractAddress);
|
||||
|
||||
const name = await contract.call("name");
|
||||
const owner = await contract.call("owner");
|
||||
|
||||
expect(name).to.equal("Direct Deploy ERC721Base");
|
||||
expect(owner).to.equal(admin);
|
||||
});
|
||||
|
||||
it("should deploy via old factory", async () => {
|
||||
const mockPublisher = process.env.contractPublisherAddress;
|
||||
process.env.contractPublisherAddress =
|
||||
"0x664244560eBa21Bf82d7150C791bE1AbcD5B4cd7";
|
||||
const adminAddress = await adminWallet.getAddress();
|
||||
|
||||
// mock publish as old-style factory deployable -- omit deployType, networksForDeployment etc
|
||||
const mockPublishUri = await mockUploadMetadataWithBytecode(
|
||||
"DropERC721",
|
||||
DropERC721__factory.abi,
|
||||
DropERC721__factory.bytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
isDeployableViaFactory: true,
|
||||
publisher: adminAddress,
|
||||
},
|
||||
);
|
||||
|
||||
// deploy implementation
|
||||
const implementationAddress = await sdk.deployer.deployContractFromUri(
|
||||
mockPublishUri,
|
||||
[],
|
||||
{
|
||||
forceDirectDeploy: true,
|
||||
},
|
||||
);
|
||||
await (
|
||||
await thirdwebFactory.addImplementation(implementationAddress)
|
||||
).wait();
|
||||
|
||||
// re-upload, with implementation address
|
||||
const mockPublishUriUpdated = await mockUploadMetadataWithBytecode(
|
||||
"DropERC721",
|
||||
DropERC721__factory.abi,
|
||||
DropERC721__factory.bytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
isDeployableViaFactory: true,
|
||||
factoryDeploymentData: {
|
||||
...extendedMetadataMock?.factoryDeploymentData,
|
||||
implementationAddresses: {
|
||||
"31337": implementationAddress,
|
||||
},
|
||||
factoryAddresses: {
|
||||
"31337": process.env.factoryAddress,
|
||||
},
|
||||
},
|
||||
publisher: adminAddress,
|
||||
},
|
||||
);
|
||||
|
||||
// Deploy proxy DropERC721
|
||||
const contractAddress = await sdk.deployer.deployContractFromUri(
|
||||
mockPublishUriUpdated,
|
||||
[
|
||||
adminAddress,
|
||||
"Drop Proxy Old",
|
||||
"DPA",
|
||||
"",
|
||||
[],
|
||||
adminAddress,
|
||||
adminAddress,
|
||||
5,
|
||||
5,
|
||||
adminAddress,
|
||||
],
|
||||
);
|
||||
|
||||
const drop = await sdk.getContract(contractAddress);
|
||||
const bytecode = await sdk.getProvider().getCode(contractAddress);
|
||||
const name = await drop.call("name");
|
||||
|
||||
expect(name).to.equal("Drop Proxy Old");
|
||||
assert(bytecode.startsWith("0x363d3d373d3d3d363d73"));
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: test any-evm vs standard chain deploys with same publish-uri
|
||||
});
|
||||
@@ -177,7 +177,7 @@ describe("Tiered Drop Contract", async () => {
|
||||
expect(nfts[0].metadata.name).to.equal("NFT #5");
|
||||
});
|
||||
|
||||
test.skip("metadata should reveal correctly", async () => {
|
||||
it("metadata should reveal correctly", async () => {
|
||||
contract = await deployTieredDrop();
|
||||
|
||||
const placeholder = {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { resolveContractUriFromAddress } from "../../src/evm";
|
||||
import {
|
||||
FullPublishMetadata,
|
||||
extractIPFSHashFromBytecode,
|
||||
resolveContractUriFromAddress,
|
||||
} from "../../src/evm";
|
||||
import { defaultProvider } from "./before-setup";
|
||||
import { mockUploadWithCID } from "./mock/MockStorage";
|
||||
import { ContractInterface, ethers } from "ethers";
|
||||
@@ -22,6 +26,8 @@ export const mockUploadContractMetadata = async (
|
||||
contractName: string,
|
||||
address: string,
|
||||
abi: any,
|
||||
extendedMetadata?: FullPublishMetadata | any,
|
||||
publishUri?: string,
|
||||
) => {
|
||||
const ipfsHash = (await resolveContractUriFromAddress(
|
||||
address,
|
||||
@@ -57,11 +63,68 @@ export const mockUploadContractMetadata = async (
|
||||
|
||||
// mock raw-metadata
|
||||
const rawMeta = {
|
||||
...extendedMetadata,
|
||||
name: contractName,
|
||||
metadataUri: ipfsHash,
|
||||
bytecodeUri: bytecodeUri,
|
||||
};
|
||||
const rawMetaUri = ipfsHash.concat("rawMeta");
|
||||
const rawMetaUri = publishUri || ipfsHash.concat("rawMeta");
|
||||
const rawMetaCID = rawMetaUri.replace("ipfs://", "");
|
||||
await mockUploadWithCID(rawMetaCID, JSON.stringify(rawMeta));
|
||||
|
||||
return rawMetaUri;
|
||||
};
|
||||
|
||||
export const mockUploadMetadataWithBytecode = async (
|
||||
contractName: string,
|
||||
abi: any,
|
||||
bytecode: string,
|
||||
deployedBytecode?: string,
|
||||
extendedMetadata?: FullPublishMetadata | any,
|
||||
publishUri?: string,
|
||||
): Promise<string> => {
|
||||
const ipfsHash =
|
||||
deployedBytecode && deployedBytecode.length > 0
|
||||
? (extractIPFSHashFromBytecode(deployedBytecode) as string)
|
||||
: (extractIPFSHashFromBytecode(bytecode) as string);
|
||||
|
||||
const metadata = {
|
||||
compiler: {},
|
||||
output: {
|
||||
abi,
|
||||
devdoc: {},
|
||||
userdoc: {},
|
||||
},
|
||||
settings: {
|
||||
compilationTarget: {
|
||||
contract: contractName,
|
||||
},
|
||||
evmVersion: {},
|
||||
metadata: {},
|
||||
optimizer: {},
|
||||
remappings: [],
|
||||
},
|
||||
sources: {},
|
||||
version: 1,
|
||||
};
|
||||
const metadataCID = ipfsHash.replace("ipfs://", "");
|
||||
await mockUploadWithCID(metadataCID, JSON.stringify(metadata));
|
||||
|
||||
// mock bytecode
|
||||
const bytecodeUri = ipfsHash.concat("bytecode");
|
||||
const bytecodeCID = bytecodeUri.replace("ipfs://", "");
|
||||
await mockUploadWithCID(bytecodeCID, bytecode);
|
||||
|
||||
// mock raw-metadata
|
||||
const rawMeta = {
|
||||
...extendedMetadata,
|
||||
name: contractName,
|
||||
metadataUri: ipfsHash,
|
||||
bytecodeUri: bytecodeUri,
|
||||
};
|
||||
const rawMetaUri = publishUri || ipfsHash.concat("rawMeta");
|
||||
const rawMetaCID = rawMetaUri.replace("ipfs://", "");
|
||||
await mockUploadWithCID(rawMetaCID, JSON.stringify(rawMeta));
|
||||
|
||||
return rawMetaUri;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @thirdweb-dev/storage
|
||||
|
||||
## 1.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1286](https://github.com/thirdweb-dev/js/pull/1286) [`2d088d36`](https://github.com/thirdweb-dev/js/commit/2d088d367ca54233836dc69712fd411ab7924205) Thanks [@jnsdls](https://github.com/jnsdls)! - fix double `//` case
|
||||
|
||||
- [#1278](https://github.com/thirdweb-dev/js/pull/1278) [`8a389f12`](https://github.com/thirdweb-dev/js/commit/8a389f1295d2bf726059997ea0ca10cf0424f2a2) Thanks [@jnsdls](https://github.com/jnsdls)! - updated various dependencies
|
||||
|
||||
- [#1232](https://github.com/thirdweb-dev/js/pull/1232) [`9daf0449`](https://github.com/thirdweb-dev/js/commit/9daf044926bf995ac8998929dbeca548c5eb8561) Thanks [@nessup](https://github.com/nessup)! - Switch over to the new `ipfs.thirdweb-storage.com` public gateway.
|
||||
Better fallback logic for if a gateway is down.
|
||||
Faster loading of files from the default gateway by skipping a roundtrip to redirect.
|
||||
|
||||
- [#1285](https://github.com/thirdweb-dev/js/pull/1285) [`546353a4`](https://github.com/thirdweb-dev/js/commit/546353a479c11533818ef917c0f6b4d6f8f69872) Thanks [@jnsdls](https://github.com/jnsdls)! - add additional fallback gateways
|
||||
|
||||
- [#1287](https://github.com/thirdweb-dev/js/pull/1287) [`0135a779`](https://github.com/thirdweb-dev/js/commit/0135a7790cf2acde6b701cb41ea10dd311da5ec3) Thanks [@jnsdls](https://github.com/jnsdls)! - fix uploaded-check
|
||||
|
||||
## 1.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/storage",
|
||||
"version": "1.1.5",
|
||||
"version": "1.1.6",
|
||||
"main": "dist/thirdweb-dev-storage.cjs.js",
|
||||
"module": "dist/thirdweb-dev-storage.esm.js",
|
||||
"browser": {
|
||||
@@ -43,28 +43,29 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@babel/preset-typescript": "^7.22.5",
|
||||
"@microsoft/api-documenter": "^7.22.21",
|
||||
"@microsoft/api-extractor": "^7.36.0",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@swc-node/register": "^1.5.1",
|
||||
"@preconstruct/cli": "^2.7.0",
|
||||
"@swc-node/register": "^1.6.6",
|
||||
"@thirdweb-dev/tsconfig": "workspace:*",
|
||||
"@types/chai": "^4.3.3",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"chai": "^4.3.6",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"esm": "^3.2.25",
|
||||
"mocha": "^10.2.0",
|
||||
"typescript": "^4.7.4"
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"cross-fetch": "^3.1.5",
|
||||
"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,5 +1,5 @@
|
||||
import { FileOrBufferOrString } from "../types";
|
||||
import { DEFAULT_GATEWAY_URLS } from "./urls";
|
||||
import { DEFAULT_GATEWAY_URLS, getGatewayUrlForCid } from "./urls";
|
||||
import { isBufferOrStringWithName } from "./utils";
|
||||
import fetch from "cross-fetch";
|
||||
import { importer } from "ipfs-unixfs-importer";
|
||||
@@ -67,7 +67,8 @@ export async function getCID(
|
||||
}
|
||||
|
||||
export async function isUploaded(cid: string) {
|
||||
const res = await fetch(`${DEFAULT_GATEWAY_URLS["ipfs://"][0]}${cid}`, {
|
||||
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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { GatewayUrls } from "../types";
|
||||
import CIDTool from "cid-tool";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -6,13 +7,12 @@ import { GatewayUrls } from "../types";
|
||||
export const DEFAULT_GATEWAY_URLS: GatewayUrls = {
|
||||
// Note: Gateway URLs should have trailing slashes (we clean this on user input)
|
||||
"ipfs://": [
|
||||
"https://ipfs-3.thirdwebcdn.com/ipfs/",
|
||||
"https://ipfs-4.thirdwebcdn.com/ipfs/",
|
||||
"https://ipfs-5.thirdwebcdn.com/ipfs/",
|
||||
"https://cloudflare-ipfs.com/ipfs/",
|
||||
"https://ipfs.io/ipfs/",
|
||||
// TODO this one can become the default again once it's stable (no more VT issues)
|
||||
"https://ipfs.thirdwebcdn.com/ipfs/",
|
||||
"https://{cid}.ipfs.thirdwebstorage.com/{path}",
|
||||
"https://{cid}.ipfs.thirdwebipfs.com/{path}",
|
||||
"https://{cid}.ipfs.thirdwebgateway.com/{path}",
|
||||
"https://{cid}.ipfs-public.thirdwebcdn.com/{path}",
|
||||
"https://cloudflare-ipfs.com/ipfs/{cid}/{path}",
|
||||
"https://ipfs.io/ipfs/{cid}/{path}",
|
||||
],
|
||||
};
|
||||
|
||||
@@ -41,6 +41,33 @@ export function parseGatewayUrls(
|
||||
return gatewayUrls || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function getGatewayUrlForCid(gatewayUrl: string, cid: string): string {
|
||||
const parts = cid.split("/");
|
||||
const hash = convertCidToV1(parts[0]);
|
||||
const filePath = parts.slice(1).join("/");
|
||||
|
||||
let url = gatewayUrl;
|
||||
|
||||
// If the URL contains {cid} or {path} tokens, replace them with the CID and path
|
||||
// Both tokens must be present for the URL to be valid
|
||||
if (gatewayUrl.includes("{cid}") && gatewayUrl.includes("{path}")) {
|
||||
url = url.replace("{cid}", hash).replace("{path}", filePath);
|
||||
}
|
||||
// If the URL contains only the {cid} token, replace it with the CID
|
||||
else if (gatewayUrl.includes("{cid}")) {
|
||||
url = url.replace("{cid}", hash);
|
||||
}
|
||||
// If those tokens don't exist, use the canonical gateway URL format
|
||||
else {
|
||||
url += `${hash}/${filePath}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@@ -53,9 +80,11 @@ export function prepareGatewayUrls(gatewayUrls?: GatewayUrls): GatewayUrls {
|
||||
for (const key of Object.keys(DEFAULT_GATEWAY_URLS)) {
|
||||
if (gatewayUrls && gatewayUrls[key]) {
|
||||
// Make sure that all user gateway URLs have trailing slashes
|
||||
const cleanedGatewayUrls = gatewayUrls[key].map(
|
||||
(url) => url.replace(/\/$/, "") + "/",
|
||||
const cleanedGatewayUrls = gatewayUrls[key].map((url) =>
|
||||
// don't add trailing slash if the URL contains {path} token
|
||||
url.includes("{path}") ? url : url.replace(/\/$/, "") + "/",
|
||||
);
|
||||
|
||||
allGatewayUrls[key] = [
|
||||
...cleanedGatewayUrls,
|
||||
...DEFAULT_GATEWAY_URLS[key],
|
||||
@@ -65,3 +94,17 @@ export function prepareGatewayUrls(gatewayUrls?: GatewayUrls): GatewayUrls {
|
||||
|
||||
return allGatewayUrls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function convertCidToV1(cid: string) {
|
||||
let normalized: string;
|
||||
try {
|
||||
const hash = cid.split("/")[0];
|
||||
normalized = CIDTool.base32(hash);
|
||||
} catch (e) {
|
||||
throw new Error(`The CID ${cid} is not valid.`);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { BufferOrStringWithName, FileOrBuffer, GatewayUrls } from "../types";
|
||||
import { getGatewayUrlForCid } from "./urls";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -85,6 +86,29 @@ export function isFileBufferOrStringEqual(input1: any, input2: any): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function parseCidAndPath(
|
||||
gatewayUrl: string,
|
||||
uri: string,
|
||||
): { hash?: string; path?: string; query?: string } | undefined {
|
||||
const regexString = gatewayUrl
|
||||
.replace("{cid}", "(?<hash>[^/]+)")
|
||||
.replace("{path}", "(?<path>[^?#]+)");
|
||||
|
||||
const regex = new RegExp(regexString);
|
||||
const match = uri.match(regex);
|
||||
|
||||
if (match) {
|
||||
const hash = match.groups?.hash;
|
||||
const path = match.groups?.path;
|
||||
const queryString = uri.includes("?") ? uri.substring(uri.indexOf("?") + 1) : "";
|
||||
|
||||
return { hash, path, query: queryString };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@@ -93,9 +117,21 @@ export function replaceGatewayUrlWithScheme(
|
||||
gatewayUrls: GatewayUrls,
|
||||
): string {
|
||||
for (const scheme of Object.keys(gatewayUrls)) {
|
||||
for (const url of gatewayUrls[scheme]) {
|
||||
if (uri.startsWith(url)) {
|
||||
return uri.replace(url, scheme);
|
||||
for (const gatewayUrl of gatewayUrls[scheme]) {
|
||||
// If the url is a tokenized url, we need to convert it to a canonical url
|
||||
// Otherwise, we just need to check if the url is a prefix of the uri
|
||||
if (gatewayUrl.includes("{cid}")) {
|
||||
// Given the url is a tokenized url, we need to lift the cid and the path from the uri
|
||||
const parsed = parseCidAndPath(gatewayUrl, uri);
|
||||
if (parsed?.hash && parsed?.path) {
|
||||
const queryString = parsed?.query ? `?${parsed?.query}` : "";
|
||||
return `${scheme}${parsed?.hash}/${parsed?.path}${queryString}`;
|
||||
} else {
|
||||
// If we can't lift the cid and path from the uri, we can't replace the gateway url, return the orig string
|
||||
return uri;
|
||||
}
|
||||
} else if (uri.startsWith(gatewayUrl)) {
|
||||
return uri.replace(gatewayUrl, scheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,7 +158,8 @@ export function replaceSchemeWithGatewayUrl(
|
||||
return uri;
|
||||
}
|
||||
|
||||
return uri.replace(scheme, schemeGatewayUrls[index]);
|
||||
const path = uri.replace(scheme, "");
|
||||
return getGatewayUrlForCid(schemeGatewayUrls[index], path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,18 +33,39 @@ export class StorageDownloader implements IStorageDownloader {
|
||||
throw new Error(
|
||||
"[FAILED_TO_DOWNLOAD_ERROR] Unable to download from URI - all gateway URLs failed to respond.",
|
||||
);
|
||||
} else if (attempts > 0) {
|
||||
console.warn(`Retrying download with backup gateway URL: ${resolvedUri}`);
|
||||
}
|
||||
|
||||
const res = await fetch(resolvedUri);
|
||||
const resOrErr = await fetch(resolvedUri).catch((err) => err);
|
||||
|
||||
if (resOrErr.ok) {
|
||||
return resOrErr;
|
||||
}
|
||||
|
||||
// can't use instanceof "Response" in node...
|
||||
if ("status" in resOrErr) {
|
||||
if (resOrErr.status === 410 || resOrErr.status === 403) {
|
||||
// Don't retry if the content is blocklisted
|
||||
console.error(
|
||||
`Request to ${resolvedUri} failed because this content seems to be blocklisted. Search VirusTotal for this URL to confirm: ${resolvedUri} `,
|
||||
);
|
||||
return resOrErr;
|
||||
}
|
||||
|
||||
// If request to the current gateway fails, recursively try the next one we know about
|
||||
if (res.status >= 500 || res.status === 403 || res.status === 408) {
|
||||
console.warn(
|
||||
`Request to ${resolvedUri} failed with status ${res.status} - ${res.statusText}`,
|
||||
`Request to ${resolvedUri} failed with status ${resOrErr.status} - ${resOrErr.statusText}`,
|
||||
);
|
||||
return this.download(uri, gatewayUrls, attempts + 1);
|
||||
|
||||
// Don't retry if we see 408 or < 500 status codes that are likely to be resolved by trying another gateway
|
||||
if (resOrErr.status !== 408 && resOrErr.status < 500) {
|
||||
return resOrErr;
|
||||
}
|
||||
} else {
|
||||
console.warn(`Request to ${resolvedUri} failed with error`, resOrErr);
|
||||
}
|
||||
|
||||
return res;
|
||||
// Since the current gateway failed, recursively try the next one we know about
|
||||
return this.download(uri, gatewayUrls, attempts + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user