Compare commits

...
Author SHA1 Message Date
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>GitHub Action
2e12c769f9 Version Packages (#2600)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <[email protected]>
2024-04-02 18:18:07 +02:00
Manan TankandGitHub d89f009f14 feat: Wallet connection improvements (#2632) 2024-04-02 16:04:34 +00:00
Joaquim VergesandGitHub 1c29556f14 refactor: get userOp gas prices from bundler (#2631) 2024-04-02 15:15:01 +00:00
15697ae741 chore(chains): update chains (#2629)
Co-authored-by: GitHub Action <[email protected]>
2024-04-02 02:01:58 -07:00
Jonas DanielsandGitHub d2ffb82071 refactor: Update import statement for AutoConnect in ConnectWallet.tsx (#2628) 2024-04-02 00:58:10 -07:00
Jonas DanielsandGitHub e8063936c9 fix(WalletConnectConnection): fix wallet connect uri parsing (#2626) 2024-04-01 22:38:20 -07:00
0394eb22bf feat: add ERC4337 account / factory extensions (#2606)
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-02 01:38:38 +00:00
+2 7234e6bc10 [SDK] Native privateKeyAccount implementation (#2525)
Signed-off-by: Joaquim Verges <[email protected]>
Signed-off-by: jxom  <[email protected]>
Signed-off-by: greg <[email protected]>
Signed-off-by: Jonas Daniels <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: GitHub Action <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
Co-authored-by: Manan Tank <[email protected]>
Co-authored-by: jxom <[email protected]>
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Winston Yeo <[email protected]>
Co-authored-by: iketw <[email protected]>
Co-authored-by: Winston Yeo <[email protected]>
Co-authored-by: Isaac Dubuque <[email protected]>
2024-04-01 18:27:35 -07:00
Jonas DanielsandGitHub 26a50b1e05 chore: update depdendencies (#2623) 2024-04-01 15:41:52 -07:00
Joaquim VergesandGitHub 00be583b89 chore(v4): get gas price from bundler for userOps (#2622) 2024-04-01 22:19:38 +00:00
Jonas DanielsandGitHub 8c9def769c feat: add turbo build and update-version commands to release script (#2621) 2024-04-01 13:47:06 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Jonas Daniels
213f313034 build(deps): bump viem from 2.9.5 to 2.9.6 (#2610)
Signed-off-by: dependabot[bot] <[email protected]>
Signed-off-by: Jonas Daniels <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-01 13:22:41 -07:00
3aaad1e9bf [SDK] generateWallet utility function (#2602)
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-01 09:59:01 -07:00
55848db4ea chore(chains): update chains (#2605)
Co-authored-by: GitHub Action <[email protected]>
2024-04-01 09:58:37 -07:00
Jonas DanielsandGitHub 0c83897f62 test: add erc20 approve test (#2596) 2024-03-30 18:12:12 -07:00
Jonas DanielsandGitHub b6a6eae3cc chore(tests): skip tests that will fail without secret key set (#2604) 2024-03-30 16:58:28 -07:00
f7b45fa04e chore(chains): update chains (#2601)
Co-authored-by: GitHub Action <[email protected]>
2024-03-30 16:57:35 -07:00
82e5f53bc4 chore(chains): update chains (#2597)
Co-authored-by: GitHub Action <[email protected]>
2024-03-30 06:34:10 -07:00
Joaquim VergesandGitHub 13c3083ac4 Update README.md (#2599)
Signed-off-by: Joaquim Verges <[email protected]>
2024-03-29 21:12:36 -07:00
155 changed files with 3792 additions and 1464 deletions
+5 -4
View File
@@ -19,6 +19,7 @@ env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TW_SECRET_KEY: ${{ secrets.TW_SECRET_KEY }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
jobs:
build:
@@ -118,9 +119,9 @@ jobs:
- run: pnpm test
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
files: ./packages/thirdweb/coverage/lcov.info
directory: ./legacy_packages
test_legacy:
timeout-minutes: 15
@@ -154,9 +155,9 @@ jobs:
- run: pnpm test:legacy
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
files: ./legacy_packages/sdk/coverage/evm/lcov.info
directory: ./legacy_packages
e2e:
timeout-minutes: 15
+2 -18
View File
@@ -18,9 +18,6 @@
<p align="center"><strong>All-in-one web3 SDK for Browser, Node and Mobile apps</strong></p>
> [!IMPORTANT]
> We rewrote the thirdweb SDK from scratch for performance! Head over to the [v5 SDK](https://github.com/thirdweb-dev/js/tree/main/packages/thirdweb).
## Features
- Support for React & React-Native
@@ -53,19 +50,6 @@
| React Native Hooks | ✅ | ❌ | ❌ | ❌ |
| React Native UI Components | ✅ | ❌ | ❌ | ❌ |
## Packages
| Package | Description |
| ----------------------------------------------- | --------------------------------------------------------------------------- |
| [/sdk](./legacy_packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps |
| [/wallets](./legacy_packages/wallets) | Unified web3 Wallet library to integrate any wallet into your applications. |
| [/react](./legacy_packages/react) | Ultimate collection of React hooks for your web3 apps |
| [/react-native](./legacy_packages/react-native) | Ultimate collection of React hooks for your native mobile web3 apps |
| [/auth](./legacy_packages/auth) | Best in class wallet authentication for Node backends |
| [/storage](./legacy_packages/storage) | Best in class decentralized storage SDK for Browser and Node |
| [/cli](./legacy_packages/cli) | Publish and deploy smart contracts without dealing with private keys |
| [/chains](./legacy_packages/chains) | All EVM chain information as JS objects for easy handling |
## Contributing
We welcome contributions from all developers regardless of experience level. If you are interested in contributing, please read our [Contributing Guide](.github/contributing.md) to learn how the repo works, how to test your changes, and how to submit a pull request.
@@ -74,9 +58,9 @@ See our [open source page](https://thirdweb.com/open-source) for more informatio
## Additional Resources
- [SDK Documentation](https://portal.thirdweb.com/typescript/v5)
- [Documentation](https://portal.thirdweb.com/typescript/v5)
- [Templates](https://thirdweb.com/templates)
- [YouTube](https://www.youtube.com/c/thirdweb_)
- [YouTube](https://www.youtube.com/c/thirdweb)
## Support
+7
View File
@@ -1,5 +1,12 @@
# @thirdweb-dev/auth
## 4.1.53
### Patch Changes
- Updated dependencies [[`00be583`](https://github.com/thirdweb-dev/js/commit/00be583b8902a1a0e5382ffdaafa6b9e31316075)]:
- @thirdweb-dev/wallets@2.4.31
## 4.1.52
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "4.1.52",
"version": "4.1.53",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
+1 -1
View File
@@ -6,7 +6,7 @@ import { describe, it, beforeAll, beforeEach, expect } from "vitest";
// eslint-disable-next-line @typescript-eslint/no-var-requires
require("dotenv-mono").load();
describe(
describe.runIf(process.env.TW_SECRET_KEY)(
"Wallet Authentication - EVM",
{
timeout: 60000,
@@ -7,7 +7,7 @@ import { describe, it, beforeEach, beforeAll, expect } from "vitest";
// eslint-disable-next-line @typescript-eslint/no-var-requires
require("dotenv-mono").load();
describe(
describe.runIf(process.env.TW_SECRET_KEY)(
"Wallet Authentication - EVM - Smart Wallet",
{
timeout: 60000,
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/chains
## 0.1.86
### Patch Changes
- [#2597](https://github.com/thirdweb-dev/js/pull/2597) [`82e5f53`](https://github.com/thirdweb-dev/js/commit/82e5f53bc49208cbc43ef3eb64e3a4b6ef6c7cf6) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
## 0.1.85
### Patch Changes
+2 -1
View File
@@ -46,7 +46,8 @@ export default {
"https://evm.humans.stakepool.dev.br",
"https://mainnet-humans-evm.konsortech.xyz",
"https://evm-rpc.mainnet.humans.zone",
"https://json-rpc.humans.bh.rocks"
"https://json-rpc.humans.bh.rocks",
"https://evm-rpc.humans.huginn.tech"
],
"shortName": "humans",
"slug": "humans-ai",
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 11227,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "Jiritsu Testnet",
"nativeCurrency": {
"name": "Jiritsu Testnet Token",
"symbol": "TZW",
"decimals": 18
},
"networkId": 11227,
"redFlags": [],
"rpc": [
"https://11227.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/jiritsutes/testnet/rpc"
],
"shortName": "Jiritsu Testnet",
"slug": "jiritsu-testnet",
"testnet": true
} as const satisfies Chain;
+5 -5
View File
@@ -11,8 +11,8 @@ export default {
"height": 300,
"format": "png"
},
"infoURL": "https://raas.gelato.network/rollups/details/public/op-celestia-testnet",
"name": "Gelato OP Celestia",
"infoURL": "https://raas.gelato.network/rollups/details/public/opcelestia-raspberry",
"name": "OP Celestia Rasberry",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
@@ -21,8 +21,8 @@ export default {
"networkId": 123420111,
"redFlags": [],
"rpc": [],
"shortName": "opcelestia",
"slug": "gelato-op-celestia",
"shortName": "opcelestia-rasberry",
"slug": "op-celestia-rasberry",
"testnet": true,
"title": "Gelato OP Celestia Testnet"
"title": "OP Celestia Rasberry"
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 12781,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "playdapp Testnet",
"nativeCurrency": {
"name": "playdapp Testnet Token",
"symbol": "PDA",
"decimals": 18
},
"networkId": 12781,
"redFlags": [],
"rpc": [
"https://12781.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/playdappte/testnet/rpc"
],
"shortName": "playdapp Testnet",
"slug": "playdapp-testnet",
"testnet": true
} as const satisfies Chain;
+12 -2
View File
@@ -2,9 +2,19 @@ import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 13396,
"explorers": [],
"explorers": [
{
"name": "Masa Explorer",
"url": "https://subnets.avax.network/masa",
"standard": "EIP3091"
}
],
"faucets": [],
"features": [],
"features": [
{
"name": "EIP1559"
}
],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 26031,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser7894 Testnet",
"nativeCurrency": {
"name": "QaUser7894 Testnet Token",
"symbol": "YUT",
"decimals": 18
},
"networkId": 26031,
"redFlags": [],
"rpc": [
"https://26031.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser7894 Testnet",
"slug": "qauser7894-testnet",
"testnet": true
} as const satisfies Chain;
+46
View File
@@ -0,0 +1,46 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 282828,
"explorers": [
{
"name": "zillscout",
"url": "https://sepolia.zillnet.io",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmfVmjLNiBh8KyCr9mwDZh34aEhhQ2LAjuP87DFxhfd9nn",
"width": 264,
"height": 264,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmfVmjLNiBh8KyCr9mwDZh34aEhhQ2LAjuP87DFxhfd9nn",
"width": 264,
"height": 264,
"format": "png"
},
"infoURL": "https://zillnet.io",
"name": "Zillion Sepolia Testnet",
"nativeCurrency": {
"name": "Sepolia Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 282828,
"parent": {
"type": "L2",
"chain": "eip155-11155111"
},
"rpc": [
"https://282828.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://sepolia.zillnet.io/rpc"
],
"shortName": "zillsep",
"slip44": 1,
"slug": "zillion-sepolia-testnet",
"status": "active",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 40868,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser5110 Testnet",
"nativeCurrency": {
"name": "QaUser5110 Testnet Token",
"symbol": "CRL",
"decimals": 18
},
"networkId": 40868,
"redFlags": [],
"rpc": [
"https://40868.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser5110 Testnet",
"slug": "qauser5110-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 54763,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser3051 Testnet",
"nativeCurrency": {
"name": "QaUser3051 Testnet Token",
"symbol": "DSX",
"decimals": 18
},
"networkId": 54763,
"redFlags": [],
"rpc": [
"https://54763.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser3051 Testnet",
"slug": "qauser3051-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 555666,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "EclipseChain Testnet",
"nativeCurrency": {
"name": "EclipseChain Testnet Token",
"symbol": "ECLPS",
"decimals": 18
},
"networkId": 555666,
"redFlags": [],
"rpc": [
"https://555666.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/eclipsecha/testnet/rpc"
],
"shortName": "EclipseChain Testnet",
"slug": "eclipsechain-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 57973,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser5524 Testnet",
"nativeCurrency": {
"name": "QaUser5524 Testnet Token",
"symbol": "ADN",
"decimals": 18
},
"networkId": 57973,
"redFlags": [],
"rpc": [
"https://57973.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser5524 Testnet",
"slug": "qauser5524-testnet",
"testnet": true
} as const satisfies Chain;
+28
View File
@@ -0,0 +1,28 @@
import type { Chain } from "../src/types";
export default {
"chain": "BounceBit",
"chainId": 6000,
"explorers": [
{
"name": "BBScan Testnet Explorer",
"url": "https://bbscan.io",
"standard": "none"
}
],
"faucets": [],
"infoURL": "https://bouncebit.io",
"name": "BounceBit Testnet",
"nativeCurrency": {
"name": "BounceBit",
"symbol": "BB",
"decimals": 18
},
"networkId": 6000,
"rpc": [
"https://6000.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://fullnode-testnet.bouncebitapi.com/"
],
"shortName": "bouncebit-testnet",
"slug": "bouncebit-testnet",
"testnet": true
} as const satisfies Chain;
+1 -1
View File
@@ -10,7 +10,7 @@ export default {
},
{
"name": "Astar zkEVM Testnet zKyoto",
"url": "hhttps://zkyoto.explorer.startale.com/",
"url": "https://zkyoto.explorer.startale.com",
"standard": "EIP3091"
}
],
+52
View File
@@ -0,0 +1,52 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 70700,
"explorers": [
{
"name": "Proof of Play Apex Explorer",
"url": "https://explorer.apex.proofofplay.com",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmW3NPDe6WRqucrWbe8pg3GqSMPi8V6Qa1fAiaQuqjxSJC",
"width": 1256,
"height": 1256,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmW3NPDe6WRqucrWbe8pg3GqSMPi8V6Qa1fAiaQuqjxSJC",
"width": 1256,
"height": 1256,
"format": "png"
},
"infoURL": "https://proofofplay.com",
"name": "Proof of Play - Apex",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 70700,
"parent": {
"type": "L2",
"chain": "eip155-42161",
"bridges": [
{
"url": "https://bridge.arbitrum.io"
},
{
"url": "https://relay.link/bridge/apex/"
}
]
},
"rpc": [
"https://70700.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.apex.proofofplay.com"
],
"shortName": "pop-apex",
"slug": "proof-of-play-apex",
"testnet": false
} as const satisfies Chain;
+44
View File
@@ -0,0 +1,44 @@
import type { Chain } from "../src/types";
export default {
"chain": "OEX",
"chainId": 7798,
"explorers": [
{
"name": "OpenEX Long Testnet Explorer",
"url": "https://scan.long.openex.network",
"standard": "EIP3091",
"icon": {
"url": "ipfs://bafkreidnu6p6vmmplerzvkboq7fz73ygkomzpnnokuxstrqv2fvxgmgg7i",
"width": 512,
"height": 512,
"format": "png"
}
}
],
"faucets": [
"https://long.hub.openex.network/faucet"
],
"icon": {
"url": "ipfs://bafkreidnu6p6vmmplerzvkboq7fz73ygkomzpnnokuxstrqv2fvxgmgg7i",
"width": 512,
"height": 512,
"format": "png"
},
"infoURL": "https://openex.network",
"name": "OpenEX LONG Testnet",
"nativeCurrency": {
"name": "USDT Testnet",
"symbol": "USDT",
"decimals": 18
},
"networkId": 7798,
"rpc": [
"https://7798.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://long.rpc.openex.network/"
],
"shortName": "oex",
"slip44": 1,
"slug": "openex-long-testnet",
"testnet": true,
"title": "OpenEX LONG Testnet"
} as const satisfies Chain;
+7 -22
View File
@@ -2,19 +2,7 @@ import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 88153591557,
"explorers": [
{
"name": "blockscout",
"url": "https://gelato-orbit-anytrust-testnet.blockscout.com/",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmQXw4QEDR4AbUwX9scH7aGhiSDhQRxu6LCQoUkgsYgGyK/Gelato%20brand%20mark.png",
"width": 300,
"height": 300,
"format": "png"
}
}
],
"explorers": [],
"faucets": [],
"features": [],
"icon": {
@@ -23,8 +11,8 @@ export default {
"height": 300,
"format": "png"
},
"infoURL": "https://raas.gelato.network/rollups/details/public/gelato-orbit-anytrust-testnet",
"name": "Gelato Orbit Anytrust",
"infoURL": "https://raas.gelato.network/rollups/details/public/arb-blueberry",
"name": "Arbitrum Blueberry",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
@@ -32,12 +20,9 @@ export default {
},
"networkId": 88153591557,
"redFlags": [],
"rpc": [
"https://88153591557.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.gelato-orbit-anytrust-testnet.gelato.digital"
],
"shortName": "orbitanytrust",
"slug": "gelato-orbit-anytrust",
"rpc": [],
"shortName": "arb-blueberry",
"slug": "arbitrum-blueberry",
"testnet": true,
"title": "Gelato Orbit Anytrust Testnet"
"title": "Arbitrum Blueberry"
} as const satisfies Chain;
+42
View File
@@ -0,0 +1,42 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 94204209,
"explorers": [
{
"name": "blockscout",
"url": "https://polygon-blackberry.gelatoscout.com/",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmYotcuJYjUBXZ33CYoWMyNnJbjK14f8ma6sge55Z5bg5W/polygon-blackberry.svg",
"width": 300,
"height": 300,
"format": "svg"
}
}
],
"faucets": [],
"features": [],
"icon": {
"url": "ipfs://QmYotcuJYjUBXZ33CYoWMyNnJbjK14f8ma6sge55Z5bg5W/polygon-blackberry.svg",
"width": 300,
"height": 300,
"format": "svg"
},
"infoURL": "https://raas.gelato.network/rollups/details/public/polygon-blackberry",
"name": "Polygon Blackberry",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 94204209,
"redFlags": [],
"rpc": [
"https://94204209.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.polygon-blackberry.gelato.digital"
],
"shortName": "polygon-blackberry",
"slug": "polygon-blackberry",
"testnet": true
} as const satisfies Chain;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.85",
"version": "0.1.86",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"exports": {
File diff suppressed because one or more lines are too long
+13
View File
@@ -1,5 +1,18 @@
# thirdweb
## 0.13.61
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
- Updated dependencies [[`00be583`](https://github.com/thirdweb-dev/js/commit/00be583b8902a1a0e5382ffdaafa6b9e31316075), [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19), [`82e5f53`](https://github.com/thirdweb-dev/js/commit/82e5f53bc49208cbc43ef3eb64e3a4b6ef6c7cf6)]:
- @thirdweb-dev/wallets@2.4.31
- @thirdweb-dev/sdk@4.0.55
- @thirdweb-dev/chains@0.1.86
- @thirdweb-dev/auth@4.1.53
- @thirdweb-dev/storage@2.0.13
## 0.13.60
### Patch Changes
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/cli",
"main": "dist/cli/index.js",
"version": "0.13.60",
"version": "0.13.61",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -15,7 +15,7 @@
"@types/cross-spawn": "^6.0.6",
"@types/inquirer": "^8.2.10",
"@types/js-yaml": "^4.0.9",
"@types/node": "20.11.30",
"@types/node": "20.12.2",
"@types/prompts": "^2.4.9",
"@types/tar": "^6.1.11",
"@types/update-notifier": "^6.0.8",
@@ -1,5 +1,11 @@
# @thirdweb-dev/contracts-js
## 1.3.20
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
## 1.3.19
### Patch Changes
+2 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/contracts-js",
"version": "1.3.19",
"version": "1.3.20",
"main": "dist/thirdweb-dev-contracts-js.cjs.js",
"module": "dist/thirdweb-dev-contracts-js.esm.js",
"exports": {
@@ -355,7 +355,6 @@
"./dist/abis/IPlatformFee.json": "./dist/abis/IPlatformFee.json",
"./dist/abis/Base64.json": "./dist/abis/Base64.json",
"./dist/abis/ProxyForUpgradeable.json": "./dist/abis/ProxyForUpgradeable.json",
"./dist/abis/Helpers.json": "./dist/abis/Helpers.json",
"./dist/abis/StringSet.json": "./dist/abis/StringSet.json",
"./dist/abis/VRFV2WrapperConsumerBase.json": "./dist/abis/VRFV2WrapperConsumerBase.json",
"./dist/abis/ITokenERC1155.json": "./dist/abis/ITokenERC1155.json",
@@ -425,7 +424,7 @@
"license": "Apache-2.0",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/contracts-js",
"dependencies": {
"@thirdweb-dev/contracts": "3.12.1"
"@thirdweb-dev/contracts": "3.13.0"
},
"devDependencies": {
"@ethersproject/abi": "^5.7.0",
+8
View File
@@ -1,5 +1,13 @@
# @thirdweb-dev/crypto
## 0.2.4
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
- [#2610](https://github.com/thirdweb-dev/js/pull/2610) [`213f313`](https://github.com/thirdweb-dev/js/commit/213f31303409698d93e5da6eea22df6833512107) Thanks [@dependabot](https://github.com/apps/dependabot)! - build(deps): bump viem from 2.9.5 to 2.9.6
## 0.2.3
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/crypto",
"version": "0.2.3",
"version": "0.2.4",
"main": "dist/thirdweb-dev-crypto.cjs.js",
"module": "dist/thirdweb-dev-crypto.esm.js",
"exports": {
@@ -37,10 +37,10 @@
"crypto-js": "^4.2.0",
"eslint-config-thirdweb": "workspace:*",
"ethers": "^5.7.2",
"js-awe": "^1.0.64",
"js-awe": "^1.0.65",
"tinybench": "^2.6.0",
"typescript": "5.4.3",
"viem": "2.9.5"
"viem": "2.9.6"
},
"scripts": {
"format": "prettier --write 'src/**/*'",
+7
View File
@@ -1,5 +1,12 @@
# @thirdweb-dev/merkletree
## 0.2.4
### Patch Changes
- Updated dependencies [[`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19), [`213f313`](https://github.com/thirdweb-dev/js/commit/213f31303409698d93e5da6eea22df6833512107)]:
- @thirdweb-dev/crypto@0.2.4
## 0.2.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/merkletree",
"version": "0.2.3",
"version": "0.2.4",
"main": "dist/thirdweb-dev-merkletree.cjs.js",
"module": "dist/thirdweb-dev-merkletree.esm.js",
"exports": {
+11
View File
@@ -1,5 +1,16 @@
# @thirdweb-dev/react-core
## 4.4.29
### Patch Changes
- Updated dependencies [[`00be583`](https://github.com/thirdweb-dev/js/commit/00be583b8902a1a0e5382ffdaafa6b9e31316075), [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19), [`82e5f53`](https://github.com/thirdweb-dev/js/commit/82e5f53bc49208cbc43ef3eb64e3a4b6ef6c7cf6)]:
- @thirdweb-dev/wallets@2.4.31
- @thirdweb-dev/sdk@4.0.55
- @thirdweb-dev/chains@0.1.86
- @thirdweb-dev/auth@4.1.53
- @thirdweb-dev/storage@2.0.13
## 4.4.28
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "4.4.28",
"version": "4.4.29",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -1,5 +1,11 @@
# @thirdweb-dev/react-native-compat
## 0.7.26
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
## 0.7.25
## 0.7.24
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/react-native-compat",
"description": "Shims for Thirdweb in React Native Projects",
"version": "0.7.25",
"version": "0.7.26",
"author": "thirdweb eng <[email protected]>",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native-compat",
"license": "Apache-2.0",
@@ -22,7 +22,7 @@
},
"dependencies": {
"@ethersproject/shims": "^5.7.0",
"@walletconnect/react-native-compat": "2.9.2",
"@walletconnect/react-native-compat": "2.11.3",
"base-64": "^1.0.0",
"big-integer": "^1.6.52",
"react-native-get-random-values": "^1.11.0",
@@ -35,7 +35,7 @@
},
"devDependencies": {
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/node": "20.11.30",
"@types/node": "20.12.2",
"babel-plugin-module-resolver": "^5.0.0",
"eslint-config-thirdweb": "workspace:*",
"ethers": "^5.7.2",
+13
View File
@@ -1,5 +1,18 @@
# @thirdweb-dev/react-native
## 0.7.26
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
- Updated dependencies [[`00be583`](https://github.com/thirdweb-dev/js/commit/00be583b8902a1a0e5382ffdaafa6b9e31316075), [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19), [`82e5f53`](https://github.com/thirdweb-dev/js/commit/82e5f53bc49208cbc43ef3eb64e3a4b6ef6c7cf6)]:
- @thirdweb-dev/wallets@2.4.31
- @thirdweb-dev/sdk@4.0.55
- @thirdweb-dev/chains@0.1.86
- @thirdweb-dev/react-core@4.4.29
- @thirdweb-dev/storage@2.0.13
## 0.7.25
### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-native",
"version": "0.7.25",
"version": "0.7.26",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -38,14 +38,14 @@
"@thirdweb-dev/wallets": "workspace:*",
"abitype": "1.0.0",
"aws-amplify": "^5.3.18",
"expo-application": "5.7.0",
"expo-application": "5.8.3",
"expo-clipboard": "^4.8.0",
"expo-document-picker": "^11.10.1",
"expo-file-system": "^15.9.0",
"expo-secure-store": "^12.8.1",
"react-native-modal": "^13.0.1",
"react-native-qrcode-svg": "6.2.0",
"react-native-svg": "^13.14.0",
"react-native-qrcode-svg": "6.3.0",
"react-native-svg": "15.1.0",
"secrets.js-34r7h": "^2.0.2",
"tiny-invariant": "^1.3.3"
},
+13
View File
@@ -1,5 +1,18 @@
# @thirdweb-dev/react
## 4.4.29
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
- Updated dependencies [[`00be583`](https://github.com/thirdweb-dev/js/commit/00be583b8902a1a0e5382ffdaafa6b9e31316075), [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19), [`82e5f53`](https://github.com/thirdweb-dev/js/commit/82e5f53bc49208cbc43ef3eb64e3a4b6ef6c7cf6)]:
- @thirdweb-dev/wallets@2.4.31
- @thirdweb-dev/sdk@4.0.55
- @thirdweb-dev/chains@0.1.86
- @thirdweb-dev/react-core@4.4.29
- @thirdweb-dev/payments@1.0.3
## 4.4.28
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "4.4.28",
"version": "4.4.29",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -102,9 +102,9 @@
"dependencies": {
"@emotion/css": "11.10.5",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.0",
"@emotion/styled": "11.11.0",
"@google/model-viewer": "^2.1.1",
"@headlessui/react": "1.7.6",
"@headlessui/react": "1.7.18",
"@radix-ui/colors": "^0.1.9",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-focus-scope": "^1.0.4",
Binary file not shown.
+13
View File
@@ -1,5 +1,18 @@
# @thirdweb-dev/sdk
## 4.0.55
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
- Updated dependencies [[`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19), [`213f313`](https://github.com/thirdweb-dev/js/commit/213f31303409698d93e5da6eea22df6833512107), [`82e5f53`](https://github.com/thirdweb-dev/js/commit/82e5f53bc49208cbc43ef3eb64e3a4b6ef6c7cf6)]:
- @thirdweb-dev/contracts-js@1.3.20
- @thirdweb-dev/crypto@0.2.4
- @thirdweb-dev/chains@0.1.86
- @thirdweb-dev/merkletree@0.2.4
- @thirdweb-dev/storage@2.0.13
## 4.0.54
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/sdk",
"version": "4.0.54",
"version": "4.0.55",
"description": "The main thirdweb SDK.",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/sdk",
"license": "Apache-2.0",
@@ -89,7 +89,7 @@
"@types/chai": "^4.3.14",
"@types/deep-equal-in-any-order": "^1.0.3",
"@types/mocha": "^10.0.6",
"@types/node": "20.11.30",
"@types/node": "20.12.2",
"@types/uuid": "^9.0.8",
"chai": "^4.4.1",
"deep-equal-in-any-order": "^1.1.20",
@@ -129,7 +129,7 @@
}
},
"dependencies": {
"@eth-optimism/sdk": "3.2.2",
"@eth-optimism/sdk": "3.2.3",
"@thirdweb-dev/chains": "workspace:*",
"@thirdweb-dev/contracts-js": "workspace:*",
"@thirdweb-dev/crypto": "workspace:*",
Binary file not shown.
+7
View File
@@ -1,5 +1,12 @@
# @thirdweb-dev/storage
## 2.0.13
### Patch Changes
- Updated dependencies [[`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19), [`213f313`](https://github.com/thirdweb-dev/js/commit/213f31303409698d93e5da6eea22df6833512107)]:
- @thirdweb-dev/crypto@0.2.4
## 2.0.12
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/storage",
"version": "2.0.12",
"version": "2.0.13",
"main": "dist/thirdweb-dev-storage.cjs.js",
"module": "dist/thirdweb-dev-storage.esm.js",
"exports": {
File diff suppressed because it is too large Load Diff
+12
View File
@@ -1,5 +1,17 @@
# @thirdweb-dev/wallets
## 2.4.31
### Patch Changes
- [#2622](https://github.com/thirdweb-dev/js/pull/2622) [`00be583`](https://github.com/thirdweb-dev/js/commit/00be583b8902a1a0e5382ffdaafa6b9e31316075) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Get gas price from bundler for userOperations
- Updated dependencies [[`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19), [`213f313`](https://github.com/thirdweb-dev/js/commit/213f31303409698d93e5da6eea22df6833512107), [`82e5f53`](https://github.com/thirdweb-dev/js/commit/82e5f53bc49208cbc43ef3eb64e3a4b6ef6c7cf6)]:
- @thirdweb-dev/contracts-js@1.3.20
- @thirdweb-dev/crypto@0.2.4
- @thirdweb-dev/sdk@4.0.55
- @thirdweb-dev/chains@0.1.86
## 2.4.30
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/wallets",
"version": "2.4.30",
"version": "2.4.31",
"main": "dist/thirdweb-dev-wallets.cjs.js",
"module": "dist/thirdweb-dev-wallets.esm.js",
"browser": {
@@ -15,6 +15,7 @@ import {
import { Transaction, getDynamicFeeData } from "@thirdweb-dev/sdk";
import { HttpRpcClient } from "./http-rpc-client";
import type { BaseApiParams, PaymasterAPI, UserOpOptions } from "../types";
import { isTwUrl } from "../../../utils/url";
const DUMMY_SIGNATURE =
"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c";
@@ -191,24 +192,34 @@ export abstract class BaseAccountAPI {
tx.encode(),
);
let { maxFeePerGas, maxPriorityFeePerGas } = info;
if (!maxFeePerGas || !maxPriorityFeePerGas) {
const feeData = await getDynamicFeeData(
this.provider as providers.JsonRpcProvider,
// get fees from bundler if available
if (isTwUrl(httpRpcClient.bundlerUrl)) {
const bundlerFeeData = await httpRpcClient.getUserOperationGasPrice();
maxFeePerGas = BigNumber.from(bundlerFeeData.maxFeePerGas);
maxPriorityFeePerGas = BigNumber.from(
bundlerFeeData.maxPriorityFeePerGas,
);
if (!maxPriorityFeePerGas) {
maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? undefined;
}
if (!maxFeePerGas) {
maxFeePerGas = feeData.maxFeePerGas ?? undefined;
const network = await this.provider.getNetwork();
const chainId = network.chainId;
} else {
// if bundler is not available, try to get fees from the network if not passed explicitly
if (!maxFeePerGas || !maxPriorityFeePerGas) {
const feeData = await getDynamicFeeData(
this.provider as providers.JsonRpcProvider,
);
if (!maxPriorityFeePerGas) {
maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? undefined;
}
if (!maxFeePerGas) {
maxFeePerGas = feeData.maxFeePerGas ?? undefined;
const network = await this.provider.getNetwork();
const chainId = network.chainId;
if (
chainId === Celo.chainId ||
chainId === CeloAlfajoresTestnet.chainId ||
chainId === CeloBaklavaTestnet.chainId
) {
maxPriorityFeePerGas = maxFeePerGas;
if (
chainId === Celo.chainId ||
chainId === CeloAlfajoresTestnet.chainId ||
chainId === CeloBaklavaTestnet.chainId
) {
maxPriorityFeePerGas = maxFeePerGas;
}
}
}
}
@@ -134,6 +134,17 @@ export class HttpRpcClient {
);
}
async getUserOperationGasPrice(): Promise<{
maxFeePerGas: string;
maxPriorityFeePerGas: string;
}> {
await this.initializing;
return await this.userOpJsonRpcProvider.send(
"thirdweb_getUserOperationGasPrice",
[],
);
}
async getUserOperationReceipt(userOpHash: string): Promise<any> {
await this.initializing;
return await this.userOpJsonRpcProvider.send(
+4 -4
View File
@@ -27,7 +27,7 @@
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"changeset": "changeset",
"version-packages": "changeset version",
"release": "node ./scripts/pre-release.mjs && changeset publish",
"release": "node ./scripts/pre-release.mjs && turbo run update-version && turbo run build && changeset publish",
"version-packages:nightly": "node scripts/pre-nightly.mjs && changeset version --snapshot nightly",
"release:nightly": "node ./scripts/pre-release.mjs && turbo run update-version && turbo run build && changeset publish --tag nightly",
"version-packages:next": "node scripts/pre-nightly.mjs && changeset version --snapshot next",
@@ -49,10 +49,10 @@
"@manypkg/get-packages": "2.2.1",
"@playwright/test": "1.31.2",
"@trivago/prettier-plugin-sort-imports": "4.3.0",
"@types/node": "20.11.30",
"@types/node": "20.12.2",
"eslint": "8.57.0",
"prettier": "3.2.5",
"turbo": "1.13.0",
"turbo": "1.13.1",
"yalc": "1.0.0-pre.53"
},
"_______ALL_PACKAGE_DEV_DEPENDENCIES_GO_IN_HERE_SO_CONSUMERS_DONT_END_UP_INSTALLING_THEM______": "_______ALL_PACKAGE_DEV_DEPENDENCIES_GO_IN_HERE_SO_CONSUMERS_DONT_END_UP_INSTALLING_THEM______",
@@ -60,7 +60,7 @@
"@codspeed/vitest-plugin": "3.1.0",
"@size-limit/preset-big-lib": "11.1.2",
"@tanstack/eslint-plugin-query": "5.28.6",
"@types/bun": "1.0.11",
"@types/bun": "1.0.12",
"@types/react": "18.2.17",
"@viem/anvil": "0.0.9",
"@vitest/coverage-v8": "1.4.0",
@@ -1,5 +1,11 @@
# eslint-config-thirdweb
## 0.1.8
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
## 0.1.7
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "eslint-config-thirdweb",
"version": "0.1.7",
"version": "0.1.8",
"main": "index.js",
"license": "Apache-2.0",
"dependencies": {
@@ -8,7 +8,7 @@
"@typescript-eslint/parser": "7.4.0",
"eslint-config-next": "13.4.12",
"eslint-config-prettier": "9.1.0",
"eslint-config-turbo": "1.13.0",
"eslint-config-turbo": "1.13.1",
"eslint-plugin-react": "7.34.1"
},
"publishConfig": {
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/service-utils
## 0.4.25
### Patch Changes
- [#2623](https://github.com/thirdweb-dev/js/pull/2623) [`26a50b1`](https://github.com/thirdweb-dev/js/commit/26a50b1e0591529748fb3f0d3fb7cd2ffcc47f19) Thanks [@jnsdls](https://github.com/jnsdls)! - update depdendencies
## 0.4.24
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/service-utils",
"version": "0.4.24",
"version": "0.4.25",
"main": "dist/thirdweb-dev-service-utils.cjs.js",
"module": "dist/thirdweb-dev-service-utils.esm.js",
"exports": {
@@ -43,10 +43,10 @@
"zod": "3.22.4"
},
"devDependencies": {
"@cloudflare/workers-types": "4.20240320.1",
"@cloudflare/workers-types": "4.20240329.0",
"@preconstruct/cli": "2.7.0",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/node": "20.11.30",
"@types/node": "20.12.2",
"eslint": "8.57.0",
"eslint-config-thirdweb": "workspace:*",
"typescript": "5.4.3"
+23
View File
@@ -1,5 +1,28 @@
# thirdweb
## 5.1.0
### Minor Changes
- [#2602](https://github.com/thirdweb-dev/js/pull/2602) [`3aaad1e`](https://github.com/thirdweb-dev/js/commit/3aaad1e9bfa978139a4c2092e17d2b93193bb890) Thanks [@gregfromstl](https://github.com/gregfromstl)! - Adds generateAccount function for generating a random local account
### Patch Changes
- [#2525](https://github.com/thirdweb-dev/js/pull/2525) [`7234e6b`](https://github.com/thirdweb-dev/js/commit/7234e6bc10e9d410b991f76d126e978a77fa203f) Thanks [@gregfromstl](https://github.com/gregfromstl)! - Better private-key account support
- [#2626](https://github.com/thirdweb-dev/js/pull/2626) [`e806393`](https://github.com/thirdweb-dev/js/commit/e8063936c91724e540bd7a20c90e480a1f86dabe) Thanks [@jnsdls](https://github.com/jnsdls)! - fix wallet connect uri parsing
- [#2632](https://github.com/thirdweb-dev/js/pull/2632) [`d89f009`](https://github.com/thirdweb-dev/js/commit/d89f009f14fc3500a05dcc21f6b7f688dfe81db4) Thanks [@MananTank](https://github.com/MananTank)! - Various Improvements for wallet connection
- change `accountsChanged` event to `accountChanged` event and emit new `Account` object instead of creating it in the connection manager
- WalletConnect connection improvements
- [#2610](https://github.com/thirdweb-dev/js/pull/2610) [`213f313`](https://github.com/thirdweb-dev/js/commit/213f31303409698d93e5da6eea22df6833512107) Thanks [@dependabot](https://github.com/apps/dependabot)! - build(deps): bump viem from 2.9.5 to 2.9.6
- [#2606](https://github.com/thirdweb-dev/js/pull/2606) [`0394eb2`](https://github.com/thirdweb-dev/js/commit/0394eb22bf5256e8e66c664834c0e7e8fe638bb4) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add ERC4337 extensions
- [#2631](https://github.com/thirdweb-dev/js/pull/2631) [`1c29556`](https://github.com/thirdweb-dev/js/commit/1c29556f146b7c8ea28ed193b4d04e7099a9363e) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Get userOp prices from bundler
## 5.0.3
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "thirdweb",
"version": "5.0.3",
"version": "5.1.0",
"repository": {
"type": "git",
"url": "git+https://github.com/thirdweb-dev/js.git#main"
@@ -191,7 +191,7 @@
"mipd": "0.0.7",
"node-libs-browser": "2.2.1",
"uqr": "0.1.2",
"viem": "2.9.5"
"viem": "2.9.6"
},
"peerDependencies": {
"ethers": "^5 || ^6",
@@ -225,7 +225,7 @@
"push": "yalc push",
"size": "size-limit",
"test:watch": "vitest -c ./test/vitest.config.ts dev",
"test": "CI=true vitest -c ./test/vitest.config.ts --coverage --bail=1",
"test": "vitest run -c ./test/vitest.config.ts --coverage --bail=1",
"test:cov": "vitest dev -c ./test/vitest.config.ts --coverage",
"test:dev": "vitest dev -c ./test/vitest.config.ts",
"typedoc": "node scripts/typedoc.mjs",
@@ -0,0 +1,53 @@
import { describe, test, expect, beforeAll } from "vitest";
import { privateKeyAccount } from "../wallets/private-key.js";
import { TEST_CLIENT } from "../../test/src/test-clients.js";
import { viemAdapter } from "./viem.js";
import { defineChain } from "../chains/utils.js";
import type { WalletClient } from "viem";
import { typedData } from "~test/typed-data.js";
import { ANVIL_PKEY_A } from "~test/test-wallets.js";
const account = privateKeyAccount({
privateKey: ANVIL_PKEY_A,
client: TEST_CLIENT,
});
describe("walletClient.toViem", () => {
let walletClient: WalletClient;
beforeAll(() => {
walletClient = viemAdapter.walletClient.toViem({
client: TEST_CLIENT,
account,
chain: defineChain(31337),
});
});
test("should return an viem wallet client", async () => {
expect(walletClient).toBeDefined();
expect(walletClient.signMessage).toBeDefined();
});
test("should sign typed data", async () => {
expect(walletClient.signTypedData).toBeDefined();
if (!walletClient.account) {
throw new Error("Account not found");
}
const signature = await walletClient.signTypedData({
...typedData.basic,
primaryType: "Mail",
account: walletClient.account,
});
expect(signature).toMatchInlineSnapshot(
`"0x32f3d5975ba38d6c2fba9b95d5cbed1febaa68003d3d588d51f2de522ad54117760cfc249470a75232552e43991f53953a3d74edf6944553c6bef2469bb9e5921b"`,
);
});
test("should contain a local account", async () => {
expect(walletClient.account?.type).toBe("local");
});
});
+23 -3
View File
@@ -4,19 +4,22 @@ import {
type GetContractReturnType,
type PublicClient,
type Chain as ViemChain,
type Account as ViemAccount,
type WalletClient,
createWalletClient,
custom,
type TransactionSerializableEIP1559,
} from "viem";
import { getContract, type ThirdwebContract } from "../contract/contract.js";
import type { Abi } from "abitype";
import type { Abi, Address } from "abitype";
import type { Chain } from "../chains/types.js";
import type { ThirdwebClient } from "../client/client.js";
import { resolveContractAbi } from "../contract/actions/resolve-abi.js";
import { getRpcUrlForChain } from "../chains/utils.js";
import type { Account } from "../wallets/interfaces/wallet.js";
import { type Account, getAccountKey } from "../wallets/interfaces/wallet.js";
import { getRpcClient } from "../rpc/rpc.js";
import { secp256k1 } from "@noble/curves/secp256k1";
import { toHex } from "../utils/encoding/hex.js";
export const viemAdapter = {
contract: {
@@ -214,9 +217,26 @@ function toViemWalletClient(options: ToViemWalletClientOptions): WalletClient {
},
});
// viem defaults to JsonRpcAccounts so we pass the whole account if it's locally generated
let viemAccountOrAddress: ViemAccount | Address;
const possibleAccountKey = getAccountKey(account);
if (possibleAccountKey && account.signTransaction) {
viemAccountOrAddress = {
...account,
signTransaction: account.signTransaction,
source: "custom",
type: "local" as const,
publicKey: toHex(
secp256k1.getPublicKey(possibleAccountKey.slice(2), false),
),
};
} else {
viemAccountOrAddress = account.address;
}
return createWalletClient({
transport,
account: account.address,
account: viemAccountOrAddress,
chain: viemChain,
key: "thirdweb-wallet",
});
@@ -12,7 +12,9 @@ import { prepareAutoFactoryDeployTransaction } from "./deploy-via-autofactory.js
import { initialize } from "../../extensions/prebuilts/__generated__/DropERC721/write/initialize.js";
import { getDeployedInfraContract } from "./utils/infra.js";
describe("deployFromMetadata", () => {
// skip this test suite if there is no secret key available to test with
// TODO: remove reliance on secret key during unit tests entirely
describe.runIf(process.env.TW_SECRET_KEY)("deployFromMetadata", () => {
it("should deploy published contract with existing infra", async () => {
const cloneFactoryContract = await getDeployedCloneFactoryContract({
chain: FORKED_ETHEREUM_CHAIN,
@@ -7,7 +7,9 @@ import { getDeployedCreate2Factory } from "./create-2-factory.js";
import { getDeployedInfraContract } from "./infra.js";
import { fail } from "assert";
describe("bootstrap", () => {
// skip this test suite if there is no secret key available to test with
// TODO: remove reliance on secret key during unit tests entirely
describe.runIf(process.env.TW_SECRET_KEY)("bootstrap", () => {
it("should bootstrap onchain infra", async () => {
await deployCloneFactory({
chain: ANVIL_CHAIN,
@@ -7,7 +7,9 @@ import {
import { transferEvent } from "../../extensions/erc721/__generated__/IERC721A/events/Transfer.js";
import { prepareEvent } from "../prepare-event.js";
describe("getEvents", () => {
// skip this test suite if there is no secret key available to test with
// TODO: remove reliance on secret key during unit tests entirely
describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
it("should get all events", async () => {
const events = await getContractEvents({
contract: USDC_CONTRACT,
+3
View File
@@ -18,3 +18,6 @@ export {
type ERC1155ContractType,
deployERC1155Contract,
} from "../extensions/prebuilts/deploy-erc1155.js";
export { prepareDirectDeployTransaction } from "../contract/deployment/deploy-with-abi.js";
export { deployViaAutoFactory } from "../contract/deployment/deploy-via-autofactory.js";
@@ -0,0 +1,60 @@
// ACCOUNT
export {
type AddAdminOptions,
addAdmin,
} from "../../extensions/erc4337/account/addAdmin.js";
export {
type RemoveAdminOptions,
removeAdmin,
} from "../../extensions/erc4337/account/removeAdmin.js";
export {
type AddSessionKeyOptions,
addSessionKey,
} from "../../extensions/erc4337/account/addSessionKey.js";
export {
type RemoveSessionKeyOptions,
removeSessionKey,
} from "../../extensions/erc4337/account/removeSessionKey.js";
export { getAllActiveSigners } from "../../extensions/erc4337/__generated__/IAccountPermissions/read/getAllActiveSigners.js";
export { getAllAdmins } from "../../extensions/erc4337/__generated__/IAccountPermissions/read/getAllAdmins.js";
export { getAllSigners } from "../../extensions/erc4337/__generated__/IAccountPermissions/read/getAllSigners.js";
export {
getPermissionsForSigner,
type GetPermissionsForSignerParams,
} from "../../extensions/erc4337/__generated__/IAccountPermissions/read/getPermissionsForSigner.js";
export {
isActiveSigner,
type IsActiveSignerParams,
} from "../../extensions/erc4337/__generated__/IAccountPermissions/read/isActiveSigner.js";
export { isAdmin } from "../../extensions/erc4337/__generated__/IAccountPermissions/read/isAdmin.js";
export { adminUpdatedEvent } from "../../extensions/erc4337/__generated__/IAccountPermissions/events/AdminUpdated.js";
export { signerPermissionsUpdatedEvent } from "../../extensions/erc4337/__generated__/IAccountPermissions/events/SignerPermissionsUpdated.js";
// FACTORY
export { getAllAccounts } from "../../extensions/erc4337/__generated__/IAccountFactory/read/getAllAccounts.js";
export {
getAccountsOfSigner,
type GetAccountsOfSignerParams,
} from "../../extensions/erc4337/__generated__/IAccountFactory/read/getAccountsOfSigner.js";
export {
getAddress as predictAccountAddress,
type GetAddressParams as PredictAccountAddressParams,
} from "../../extensions/erc4337/__generated__/IAccountFactory/read/getAddress.js";
// ENTRYPOINT
export { accountDeployedEvent } from "../../extensions/erc4337/__generated__/IEntryPoint/events/AccountDeployed.js";
export { userOperationEventEvent } from "../../extensions/erc4337/__generated__/IEntryPoint/events/UserOperationEvent.js";
export { userOperationRevertReasonEvent } from "../../extensions/erc4337/__generated__/IEntryPoint/events/UserOperationRevertReason.js";
export {
getUserOpHash,
type GetUserOpHashParams,
} from "../../extensions/erc4337/__generated__/IEntryPoint/read/getUserOpHash.js";
export {
simulateHandleOp,
type SimulateHandleOpParams,
} from "../../extensions/erc4337/__generated__/IEntryPoint/write/simulateHandleOp.js";
@@ -108,6 +108,7 @@ export {
type SimulateOptions,
} from "../transaction/actions/simulate.js";
export { waitForReceipt } from "../transaction/actions/wait-for-tx-receipt.js";
export { signTransaction } from "../transaction/actions/sign-transaction.js";
/**
* EVENTS
@@ -43,6 +43,10 @@ export {
simulateTransaction,
type SimulateOptions,
} from "../transaction/actions/simulate.js";
export {
signTransaction,
type SignTransactionOptions,
} from "../transaction/actions/sign-transaction.js";
//types & utils
export {
+10
View File
@@ -27,6 +27,16 @@ export {
resolveSignature,
resolveSignatures,
} from "../utils/signatures/resolve-signature.js";
export { type SignOptions, sign } from "../utils/signatures/sign.js";
export { signatureToHex } from "../utils/signatures/signature-to-hex.js";
export {
type SignMessageOptions,
signMessage,
} from "../utils/signatures/sign-message.js";
export {
type SignTypedDataOptions,
signTypedData,
} from "../utils/signatures/sign-typed-data.js";
// ------------------------------------------------
// encoding
+6
View File
@@ -8,14 +8,20 @@ export {
export type { Wallet, Account } from "../wallets/interfaces/wallet.js";
export type { ConnectionStatus } from "../wallets/manager/index.js";
// utils
export {
getWalletBalance,
type GetWalletBalanceOptions,
} from "../wallets/utils/getWalletBalance.js";
export {
generateAccount,
type GenerateAccountOptions,
} from "../wallets/utils/generateAccount.js";
// private-key
export {
privateKeyAccount,
privateKeyToAccount,
type PrivateKeyAccountOptions,
} from "../wallets/private-key.js";
@@ -13,4 +13,4 @@ export type {
LocalWalletLoadOrCreateOptions,
LocalWalletSaveOptions,
LocalWalletStorageData,
} from "../../wallets/local/types._ts";
} from "../../wallets/local/types._ts";
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
import { getContractMetadata } from "./getContractMetadata.js";
import { USDC_CONTRACT } from "../../../../test/src/test-contracts.js";
describe("shared.getContractMetadata", () => {
describe.runIf(process.env.TW_SECRET_KEY)("shared.getContractMetadata", () => {
it("should return the correct contract metadata", async () => {
const metadata = await getContractMetadata({
contract: USDC_CONTRACT,
@@ -2,7 +2,9 @@ import { describe, it, expect } from "vitest";
import { resolveAddress } from "./resolve-address.js";
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
describe("ENS", () => {
// skip this test suite if there is no secret key available to test with
// TODO: remove reliance on secret key during unit tests entirely
describe.runIf(process.env.TW_SECRET_KEY)("ENS", () => {
it("should resolve ENS", async () => {
const name = "vitalik.eth";
const address = await resolveAddress({
@@ -3,7 +3,7 @@ import { describe, it, expect } from "vitest";
import { DROP1155_CONTRACT } from "../../../../../test/src/test-contracts.js";
import { getActiveClaimCondition } from "./getActiveClaimCondition.js";
describe("erc1155.getClaimConditions", () => {
describe.runIf(process.env.TW_SECRET_KEY)("erc1155.getClaimConditions", () => {
it("should return the correct claim conditions", async () => {
const cc = await getActiveClaimCondition({
contract: DROP1155_CONTRACT,
@@ -3,8 +3,8 @@ import { describe, it, expect } from "vitest";
import { getNFT } from "./getNFT.js";
import { DROP1155_CONTRACT } from "~test/test-contracts.js";
describe("erc1155.getNFT", () => {
it.runIf(process.env.TW_SECRET_KEY)("without owner", async () => {
describe.runIf(process.env.TW_SECRET_KEY)("erc1155.getNFT", () => {
it("without owner", async () => {
const nft = await getNFT({
contract: DROP1155_CONTRACT,
tokenId: 2n,
@@ -4,7 +4,7 @@ import { getBalance } from "./getBalance.js";
import { USDC_CONTRACT } from "~test/test-contracts.js";
import { VITALIK_WALLET } from "~test/addresses.js";
describe("erc20.getBalance", () => {
describe.runIf(process.env.TW_SECRET_KEY)("erc20.getBalance", () => {
it("should return the getBalance result", async () => {
const balance = await getBalance({
contract: USDC_CONTRACT,
@@ -0,0 +1,21 @@
import { it, expect } from "vitest";
import { approve } from "./approve.js";
import { USDC_CONTRACT } from "~test/test-contracts.js";
import { VITALIK_WALLET } from "~test/addresses.js";
import { estimateGas } from "../../../transaction/actions/estimate-gas.js";
it.runIf(process.env.TW_SECRET_KEY)(
"estimates erc20 approval gas correctly",
async () => {
const transaction = approve({
contract: USDC_CONTRACT,
amount: 100,
spender: VITALIK_WALLET,
});
const result = await estimateGas({
transaction,
from: VITALIK_WALLET,
});
expect(result).toMatchInlineSnapshot(`55937n`);
},
);
@@ -0,0 +1,50 @@
import type { BaseTransactionOptions } from "../../../transaction/types.js";
import type { Account } from "../../../wallets/interfaces/wallet.js";
import { setPermissionsForSigner } from "../__generated__/IAccountPermissions/write/setPermissionsForSigner.js";
import { defaultPermissionsForAdmin, signPermissionRequest } from "./common.js";
export type AddAdminOptions = {
/**
* The admin account that will perform the operation.
*/
account: Account;
/**
* The address to add as an admin.
*/
adminAddress: string;
};
/**
* Adds admin permissions for a specified address.
* @param options - The options for the addAdmin function.
* @returns The transaction object to be sent.
* @example
* ```
* import { addAdmin } from 'thirdweb/extensions/erc4337';
*
* const transaction = addAdmin({
* contract,
* account,
* adminAddress: '0x...'
* });
* await sendTransaction({ transaction, account });
* ```
* @extension ERC4337
*/
export function addAdmin(options: BaseTransactionOptions<AddAdminOptions>) {
const { contract, account, adminAddress } = options;
return setPermissionsForSigner({
contract,
async asyncParams() {
const { req, signature } = await signPermissionRequest({
account,
contract,
req: await defaultPermissionsForAdmin({
target: adminAddress,
action: "add-admin",
}),
});
return { signature, req };
},
});
}
@@ -0,0 +1,63 @@
import type { BaseTransactionOptions } from "../../../transaction/types.js";
import type { Account } from "../../../wallets/interfaces/wallet.js";
import { setPermissionsForSigner } from "../__generated__/IAccountPermissions/write/setPermissionsForSigner.js";
import { signPermissionRequest, toContractPermissions } from "./common.js";
import type { AccountPermissions } from "./types.js";
export type AddSessionKeyOptions = {
/**
* The adming account that will perform the operation.
*/
account: Account;
/**
* The address to add as a session key.
*/
sessionKeyAddress: string;
/**
* The permissions to assign to the session key.
*/
permissions: AccountPermissions;
};
/**
* Adds session key permissions for a specified address.
* @param options - The options for the removeSessionKey function.
* @returns The transaction object to be sent.
* @example
* ```
* import { addSessionKey } from 'thirdweb/extensions/erc4337';
*
* const transaction = addSessionKey({
* contract,
* account,
* sessionKeyAddress,
* permissions: {
* approvedTargets: ['0x...'],
* nativeTokenLimitPerTransaction: 0.1, // in ETH
* permissionStartTimestamp: new Date(),
* permissionEndTimestamp: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
* }
* });
* await sendTransaction({ transaction, account });
* ```
* @extension ERC4337
*/
export function addSessionKey(
options: BaseTransactionOptions<AddSessionKeyOptions>,
) {
const { contract, sessionKeyAddress, account, permissions } = options;
return setPermissionsForSigner({
contract,
async asyncParams() {
const { req, signature } = await signPermissionRequest({
account,
contract,
req: await toContractPermissions({
target: sessionKeyAddress,
permissions,
}),
});
return { signature, req };
},
});
}
@@ -0,0 +1,82 @@
import { ADDRESS_ZERO } from "../../../constants/addresses.js";
import type { ThirdwebContract } from "../../../contract/contract.js";
import { dateToSeconds, tenYearsFromNow } from "../../../utils/date.js";
import { toWei } from "../../../utils/units.js";
import { randomBytes32 } from "../../../utils/uuid.js";
import type { Account } from "../../../wallets/interfaces/wallet.js";
import type { SetPermissionsForSignerParams } from "../__generated__/IAccountPermissions/write/setPermissionsForSigner.js";
import { SignerPermissionRequest, type AccountPermissions } from "./types.js";
/**
* @internal
*/
export async function signPermissionRequest(options: {
account: Account;
contract: ThirdwebContract;
req: SetPermissionsForSignerParams["req"];
}) {
const { account, contract, req } = options;
const signature = await account.signTypedData({
domain: {
name: "Account",
version: "1",
verifyingContract: contract.address,
chainId: contract.chain.id,
},
primaryType: "SignerPermissionRequest",
types: { SignerPermissionRequest },
message: req,
});
return { req, signature };
}
/**
* @internal
*/
export async function toContractPermissions(options: {
target: string;
permissions: AccountPermissions;
}): Promise<SetPermissionsForSignerParams["req"]> {
const { target, permissions } = options;
return {
approvedTargets:
permissions.approvedTargets === "*"
? [ADDRESS_ZERO]
: permissions.approvedTargets,
nativeTokenLimitPerTransaction: toWei(
permissions.nativeTokenLimitPerTransaction?.toString() || "0",
),
permissionStartTimestamp: dateToSeconds(
permissions.permissionStartTimestamp || new Date(0),
),
permissionEndTimestamp: dateToSeconds(
permissions.permissionEndTimestamp || tenYearsFromNow(),
),
reqValidityStartTimestamp: 0n,
reqValidityEndTimestamp: dateToSeconds(tenYearsFromNow()),
uid: await randomBytes32(),
isAdmin: 0, // session key flag
signer: target,
};
}
/**
* @internal
*/
export async function defaultPermissionsForAdmin(options: {
target: string;
action: "add-admin" | "remove-admin";
}): Promise<SetPermissionsForSignerParams["req"]> {
const { target, action } = options;
return {
approvedTargets: [],
nativeTokenLimitPerTransaction: 0n,
permissionStartTimestamp: 0n,
permissionEndTimestamp: 0n,
reqValidityStartTimestamp: 0n,
reqValidityEndTimestamp: dateToSeconds(tenYearsFromNow()),
uid: await randomBytes32(),
isAdmin: action === "add-admin" ? 1 : action === "remove-admin" ? 2 : 0,
signer: target,
};
}
@@ -0,0 +1,148 @@
import { beforeAll, describe, expect, it } from "vitest";
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
import {
TEST_ACCOUNT_A,
TEST_ACCOUNT_B,
} from "../../../../test/src/test-wallets.js";
import { ENTRYPOINT_ADDRESS } from "../../../wallets/smart/lib/constants.js";
import { getOrDeployInfraContract } from "../../../contract/deployment/utils/bootstrap.js";
import { createAccount } from "../__generated__/IAccountFactory/write/createAccount.js";
import { sendAndConfirmTransaction } from "../../../transaction/actions/send-and-confirm-transaction.js";
import {
getContract,
type ThirdwebContract,
} from "../../../contract/contract.js";
import { simulateTransaction } from "../../../transaction/actions/simulate.js";
import { addAdmin } from "./addAdmin.js";
import { getAllAdmins } from "../__generated__/IAccountPermissions/read/getAllAdmins.js";
import { removeAdmin } from "./removeAdmin.js";
import { getAllSigners } from "../__generated__/IAccountPermissions/read/getAllSigners.js";
import { addSessionKey } from "./addSessionKey.js";
import { parseEventLogs } from "../../../event/actions/parse-logs.js";
import { adminUpdatedEvent } from "../__generated__/IAccountPermissions/events/AdminUpdated.js";
import { signerPermissionsUpdatedEvent } from "../__generated__/IAccountPermissions/events/SignerPermissionsUpdated.js";
import { ADDRESS_ZERO } from "../../../constants/addresses.js";
describe.todo("Account Permissions", () => {
let accountFactoryContract: ThirdwebContract;
let accountContract: ThirdwebContract;
beforeAll(async () => {
// TODO stub response to not fetch from registry
accountFactoryContract = await getOrDeployInfraContract({
account: TEST_ACCOUNT_A,
chain: ANVIL_CHAIN,
client: TEST_CLIENT,
contractId: "AccountFactory",
constructorParams: [TEST_ACCOUNT_A.address, ENTRYPOINT_ADDRESS],
});
const transaction = createAccount({
contract: accountFactoryContract,
admin: TEST_ACCOUNT_A.address,
data: "0x",
});
const accountAddress = await simulateTransaction({
transaction,
account: TEST_ACCOUNT_A,
});
await sendAndConfirmTransaction({
transaction,
account: TEST_ACCOUNT_A,
});
accountContract = getContract({
address: accountAddress,
chain: ANVIL_CHAIN,
client: TEST_CLIENT,
});
});
it("should fetch the correct inital state", async () => {
const admins = await getAllAdmins({
contract: accountContract,
});
expect(admins).toEqual([TEST_ACCOUNT_A.address]);
});
it("should allow adding admins", async () => {
const receipt = await sendAndConfirmTransaction({
transaction: addAdmin({
account: TEST_ACCOUNT_A,
contract: accountContract,
adminAddress: TEST_ACCOUNT_B.address,
}),
account: TEST_ACCOUNT_A,
});
const logs = parseEventLogs({
events: [adminUpdatedEvent()],
logs: receipt.logs,
});
expect(logs.length).toBe(1);
expect(logs[0]?.args.signer).toBe(TEST_ACCOUNT_B.address);
expect(logs[0]?.args.isAdmin).toBe(true);
});
it("should fetch the correct state after adding", async () => {
const admins = await getAllAdmins({
contract: accountContract,
});
expect(admins.length).toBe(2);
expect(admins).toStrictEqual([
TEST_ACCOUNT_A.address,
TEST_ACCOUNT_B.address,
]);
});
it("should allow removing admins", async () => {
const receipt = await sendAndConfirmTransaction({
transaction: removeAdmin({
account: TEST_ACCOUNT_B,
contract: accountContract,
adminAddress: TEST_ACCOUNT_A.address,
}),
account: TEST_ACCOUNT_B,
});
const logs = parseEventLogs({
events: [adminUpdatedEvent()],
logs: receipt.logs,
});
expect(logs[0]?.args.signer).toBe(TEST_ACCOUNT_A.address);
expect(logs[0]?.args.isAdmin).toBe(false);
});
it("should fetch the correct state after removing", async () => {
const admins = await getAllAdmins({
contract: accountContract,
});
expect(admins.length).toBe(1);
expect(admins).toStrictEqual([TEST_ACCOUNT_B.address]);
});
it("should fetch the correct before adding a session key", async () => {
const signers = await getAllSigners({
contract: accountContract,
});
expect(signers).toEqual([]);
});
it("should allow adding session keys", async () => {
const receipt = await sendAndConfirmTransaction({
transaction: addSessionKey({
account: TEST_ACCOUNT_B,
contract: accountContract,
sessionKeyAddress: TEST_ACCOUNT_A.address,
permissions: {
approvedTargets: "*",
},
}),
account: TEST_ACCOUNT_B,
});
const logs = parseEventLogs({
events: [signerPermissionsUpdatedEvent()],
logs: receipt.logs,
});
expect(logs[0]?.args.authorizingSigner).toBe(TEST_ACCOUNT_B.address);
expect(logs[0]?.args.targetSigner).toBe(TEST_ACCOUNT_A.address);
expect(logs[0]?.args.permissions.approvedTargets).toBe([ADDRESS_ZERO]);
});
});
@@ -0,0 +1,55 @@
import type { BaseTransactionOptions } from "../../../transaction/types.js";
import type { Account } from "../../../wallets/interfaces/wallet.js";
import { setPermissionsForSigner } from "../__generated__/IAccountPermissions/write/setPermissionsForSigner.js";
import { defaultPermissionsForAdmin, signPermissionRequest } from "./common.js";
export type RemoveAdminOptions = {
/**
* The admin account that will perform the operation.
*/
account: Account;
/**
* The address to remove as an admin.
*/
adminAddress: string;
};
/**
* Removes admin permissions for a specified address.
* @param options - The options for the removeAdmin function.
* @returns The transaction object to be sent.
* @example
* ```
* import { removeAdmin } from 'thirdweb/extensions/erc4337';
*
* const transaction = removeAdmin({
* contract,
* account,
* adminAddress: '0x...'
* });
* await sendTransaction({ transaction, account });
* ```
* @extension ERC4337
*/
export function removeAdmin(
options: BaseTransactionOptions<RemoveAdminOptions>,
) {
const { contract, account, adminAddress } = options;
return setPermissionsForSigner({
contract,
async asyncParams() {
const { req, signature } = await signPermissionRequest({
account,
contract,
req: await defaultPermissionsForAdmin({
target: adminAddress,
action: "remove-admin",
}),
});
return {
signature,
req,
};
},
});
}
@@ -0,0 +1,57 @@
import type { BaseTransactionOptions } from "../../../transaction/types.js";
import type { Account } from "../../../wallets/interfaces/wallet.js";
import { setPermissionsForSigner } from "../__generated__/IAccountPermissions/write/setPermissionsForSigner.js";
import { signPermissionRequest, toContractPermissions } from "./common.js";
export type RemoveSessionKeyOptions = {
/**
* The account that will perform the operation.
*/
account: Account;
/**
* The address to remove as a session key.
*/
sessionKeyAddress: string;
};
/**
* Removes session key permissions for a specified address.
* @param options - The options for the removeSessionKey function.
* @returns The transaction object to be sent.
* @example
* ```
* import { removeSessionKey } from 'thirdweb/extensions/erc4337';
*
* const transaction = removeSessionKey({
* contract,
* account,
* sessionKeyAddress
* });
* await sendTransaction({ transaction, account });
* ```
* @extension ERC4337
*/
export function removeSessionKey(
options: BaseTransactionOptions<RemoveSessionKeyOptions>,
) {
const { contract, account, sessionKeyAddress } = options;
return setPermissionsForSigner({
contract,
async asyncParams() {
const { req, signature } = await signPermissionRequest({
account,
contract,
req: await toContractPermissions({
target: sessionKeyAddress,
permissions: {
approvedTargets: [],
nativeTokenLimitPerTransaction: 0,
permissionStartTimestamp: new Date(0),
permissionEndTimestamp: new Date(0),
},
}),
});
return { signature, req };
},
});
}
@@ -0,0 +1,20 @@
export type AccountPermissions = {
approvedTargets: string[] | "*";
nativeTokenLimitPerTransaction?: number | string;
permissionStartTimestamp?: Date;
permissionEndTimestamp?: Date;
reqValidityStartTimestamp?: Date;
reqValidityEndTimestamp?: Date;
};
export const SignerPermissionRequest = [
{ name: "signer", type: "address" },
{ name: "isAdmin", type: "uint8" },
{ name: "approvedTargets", type: "address[]" },
{ name: "nativeTokenLimitPerTransaction", type: "uint256" },
{ name: "permissionStartTimestamp", type: "uint128" },
{ name: "permissionEndTimestamp", type: "uint128" },
{ name: "reqValidityStartTimestamp", type: "uint128" },
{ name: "reqValidityEndTimestamp", type: "uint128" },
{ name: "uid", type: "bytes32" },
];
@@ -3,7 +3,7 @@ import { describe, it, expect } from "vitest";
import { NFT_DROP_CONTRACT } from "../../../../../test/src/test-contracts.js";
import { getActiveClaimCondition } from "./getActiveClaimCondition.js";
describe("erc721.getClaimConditions", () => {
describe.runIf(process.env.TW_SECRET_KEY)("erc721.getClaimConditions", () => {
it("should return the correct claim conditions", async () => {
const cc = await getActiveClaimCondition({
contract: NFT_DROP_CONTRACT,
@@ -3,8 +3,8 @@ import { describe, it, expect } from "vitest";
import { getNFT } from "./getNFT.js";
import { DOODLES_CONTRACT } from "~test/test-contracts.js";
describe("erc721.getNFT", () => {
it.runIf(process.env.TW_SECRET_KEY)("without owner", async () => {
describe.runIf(process.env.TW_SECRET_KEY)("erc721.getNFT", () => {
it("without owner", async () => {
const nft = await getNFT({
contract: { ...DOODLES_CONTRACT },
tokenId: 1n,
@@ -47,7 +47,7 @@ describe("erc721.getNFT", () => {
`);
});
it.runIf(process.env.TW_SECRET_KEY)("with owner", async () => {
it("with owner", async () => {
const nft = await getNFT({
contract: { ...DOODLES_CONTRACT },
tokenId: 1n,
@@ -16,7 +16,9 @@ import { USDC_CONTRACT_ADDRESS } from "../../../../test/src/test-contracts.js";
import { toHex } from "../../../utils/encoding/hex.js";
import { sendTransaction } from "../../../transaction/actions/send-transaction.js";
describe(
// skip this test suite if there is no secret key available to test with
// TODO: remove reliance on secret key during unit tests entirely
describe.runIf(process.env.TW_SECRET_KEY)(
"generateMintSignature",
{
timeout: 60000,
@@ -1,8 +1,6 @@
import { NATIVE_TOKEN_ADDRESS } from "../../../constants/addresses.js";
import type { ThirdwebContract } from "../../../contract/contract.js";
import { universalCrypto } from "../../../crypto/aes/lib/universal-crypto.js";
import { toBigInt } from "../../../utils/bigint.js";
import { uint8ArrayToHex } from "../../../utils/encoding/hex.js";
import type { NFTInput } from "../../../utils/nft/parseNft.js";
import { toUnits } from "../../../utils/units.js";
import { decimals } from "../../erc20/read/decimals.js";
@@ -10,6 +8,8 @@ import type { AbiParameterToPrimitiveType } from "abitype";
import { mintWithSignature as generatedMintWithSignature } from "../__generated__/ISignatureMintERC721/write/mintWithSignature.js";
import { upload } from "../../../storage/upload.js";
import type { Account } from "../../../wallets/interfaces/wallet.js";
import { randomBytes32 } from "../../../utils/uuid.js";
import { dateToSeconds, tenYearsFromNow } from "../../../utils/date.js";
/**
* Mints a new ERC721 token with the given minter signature
@@ -72,22 +72,16 @@ export async function generateMintSignature(
options: GenerateMintSignatureOptions,
) {
const { mintRequest, account, contract } = options;
let priceInWei: bigint = 0n;
let priceInWei = 0n;
if (mintRequest.price) {
const d = await decimals(options).catch(() => 18);
priceInWei = toUnits(mintRequest.price.toString(), d);
}
const startTime = mintRequest.validityStartTimestamp || new Date(0);
const endTime =
mintRequest.validityEndTimestamp ||
new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 10); // 10 years
const endTime = mintRequest.validityEndTimestamp || tenYearsFromNow();
const uid =
mintRequest.uid ||
uint8ArrayToHex(
(await universalCrypto()).getRandomValues(new Uint8Array(32)),
);
const uid = mintRequest.uid || (await randomBytes32());
let uri: string;
if (typeof mintRequest.metadata === "object") {
@@ -109,8 +103,8 @@ export async function generateMintSignature(
uri: uri || "",
price: priceInWei,
currency: mintRequest.currency || NATIVE_TOKEN_ADDRESS,
validityStartTimestamp: toBigInt(Math.floor(startTime.getTime() / 1000)),
validityEndTimestamp: toBigInt(Math.floor(endTime.getTime() / 1000)),
validityStartTimestamp: dateToSeconds(startTime),
validityEndTimestamp: dateToSeconds(endTime),
uid,
} as PayloadType;
@@ -6,53 +6,49 @@ import { deployERC1155Contract } from "./deploy-erc1155.js";
import { name } from "../common/read/name.js";
import { getContract } from "../../contract/contract.js";
describe(
"deployERC1155",
{
retry: 0,
},
() => {
it("should deploy ERC1155 drop", async () => {
const address = await deployERC1155Contract({
// skip this test suite if there is no secret key available to test with
// TODO: remove reliance on secret key during unit tests entirely
describe.runIf(process.env.TW_SECRET_KEY)("deployERC1155", () => {
it("should deploy ERC1155 drop", async () => {
const address = await deployERC1155Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "DropERC1155",
params: {
name: "EditionDrop",
symbol: "NFTD",
},
});
expect(address).toBe("0xd91A47278829a0128D7212225FE74BC153A7FAF8");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "DropERC1155",
params: {
name: "EditionDrop",
symbol: "NFTD",
},
});
expect(address).toBe("0xd91A47278829a0128D7212225FE74BC153A7FAF8");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
address,
}),
});
expect(deployedName).toBe("EditionDrop");
address,
}),
});
expect(deployedName).toBe("EditionDrop");
});
it("should deploy ERC1155 token", async () => {
const address = await deployERC1155Contract({
it("should deploy ERC1155 token", async () => {
const address = await deployERC1155Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "TokenERC1155",
params: {
name: "Edition",
},
});
expect(address).toBe("0x7dD915A335Af52698bFFFE14D1D3F0DCfdC0a8E6");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "TokenERC1155",
params: {
name: "Edition",
},
});
expect(address).toBe("0x7dD915A335Af52698bFFFE14D1D3F0DCfdC0a8E6");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
address,
}),
});
expect(deployedName).toBe("Edition");
address,
}),
});
},
);
expect(deployedName).toBe("Edition");
});
});
@@ -6,53 +6,49 @@ import { deployERC20Contract } from "./deploy-erc20.js";
import { name } from "../common/read/name.js";
import { getContract } from "../../contract/contract.js";
describe(
"deployERC20",
{
retry: 0,
},
() => {
it("should deploy ERC20 drop", async () => {
const address = await deployERC20Contract({
// skip this test suite if there is no secret key available to test with
// TODO: remove reliance on secret key during unit tests entirely
describe.runIf(process.env.TW_SECRET_KEY)("deployERC20", () => {
it("should deploy ERC20 drop", async () => {
const address = await deployERC20Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "DropERC20",
params: {
name: "TokenDrop",
symbol: "NFTD",
},
});
expect(address).toBe("0x61Ae22E7240C7e5853749AF49f2552CB8D7C3e35");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "DropERC20",
params: {
name: "TokenDrop",
symbol: "NFTD",
},
});
expect(address).toBe("0x61Ae22E7240C7e5853749AF49f2552CB8D7C3e35");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
address,
}),
});
expect(deployedName).toBe("TokenDrop");
address,
}),
});
expect(deployedName).toBe("TokenDrop");
});
it("should deploy ERC20 token", async () => {
const address = await deployERC20Contract({
it("should deploy ERC20 token", async () => {
const address = await deployERC20Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "TokenERC20",
params: {
name: "Token",
},
});
expect(address).toBe("0x3E8437C96275E9873b0379c1e5d5F0998A9546e9");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "TokenERC20",
params: {
name: "Token",
},
});
expect(address).toBe("0x3E8437C96275E9873b0379c1e5d5F0998A9546e9");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
address,
}),
});
expect(deployedName).toBe("Token");
address,
}),
});
},
);
expect(deployedName).toBe("Token");
});
});
@@ -6,73 +6,69 @@ import { deployERC721Contract } from "./deploy-erc721.js";
import { getContract } from "../../contract/contract.js";
import { name } from "../common/read/name.js";
describe(
"deployERC721",
{
retry: 0,
},
() => {
it("should deploy ERC721 drop", async () => {
const address = await deployERC721Contract({
// skip this test suite if there is no secret key available to test with
// TODO: remove reliance on secret key during unit tests entirely
describe.runIf(process.env.TW_SECRET_KEY)("deployERC721", () => {
it("should deploy ERC721 drop", async () => {
const address = await deployERC721Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "DropERC721",
params: {
name: "NFTDrop",
},
});
expect(address).toBe("0x6AA2E0148a57EcDdb025C856c4e68682CFfcac78");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "DropERC721",
params: {
name: "NFTDrop",
},
});
expect(address).toBe("0x6AA2E0148a57EcDdb025C856c4e68682CFfcac78");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
address,
}),
});
expect(deployedName).toBe("NFTDrop");
address,
}),
});
expect(deployedName).toBe("NFTDrop");
});
it("should deploy ERC721 token", async () => {
const address = await deployERC721Contract({
it("should deploy ERC721 token", async () => {
const address = await deployERC721Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "TokenERC721",
params: {
name: "NFTCollection",
},
});
expect(address).toBe("0x349D9e8751C40Be121a862FaC1Dc7c357281846E");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "TokenERC721",
params: {
name: "NFTCollection",
},
});
expect(address).toBe("0x349D9e8751C40Be121a862FaC1Dc7c357281846E");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
address,
}),
});
expect(deployedName).toBe("NFTCollection");
address,
}),
});
expect(deployedName).toBe("NFTCollection");
});
it("should deploy ERC721 open edition", async () => {
const address = await deployERC721Contract({
it("should deploy ERC721 open edition", async () => {
const address = await deployERC721Contract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "OpenEditionERC721",
params: {
name: "OE",
},
});
expect(address).toBe("0x5804ebCE1834B8F57D31f0078B8f7Dd1F1Da4985");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
type: "OpenEditionERC721",
params: {
name: "OE",
},
});
expect(address).toBe("0x5804ebCE1834B8F57D31f0078B8f7Dd1F1Da4985");
const deployedName = await name({
contract: getContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
address,
}),
});
expect(deployedName).toBe("OE");
address,
}),
});
},
);
expect(deployedName).toBe("OE");
});
});
@@ -8,7 +8,7 @@ import {
MOG_CONTRACT_ADDRESS,
} from "~test/test-contracts.js";
describe("uniswap.getUniswapV3Pool", () => {
describe.runIf(process.env.TW_SECRET_KEY)("uniswap.getUniswapV3Pool", () => {
it("should return the WETH/OHM pool address and fee", async () => {
const pools = await getUniswapV3Pools({
contract: UNISWAPV3_FACTORY_CONTRACT,
@@ -0,0 +1,31 @@
import { useMutation, type UseMutationResult } from "@tanstack/react-query";
import {
estimateGas,
type EstimateGasResult,
} from "../../../../transaction/actions/estimate-gas.js";
import type { PreparedTransaction } from "../../../../transaction/prepare-transaction.js";
import { useActiveAccount } from "../wallets/wallet-hooks.js";
/**
* A hook to estimate the gas for a given transaction.
* @returns A mutation object to estimate gas.
* @example
* ```jsx
* import { useEstimateGas } from "thirdweb/react";
* const { mutate: estimateGas, data: gasEstimate } = useEstimateGas();
*
* // later
* const estimatedGas = await estimateGas(tx);
* ```
*/
export function useEstimateGas(): UseMutationResult<
EstimateGasResult,
Error,
PreparedTransaction
> {
const account = useActiveAccount();
return useMutation({
mutationFn: (transaction) => estimateGas({ transaction, account }),
});
}
@@ -9,6 +9,7 @@ import type { WCSupportedWalletIds } from "../../../../wallets/__generated__/wal
import { isMobile, isAndroid, isIOS } from "../../../../utils/web/isMobile.js";
import { openWindow } from "../../../../utils/web/openWindow.js";
import { wait } from "../../../../utils/promise/wait.js";
import { formatWalletConnectUrl } from "../../../../utils/url.js";
/**
* QR Scan UI for connecting a specific wallet on desktop.
@@ -49,15 +50,15 @@ export const WalletConnectConnection: React.FC<{
if (isMobile()) {
if (isAndroid()) {
openWindow(
`${platformUris.android}wc?uri=${encodeURIComponent(uri)}`,
formatWalletConnectUrl(platformUris.android, uri).redirect,
);
} else if (isIOS()) {
openWindow(
`${platformUris.ios}wc?uri=${encodeURIComponent(uri)}`,
formatWalletConnectUrl(platformUris.ios, uri).redirect,
);
} else {
openWindow(
`${platformUris.other}wc?uri=${encodeURIComponent(uri)}`,
formatWalletConnectUrl(platformUris.other, uri).redirect,
);
}
}
@@ -9,7 +9,7 @@ const rpcClient = getRpcClient({
client: TEST_CLIENT,
});
describe("eth_blockNumber", () => {
describe.runIf(process.env.TW_SECRET_KEY)("eth_blockNumber", () => {
it("should return the block number", async () => {
const blockNumber = await eth_blockNumber(rpcClient);
expect(blockNumber).toEqual(19139495n);

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