Repository: gakonst/ethers-rs
Pull request #2270 (2023-03-16 17:14:55)

feat(core): roundtrip serde + to/from strings
<!--
Thank you for your Pull Request. Please provide a description above and review
the requirements below.

Bug fixes and new features should include tests.

Contributors guide: https://github.com/gakonst/ethers-rs/blob/master/CONTRIBUTING.md

The contributors guide includes instructions for running rustfmt and building the
documentation.
-->

## Motivation

Refs #2038, https://github.com/gakonst/ethers-rs/pull/2268#discussion_r1138931364

Doesn't fix it because you still need to replace kebab-case to snake_case

<!--
Explain the context and why you're making that change. What is the problem
you're trying to solve? In some cases there is not a problem and this can be
thought of as being the motivation for your change.
-->

## Solution

<!--
Summarize the solution and provide any necessary context needed to understand
the code change.
-->

## PR Checklist

-   [x] Added Tests
-   [x] Added Documentation
-   [x] Updated the changelog
-   [ ] Breaking changes


CodeSandwich: From tests I wrote when adding `ethlive` I've found out that the **last** `serialize` parameter is the one which is used when doing `to_string`. In this PR you're promoting the **first** one, which will break a lot of downstream.

Patch:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index db41d65b..95b21bd1 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -6,44 +6,3 @@ updates:
           interval: daily
           time: "03:00"
       open-pull-requests-limit: 10
-      ignore:
-          - dependency-name: async-trait
-            versions:
-                - 0.1.48
-                - 0.1.49
-          - dependency-name: futures-core
-            versions:
-                - 0.3.13
-                - 0.3.14
-          - dependency-name: futures-channel
-            versions:
-                - 0.3.14
-          - dependency-name: anyhow
-            versions:
-                - 1.0.40
-          - dependency-name: elliptic-curve
-            versions:
-                - 0.9.0
-                - 0.9.2
-                - 0.9.6
-          - dependency-name: pin-project
-            versions:
-                - 1.0.6
-          - dependency-name: arrayvec
-            versions:
-                - 0.6.0
-          - dependency-name: serde
-            versions:
-                - 1.0.125
-          - dependency-name: tokio
-            versions:
-                - 1.3.0
-          - dependency-name: serde_json
-            versions:
-                - 1.0.63
-          - dependency-name: ethereum-types
-            versions:
-                - 0.11.0
-          - dependency-name: yubihsm
-            versions:
-                - 0.38.0
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e88dd44a..69bc3f5f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -17,22 +17,40 @@ env:
 
 jobs:
     test:
-        name: test ${{ matrix.os }} ${{ matrix.flags }}
+        name: test ${{ matrix.os }} (${{ matrix.flags.name }})
         runs-on: ${{ matrix.os }}
         strategy:
             fail-fast: false
             matrix:
-                os: ["ubuntu-latest", "macos-latest", "windows-latest"]
-                flags: ["--workspace", "--workspace --all-features"]
-                exclude:
-                    # sha2-asm
-                    - os: windows-latest
+                os: ["ubuntu-latest", "macos-latest"]
+                flags:
+                    - name: no default features
+                      flags: --workspace --no-default-features
+                    - name: default features
+                      flags: --workspace
+                    - name: all features
                       flags: --workspace --all-features
+                include:
+                    # not workspace because compiling examples fails for no reason in CI,
+                    - os: windows-latest
+                      flags:
+                          name: no default features
+                          flags: -p ethers --no-default-features
+                    - os: windows-latest
+                      flags:
+                          name: default features
+                          flags: -p ethers
+                    - os: windows-latest
+                      flags:
+                          name: all features
+                          flags: -p ethers --all-features
         steps:
             - uses: actions/checkout@v3
             - uses: dtolnay/rust-toolchain@stable
               with:
-                toolchain: ${{ matrix.os == 'windows-latest' && 'stable-x86_64-pc-windows-gnu' || 'stable' }}
+                  toolchain:
+                      ${{ matrix.os == 'windows-latest' && 'stable-x86_64-pc-windows-gnu' ||
+                      'stable' }}
             - name: Install Anvil
               uses: foundry-rs/foundry-toolchain@v1
               with:
@@ -43,12 +61,12 @@ jobs:
             - name: Install nextest
               uses: taiki-e/install-action@nextest
             - uses: Swatinem/rust-cache@v2
-            - name: test
+            - name: test ${{ matrix.flags.flags }}
               shell: bash
               # skip `ethers_etherscan::it` and `ethers::live`
               run: |
                   cargo nextest run \
-                  ${{ matrix.flags }} \
+                  ${{ matrix.flags.flags }} \
                   -E "!binary(~live) & !(deps(ethers-etherscan) & kind(test))"
 
     etherscan-tests:
@@ -147,9 +165,6 @@ jobs:
             - uses: Swatinem/rust-cache@v2
             - name: Check
               run: cargo check --workspace --target wasm32-unknown-unknown
-            # TODO: [#2191](https://github.com/gakonst/ethers-rs/issues/2191)
-            # - name: Check all features
-            #   run: cargo check --workspace --target wasm32-unknown-unknown --all-features
 
             - name: Install wasm-pack
               run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3b9fb0f2..d31e8407 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,8 @@
 
 ### Unreleased
 
-- Add `other: OtherFields` to `TransactionReceipt` [#2209[](https://github.com/gakonst/ethers-rs/pull/2209)
+- Make `Chain` more round-trip friendly [#2270](https://github.com/gakonst/ethers-rs/pull/2270)
+- Add `other: OtherFields` to `TransactionReceipt` [#2209](https://github.com/gakonst/ethers-rs/pull/2209)
 - Add `Signature::recover_typed_data` [#2120](https://github.com/gakonst/ethers-rs/pull/2120)
 - Add `abi::encode_packed` [#2104](https://github.com/gakonst/ethers-rs/pull/2104)
 - Add support for custom JavaScript tracer to `debug_traceCall` and `debug_traceTransaction` [#2064](https://github.com/gakonst/ethers-rs/pull/2064)
diff --git a/Cargo.lock b/Cargo.lock
index 34c95667..aa4eeafb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -25,7 +25,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8"
 dependencies = [
  "crypto-common",
- "generic-array 0.14.6",
+ "generic-array",
 ]
 
 [[package]]
@@ -34,10 +34,10 @@ version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "cipher 0.3.0",
  "cpufeatures",
- "opaque-debug 0.3.0",
+ "opaque-debug",
 ]
 
 [[package]]
@@ -46,8 +46,8 @@ version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241"
 dependencies = [
- "cfg-if 1.0.0",
- "cipher 0.4.3",
+ "cfg-if",
+ "cipher 0.4.4",
  "cpufeatures",
 ]
 
@@ -77,21 +77,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
 
 [[package]]
 name = "anyhow"
-version = "1.0.68"
+version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
-
-[[package]]
-name = "arrayref"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
-
-[[package]]
-name = "arrayvec"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
+checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
 
 [[package]]
 name = "arrayvec"
@@ -110,9 +98,9 @@ dependencies = [
 
 [[package]]
 name = "async-trait"
-version = "0.1.61"
+version = "0.1.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "705339e0e4a9690e2908d2b3d049d85682cf19fbd5782494498fbf7003a6a282"
+checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -159,40 +147,12 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
-[[package]]
-name = "base16ct"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
-
 [[package]]
 name = "base16ct"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
 
-[[package]]
-name = "base58"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
-
-[[package]]
-name = "base58check"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ee2fe4c9a0c84515f136aaae2466744a721af6d63339c18689d9e995d74d99b"
-dependencies = [
- "base58",
- "sha2 0.8.2",
-]
-
-[[package]]
-name = "base64"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
-
 [[package]]
 name = "base64"
 version = "0.13.1"
@@ -207,9 +167,9 @@ checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
 
 [[package]]
 name = "base64ct"
-version = "1.5.3"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
+checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
 
 [[package]]
 name = "bech32"
@@ -249,9 +209,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitflags"
-version = "2.0.0"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f6e5df9abedba5099a01a6567c6086a6fbcff57af07c360d356737f9e0c644"
+checksum = "d5dd14596c0e5b954530d0e6f1fd99b89c03e313aa2086e8da4303701a09e1cf"
 
 [[package]]
 name = "bitvec"
@@ -275,63 +235,22 @@ dependencies = [
  "wyz",
 ]
 
-[[package]]
-name = "blake2"
-version = "0.10.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
-dependencies = [
- "digest 0.10.6",
-]
-
-[[package]]
-name = "blake2b_simd"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
-dependencies = [
- "arrayref",
- "arrayvec 0.5.2",
- "constant_time_eq",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
-dependencies = [
- "block-padding 0.1.5",
- "byte-tools",
- "byteorder",
- "generic-array 0.12.4",
-]
-
 [[package]]
 name = "block-buffer"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
 dependencies = [
- "generic-array 0.14.6",
+ "generic-array",
 ]
 
 [[package]]
 name = "block-buffer"
-version = "0.10.3"
+version = "0.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
 dependencies = [
- "generic-array 0.14.6",
-]
-
-[[package]]
-name = "block-padding"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
-dependencies = [
- "byte-tools",
+ "generic-array",
 ]
 
 [[package]]
@@ -340,7 +259,7 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0a90ec2df9600c28a01c56c4784c9207a96d2451833aeceb8cc97e4c9548bb78"
 dependencies = [
- "generic-array 0.14.6",
+ "generic-array",
 ]
 
 [[package]]
@@ -348,6 +267,9 @@ name = "bs58"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
+dependencies = [
+ "sha2 0.9.9",
+]
 
 [[package]]
 name = "build_const"
@@ -357,9 +279,9 @@ checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
 
 [[package]]
 name = "bumpalo"
-version = "3.11.1"
+version = "3.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
 
 [[package]]
 name = "byte-slice-cast"
@@ -367,12 +289,6 @@ version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
 
-[[package]]
-name = "byte-tools"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
-
 [[package]]
 name = "byteorder"
 version = "1.4.3"
@@ -411,9 +327,9 @@ dependencies = [
 
 [[package]]
 name = "camino"
-version = "1.1.2"
+version = "1.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c77df041dc383319cc661b428b6961a005db4d6808d5e12536931b1ca9556055"
+checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2"
 dependencies = [
  "serde",
 ]
@@ -453,14 +369,14 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
 dependencies = [
- "cipher 0.4.3",
+ "cipher 0.4.4",
 ]
 
 [[package]]
 name = "cc"
-version = "1.0.78"
+version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
 dependencies = [
  "jobserver",
 ]
@@ -472,17 +388,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9ae3c82e4355234767756212c570e29833699ab63e6ffd161887314cc5b43847"
 dependencies = [
  "aead",
- "cipher 0.4.3",
+ "cipher 0.4.4",
  "ctr",
  "subtle",
 ]
 
-[[package]]
-name = "cfg-if"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
-
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -535,14 +445,14 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
 dependencies = [
- "generic-array 0.14.6",
+ "generic-array",
 ]
 
 [[package]]
 name = "cipher"
-version = "0.4.3"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
 dependencies = [
  "crypto-common",
  "inout",
@@ -589,11 +499,11 @@ dependencies = [
 
 [[package]]
 name = "cmac"
-version = "0.7.1"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "606383658416244b8dc4b36f864ec1f86cb922b95c41a908fd07aeb01cad06fa"
+checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa"
 dependencies = [
- "cipher 0.4.3",
+ "cipher 0.4.4",
  "dbl",
  "digest 0.10.6",
 ]
@@ -610,9 +520,9 @@ dependencies = [
 
 [[package]]
 name = "coins-bip32"
-version = "0.8.0"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a3b95d26eace980ade01e0ea8d996f7d5ae7031f9c5f258317ec82e400f33c1"
+checksum = "b30a84aab436fcb256a2ab3c80663d8aec686e6bae12827bb05fef3e1e439c9f"
 dependencies = [
  "bincode",
  "bs58",
@@ -620,7 +530,7 @@ dependencies = [
  "digest 0.10.6",
  "getrandom",
  "hmac 0.12.1",
- "k256 0.11.6",
+ "k256",
  "lazy_static",
  "serde",
  "sha2 0.10.6",
@@ -629,9 +539,9 @@ dependencies = [
 
 [[package]]
 name = "coins-bip39"
-version = "0.8.1"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a05ceda6ab4876de899fe23e8a171b200be9a346289bce12d41311e4bce2f104"
+checksum = "efb68f3b6c3fee83828ecd8d463f360a397c32aaeb35bd931c01e5ddf5631c69"
 dependencies = [
  "bitvec 0.17.4",
  "coins-bip32",
@@ -639,7 +549,7 @@ dependencies = [
  "hex",
  "hmac 0.12.1",
  "once_cell",
- "pbkdf2 0.11.0",
+ "pbkdf2 0.12.1",
  "rand",
  "sha2 0.10.6",
  "thiserror",
@@ -648,16 +558,15 @@ dependencies = [
 
 [[package]]
 name = "coins-core"
-version = "0.8.0"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87637d08a1dd6bfa3bcd697f0a4de6c1b3a03e085b9d841a7e9cde4ccb61514b"
+checksum = "9b949a1c63fb7eb591eb7ba438746326aedf0ae843e51ec92ba6bec5bb382c4f"
 dependencies = [
- "base58check",
- "base64 0.12.3",
+ "base64 0.21.0",
  "bech32",
- "blake2",
+ "bs58",
  "digest 0.10.6",
- "generic-array 0.14.6",
+ "generic-array",
  "hex",
  "ripemd",
  "serde",
@@ -669,14 +578,13 @@ dependencies = [
 
 [[package]]
 name = "coins-ledger"
-version = "0.7.1"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9da2894aa851a2b2726f20b05e61c7dfebc39a06e23258e74d176d60093dd508"
+checksum = "863cc93703bfc6f02f4401b42663b767783179f4080d89a0c4876766c7c0fb78"
 dependencies = [
  "async-trait",
- "blake2b_simd",
  "byteorder",
- "cfg-if 0.1.10",
+ "cfg-if",
  "futures",
  "hex",
  "hidapi-rusb",
@@ -711,14 +619,14 @@ dependencies = [
 
 [[package]]
 name = "console"
-version = "0.15.4"
+version = "0.15.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9b6515d269224923b26b5febea2ed42b2d5f2ce37284a4dd670fedd6cb8347a"
+checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
 dependencies = [
  "encode_unicode",
  "lazy_static",
  "libc",
- "windows-sys",
+ "windows-sys 0.42.0",
 ]
 
 [[package]]
@@ -727,7 +635,7 @@ version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "wasm-bindgen",
 ]
 
@@ -783,7 +691,7 @@ version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
 ]
 
 [[package]]
@@ -826,45 +734,45 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.6"
+version = "0.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-deque"
-version = "0.8.2"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
+checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "crossbeam-epoch",
  "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.13"
+version = "0.9.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
+checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
 dependencies = [
  "autocfg",
- "cfg-if 1.0.0",
+ "cfg-if",
  "crossbeam-utils",
- "memoffset",
+ "memoffset 0.8.0",
  "scopeguard",
 ]
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.14"
+version = "0.8.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
+checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
 ]
 
 [[package]]
@@ -875,23 +783,11 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
 
 [[package]]
 name = "crypto-bigint"
-version = "0.4.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef"
-dependencies = [
- "generic-array 0.14.6",
- "rand_core",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "crypto-bigint"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071c0f5945634bc9ba7a452f492377dd6b1993665ddb58f28704119b32f07a9a"
+checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7"
 dependencies = [
- "generic-array 0.14.6",
+ "generic-array",
  "rand_core",
  "subtle",
  "zeroize",
@@ -903,7 +799,7 @@ version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
 dependencies = [
- "generic-array 0.14.6",
+ "generic-array",
  "rand_core",
  "typenum",
 ]
@@ -914,7 +810,7 @@ version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
 dependencies = [
- "generic-array 0.14.6",
+ "generic-array",
  "subtle",
 ]
 
@@ -934,7 +830,7 @@ version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
 dependencies = [
- "cipher 0.4.3",
+ "cipher 0.4.4",
 ]
 
 [[package]]
@@ -943,7 +839,7 @@ version = "4.0.0-rc.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d4ba9852b42210c7538b75484f9daa0655e9a3ac04f693747bb0f02cf3cfe16"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "digest 0.10.6",
  "fiat-crypto",
  "packed_simd_2",
@@ -954,9 +850,9 @@ dependencies = [
 
 [[package]]
 name = "cxx"
-version = "1.0.86"
+version = "1.0.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579"
+checksum = "9a140f260e6f3f79013b8bfc65e7ce630c9ab4388c6a89c71e07226f49487b72"
 dependencies = [
  "cc",
  "cxxbridge-flags",
@@ -966,9 +862,9 @@ dependencies = [
 
 [[package]]
 name = "cxx-build"
-version = "1.0.86"
+version = "1.0.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70"
+checksum = "da6383f459341ea689374bf0a42979739dc421874f112ff26f829b8040b8e613"
 dependencies = [
  "cc",
  "codespan-reporting",
@@ -981,15 +877,15 @@ dependencies = [
 
 [[package]]
 name = "cxxbridge-flags"
-version = "1.0.86"
+version = "1.0.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c"
+checksum = "90201c1a650e95ccff1c8c0bb5a343213bdd317c6e600a93075bca2eff54ec97"
 
 [[package]]
 name = "cxxbridge-macro"
-version = "1.0.86"
+version = "1.0.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5"
+checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1002,11 +898,11 @@ version = "5.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "hashbrown",
  "lock_api",
  "once_cell",
- "parking_lot_core 0.9.6",
+ "parking_lot_core",
 ]
 
 [[package]]
@@ -1015,17 +911,7 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9"
 dependencies = [
- "generic-array 0.14.6",
-]
-
-[[package]]
-name = "der"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de"
-dependencies = [
- "const-oid",
- "zeroize",
+ "generic-array",
 ]
 
 [[package]]
@@ -1067,22 +953,13 @@ version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
 
-[[package]]
-name = "digest"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
-dependencies = [
- "generic-array 0.12.4",
-]
-
 [[package]]
 name = "digest"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
 dependencies = [
- "generic-array 0.14.6",
+ "generic-array",
 ]
 
 [[package]]
@@ -1091,7 +968,7 @@ version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
 dependencies = [
- "block-buffer 0.10.3",
+ "block-buffer 0.10.4",
  "crypto-common",
  "subtle",
 ]
@@ -1102,7 +979,7 @@ version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "dirs-sys-next",
 ]
 
@@ -1123,28 +1000,16 @@ version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c"
 
-[[package]]
-name = "ecdsa"
-version = "0.14.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c"
-dependencies = [
- "der 0.6.1",
- "elliptic-curve 0.12.3",
- "rfc6979 0.3.1",
- "signature 1.6.4",
-]
-
 [[package]]
 name = "ecdsa"
 version = "0.16.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d1b0a1222f8072619e8a6b667a854020a03d363738303203c09468b3424a420a"
 dependencies = [
- "der 0.7.1",
- "elliptic-curve 0.13.2",
- "rfc6979 0.4.0",
- "signature 2.0.0",
+ "der",
+ "elliptic-curve",
+ "rfc6979",
+ "signature",
 ]
 
 [[package]]
@@ -1153,8 +1018,8 @@ version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "be522bee13fa6d8059f4903a4084aa3bd50725e18150202f0238deb615cd6371"
 dependencies = [
- "pkcs8 0.10.1",
- "signature 2.0.0",
+ "pkcs8",
+ "signature",
 ]
 
 [[package]]
@@ -1173,29 +1038,9 @@ dependencies = [
 
 [[package]]
 name = "either"
-version = "1.8.0"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
-
-[[package]]
-name = "elliptic-curve"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3"
-dependencies = [
- "base16ct 0.1.1",
- "crypto-bigint 0.4.9",
- "der 0.6.1",
- "digest 0.10.6",
- "ff 0.12.1",
- "generic-array 0.14.6",
- "group 0.12.1",
- "pkcs8 0.9.0",
- "rand_core",
- "sec1 0.3.0",
- "subtle",
- "zeroize",
-]
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
 
 [[package]]
 name = "elliptic-curve"
@@ -1203,24 +1048,24 @@ version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6ea5a92946e8614bb585254898bb7dd1ddad241ace60c52149e3765e34cc039d"
 dependencies = [
- "base16ct 0.2.0",
- "crypto-bigint 0.5.0",
+ "base16ct",
+ "crypto-bigint",
  "digest 0.10.6",
- "ff 0.13.0",
- "generic-array 0.14.6",
- "group 0.13.0",
- "pkcs8 0.10.1",
+ "ff",
+ "generic-array",
+ "group",
+ "pkcs8",
  "rand_core",
- "sec1 0.7.1",
+ "sec1",
  "subtle",
  "zeroize",
 ]
 
 [[package]]
 name = "ena"
-version = "0.14.0"
+version = "0.14.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
+checksum = "b2e5d13ca2353ab7d0230988629def93914a8c4015f621f9b13ed2955614731d"
 dependencies = [
  "log",
 ]
@@ -1233,11 +1078,11 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
 [[package]]
 name = "encoding_rs"
-version = "0.8.31"
+version = "0.8.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
+checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
 ]
 
 [[package]]
@@ -1249,7 +1094,7 @@ dependencies = [
  "base64 0.13.1",
  "bytes",
  "hex",
- "k256 0.13.0",
+ "k256",
  "log",
  "rand",
  "rlp",
@@ -1366,7 +1211,6 @@ dependencies = [
 name = "ethers"
 version = "2.0.0"
 dependencies = [
- "bytes",
  "ethers-addressbook",
  "ethers-contract",
  "ethers-core",
@@ -1375,12 +1219,6 @@ dependencies = [
  "ethers-providers",
  "ethers-signers",
  "ethers-solc",
- "eyre",
- "hex",
- "rand",
- "serde",
- "serde_json",
- "tempfile",
  "tokio",
 ]
 
@@ -1420,7 +1258,6 @@ name = "ethers-contract-abigen"
 version = "2.0.0"
 dependencies = [
  "Inflector",
- "cfg-if 1.0.0",
  "dunce",
  "ethers-core",
  "ethers-etherscan",
@@ -1459,26 +1296,25 @@ dependencies = [
 name = "ethers-core"
 version = "2.0.0"
 dependencies = [
- "arrayvec 0.7.2",
+ "arrayvec",
  "bincode",
  "bytes",
  "cargo_metadata",
  "chrono",
  "convert_case",
- "elliptic-curve 0.13.2",
+ "elliptic-curve",
  "ethabi",
- "generic-array 0.14.6",
+ "generic-array",
  "getrandom",
  "hex",
  "hex-literal",
- "k256 0.13.0",
+ "k256",
  "num_enum",
  "once_cell",
  "open-fastrlp",
  "proc-macro2",
  "rand",
  "rlp",
- "rlp-derive",
  "serde",
  "serde_json",
  "strum",
@@ -1511,7 +1347,6 @@ dependencies = [
  "reqwest",
  "semver",
  "serde",
- "serde-aux",
  "serde_json",
  "serial_test",
  "tempfile",
@@ -1567,8 +1402,8 @@ dependencies = [
  "hashers",
  "hex",
  "http",
+ "instant",
  "once_cell",
- "parking_lot 0.11.2",
  "pin-project",
  "reqwest",
  "serde",
@@ -1583,7 +1418,6 @@ dependencies = [
  "url",
  "wasm-bindgen",
  "wasm-bindgen-futures",
- "wasm-timer",
  "web-sys",
  "winapi",
  "ws_stream_wasm",
@@ -1597,7 +1431,7 @@ dependencies = [
  "coins-bip32",
  "coins-bip39",
  "coins-ledger",
- "elliptic-curve 0.13.2",
+ "elliptic-curve",
  "eth-keystore",
  "ethers-contract-derive",
  "ethers-core",
@@ -1612,7 +1446,7 @@ dependencies = [
  "semver",
  "serde_json",
  "sha2 0.10.6",
- "spki 0.6.0",
+ "spki",
  "tempfile",
  "thiserror",
  "tokio",
@@ -1626,7 +1460,7 @@ dependencies = [
 name = "ethers-solc"
 version = "2.0.0"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "criterion",
  "dunce",
  "env_logger",
@@ -1665,7 +1499,7 @@ dependencies = [
 
 [[package]]
 name = "ethers-wasm"
-version = "0.1.0"
+version = "2.0.0"
 dependencies = [
  "console_error_panic_hook",
  "ethers",
@@ -1677,7 +1511,6 @@ dependencies = [
  "wasm-bindgen-futures",
  "wasm-bindgen-test",
  "web-sys",
- "wee_alloc",
 ]
 
 [[package]]
@@ -1718,6 +1551,18 @@ dependencies = [
  "tokio",
 ]
 
+[[package]]
+name = "examples-geth"
+version = "0.0.0"
+dependencies = [
+ "ethers",
+ "eyre",
+ "serde",
+ "serde_json",
+ "tempfile",
+ "tokio",
+]
+
 [[package]]
 name = "examples-middleware"
 version = "2.0.0"
@@ -1725,6 +1570,7 @@ dependencies = [
  "async-trait",
  "ethers",
  "eyre",
+ "serde",
  "serde_json",
  "thiserror",
  "tokio",
@@ -1799,31 +1645,15 @@ dependencies = [
  "once_cell",
 ]
 
-[[package]]
-name = "fake-simd"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
-
 [[package]]
 name = "fastrand"
-version = "1.8.0"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
 dependencies = [
  "instant",
 ]
 
-[[package]]
-name = "ff"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
-dependencies = [
- "rand_core",
- "subtle",
-]
-
 [[package]]
 name = "ff"
 version = "0.13.0"
@@ -1922,9 +1752,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
 
 [[package]]
 name = "futures"
-version = "0.3.25"
+version = "0.3.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
+checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -2006,6 +1836,10 @@ name = "futures-timer"
 version = "3.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
+dependencies = [
+ "gloo-timers",
+ "send_wrapper 0.4.0",
+]
 
 [[package]]
 name = "futures-util"
@@ -2034,15 +1868,6 @@ dependencies = [
  "byteorder",
 ]
 
-[[package]]
-name = "generic-array"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
-dependencies = [
- "typenum",
-]
-
 [[package]]
 name = "generic-array"
 version = "0.14.6"
@@ -2060,7 +1885,7 @@ version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "js-sys",
  "libc",
  "wasi",
@@ -2074,14 +1899,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
 
 [[package]]
-name = "group"
-version = "0.12.1"
+name = "gloo-timers"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
+checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c"
 dependencies = [
- "ff 0.12.1",
- "rand_core",
- "subtle",
+ "futures-channel",
+ "futures-core",
+ "js-sys",
+ "wasm-bindgen",
 ]
 
 [[package]]
@@ -2090,16 +1916,16 @@ version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
 dependencies = [
- "ff 0.13.0",
+ "ff",
  "rand_core",
  "subtle",
 ]
 
 [[package]]
 name = "h2"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
+checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d"
 dependencies = [
  "bytes",
  "fnv",
@@ -2137,9 +1963,9 @@ dependencies = [
 
 [[package]]
 name = "heck"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 
 [[package]]
 name = "hermit-abi"
@@ -2159,6 +1985,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
 [[package]]
 name = "hex"
 version = "0.4.3"
@@ -2253,9 +2085,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
 name = "hyper"
-version = "0.14.23"
+version = "0.14.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
+checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -2397,7 +2229,7 @@ version = "0.16.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b"
 dependencies = [
- "console 0.15.4",
+ "console 0.15.5",
  "lazy_static",
  "number_prefix",
  "regex",
@@ -2409,8 +2241,8 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
 dependencies = [
- "block-padding 0.3.2",
- "generic-array 0.14.6",
+ "block-padding",
+ "generic-array",
 ]
 
 [[package]]
@@ -2419,20 +2251,17 @@ version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
 dependencies = [
- "cfg-if 1.0.0",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
+ "cfg-if",
 ]
 
 [[package]]
 name = "io-lifetimes"
-version = "1.0.4"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
+checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3"
 dependencies = [
  "libc",
- "windows-sys",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -2443,14 +2272,14 @@ checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146"
 
 [[package]]
 name = "is-terminal"
-version = "0.4.2"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
+checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857"
 dependencies = [
- "hermit-abi 0.2.6",
+ "hermit-abi 0.3.1",
  "io-lifetimes",
  "rustix",
- "windows-sys",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -2464,15 +2293,15 @@ dependencies = [
 
 [[package]]
 name = "itoa"
-version = "1.0.5"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
 
 [[package]]
 name = "jobserver"
-version = "0.1.25"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
+checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
 dependencies = [
  "libc",
 ]
@@ -2486,30 +2315,18 @@ dependencies = [
  "wasm-bindgen",
 ]
 
-[[package]]
-name = "k256"
-version = "0.11.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b"
-dependencies = [
- "cfg-if 1.0.0",
- "ecdsa 0.14.8",
- "elliptic-curve 0.12.3",
- "sha2 0.10.6",
-]
-
 [[package]]
 name = "k256"
 version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "955890845095ccf31ef83ad41a05aabb4d8cc23dc3cac5a9f5c89cf26dd0da75"
 dependencies = [
- "cfg-if 1.0.0",
- "ecdsa 0.16.1",
- "elliptic-curve 0.13.2",
+ "cfg-if",
+ "ecdsa",
+ "elliptic-curve",
  "once_cell",
  "sha2 0.10.6",
- "signature 2.0.0",
+ "signature",
 ]
 
 [[package]]
@@ -2561,9 +2378,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.139"
+version = "0.2.140"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
 
 [[package]]
 name = "libm"
@@ -2614,7 +2431,7 @@ version = "0.4.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
 ]
 
 [[package]]
@@ -2628,9 +2445,9 @@ dependencies = [
 
 [[package]]
 name = "matches"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
+checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
 
 [[package]]
 name = "md-5"
@@ -2640,7 +2457,7 @@ checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15"
 dependencies = [
  "block-buffer 0.9.0",
  "digest 0.9.0",
- "opaque-debug 0.3.0",
+ "opaque-debug",
 ]
 
 [[package]]
@@ -2668,10 +2485,13 @@ dependencies = [
 ]
 
 [[package]]
-name = "memory_units"
-version = "0.4.0"
+name = "memoffset"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
+checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
+dependencies = [
+ "autocfg",
+]
 
 [[package]]
 name = "mime"
@@ -2690,14 +2510,14 @@ dependencies = [
 
 [[package]]
 name = "mio"
-version = "0.8.5"
+version = "0.8.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
+checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
 dependencies = [
  "libc",
  "log",
  "wasi",
- "windows-sys",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -2731,9 +2551,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
 dependencies = [
  "bitflags 1.3.2",
- "cfg-if 1.0.0",
+ "cfg-if",
  "libc",
- "memoffset",
+ "memoffset 0.7.1",
  "pin-utils",
  "static_assertions",
 ]
@@ -2816,12 +2636,6 @@ version = "11.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
 
-[[package]]
-name = "opaque-debug"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
-
 [[package]]
 name = "opaque-debug"
 version = "0.3.0"
@@ -2834,7 +2648,7 @@ version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce"
 dependencies = [
- "arrayvec 0.7.2",
+ "arrayvec",
  "auto_impl",
  "bytes",
  "ethereum-types",
@@ -2855,12 +2669,12 @@ dependencies = [
 
 [[package]]
 name = "openssl"
-version = "0.10.45"
+version = "0.10.46"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1"
+checksum = "fd2523381e46256e40930512c7fd25562b9eae4812cb52078f155e87217c9d1e"
 dependencies = [
  "bitflags 1.3.2",
- "cfg-if 1.0.0",
+ "cfg-if",
  "foreign-types",
  "libc",
  "once_cell",
@@ -2887,9 +2701,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.80"
+version = "0.9.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7"
+checksum = "176be2629957c157240f68f61f2d0053ad3a4ecfdd9ebf1e6521d18d9635cf67"
 dependencies = [
  "autocfg",
  "cc",
@@ -2925,8 +2739,8 @@ version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7270da3e5caa82afd3deb054cc237905853813aea3859544bc082c3fe55b8d47"
 dependencies = [
- "ecdsa 0.16.1",
- "elliptic-curve 0.13.2",
+ "ecdsa",
+ "elliptic-curve",
  "primeorder",
  "sha2 0.10.6",
 ]
@@ -2937,8 +2751,8 @@ version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209"
 dependencies = [
- "ecdsa 0.16.1",
- "elliptic-curve 0.13.2",
+ "ecdsa",
+ "elliptic-curve",
  "primeorder",
  "sha2 0.10.6",
 ]
@@ -2949,17 +2763,17 @@ version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "libm",
 ]
 
 [[package]]
 name = "parity-scale-codec"
-version = "3.2.1"
+version = "3.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "366e44391a8af4cfd6002ef6ba072bae071a96aafca98d7d448a34c5dca38b6a"
+checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac"
 dependencies = [
- "arrayvec 0.7.2",
+ "arrayvec",
  "bitvec 1.0.1",
  "byte-slice-cast",
  "impl-trait-for-tuples",
@@ -2969,9 +2783,9 @@ dependencies = [
 
 [[package]]
 name = "parity-scale-codec-derive"
-version = "3.1.3"
+version = "3.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd"
+checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -2979,17 +2793,6 @@ dependencies = [
  "syn",
 ]
 
-[[package]]
-name = "parking_lot"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
-dependencies = [
- "instant",
- "lock_api",
- "parking_lot_core 0.8.6",
-]
-
 [[package]]
 name = "parking_lot"
 version = "0.12.1"
@@ -2997,34 +2800,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
 dependencies = [
  "lock_api",
- "parking_lot_core 0.9.6",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
-dependencies = [
- "cfg-if 1.0.0",
- "instant",
- "libc",
- "redox_syscall",
- "smallvec",
- "winapi",
+ "parking_lot_core",
 ]
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.6"
+version = "0.9.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
+checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "libc",
  "redox_syscall",
  "smallvec",
- "windows-sys",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -3074,9 +2863,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
 
 [[package]]
 name = "petgraph"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143"
+checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
 dependencies = [
  "fixedbitset",
  "indexmap",
@@ -3181,24 +2970,14 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
-[[package]]
-name = "pkcs8"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba"
-dependencies = [
- "der 0.6.1",
- "spki 0.6.0",
-]
-
 [[package]]
 name = "pkcs8"
 version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3d2820d87d2b008616e5c27212dd9e0e694fb4c6b522de06094106813328cb49"
 dependencies = [
- "der 0.7.1",
- "spki 0.7.0",
+ "der",
+ "spki",
 ]
 
 [[package]]
@@ -3267,9 +3046,9 @@ dependencies = [
 
 [[package]]
 name = "prettyplease"
-version = "0.1.23"
+version = "0.1.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78"
+checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
 dependencies = [
  "proc-macro2",
  "syn",
@@ -3281,7 +3060,7 @@ version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7613fdcc0831c10060fa69833ea8fa2caa94b6456f51e25356a885b530a2e3d0"
 dependencies = [
- "elliptic-curve 0.13.2",
+ "elliptic-curve",
 ]
 
 [[package]]
@@ -3300,13 +3079,12 @@ dependencies = [
 
 [[package]]
 name = "proc-macro-crate"
-version = "1.2.1"
+version = "1.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
 dependencies = [
  "once_cell",
- "thiserror",
- "toml",
+ "toml_edit",
 ]
 
 [[package]]
@@ -3350,9 +3128,9 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
 
 [[package]]
 name = "quote"
-version = "1.0.23"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
+checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
 dependencies = [
  "proc-macro2",
 ]
@@ -3509,17 +3287,6 @@ dependencies = [
  "winreg",
 ]
 
-[[package]]
-name = "rfc6979"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb"
-dependencies = [
- "crypto-bigint 0.4.9",
- "hmac 0.12.1",
- "zeroize",
-]
-
 [[package]]
 name = "rfc6979"
 version = "0.4.0"
@@ -3561,6 +3328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec"
 dependencies = [
  "bytes",
+ "rlp-derive",
  "rustc-hex",
 ]
 
@@ -3685,16 +3453,16 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.36.6"
+version = "0.36.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
+checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc"
 dependencies = [
  "bitflags 1.3.2",
  "errno",
  "io-lifetimes",
  "libc",
  "linux-raw-sys",
- "windows-sys",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -3732,15 +3500,15 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "1.0.11"
+version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70"
+checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
 
 [[package]]
 name = "ryu"
-version = "1.0.12"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
+checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
 
 [[package]]
 name = "salsa20"
@@ -3748,7 +3516,7 @@ version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213"
 dependencies = [
- "cipher 0.4.3",
+ "cipher 0.4.4",
 ]
 
 [[package]]
@@ -3766,7 +3534,7 @@ version = "2.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "001cf62ece89779fd16105b5f515ad0e5cedcd5440d3dd806bb067978e7c3608"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "derive_more",
  "parity-scale-codec",
  "scale-info-derive",
@@ -3790,7 +3558,7 @@ version = "0.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
 dependencies = [
- "windows-sys",
+ "windows-sys 0.42.0",
 ]
 
 [[package]]
@@ -3807,9 +3575,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
 name = "scratch"
-version = "1.0.3"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
+checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
 
 [[package]]
 name = "scrypt"
@@ -3833,39 +3601,25 @@ dependencies = [
  "untrusted",
 ]
 
-[[package]]
-name = "sec1"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928"
-dependencies = [
- "base16ct 0.1.1",
- "der 0.6.1",
- "generic-array 0.14.6",
- "pkcs8 0.9.0",
- "subtle",
- "zeroize",
-]
-
 [[package]]
 name = "sec1"
 version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e"
 dependencies = [
- "base16ct 0.2.0",
- "der 0.7.1",
- "generic-array 0.14.6",
- "pkcs8 0.10.1",
+ "base16ct",
+ "der",
+ "generic-array",
+ "pkcs8",
  "subtle",
  "zeroize",
 ]
 
 [[package]]
 name = "security-framework"
-version = "2.7.0"
+version = "2.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c"
+checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
 dependencies = [
  "bitflags 1.3.2",
  "core-foundation",
@@ -3876,9 +3630,9 @@ dependencies = [
 
 [[package]]
 name = "security-framework-sys"
-version = "2.6.1"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
+checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -3893,6 +3647,12 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "send_wrapper"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0"
+
 [[package]]
 name = "send_wrapper"
 version = "0.6.0"
@@ -3901,28 +3661,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
 
 [[package]]
 name = "serde"
-version = "1.0.152"
+version = "1.0.156"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+checksum = "314b5b092c0ade17c00142951e50ced110ec27cea304b1037c6969246c2469a4"
 dependencies = [
  "serde_derive",
 ]
 
-[[package]]
-name = "serde-aux"
-version = "4.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c599b3fd89a75e0c18d6d2be693ddb12cccaf771db4ff9e39097104808a014c0"
-dependencies = [
- "serde",
- "serde_json",
-]
-
 [[package]]
 name = "serde-wasm-bindgen"
-version = "0.4.5"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf"
+checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e"
 dependencies = [
  "js-sys",
  "serde",
@@ -3931,9 +3681,9 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.152"
+version = "1.0.156"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
+checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3942,9 +3692,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.91"
+version = "1.0.94"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
+checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
 dependencies = [
  "itoa",
  "ryu",
@@ -3960,6 +3710,15 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "serde_spanned"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "serde_urlencoded"
 version = "0.7.1"
@@ -3982,7 +3741,7 @@ dependencies = [
  "futures",
  "lazy_static",
  "log",
- "parking_lot 0.12.1",
+ "parking_lot",
  "serial_test_derive",
 ]
 
@@ -4003,23 +3762,11 @@ version = "0.10.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "cpufeatures",
  "digest 0.10.6",
 ]
 
-[[package]]
-name = "sha2"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
-dependencies = [
- "block-buffer 0.7.3",
- "digest 0.8.1",
- "fake-simd",
- "opaque-debug 0.2.3",
-]
-
 [[package]]
 name = "sha2"
 version = "0.9.9"
@@ -4027,11 +3774,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
 dependencies = [
  "block-buffer 0.9.0",
- "cfg-if 1.0.0",
+ "cfg-if",
  "cpufeatures",
  "digest 0.9.0",
- "opaque-debug 0.3.0",
- "sha2-asm",
+ "opaque-debug",
 ]
 
 [[package]]
@@ -4040,19 +3786,9 @@ version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "cpufeatures",
  "digest 0.10.6",
- "sha2-asm",
-]
-
-[[package]]
-name = "sha2-asm"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf27176fb5d15398e3a479c652c20459d9dac830dedd1fa55b42a77dbcdbfcea"
-dependencies = [
- "cc",
 ]
 
 [[package]]
@@ -4082,23 +3818,13 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
 
 [[package]]
 name = "signal-hook-registry"
-version = "1.4.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
 dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "signature"
-version = "1.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
-dependencies = [
- "digest 0.10.6",
- "rand_core",
-]
-
 [[package]]
 name = "signature"
 version = "2.0.0"
@@ -4129,9 +3855,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
 
 [[package]]
 name = "slab"
-version = "0.4.7"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
 dependencies = [
  "autocfg",
 ]
@@ -4144,9 +3870,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
 
 [[package]]
 name = "socket2"
-version = "0.4.7"
+version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
+checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
 dependencies = [
  "libc",
  "winapi",
@@ -4171,16 +3897,6 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
-[[package]]
-name = "spki"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b"
-dependencies = [
- "base64ct",
- "der 0.6.1",
-]
-
 [[package]]
 name = "spki"
 version = "0.7.0"
@@ -4188,7 +3904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0445c905640145c7ea8c1993555957f65e7c46d0535b91ba501bc9bfc85522f"
 dependencies = [
  "base64ct",
- "der 0.7.1",
+ "der",
 ]
 
 [[package]]
@@ -4199,13 +3915,13 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 
 [[package]]
 name = "string_cache"
-version = "0.8.4"
+version = "0.8.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08"
+checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
 dependencies = [
  "new_debug_unreachable",
  "once_cell",
- "parking_lot 0.12.1",
+ "parking_lot",
  "phf_shared 0.10.0",
  "precomputed-hash",
 ]
@@ -4251,7 +3967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "01afefe60c02f4a2271fb15d1965c37856712cebb338330b06649d12afec42df"
 dependencies = [
  "anyhow",
- "cfg-if 1.0.0",
+ "cfg-if",
  "clap",
  "console 0.14.1",
  "dialoguer",
@@ -4323,11 +4039,11 @@ version = "3.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "fastrand",
  "redox_syscall",
  "rustix",
- "windows-sys",
+ "windows-sys 0.42.0",
 ]
 
 [[package]]
@@ -4343,9 +4059,9 @@ dependencies = [
 
 [[package]]
 name = "termcolor"
-version = "1.1.3"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
 dependencies = [
  "winapi-util",
 ]
@@ -4388,20 +4104,20 @@ dependencies = [
 
 [[package]]
 name = "thread_local"
-version = "1.1.4"
+version = "1.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
+checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
 dependencies = [
+ "cfg-if",
  "once_cell",
 ]
 
 [[package]]
 name = "time"
-version = "0.3.17"
+version = "0.3.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
+checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
 dependencies = [
- "itoa",
  "serde",
  "time-core",
  "time-macros",
@@ -4415,9 +4131,9 @@ checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
 
 [[package]]
 name = "time-macros"
-version = "0.2.6"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
+checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36"
 dependencies = [
  "time-core",
 ]
@@ -4452,15 +4168,15 @@ dependencies = [
 
 [[package]]
 name = "tinyvec_macros"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.24.1"
+version = "1.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae"
+checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
 dependencies = [
  "autocfg",
  "bytes",
@@ -4468,12 +4184,12 @@ dependencies = [
  "memchr",
  "mio",
  "num_cpus",
- "parking_lot 0.12.1",
+ "parking_lot",
  "pin-project-lite",
  "signal-hook-registry",
  "socket2",
  "tokio-macros",
- "windows-sys",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -4489,9 +4205,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-native-tls"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
 dependencies = [
  "native-tls",
  "tokio",
@@ -4528,9 +4244,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-util"
-version = "0.7.4"
+version = "0.7.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
+checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
 dependencies = [
  "bytes",
  "futures-core",
@@ -4542,13 +4258,38 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.5.10"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f"
+checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
 dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "toml_edit"
+version = "0.19.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274"
+dependencies = [
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
 [[package]]
 name = "tower-service"
 version = "0.3.2"
@@ -4561,7 +4302,7 @@ version = "0.1.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "pin-project-lite",
  "tracing-attributes",
  "tracing-core",
@@ -4713,15 +4454,15 @@ dependencies = [
 
 [[package]]
 name = "unicode-bidi"
-version = "0.3.8"
+version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+checksum = "524b68aca1d05e03fdf03fcdce2c6c94b6daf6d16861ddaa7e4f2b6638a9052c"
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.6"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
+checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
 
 [[package]]
 name = "unicode-normalization"
@@ -4734,9 +4475,9 @@ dependencies = [
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.10.0"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
 
 [[package]]
 name = "unicode-width"
@@ -4785,9 +4526,9 @@ dependencies = [
 
 [[package]]
 name = "uuid"
-version = "1.2.2"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
+checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
 dependencies = [
  "serde",
 ]
@@ -4812,12 +4553,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "walkdir"
-version = "2.3.2"
+version = "2.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
 dependencies = [
  "same-file",
- "winapi",
  "winapi-util",
 ]
 
@@ -4843,7 +4583,7 @@ version = "0.2.84"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "serde",
  "serde_json",
  "wasm-bindgen-macro",
@@ -4870,7 +4610,7 @@ version = "0.4.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
 dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
  "js-sys",
  "wasm-bindgen",
  "web-sys",
@@ -4929,21 +4669,6 @@ dependencies = [
  "quote",
 ]
 
-[[package]]
-name = "wasm-timer"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
-dependencies = [
- "futures",
- "js-sys",
- "parking_lot 0.11.2",
- "pin-utils",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
-]
-
 [[package]]
 name = "web-sys"
 version = "0.3.61"
@@ -4973,18 +4698,6 @@ dependencies = [
  "webpki",
 ]
 
-[[package]]
-name = "wee_alloc"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "memory_units",
- "winapi",
-]
-
 [[package]]
 name = "winapi"
 version = "0.3.9"
@@ -5031,47 +4744,80 @@ dependencies = [
  "windows_x86_64_msvc",
 ]
 
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
 [[package]]
 name = "windows_aarch64_gnullvm"
-version = "0.42.1"
+version = "0.42.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.42.1"
+version = "0.42.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.42.1"
+version = "0.42.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.42.1"
+version = "0.42.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.42.1"
+version = "0.42.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.42.1"
+version = "0.42.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.42.1"
+version = "0.42.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "winnow"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966"
+dependencies = [
+ "memchr",
+]
 
 [[package]]
 name = "winreg"
@@ -5094,7 +4840,7 @@ dependencies = [
  "log",
  "pharos",
  "rustc_version",
- "send_wrapper",
+ "send_wrapper 0.6.0",
  "thiserror",
  "wasm-bindgen",
  "wasm-bindgen-futures",
@@ -5129,16 +4875,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f6a89568917376ff46a3de7bd0abdac47e9cc8ded4e1018e4a36d071d43a54ad"
 dependencies = [
  "aes 0.8.2",
- "bitflags 2.0.0",
+ "bitflags 2.0.1",
  "cbc",
  "ccm",
  "cmac",
  "digest 0.10.6",
- "ecdsa 0.16.1",
+ "ecdsa",
  "ed25519",
  "ed25519-dalek",
  "hmac 0.12.1",
- "k256 0.13.0",
+ "k256",
  "log",
  "p256",
  "p384",
@@ -5148,11 +4894,11 @@ dependencies = [
  "serde",
  "serde_json",
  "sha2 0.10.6",
- "signature 2.0.0",
+ "signature",
  "subtle",
  "thiserror",
  "time",
- "uuid 1.2.2",
+ "uuid 1.3.0",
  "zeroize",
 ]
 
@@ -5179,9 +4925,9 @@ dependencies = [
 
 [[package]]
 name = "zip"
-version = "0.6.3"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080"
+checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef"
 dependencies = [
  "aes 0.7.5",
  "byteorder",
@@ -5218,9 +4964,9 @@ dependencies = [
 
 [[package]]
 name = "zstd-sys"
-version = "2.0.5+zstd.1.5.2"
+version = "2.0.7+zstd.1.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edc50ffce891ad571e9f9afe5039c4837bede781ac4bb13052ed7ae695518596"
+checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5"
 dependencies = [
  "cc",
  "libc",
diff --git a/Cargo.toml b/Cargo.toml
index e692e203..7e70cb7e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,128 +1,134 @@
-[package]
-name = "ethers"
+[workspace.package]
 version = "2.0.0"
 edition = "2021"
-rust-version = "1.64" # must also be changed in **/Cargo.toml and .clippy.toml
-authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
+rust-version = "1.64"
 license = "MIT OR Apache-2.0"
-readme = "README.md"
 documentation = "https://docs.rs/ethers"
 repository = "https://github.com/gakonst/ethers-rs"
-homepage = "https://docs.rs/ethers"
-description = "A complete Ethereum and Celo Rust library"
+homepage = "https://github.com/gakonst/ethers-rs"
+categories = ["cryptography::cryptocurrencies"]
+keywords = ["crypto", "ethers", "ethereum", "web3", "celo"]
+exclude = [
+    ".github/",
+    "bin/",
+    "book/",
+    "**/tests/",
+    "**/test-data/",
+    "**/testdata/",
+    "examples",
+    "scripts/",
+]
+
+# https://docs.rs/about/metadata
+[workspace.metadata.docs.rs]
+all-features = true
+rustc-args = ["--cfg", "docsrs"]
+rustdoc-args = ["--cfg", "docsrs"]
+
+# https://github.com/integer32llc/rust-playground/blob/c6165a36923db5d99313e6056b5b610a2ede5bb0/top-crates/src/lib.rs#L175-L184
+[workspace.metadata.playground]
+all-features = true
 
 [workspace]
 members = [
+    "ethers",
     "ethers-addressbook",
     "ethers-contract",
-    "ethers-providers",
-    "ethers-signers",
     "ethers-core",
-    "ethers-middleware",
     "ethers-etherscan",
+    "ethers-middleware",
+    "ethers-providers",
+    "ethers-signers",
     "ethers-solc",
+
     # Example crates
     "examples/*",
 ]
 
+# Do not include example crates in default members
 default-members = [
+    "ethers",
     "ethers-addressbook",
     "ethers-contract",
-    "ethers-providers",
-    "ethers-signers",
     "ethers-core",
-    "ethers-middleware",
     "ethers-etherscan",
+    "ethers-middleware",
+    "ethers-providers",
+    "ethers-signers",
     "ethers-solc",
 ]
 
-[package.metadata.docs.rs]
-all-features = true
-rustc-args = ["--cfg", "docsrs"]
-rustdoc-args = ["--cfg", "docsrs"]
-
-[package.metadata.playground]
-features = ["full"]
+[workspace.dependencies]
+# workspace crates
+ethers = { version = "2.0.0", path = "ethers", default-features = false }
+ethers-addressbook = { version = "2.0.0", path = "ethers-addressbook", default-features = false }
+ethers-contract = { version = "2.0.0", path = "ethers-contract", default-features = false }
+ethers-core = { version = "2.0.0", path = "ethers-core", default-features = false }
+ethers-etherscan = { version = "2.0.0", path = "ethers-etherscan", default-features = false }
+ethers-middleware = { version = "2.0.0", path = "ethers-middleware", default-features = false }
+ethers-providers = { version = "2.0.0", path = "ethers-providers", default-features = false }
+ethers-signers = { version = "2.0.0", path = "ethers-signers", default-features = false }
+ethers-solc = { version = "2.0.0", path = "ethers-solc", default-features = false }
 
-[features]
-default = ["abigen"]
+ethers-contract-abigen = { version = "2.0.0", path = "ethers-contract/ethers-contract-abigen", default-features = false }
+ethers-contract-derive = { version = "2.0.0", path = "ethers-contract/ethers-contract-derive", default-features = false }
+ethers-derive-eip712 = { version = "2.0.0", path = "ethers-core/ethers-derive-eip712", default-features = false }
 
-celo = [
-    "ethers-core/celo",
-    "ethers-providers/celo",
-    "ethers-signers/celo",
-    "ethers-contract/celo",
-    "ethers-middleware/celo",
-    "legacy",
-]
+# async / async utils
+tokio = "1.26"
+tokio-tungstenite = { version = "0.18.0", default-features = false }
+futures = { version = "0.3.27", default-features = false }
+futures-core = { version = "0.3.27", default-features = false }
+futures-util = { version = "0.3.27", default-features = false }
+futures-executor = { version = "0.3.27", default-features = false }
+futures-channel = { version = "0.3.27", default-features = false }
+futures-locks = { version = "0.7.1", default-features = false }
+futures-timer = { version = "3.0.2", default-features = false, features = ["wasm-bindgen"] }
+pin-project = "1.0"
+reqwest = { version = "0.11.14", default-features = false }
+url = { version = "2.3", default-features = false }
 
-legacy = ["ethers-core/legacy", "ethers-contract/legacy"]
+# crypto
+elliptic-curve = { version = "0.13.2", default-features = false }
+generic-array = { version = "0.14.6", default-features = false }
+k256 = { version = "0.13.0", default-features = false, features = ["ecdsa", "std"] }
+sha2 = { version = "0.10.6", default-features = false }
+tiny-keccak = { version = "2.0.2", default-features = false }
+spki = { version = "0.7.0", default-features = false }
 
-# individual features per sub-crate
-## core
-eip712 = ["ethers-contract/eip712", "ethers-core/eip712"]
-## providers
-ws = ["ethers-providers/ws"]
-ipc = ["ethers-providers/ipc"]
-rustls = [
-    "ethers-middleware/rustls",
-    "ethers-providers/rustls",
-    "ethers-etherscan/rustls",
-    "ethers-contract/rustls",
-    "ethers-solc/rustls",
-]
-openssl = [
-    "ethers-middleware/openssl",
-    "ethers-providers/openssl",
-    "ethers-etherscan/openssl",
-    "ethers-contract/openssl",
-    "ethers-solc/openssl",
-]
-dev-rpc = ["ethers-providers/dev-rpc"]
-## signers
-ledger = ["ethers-signers/ledger"]
-trezor = ["ethers-signers/trezor"]
-yubi = ["ethers-signers/yubi"]
-## contracts
-abigen = ["ethers-contract/abigen"]
-### abigen without reqwest
-abigen-offline = ["ethers-contract/abigen-offline"]
-## solc
-ethers-solc = ["dep:ethers-solc", "ethers-etherscan/ethers-solc"]
-solc-full = ["ethers-solc", "ethers-solc/full"]
-solc-tests = ["ethers-solc", "ethers-solc/tests"]
-solc-sha2-asm = ["ethers-solc", "ethers-solc/asm"]
-
-[dependencies]
-ethers-addressbook = { version = "^2.0.0", default-features = false, path = "./ethers-addressbook" }
-ethers-contract = { version = "^2.0.0", default-features = false, path = "./ethers-contract" }
-ethers-core = { version = "^2.0.0", default-features = false, path = "./ethers-core" }
-ethers-providers = { version = "^2.0.0", default-features = false, path = "./ethers-providers" }
-ethers-signers = { version = "^2.0.0", default-features = false, path = "./ethers-signers" }
-ethers-middleware = { version = "^2.0.0", default-features = false, path = "./ethers-middleware" }
-ethers-solc = { version = "^2.0.0", default-features = false, path = "./ethers-solc", optional = true }
-ethers-etherscan = { version = "^2.0.0", default-features = false, path = "./ethers-etherscan" }
+# serde
+serde = "1.0"
+serde_json = "1.0"
 
-[dev-dependencies]
-ethers-contract = { version = "^2.0.0", default-features = false, path = "./ethers-contract", features = [
-    "abigen",
-    "eip712",
-] }
-ethers-providers = { version = "^2.0.0", default-features = false, path = "./ethers-providers", features = [
-    "ws",
-    "ipc",
-] }
+# macros
+proc-macro2 = "1.0"
+quote = "1.0"
+syn = "1.0"
+async-trait = "0.1.66"
+auto_impl = "1.0"
 
-bytes = "1.4.0"
+# misc
+thiserror = "1.0"
+once_cell = "1.17"
+hex = "0.4"
 eyre = "0.6"
-hex = "0.4.3"
-rand = "0.8.5"
-serde = { version = "1.0.124", features = ["derive"] }
-serde_json = "1.0.64"
-tempfile = "3.3.0"
-tokio = { version = "1.18", features = ["macros", "rt-multi-thread"] }
+tempfile = "3.4"
+dunce = "1.0"
+walkdir = "2.3"
+regex = "1.7"
+toml = "0.7"
+hex-literal = "0.3"
+rand = "0.8"
+bytes = "1.4"
+semver = "1.0"
+criterion = "0.4"
+rayon = "1.7"
+
+# tracing
+tracing = "0.1.37"
+tracing-subscriber = { version = "0.3.16", default-features = false }
+tracing-futures = "0.2.5"
 
-# profile for the wasm example
-[profile.release.package.ethers-wasm]
-# Tell `rustc` to optimize for small code size.
-opt-level = "s"
+# wasm
+getrandom = { version = "0.2", features = ["js"] }
+instant = "0.1.12"
diff --git a/ethers-addressbook/Cargo.toml b/ethers-addressbook/Cargo.toml
index 758f9008..fc9c4ca0 100644
--- a/ethers-addressbook/Cargo.toml
+++ b/ethers-addressbook/Cargo.toml
@@ -1,18 +1,31 @@
 [package]
 name = "ethers-addressbook"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
-authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
-license = "MIT OR Apache-2.0"
+authors = ["Rohit Narurkar <rohit.narurkar@protonmail.com>"]
+readme = "README.md"
 description = "Common Ethereum name to address mappings"
-homepage = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-keywords = ["ethereum", "web3", "celo", "ethers"]
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
+exclude.workspace = true
+
+[package.metadata.docs.rs]
+all-features = true
+rustc-args = ["--cfg", "docsrs"]
+rustdoc-args = ["--cfg", "docsrs"]
+
+[package.metadata.playground]
+all-features = true
 
 [dependencies]
-ethers-core = { version = "^2.0.0", path = "../ethers-core", default-features = false }
+ethers-core.workspace = true
 
-once_cell = "1.17.1"
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
+once_cell.workspace = true
+serde.workspace = true
+serde_json.workspace = true
diff --git a/ethers-contract/Cargo.toml b/ethers-contract/Cargo.toml
index d6f9a579..a0c65795 100644
--- a/ethers-contract/Cargo.toml
+++ b/ethers-contract/Cargo.toml
@@ -1,45 +1,53 @@
 [package]
 name = "ethers-contract"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
-license = "MIT OR Apache-2.0"
-description = "Smart contract bindings for the ethers-rs crate"
-homepage = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-keywords = ["ethereum", "web3", "celo", "ethers"]
+readme = "README.md"
+description = "Type-safe abstractions for interacting with Ethereum smart contracts"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
+exclude.workspace = true
+
+[package.metadata.docs.rs]
+all-features = true
+rustc-args = ["--cfg", "docsrs"]
+rustdoc-args = ["--cfg", "docsrs"]
+
+[package.metadata.playground]
+all-features = true
 
 [dependencies]
-ethers-providers = { version = "^2.0.0", path = "../ethers-providers", default-features = false }
-ethers-core = { version = "^2.0.0", path = "../ethers-core", default-features = false }
-ethers-contract-abigen = { version = "^2.0.0", path = "ethers-contract-abigen", default-features = false, optional = true }
-ethers-contract-derive = { version = "^2.0.0", path = "ethers-contract-derive", optional = true }
-ethers-derive-eip712 = { version = "^2.0.0", path = "../ethers-core/ethers-derive-eip712", optional = true }
-
-serde = { version = "1.0.124", default-features = false }
-serde_json = { version = "1.0.64", default-features = false }
-thiserror = { version = "1.0", default-features = false }
-once_cell = { version = "1.17.1" }
-pin-project = { version = "1.0.11", default-features = false }
-futures-util = { version = "^0.3" }
-hex = { version = "0.4.3", default-features = false, features = ["std"] }
+ethers-providers.workspace = true
+ethers-core.workspace = true
+
+serde.workspace = true
+serde_json.workspace = true
+futures-util.workspace = true
+pin-project.workspace = true
+thiserror.workspace = true
+once_cell.workspace = true
+hex.workspace = true
+
+# abigen
+ethers-contract-abigen = { workspace = true, optional = true }
+ethers-contract-derive = { workspace = true, optional = true }
+
+# eip712
+ethers-derive-eip712 = { workspace = true, optional = true }
 
 [dev-dependencies]
-ethers-providers = { version = "^2.0.0", path = "../ethers-providers", default-features = false, features = [
-    "ws",
-] }
-ethers-signers = { version = "^2.0.0", path = "../ethers-signers" }
-ethers-contract-abigen = { version = "^2.0.0", path = "ethers-contract-abigen" }
-ethers-contract-derive = { version = "^2.0.0", path = "ethers-contract-derive" }
-ethers-core = { version = "^2.0.0", path = "../ethers-core", default-features = false, features = [
-    "eip712",
-] }
-ethers-derive-eip712 = { version = "^2.0.0", path = "../ethers-core/ethers-derive-eip712" }
-ethers-solc = { version = "^2.0.0", path = "../ethers-solc", default-features = false }
+ethers-signers.workspace = true
+ethers-solc.workspace = true
 
 [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
-tokio = { version = "1.18", default-features = false, features = ["macros"] }
+tokio = { workspace = true, features = ["macros"] }
 
 [features]
 default = ["abigen"]
@@ -54,8 +62,3 @@ legacy = []
 
 rustls = ["ethers-contract-abigen/rustls"]
 openssl = ["ethers-contract-abigen/openssl"]
-
-[package.metadata.docs.rs]
-all-features = true
-rustc-args = ["--cfg", "docsrs"]
-rustdoc-args = ["--cfg", "docsrs"]
diff --git a/ethers-contract/ethers-contract-abigen/Cargo.toml b/ethers-contract/ethers-contract-abigen/Cargo.toml
index ba752d62..3c15c8a0 100644
--- a/ethers-contract/ethers-contract-abigen/Cargo.toml
+++ b/ethers-contract/ethers-contract-abigen/Cargo.toml
@@ -1,50 +1,58 @@
 [package]
 name = "ethers-contract-abigen"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = [
     "Nicholas Rodrigues Lordello <nlordell@gmail.com>",
     "Georgios Konstantopoulos <me@gakonst.com>",
 ]
-license = "MIT OR Apache-2.0"
+readme = "README.md"
 description = "Code generation for type-safe bindings to Ethereum smart contracts"
-homepage = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-keywords = ["ethereum", "web3", "celo", "ethers"]
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
+
+[package.metadata.docs.rs]
+all-features = true
+rustc-args = ["--cfg", "docsrs"]
+rustdoc-args = ["--cfg", "docsrs"]
+
+[package.metadata.playground]
+all-features = true
 
 [dependencies]
-ethers-core = { version = "^2.0.0", path = "../../ethers-core", features = ["macros"] }
-ethers-etherscan = { version = "^2.0.0", path = "../../ethers-etherscan", default-features = false, optional = true }
+ethers-core = { workspace = true, features = ["macros"] }
 
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = { version = "1.0.12", default-features = false, features = ["full", "extra-traits"] }
-prettyplease = "0.1.23"
+proc-macro2.workspace = true
+quote.workspace = true
+syn = { workspace = true, features = ["full"] }
+prettyplease = "0.1.25"
 
 Inflector = "0.11"
-serde_json = "1.0.61"
-serde = { version = "1.0.124", features = ["derive"] }
-hex = { version = "0.4.2", default-features = false, features = ["std"] }
-cfg-if = "1.0.0"
-dunce = "1.0.2"
-walkdir = "2.3.2"
-eyre = "0.6"
-regex = "1.6.0"
-toml = "0.5.9"
-
-reqwest = { version = "0.11.3", default-features = false, features = ["blocking"], optional = true }
-tokio = { version = "1.0", default-features = false, features = ["sync"], optional = true }
-url = { version = "2.3.1", default-features = false, optional = true }
+serde.workspace = true
+serde_json.workspace = true
+hex.workspace = true
+dunce.workspace = true
+walkdir.workspace = true
+eyre.workspace = true
+regex.workspace = true
+toml.workspace = true
+
+[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
+# online
+ethers-etherscan = { workspace = true, optional = true }
+reqwest = { workspace = true, features = ["blocking"], optional = true }
+tokio = { workspace = true, optional = true }
+url = { workspace = true, optional = true }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 # NOTE: this enables wasm compatibility for getrandom indirectly
-getrandom = { version = "0.2", features = ["js"] }
-
-[package.metadata.docs.rs]
-all-features = true
-rustc-args = ["--cfg", "docsrs"]
-rustdoc-args = ["--cfg", "docsrs"]
+getrandom.workspace = true
 
 [features]
 online = ["reqwest", "ethers-etherscan", "url", "tokio"]
@@ -52,8 +60,5 @@ openssl = ["online", "reqwest/native-tls", "ethers-etherscan/openssl"]
 rustls = ["online", "reqwest/rustls-tls", "ethers-etherscan/rustls"]
 
 [dev-dependencies]
-tempfile = "3.2.0"
-ethers-solc = { version = "^2.0.0", path = "../../ethers-solc", default-features = false, features = [
-    "project-util",
-    "svm-solc",
-] }
+tempfile.workspace = true
+ethers-solc = { workspace = true, features = ["project-util", "svm-solc"] }
diff --git a/ethers-contract/ethers-contract-abigen/README.md b/ethers-contract/ethers-contract-abigen/README.md
index 32456f83..ec62cd58 100644
--- a/ethers-contract/ethers-contract-abigen/README.md
+++ b/ethers-contract/ethers-contract-abigen/README.md
@@ -1,1 +1,7 @@
+# ethers-contract-abigen
+
+Code generation for type-safe bindings to Ethereum smart contracts.
+
 This code generator was adapted from the original [ethcontract-rs repository by Gnosis](https://github.com/gnosis/ethcontract-rs/tree/master/generate).
+
+For more information, please refer to the [book](https://gakonst.com/ethers-rs).
diff --git a/ethers-contract/ethers-contract-derive/Cargo.toml b/ethers-contract/ethers-contract-derive/Cargo.toml
index 4e87a4cf..65348d4b 100644
--- a/ethers-contract/ethers-contract-derive/Cargo.toml
+++ b/ethers-contract/ethers-contract-derive/Cargo.toml
@@ -1,32 +1,31 @@
 [package]
 name = "ethers-contract-derive"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = [
     "Nicholas Rodrigues Lordello <nlordell@gmail.com>",
     "Georgios Konstantopoulos <me@gakonst.com>",
 ]
-license = "MIT OR Apache-2.0"
-description = "Proc macro for type-safe bindings generation to Ethereum and Celo smart contracts"
-homepage = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-keywords = ["ethereum", "web3", "celo", "ethers"]
+readme = "README.md"
+description = "Proc macros for type-safe bindings generation to Ethereum smart contracts"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
 
 [lib]
 proc-macro = true
 
 [dependencies]
-ethers-core = { version = "^2.0.0", path = "../../ethers-core" }
-ethers-contract-abigen = { version = "^2.0.0", path = "../ethers-contract-abigen", default-features = false }
-
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = "1.0.12"
+ethers-core.workspace = true
+ethers-contract-abigen.workspace = true
 
-hex = { version = "0.4.3", default-features = false, features = ["std"] }
+proc-macro2.workspace = true
+quote.workspace = true
+syn.workspace = true
 
-[package.metadata.docs.rs]
-all-features = true
-rustc-args = ["--cfg", "docsrs"]
-rustdoc-args = ["--cfg", "docsrs"]
+hex.workspace = true
diff --git a/ethers-contract/ethers-contract-derive/README.md b/ethers-contract/ethers-contract-derive/README.md
index 9ca54ec8..6a42444b 100644
--- a/ethers-contract/ethers-contract-derive/README.md
+++ b/ethers-contract/ethers-contract-derive/README.md
@@ -1,1 +1,7 @@
-This proc-macro was adapted from the original [ethcontract-rs repository by Gnosis](https://github.com/gnosis/ethcontract-rs/tree/master/derive).
+# ethers-contract-derive
+
+Proc macros for type-safe bindings generation to Ethereum smart contracts.
+
+Adapted from the original [ethcontract-rs repository by Gnosis](https://github.com/gnosis/ethcontract-rs/tree/master/derive).
+
+For more information, please refer to the [book](https://gakonst.com/ethers-rs).
diff --git a/ethers-contract/ethers-contract-derive/src/event.rs b/ethers-contract/ethers-contract-derive/src/event.rs
index e6c8594b..f7876e65 100644
--- a/ethers-contract/ethers-contract-derive/src/event.rs
+++ b/ethers-contract/ethers-contract-derive/src/event.rs
@@ -207,7 +207,7 @@ fn derive_decode_from_log_impl(input: &DeriveInput, event: &Event) -> Result<Tok
             #signature_check
 
             if topics.len() != 1usize || !data.is_empty() {
-                return Err(::ethers_core::abi::Error::InvalidData);
+                return Err(#ethers_core::abi::Error::InvalidData);
             }
 
             #ethers_core::abi::Tokenizable::from_token(#ethers_core::abi::Token::Tuple(::std::vec::Vec::new())).map_err(|_|#ethers_core::abi::Error::InvalidData)
diff --git a/ethers-contract/src/factory.rs b/ethers-contract/src/factory.rs
index 6aa08eab..b396ef0b 100644
--- a/ethers-contract/src/factory.rs
+++ b/ethers-contract/src/factory.rs
@@ -275,7 +275,7 @@ where
     /// Broadcasts the contract deployment transaction and after waiting for it to
     /// be sufficiently confirmed (default: 1), it returns a tuple with
     /// the [`Contract`](crate::Contract) struct at the deployed contract's address
-    /// and the corresponding [`TransactionReceipt`](ethers_core::types::TransactionReceipt).
+    /// and the corresponding [`TransactionReceipt`].
     pub async fn send_with_receipt(
         self,
     ) -> Result<(ContractInstance<B, M>, TransactionReceipt), ContractError<M>> {
@@ -290,11 +290,12 @@ where
         let receipt = pending_tx
             .confirmations(self.confs)
             .await
-            .map_err(|_| ContractError::ContractNotDeployed)?
+            .ok()
+            .flatten()
             .ok_or(ContractError::ContractNotDeployed)?;
         let address = receipt.contract_address.ok_or(ContractError::ContractNotDeployed)?;
 
-        let contract = ContractInstance::new(address, self.abi.clone(), self.client.clone());
+        let contract = ContractInstance::new(address, self.abi, self.client);
         Ok((contract, receipt))
     }
 
diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml
index dc8eaced..fd5211ec 100644
--- a/ethers-core/Cargo.toml
+++ b/ethers-core/Cargo.toml
@@ -1,70 +1,77 @@
 [package]
 name = "ethers-core"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
-license = "MIT OR Apache-2.0"
-description = "Core structures for the ethers-rs crate"
-homepage = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-keywords = ["ethereum", "web3", "celo", "ethers"]
+readme = "README.md"
+description = "Ethereum data types, cryptography and utilities"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
+exclude.workspace = true
+
+[package.metadata.docs.rs]
+all-features = true
+rustc-args = ["--cfg", "docsrs"]
+rustdoc-args = ["--cfg", "docsrs"]
+
+[package.metadata.playground]
+all-features = true
 
 [dependencies]
+# abi
 open-fastrlp = { version = "0.1.4", features = ["std", "derive", "ethereum-types"] }
-rlp = { version = "0.5.2", default-features = false, features = ["std"] }
+rlp = { version = "0.5", features = ["derive"] }
 ethabi = { version = "18.0.0", default-features = false, features = ["full-serde", "rlp"] }
-arrayvec = { version = "0.7.2", default-features = false }
-rlp-derive = { version = "0.1.0", default-features = false }
+arrayvec = { version = "0.7", default-features = false }
 
 # crypto
-elliptic-curve = { version = "0.13.2", default-features = false }
-generic-array = { version = "0.14.6", default-features = false }
-k256 = { version = "0.13.0", default-features = false, features = ["ecdsa", "std"] }
-rand = { version = "0.8.5", default-features = false }
-tiny-keccak = { version = "2.0.2", default-features = false }
+elliptic-curve.workspace = true
+generic-array.workspace = true
+k256 = { workspace = true, features = ["ecdsa", "std"] }
+tiny-keccak.workspace = true
+rand.workspace = true
 
 # misc
 chrono = { version = "0.4", default-features = false }
-serde = { version = "1.0.124", default-features = false, features = ["derive"] }
-serde_json = { version = "1.0.64", default-features = false, features = ["arbitrary_precision"] }
-thiserror = { version = "1.0", default-features = false }
-bytes = { version = "1.4.0", features = ["serde"] }
-hex = { version = "0.4.3", default-features = false, features = ["std"] }
-once_cell = { version = "1.17.1", optional = true }
-unicode-xid = "0.2.4"
+serde.workspace = true
+serde_json = { workspace = true, features = ["arbitrary_precision"] }
+thiserror.workspace = true
+bytes = { workspace = true, features = ["serde"] }
+hex.workspace = true
+once_cell = { workspace = true, optional = true }
+unicode-xid = "0.2"
 strum = { version = "0.24", features = ["derive"] }
+num_enum = "0.5"
 
 # macros feature enabled dependencies
 cargo_metadata = { version = "0.15.3", optional = true }
 
 # eip712 feature enabled dependencies
 convert_case = { version = "0.6.0", optional = true }
-syn = { version = "1.0.109", optional = true }
-proc-macro2 = { version = "1.0.52", optional = true }
-num_enum = "0.5.11"
+syn = { workspace = true, optional = true }
+proc-macro2 = { workspace = true, optional = true }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
-tempfile = { version = "3.4.0", default-features = false }
+tempfile.workspace = true
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 # NOTE: this enables wasm compatibility for getrandom indirectly
-getrandom = { version = "0.2", features = ["js"] }
+getrandom.workspace = true
 
 [dev-dependencies]
-serde_json = { version = "1.0.64", default-features = false }
 bincode = { version = "1.3.3", default-features = false }
-once_cell = { version = "1.17.1" }
-hex-literal = "0.3.4"
-rand = "0.8.5"
+once_cell.workspace = true
+hex-literal.workspace = true
+rand.workspace = true
 
 [features]
 celo = ["legacy"] # celo support extends the transaction format with extra fields
 legacy = []
 eip712 = ["convert_case", "syn", "proc-macro2"]
 macros = ["syn", "cargo_metadata", "once_cell"]
-
-[package.metadata.docs.rs]
-all-features = true
-rustc-args = ["--cfg", "docsrs"]
-rustdoc-args = ["--cfg", "docsrs"]
diff --git a/ethers-core/ethers-derive-eip712/Cargo.toml b/ethers-core/ethers-derive-eip712/Cargo.toml
index c301aecd..5f2e320a 100644
--- a/ethers-core/ethers-derive-eip712/Cargo.toml
+++ b/ethers-core/ethers-derive-eip712/Cargo.toml
@@ -1,23 +1,29 @@
 [package]
 name = "ethers-derive-eip712"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
-description = "Custom derive macro for EIP-712 typed data"
-license = "MIT OR Apache-2.0"
+authors = ["Ryan Tate <ryan.michael.tate@gmail.com>"]
+description = "Derive procedural macro for EIP-712 typed data"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
 
 [lib]
 proc-macro = true
 
 [dependencies]
-quote = "1.0.9"
-syn = "1.0.77"
-ethers-core = { version = "^2.0.0", path = "../", default-features = false, features = [
-    "eip712",
-    "macros",
-] }
-hex = "0.4.3"
-serde_json = "1.0.68"
+ethers-core = { workspace = true, features = ["eip712", "macros"] }
+
+quote.workspace = true
+syn.workspace = true
+
+hex.workspace = true
+serde_json.workspace = true
 
 [dev-dependencies]
-ethers-contract-derive = { version = "^2.0.0", path = "../../ethers-contract/ethers-contract-derive" }
+ethers-contract-derive.workspace = true
diff --git a/ethers-core/ethers-derive-eip712/src/lib.rs b/ethers-core/ethers-derive-eip712/src/lib.rs
index 2670c3f7..e1c1272a 100644
--- a/ethers-core/ethers-derive-eip712/src/lib.rs
+++ b/ethers-core/ethers-derive-eip712/src/lib.rs
@@ -1,4 +1,5 @@
 //! # EIP-712 Derive Macro
+//!
 //! This crate provides a derive macro `Eip712` that is used to encode a rust struct
 //! into a payload hash, according to [https://eips.ethereum.org/EIPS/eip-712](https://eips.ethereum.org/EIPS/eip-712)
 //!
diff --git a/ethers-core/src/macros/ethers_crate.rs b/ethers-core/src/macros/ethers_crate.rs
index d1f8b263..83b20b5c 100644
--- a/ethers-core/src/macros/ethers_crate.rs
+++ b/ethers-core/src/macros/ethers_crate.rs
@@ -564,13 +564,14 @@ mod tests {
             String::with_capacity(150 * (ethers as usize + dependencies.len()));
 
         if ethers {
-            let ethers = format!("ethers = {{ path = {ethers_root:?} }}\n");
+            let path = ethers_root.join("ethers");
+            let ethers = format!("ethers = {{ path = \"{}\" }}\n", path.display());
             dependencies_toml.push_str(&ethers);
         }
 
         for dep in dependencies.iter() {
             let path = ethers_root.join(dep.fs_path());
-            let dep = format!("{dep} = {{ path = {path:?} }}\n");
+            let dep = format!("{dep} = {{ path = \"{}\" }}\n", path.display());
             dependencies_toml.push_str(&dep);
         }
 
diff --git a/ethers-core/src/types/chain.rs b/ethers-core/src/types/chain.rs
index f5264a21..979b4c98 100644
--- a/ethers-core/src/types/chain.rs
+++ b/ethers-core/src/types/chain.rs
@@ -16,9 +16,15 @@ pub type ParseChainError = TryFromPrimitiveError<Chain>;
 // When adding a new chain:
 //   1. add new variant to the Chain enum;
 //   2. add extra information in the last `impl` block (explorer URLs, block time) when applicable;
-//   3. (optional) add aliases: `#[strum(serialize = "main", serialize = "alias", ...)]`;
-//      "main" must be present and will be used in `Display`, `Serialize` and `FromStr`,
-//      while the aliases will be added only to `FromStr`.
+//   3. (optional) add aliases:
+//     - Strum (in kebab-case): `#[strum(to_string = "<main>", serialize = "<aliasX>", ...)]`
+//      `to_string = "<main>"` must be present and will be used in `Display`, `Serialize`
+//      and `FromStr`, while `serialize = "<aliasX>"` will be appended to `FromStr`.
+//      More info: <https://docs.rs/strum/latest/strum/additional_attributes/index.html#attributes-on-variants>
+//     - Serde (in snake_case): `#[serde(alias = "<aliasX>", ...)]`
+//      Aliases are appended to the `Deserialize` implementation.
+//      More info: <https://serde.rs/variant-attrs.html>
+//     - Add a test at the bottom of the file
 
 // We don't derive Serialize because it is manually implemented using AsRef<str> and it would
 // break a lot of things since Serialize is `kebab-case` vs Deserialize `snake_case`.
@@ -69,19 +75,23 @@ pub enum Chain {
 
     Rsk = 30,
 
-    #[strum(serialize = "bsc")]
+    #[strum(to_string = "bsc", serialize = "binance-smart-chain")]
+    #[serde(alias = "bsc")]
     BinanceSmartChain = 56,
-    #[strum(serialize = "bsc-testnet")]
+    #[strum(to_string = "bsc-testnet", serialize = "binance-smart-chain-testnet")]
+    #[serde(alias = "bsc_testnet")]
     BinanceSmartChainTestnet = 97,
 
     Poa = 99,
     Sokol = 77,
 
-    #[strum(serialize = "gnosis", serialize = "xdai", serialize = "gnosis-chain")]
+    #[strum(to_string = "xdai", serialize = "gnosis", serialize = "gnosis-chain")]
+    #[serde(alias = "xdai", alias = "gnosis", alias = "gnosis_chain")]
     XDai = 100,
 
     Polygon = 137,
-    #[strum(serialize = "mumbai", serialize = "polygon-mumbai")]
+    #[strum(to_string = "mumbai", serialize = "polygon-mumbai")]
+    #[serde(alias = "mumbai")]
     PolygonMumbai = 80001,
 
     Fantom = 250,
@@ -94,9 +104,9 @@ pub enum Chain {
 
     Moonbase = 1287,
 
-    #[strum(serialize = "dev")]
     Dev = 1337,
-    #[strum(serialize = "anvil-hardhat", serialize = "anvil", serialize = "hardhat")]
+    #[strum(to_string = "anvil-hardhat", serialize = "anvil", serialize = "hardhat")]
+    #[serde(alias = "anvil", alias = "hardhat")]
     AnvilHardhat = 31337,
 
     Evmos = 9001,
@@ -113,7 +123,8 @@ pub enum Chain {
     FilecoinHyperspaceTestnet = 3141,
 
     Avalanche = 43114,
-    #[strum(serialize = "fuji", serialize = "avalanche-fuji")]
+    #[strum(to_string = "fuji", serialize = "avalanche-fuji")]
+    #[serde(alias = "fuji")]
     AvalancheFuji = 43113,
 
     Celo = 42220,
@@ -213,6 +224,7 @@ impl Serialize for Chain {
 
 // NB: all utility functions *should* be explicitly exhaustive (not use `_` matcher) so we don't
 //     forget to update them when adding a new `Chain` variant.
+#[allow(clippy::match_like_matches_macro)]
 impl Chain {
     /// Returns the chain's average blocktime, if applicable.
     ///
@@ -274,7 +286,6 @@ impl Chain {
     /// assert!(!Chain::Mainnet.is_legacy());
     /// assert!(Chain::Celo.is_legacy());
     /// ```
-    #[allow(clippy::match_like_matches_macro)]
     pub const fn is_legacy(&self) -> bool {
         use Chain::*;
 
@@ -550,12 +561,56 @@ mod tests {
     use strum::IntoEnumIterator;
 
     #[test]
-    fn test_default_chain() {
+    fn default() {
         assert_eq!(serde_json::to_string(&Chain::default()).unwrap(), "\"mainnet\"");
     }
 
     #[test]
-    fn test_enum_iter() {
+    fn enum_iter() {
         assert_eq!(Chain::COUNT, Chain::iter().size_hint().0);
     }
+
+    #[test]
+    fn roundtrip_string() {
+        for chain in Chain::iter() {
+            let chain_string = chain.to_string();
+            assert_eq!(chain_string, format!("{chain}"));
+            assert_eq!(chain_string.as_str(), chain.as_ref());
+            assert_eq!(serde_json::to_string(&chain).unwrap(), format!("\"{chain_string}\""));
+
+            assert_eq!(chain_string.parse::<Chain>().unwrap(), chain);
+        }
+    }
+
+    #[test]
+    fn roundtrip_serde() {
+        for chain in Chain::iter() {
+            let chain_string = serde_json::to_string(&chain).unwrap();
+            let chain_string = chain_string.replace('-', "_");
+            assert_eq!(serde_json::from_str::<'_, Chain>(&chain_string).unwrap(), chain);
+        }
+    }
+
+    #[test]
+    fn aliases() {
+        use Chain::*;
+
+        // kebab-case
+        const ALIASES: &[(Chain, &[&str])] = &[
+            (BinanceSmartChain, &["bsc", "binance-smart-chain"]),
+            (BinanceSmartChainTestnet, &["bsc-testnet", "binance-smart-chain-testnet"]),
+            (XDai, &["xdai", "gnosis", "gnosis-chain"]),
+            (PolygonMumbai, &["mumbai"]),
+            (AnvilHardhat, &["anvil", "hardhat"]),
+            (AvalancheFuji, &["fuji"]),
+        ];
+
+        for &(chain, aliases) in ALIASES {
+            for &alias in aliases {
+                assert_eq!(alias.parse::<Chain>().unwrap(), chain);
+                let s = alias.to_string().replace('-', "_");
+                assert_eq!(serde_json::from_str::<Chain>(&format!("\"{s}\"")).unwrap(), chain);
+            }
+        }
+    }
 }
diff --git a/ethers-core/src/types/transaction/eip2930.rs b/ethers-core/src/types/transaction/eip2930.rs
index 4f430e5a..d4a04b8f 100644
--- a/ethers-core/src/types/transaction/eip2930.rs
+++ b/ethers-core/src/types/transaction/eip2930.rs
@@ -6,8 +6,9 @@ use open_fastrlp::{
     RlpDecodable as FastRlpDecodable, RlpDecodableWrapper as FastRlpDecodableWrapper,
     RlpEncodable as FastRlpEncodable, RlpEncodableWrapper as FastRlpEncodableWrapper,
 };
-use rlp::{Decodable, RlpStream};
-use rlp_derive::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
+use rlp::{
+    Decodable, RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper, RlpStream,
+};
 use serde::{Deserialize, Serialize};
 use thiserror::Error;
 
diff --git a/ethers-etherscan/Cargo.toml b/ethers-etherscan/Cargo.toml
index 04d909d1..b402810b 100644
--- a/ethers-etherscan/Cargo.toml
+++ b/ethers-etherscan/Cargo.toml
@@ -1,49 +1,54 @@
 [package]
 name = "ethers-etherscan"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = [
     "Matthias Seitz <matthias.seitz@outlook.de>",
     "Georgios Konstantopoulos <me@gakonst.com>",
 ]
-license = "MIT OR Apache-2.0"
-readme = "../README.md"
-documentation = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-homepage = "https://docs.rs/ethers"
-description = """
-Rust API bindings for the etherscan.io web API
-"""
-keywords = ["ethereum", "web3", "etherscan", "ethers"]
+readme = "README.md"
+description = "Bindings for the etherscan.io web API"
+keywords = ["crypto", "ethers", "ethereum", "web3", "etherscan"]
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+exclude.workspace = true
+
+[package.metadata.docs.rs]
+all-features = true
+rustc-args = ["--cfg", "docsrs"]
+rustdoc-args = ["--cfg", "docsrs"]
+
+[package.metadata.playground]
+all-features = true
 
 [dependencies]
-ethers-core = { version = "^2.0.0", path = "../ethers-core", default-features = false }
-ethers-solc = { version = "^2.0.0", path = "../ethers-solc", default-features = false, optional = true }
-reqwest = { version = "0.11.14", default-features = false, features = ["json"] }
-serde = { version = "1.0.124", default-features = false, features = ["derive"] }
-serde_json = { version = "1.0.64", default-features = false }
-serde-aux = { version = "4.1.2", default-features = false }
-thiserror = "1.0"
-tracing = "0.1.37"
-semver = "1.0.17"
+ethers-core.workspace = true
+
+ethers-solc = { workspace = true, optional = true }
+
+reqwest = { workspace = true, features = ["json"] }
+serde = { workspace = true, features = ["derive"] }
+serde_json.workspace = true
+thiserror.workspace = true
+tracing.workspace = true
+semver.workspace = true
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 # NOTE: this enables wasm compatibility for getrandom indirectly
-getrandom = { version = "0.2", features = ["js"] }
+getrandom.workspace = true
 
 [dev-dependencies]
-ethers-solc = { version = "^2.0.0", path = "../ethers-solc", default-features = false }
+ethers-solc.workspace = true
 
-tempfile = "3.4.0"
-tokio = { version = "1.18", features = ["macros", "rt-multi-thread", "time"] }
+tempfile.workspace = true
+tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] }
 serial_test = "1.0.0"
-tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] }
-
-[package.metadata.docs.rs]
-all-features = true
-rustc-args = ["--cfg", "docsrs"]
-rustdoc-args = ["--cfg", "docsrs"]
+tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
 
 [features]
 default = ["rustls"]
diff --git a/ethers-etherscan/src/gas.rs b/ethers-etherscan/src/gas.rs
index 11fd311d..e58fc2f3 100644
--- a/ethers-etherscan/src/gas.rs
+++ b/ethers-etherscan/src/gas.rs
@@ -1,11 +1,7 @@
-use std::{collections::HashMap, str::FromStr};
-
-use serde::{de, Deserialize};
-use serde_aux::prelude::*;
-
-use ethers_core::types::U256;
-
 use crate::{Client, EtherscanError, Response, Result};
+use ethers_core::types::U256;
+use serde::{de, Deserialize, Deserializer};
+use std::{collections::HashMap, str::FromStr};
 
 #[derive(Deserialize, Clone, Debug)]
 #[serde(rename_all = "PascalCase")]
@@ -26,6 +22,25 @@ pub struct GasOracle {
     pub gas_used_ratio: Vec<f64>,
 }
 
+fn deserialize_number_from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
+where
+    D: Deserializer<'de>,
+    T: FromStr + serde::Deserialize<'de>,
+    <T as FromStr>::Err: std::fmt::Display,
+{
+    #[derive(Deserialize)]
+    #[serde(untagged)]
+    enum StringOrInt<T> {
+        String(String),
+        Number(T),
+    }
+
+    match StringOrInt::<T>::deserialize(deserializer)? {
+        StringOrInt::String(s) => s.parse::<T>().map_err(serde::de::Error::custom),
+        StringOrInt::Number(i) => Ok(i),
+    }
+}
+
 fn deserialize_f64_vec<'de, D>(deserializer: D) -> core::result::Result<Vec<f64>, D::Error>
 where
     D: de::Deserializer<'de>,
diff --git a/ethers-etherscan/src/lib.rs b/ethers-etherscan/src/lib.rs
index 453eaefb..b9594e3e 100644
--- a/ethers-etherscan/src/lib.rs
+++ b/ethers-etherscan/src/lib.rs
@@ -27,7 +27,7 @@ pub mod transaction;
 pub mod utils;
 pub mod verify;
 
-pub(crate) type Result<T> = std::result::Result<T, EtherscanError>;
+pub(crate) type Result<T, E = EtherscanError> = std::result::Result<T, E>;
 
 /// The Etherscan.io API client.
 #[derive(Clone, Debug)]
diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml
index 4c6cb331..fce13218 100644
--- a/ethers-middleware/Cargo.toml
+++ b/ethers-middleware/Cargo.toml
@@ -1,62 +1,65 @@
 [package]
 name = "ethers-middleware"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
-license = "MIT OR Apache-2.0"
+readme = "README.md"
 description = "Middleware implementations for the ethers-rs crate"
-homepage = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-keywords = ["ethereum", "web3", "celo", "ethers"]
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
+exclude.workspace = true
 
 [package.metadata.docs.rs]
 all-features = true
 rustc-args = ["--cfg", "docsrs"]
 rustdoc-args = ["--cfg", "docsrs"]
 
+[package.metadata.playground]
+all-features = true
+
 [dependencies]
-ethers-contract = { version = "^2.0.0", path = "../ethers-contract", default-features = false, features = [
-    "abigen",
-] }
-ethers-core = { version = "^2.0.0", path = "../ethers-core", default-features = false }
-ethers-etherscan = { version = "^2.0.0", path = "../ethers-etherscan", default-features = false }
-ethers-providers = { version = "^2.0.0", path = "../ethers-providers", default-features = false }
-ethers-signers = { version = "^2.0.0", path = "../ethers-signers", default-features = false }
+ethers-contract = { workspace = true, features = ["abigen"] }
+ethers-core.workspace = true
+ethers-etherscan.workspace = true
+ethers-providers.workspace = true
+ethers-signers.workspace = true
 
-async-trait = { version = "0.1.50", default-features = false }
-auto_impl = { version = "1.0.1", default-features = false }
-serde = { version = "1.0.124", default-features = false, features = ["derive"] }
-thiserror = { version = "1.0", default-features = false }
-futures-util = { version = "^0.3" }
-futures-locks = { version = "0.7", default-features = false }
-tracing = { version = "0.1.37", default-features = false }
-tracing-futures = { version = "0.2.5", default-features = false }
+async-trait.workspace = true
+auto_impl.workspace = true
+serde.workspace = true
+thiserror.workspace = true
+futures-util.workspace = true
+futures-locks.workspace = true
+tracing.workspace = true
+tracing-futures.workspace = true
+instant.workspace = true
 
 # for gas oracles
-reqwest = { version = "0.11.14", default-features = false, features = ["json", "rustls-tls"] }
-url = { version = "2.3.1", default-features = false }
+reqwest.workspace = true
+url.workspace = true
 
-serde_json = { version = "1.0.64", default-features = false }
-instant = { version = "0.1.12", features = ["now"] }
+serde_json.workspace = true
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
-tokio = { version = "1.18" }
+tokio.workspace = true
 
 [dev-dependencies]
-ethers-providers = { version = "^2.0.0", path = "../ethers-providers", default-features = false, features = [
-    "ws",
-    "rustls",
-] }
-ethers-solc = { version = "^2.0.0", path = "../ethers-solc" }
+ethers-providers = { workspace = true, features = ["ws", "rustls"] }
+ethers-solc.workspace = true
 
-hex = { version = "0.4.3", default-features = false, features = ["std"] }
-rand = { version = "0.8.5", default-features = false }
-once_cell = "1.17.1"
-reqwest = { version = "0.11.14", default-features = false, features = ["json", "rustls"] }
+hex.workspace = true
+rand.workspace = true
+once_cell.workspace = true
+reqwest = { workspace = true, features = ["json", "rustls"] }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
-tokio = { version = "1.18", default-features = false, features = ["rt", "macros", "time"] }
+tokio = { workspace = true, features = ["rt", "macros", "time"] }
 
 [features]
 default = ["rustls"]
diff --git a/ethers-middleware/src/gas_oracle/cache.rs b/ethers-middleware/src/gas_oracle/cache.rs
index d840cb0f..482d9625 100644
--- a/ethers-middleware/src/gas_oracle/cache.rs
+++ b/ethers-middleware/src/gas_oracle/cache.rs
@@ -2,11 +2,8 @@ use super::{GasOracle, Result};
 use async_trait::async_trait;
 use ethers_core::types::U256;
 use futures_locks::RwLock;
-use std::{
-    fmt::Debug,
-    future::Future,
-    time::{Duration, Instant},
-};
+use instant::{Duration, Instant};
+use std::{fmt::Debug, future::Future};
 
 #[derive(Debug)]
 pub struct Cache<T: GasOracle> {
diff --git a/ethers-providers/Cargo.toml b/ethers-providers/Cargo.toml
index 25b0b292..210ffedd 100644
--- a/ethers-providers/Cargo.toml
+++ b/ethers-providers/Cargo.toml
@@ -1,75 +1,80 @@
 [package]
 name = "ethers-providers"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
-license = "MIT OR Apache-2.0"
-description = "Provider implementations for the ethers-rs crate"
-homepage = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-keywords = ["ethereum", "web3", "celo", "ethers"]
+readme = "README.md"
+description = "Clients for interacting with Ethereum nodes"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
+exclude.workspace = true
 
 [package.metadata.docs.rs]
 all-features = true
 rustc-args = ["--cfg", "docsrs"]
 rustdoc-args = ["--cfg", "docsrs"]
 
+[package.metadata.playground]
+all-features = true
+
 [dependencies]
-ethers-core = { version = "^2.0.0", path = "../ethers-core", default-features = false }
-
-async-trait = { version = "0.1.50", default-features = false }
-hex = { version = "0.4.3", default-features = false, features = ["std"] }
-reqwest = { version = "0.11.14", default-features = false, features = ["json"] }
-serde = { version = "1.0.124", default-features = false, features = ["derive"] }
-serde_json = { version = "1.0.64", default-features = false, features = ["raw_value"] }
-thiserror = { version = "1.0", default-features = false }
-url = { version = "2.3.1", default-features = false }
-auto_impl = { version = "1.0.1", default-features = false }
-http = { version = "0.2" }
+ethers-core.workspace = true
+
+serde.workspace = true
+serde_json = { workspace = true, features = ["raw_value"] }
+
+http = "0.2"
+reqwest = { workspace = true, features = ["json"] }
+url.workspace = true
 base64 = "0.21"
 
+async-trait.workspace = true
+hex.workspace = true
+thiserror.workspace = true
+auto_impl.workspace = true
+once_cell.workspace = true
+bytes.workspace = true
+instant.workspace = true
+hashers = "1.0"
+
 # required for implementing stream on the filters
-futures-core = { version = "0.3.16", default-features = false }
-futures-util = { version = "^0.3" }
-futures-timer = { version = "3.0.2", default-features = false }
-futures-channel = { version = "0.3.16", default-features = false, optional = true }
-pin-project = { version = "1.0.11", default-features = false }
+futures-core.workspace = true
+futures-util.workspace = true
+futures-timer.workspace = true
+futures-channel = { workspace = true, optional = true }
+pin-project.workspace = true
 
 # peer-related admin namespace
 enr = { version = "0.8.0", default-features = false, features = ["k256", "serde"] }
 
 # tracing
-tracing = { version = "0.1.37", default-features = false, features = ["attributes"] }
-tracing-futures = { version = "0.2.5", default-features = false, features = ["std-future"] }
-
-bytes = { version = "1.4.0", default-features = false, optional = true }
-once_cell = "1.17.1"
-hashers = "1.0.1"
+tracing = { workspace = true, features = ["attributes"] }
+tracing-futures = { workspace = true, features = ["std-future"] }
 
 [target.'cfg(target_family = "windows")'.dependencies]
 winapi = { version = "0.3", optional = true }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 # tokio
-tokio = { version = "1.18", default-features = false, features = ["time"] }
-tokio-tungstenite = { version = "0.18.0", default-features = false, features = [
-    "connect",
-], optional = true }
+tokio = { workspace = true, features = ["time"] }
+tokio-tungstenite = { workspace = true, features = ["connect"], optional = true }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 ws_stream_wasm = "0.7"
 wasm-bindgen = "0.2"
 wasm-bindgen-futures = "0.4"
 web-sys = { version = "0.3", features = ["console"] }
-wasm-timer = "0.2"
-# this is currently necessary for `wasm-timer::Delay` to work
-parking_lot = { version = "0.11", features = ["wasm-bindgen"] }
 # NOTE: this enables wasm compatibility for getrandom indirectly
-getrandom = { version = "0.2", features = ["js"] }
+getrandom.workspace = true
 
 [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
-tokio = { version = "1.18", default-features = false, features = ["rt", "macros", "time"] }
+tokio = { workspace = true, features = ["rt", "macros", "time"] }
 tempfile = "3.4.0"
 
 [features]
@@ -78,7 +83,7 @@ celo = ["ethers-core/celo"]
 
 ws = ["tokio-tungstenite", "futures-channel"]
 legacy-ws = ["ws"]
-ipc = ["tokio/io-util", "bytes", "futures-channel", "winapi"]
+ipc = ["tokio/io-util", "futures-channel", "winapi"]
 
 openssl = ["tokio-tungstenite/native-tls", "reqwest/native-tls"]
 # we use the webpki roots so we can build static binaries w/o any root cert dependencies
diff --git a/ethers-providers/src/rpc/transports/retry.rs b/ethers-providers/src/rpc/transports/retry.rs
index 9af8c7a0..ba283b31 100644
--- a/ethers-providers/src/rpc/transports/retry.rs
+++ b/ethers-providers/src/rpc/transports/retry.rs
@@ -210,8 +210,6 @@ pub enum RetryClientError {
     /// (De)Serialization error
     #[error(transparent)]
     SerdeJson(serde_json::Error),
-    /// TimerError (wasm only)
-    TimerError,
 }
 
 impl crate::RpcError for RetryClientError {
@@ -244,7 +242,6 @@ impl From<RetryClientError> for ProviderError {
             RetryClientError::ProviderError(err) => err,
             RetryClientError::TimeoutError => ProviderError::JsonRpcClientError(Box::new(src)),
             RetryClientError::SerdeJson(err) => err.into(),
-            RetryClientError::TimerError => ProviderError::JsonRpcClientError(Box::new(src)),
         }
     }
 }
@@ -338,9 +335,7 @@ where
                 trace!("retrying and backing off for {:?}", next_backoff);
 
                 #[cfg(target_arch = "wasm32")]
-                wasm_timer::Delay::new(next_backoff)
-                    .await
-                    .map_err(|_| RetryClientError::TimerError)?;
+                futures_timer::Delay::new(next_backoff).await;
 
                 #[cfg(not(target_arch = "wasm32"))]
                 tokio::time::sleep(next_backoff).await;
diff --git a/ethers-providers/src/stream/tx_stream.rs b/ethers-providers/src/stream/tx_stream.rs
index 5ec54334..3444df59 100644
--- a/ethers-providers/src/stream/tx_stream.rs
+++ b/ethers-providers/src/stream/tx_stream.rs
@@ -178,7 +178,7 @@ mod tests {
         utils::Anvil,
     };
     use futures_util::{FutureExt, StreamExt};
-    use std::{collections::HashSet, convert::TryFrom, time::Duration};
+    use std::{collections::HashSet, time::Duration};
 
     #[tokio::test]
     async fn can_stream_pending_transactions() {
diff --git a/ethers-providers/src/toolbox/pending_escalator.rs b/ethers-providers/src/toolbox/pending_escalator.rs
index 77803ba4..b7713525 100644
--- a/ethers-providers/src/toolbox/pending_escalator.rs
+++ b/ethers-providers/src/toolbox/pending_escalator.rs
@@ -1,19 +1,11 @@
 #![allow(clippy::return_self_not_must_use)]
 
 use ethers_core::types::{Bytes, TransactionReceipt, H256};
+use futures_timer::Delay;
 use futures_util::{stream::FuturesUnordered, StreamExt};
+use instant::{Duration, Instant};
 use pin_project::pin_project;
-use std::{
-    future::Future,
-    pin::Pin,
-    task::Poll,
-    time::{Duration, Instant},
-};
-
-#[cfg(not(target_arch = "wasm32"))]
-use futures_timer::Delay;
-#[cfg(target_arch = "wasm32")]
-use wasm_timer::Delay;
+use std::{future::Future, pin::Pin, task::Poll};
 
 use crate::{
     utils::PinBoxFut, JsonRpcClient, Middleware, PendingTransaction, Provider, ProviderError,
diff --git a/ethers-providers/src/toolbox/pending_transaction.rs b/ethers-providers/src/toolbox/pending_transaction.rs
index 74bead5a..d9deabc3 100644
--- a/ethers-providers/src/toolbox/pending_transaction.rs
+++ b/ethers-providers/src/toolbox/pending_transaction.rs
@@ -4,7 +4,9 @@ use crate::{
 };
 use ethers_core::types::{Transaction, TransactionReceipt, TxHash, U64};
 use futures_core::stream::Stream;
+use futures_timer::Delay;
 use futures_util::stream::StreamExt;
+use instant::Duration;
 use pin_project::pin_project;
 use std::{
     fmt,
@@ -12,14 +14,8 @@ use std::{
     ops::Deref,
     pin::Pin,
     task::{Context, Poll},
-    time::Duration,
 };
 
-#[cfg(not(target_arch = "wasm32"))]
-use futures_timer::Delay;
-#[cfg(target_arch = "wasm32")]
-use wasm_timer::Delay;
-
 /// A pending transaction is a transaction which has been submitted but is not yet mined.
 /// `await`'ing on a pending transaction will resolve to a transaction receipt
 /// once the transaction has enough `confirmations`. The default number of confirmations
diff --git a/ethers-providers/src/utils.rs b/ethers-providers/src/utils.rs
index ec53ec2a..34fd12d3 100644
--- a/ethers-providers/src/utils.rs
+++ b/ethers-providers/src/utils.rs
@@ -1,14 +1,9 @@
+use crate::ProviderError;
 use ethers_core::types::U256;
+use futures_timer::Delay;
 use futures_util::{stream, FutureExt, StreamExt};
 use std::{future::Future, pin::Pin};
 
-#[cfg(not(target_arch = "wasm32"))]
-use futures_timer::Delay;
-#[cfg(target_arch = "wasm32")]
-use wasm_timer::Delay;
-
-use crate::ProviderError;
-
 /// A simple gas escalation policy
 pub type EscalationPolicy = Box<dyn Fn(U256, usize) -> U256 + Send + Sync>;
 
@@ -34,7 +29,7 @@ where
 // https://github.com/tomusdrw/rust-web3/blob/befcb2fb8f3ca0a43e3081f68886fa327e64c8e6/src/api/eth_filter.rs#L20
 /// Create a stream that emits items at a fixed interval. Used for rate control
 pub fn interval(
-    duration: std::time::Duration,
+    duration: instant::Duration,
 ) -> impl futures_core::stream::Stream<Item = ()> + Send + Unpin {
     stream::unfold((), move |_| Delay::new(duration).map(|_| Some(((), ())))).map(drop)
 }
diff --git a/ethers-signers/Cargo.toml b/ethers-signers/Cargo.toml
index 46e1e99b..cd23c776 100644
--- a/ethers-signers/Cargo.toml
+++ b/ethers-signers/Cargo.toml
@@ -1,63 +1,87 @@
 [package]
 name = "ethers-signers"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
-license = "MIT OR Apache-2.0"
-description = "Signer implementations for the ethers-rs crate"
-homepage = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-keywords = ["ethereum", "web3", "celo", "ethers"]
+readme = "README.md"
+description = "A unified interface for locally signing Ethereum transactions"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
+exclude.workspace = true
 
 [package.metadata.docs.rs]
 all-features = true
 rustc-args = ["--cfg", "docsrs"]
 rustdoc-args = ["--cfg", "docsrs"]
 
+[package.metadata.playground]
+all-features = true
+
 [dependencies]
-ethers-core = { version = "^2.0.0", path = "../ethers-core", features = ["eip712"] }
-thiserror = { version = "1.0.39", default-features = false }
-coins-bip32 = "0.8.0"
-coins-bip39 = "0.8.1"
-coins-ledger = { version = "0.7.1", default-features = false, optional = true }
-hex = { version = "0.4.3", default-features = false, features = ["std"] }
-async-trait = { version = "0.1.50", default-features = false }
-elliptic-curve = { version = "0.13.2", default-features = false }
-sha2 = { version = "0.10.6", default-features = false }
-rand = { version = "0.8.5", default-features = false }
-yubihsm = { version = "0.42.0-pre.0", features = ["secp256k1", "http", "usb"], optional = true }
-futures-util = { version = "^0.3", optional = true }
-futures-executor = { version = "^0.3", optional = true }
-semver = { version = "1.0.17", optional = true }
-tracing = { version = "0.1.37" }
-trezor-client = { version = "0.0.7", optional = true, default-features = false, features = [
-    "f_ethereum",
-] }
+ethers-core = { workspace = true, features = ["eip712"] }
+
+# crypto
+coins-bip32 = "0.8.3"
+coins-bip39 = "0.8.3"
+elliptic-curve.workspace = true
+sha2.workspace = true
+rand.workspace = true
+
+# misc
+thiserror.workspace = true
+tracing.workspace = true
+async-trait.workspace = true
+hex.workspace = true
+
+# futures
+futures-util = { workspace = true, optional = true }
+futures-executor = { workspace = true, optional = true }
 
 # aws
 rusoto_core = { version = "0.48.0", default-features = false, optional = true }
 rusoto_kms = { version = "0.48.0", default-features = false, optional = true }
-spki = { version = "0.6.0", optional = true }
+spki = { workspace = true, optional = true }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
-eth-keystore = { version = "0.5.0" }
+eth-keystore = "0.5.0"
 home = { version = "0.5.4", optional = true }
 
+# ledger
+coins-ledger = { version = "0.8.3", default-features = false, optional = true }
+semver = { workspace = true, optional = true }
+
+# trezor
+trezor-client = { version = "0.0.7", default-features = false, features = [
+    "f_ethereum",
+], optional = true }
+
+# yubi
+yubihsm = { version = "0.42.0-pre.0", features = ["secp256k1", "http", "usb"], optional = true }
+
 [dev-dependencies]
-ethers-contract-derive = { version = "^2.0.0", path = "../ethers-contract/ethers-contract-derive" }
-ethers-derive-eip712 = { version = "^2.0.0", path = "../ethers-core/ethers-derive-eip712" }
+ethers-contract-derive.workspace = true
+ethers-derive-eip712.workspace = true
 
-serde_json = { version = "1.0.64" }
+serde_json.workspace = true
+tempfile.workspace = true
+tracing-subscriber.workspace = true
+
+[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
 yubihsm = { version = "0.42.0-pre.0", features = ["secp256k1", "usb", "mockhsm"] }
-tokio = { version = "1.18", default-features = false, features = ["macros", "rt"] }
-tempfile = "3.4.0"
-tracing-subscriber = "0.3.16"
+tokio = { workspace = true, features = ["macros", "rt"] }
 
 [features]
 futures = ["futures-util", "futures-executor"]
+
 celo = ["ethers-core/celo"]
+
 ledger = ["coins-ledger", "futures", "semver"]
-yubi = ["yubihsm"]
-aws = ["rusoto_core/rustls", "rusoto_kms/rustls", "spki"]
 trezor = ["trezor-client", "futures", "semver", "home"]
+aws = ["rusoto_core/rustls", "rusoto_kms/rustls", "spki"]
+yubi = ["yubihsm"]
diff --git a/ethers-signers/README.md b/ethers-signers/README.md
index a3c45cbd..e4f90880 100644
--- a/ethers-signers/README.md
+++ b/ethers-signers/README.md
@@ -1,6 +1,6 @@
 # ethers-signers
 
-A unified interface for locally signing transactions.
+A unified interface for locally signing Ethereum transactions.
 
 You can implement the `Signer` trait to extend functionality to other signers
 such as Hardware Security Modules, KMS etc.
diff --git a/ethers-signers/src/aws/utils.rs b/ethers-signers/src/aws/utils.rs
index 481971df..e6687c98 100644
--- a/ethers-signers/src/aws/utils.rs
+++ b/ethers-signers/src/aws/utils.rs
@@ -71,8 +71,8 @@ pub(super) fn decode_pubkey(resp: GetPublicKeyResponse) -> Result<VerifyingKey,
         .public_key
         .ok_or_else(|| AwsSignerError::from("Pubkey not found in response".to_owned()))?;
 
-    let spk = spki::SubjectPublicKeyInfo::try_from(raw.as_ref())?;
-    let key = VerifyingKey::from_sec1_bytes(spk.subject_public_key)?;
+    let spki = spki::SubjectPublicKeyInfoRef::try_from(raw.as_ref())?;
+    let key = VerifyingKey::from_sec1_bytes(spki.subject_public_key.raw_bytes())?;
 
     Ok(key)
 }
diff --git a/ethers-signers/src/lib.rs b/ethers-signers/src/lib.rs
index ed9594be..67cc78e2 100644
--- a/ethers-signers/src/lib.rs
+++ b/ethers-signers/src/lib.rs
@@ -10,32 +10,31 @@ pub use coins_bip39;
 /// A wallet instantiated with a locally stored private key
 pub type LocalWallet = Wallet<ethers_core::k256::ecdsa::SigningKey>;
 
-#[cfg(feature = "yubi")]
+#[cfg(all(feature = "yubihsm", not(target_arch = "wasm32")))]
 /// A wallet instantiated with a YubiHSM
 pub type YubiWallet = Wallet<yubihsm::ecdsa::Signer<ethers_core::k256::Secp256k1>>;
 
-#[cfg(feature = "ledger")]
+#[cfg(all(feature = "ledger", not(target_arch = "wasm32")))]
 mod ledger;
-#[cfg(feature = "ledger")]
+#[cfg(all(feature = "ledger", not(target_arch = "wasm32")))]
 pub use ledger::{
     app::LedgerEthereum as Ledger,
     types::{DerivationType as HDPath, LedgerError},
 };
 
-#[cfg(feature = "trezor")]
+#[cfg(all(feature = "trezor", not(target_arch = "wasm32")))]
 mod trezor;
-#[cfg(feature = "trezor")]
+#[cfg(all(feature = "trezor", not(target_arch = "wasm32")))]
 pub use trezor::{
     app::TrezorEthereum as Trezor,
     types::{DerivationType as TrezorHDPath, TrezorError},
 };
 
-#[cfg(feature = "yubi")]
+#[cfg(all(feature = "yubihsm", not(target_arch = "wasm32")))]
 pub use yubihsm;
 
 #[cfg(feature = "aws")]
 mod aws;
-
 #[cfg(feature = "aws")]
 pub use aws::{AwsSigner, AwsSignerError};
 
diff --git a/ethers-signers/src/wallet/mod.rs b/ethers-signers/src/wallet/mod.rs
index 95429ce4..b062dd57 100644
--- a/ethers-signers/src/wallet/mod.rs
+++ b/ethers-signers/src/wallet/mod.rs
@@ -4,7 +4,7 @@ pub use mnemonic::{MnemonicBuilder, MnemonicBuilderError};
 mod private_key;
 pub use private_key::WalletError;
 
-#[cfg(feature = "yubihsm")]
+#[cfg(all(feature = "yubihsm", not(target_arch = "wasm32")))]
 mod yubi;
 
 use crate::{to_eip155_v, Signer};
diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml
index 16afdb56..dd8a2a5c 100644
--- a/ethers-solc/Cargo.toml
+++ b/ethers-solc/Cargo.toml
@@ -1,67 +1,82 @@
 [package]
 name = "ethers-solc"
-version = "2.0.0"
-edition = "2021"
-rust-version = "1.64"
 authors = [
     "Matthias Seitz <matthias.seitz@outlook.de>",
     "Georgios Konstantopoulos <me@gakonst.com>",
 ]
-license = "MIT OR Apache-2.0"
-readme = "../README.md"
-documentation = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-homepage = "https://docs.rs/ethers"
+readme = "README.md"
 description = "Utilites for working with solc"
-keywords = ["ethereum", "web3", "solc", "solidity", "ethers"]
+keywords = ["ethers", "ethereum", "web3", "solc", "solidity"]
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+exclude.workspace = true
+
+[package.metadata.docs.rs]
+all-features = true
+rustc-args = ["--cfg", "docsrs"]
+rustdoc-args = ["--cfg", "docsrs"]
+
+[package.metadata.playground]
+all-features = true
 
 [dependencies]
-ethers-core = { version = "^2.0.0", path = "../ethers-core", default-features = false }
-serde_json = "1.0.68"
-serde = { version = "1.0.130", features = ["derive", "rc"] }
-semver = { version = "1.0.17", features = ["serde"] }
-walkdir = "2.3.2"
-tokio = { version = "1.18", default-features = false, features = ["rt"] }
-futures-util = { version = "^0.3", optional = true }
-once_cell = "1.17.1"
-regex = "1.7.1"
+ethers-core.workspace = true
+
+solang-parser = { version = "=0.2.3", default-features = false }
+
+serde = { workspace = true, features = ["derive", "rc"] }
+serde_json.workspace = true
+
+tiny-keccak = { version = "2.0.2", default-features = false }
+sha2 = { workspace = true, optional = true }
 md-5 = "0.10.5"
-thiserror = "1.0"
-hex = "0.4.3"
+
+semver = { workspace = true, features = ["serde"] }
+walkdir.workspace = true
+once_cell.workspace = true
+regex.workspace = true
+thiserror.workspace = true
+hex.workspace = true
 yansi = "0.5.1"
 glob = "0.3.1"
-tracing = "0.1.37"
+tracing.workspace = true
 num_cpus = "1.15.0"
-tiny-keccak = { version = "2.0.2", default-features = false }
-tempfile = { version = "3.4.0", optional = true }
-fs_extra = { version = "1.3.0", optional = true }
-sha2 = { version = "0.10.6", default-features = false, optional = true }
-dunce = "1.0.3"
-solang-parser = { default-features = false, version = "=0.2.3" }
-rayon = "1.7.0"
-rand = { version = "0.8.5", optional = true }
+dunce.workspace = true
+rayon.workspace = true
 path-slash = "0.2.1"
 cfg-if = "1.0.0"
 
+tempfile = { version = "3.4.0", optional = true }
+fs_extra = { version = "1.3.0", optional = true }
+rand = { workspace = true, optional = true }
+futures-util = { workspace = true, optional = true }
+
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 home = "0.5.4"
-svm = { package = "svm-rs", version = "0.2", default-features = false, optional = true, features = [
+svm = { package = "svm-rs", version = "0.2", default-features = false, features = [
     "blocking",
-] }
+], optional = true }
 svm-builds = { package = "svm-rs-builds", version = "0.1", optional = true }
+tokio = { workspace = true, features = ["rt"] }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 # NOTE: this enables wasm compatibility for getrandom indirectly
-getrandom = { version = "0.2", features = ["js"] }
+getrandom.workspace = true
 
 [dev-dependencies]
-criterion = { version = "0.4", features = ["async_tokio"] }
+criterion.workspace = true
 env_logger = "0.10.0"
-tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] }
-rand = "0.8.5"
+tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
+rand.workspace = true
 pretty_assertions = "1.3.0"
-tempfile = "3.4.0"
-tokio = { version = "1.18", features = ["full"] }
+tempfile.workspace = true
 serde_path_to_error = "0.1.10"
 
 [[bench]]
@@ -85,12 +100,25 @@ required-features = ["full", "project-util"]
 
 [features]
 default = ["rustls"]
-async = ["tokio/process", "tokio/io-util", "tokio/fs", "tokio/time", "futures-util"]
+
 full = ["async", "svm-solc"]
-svm-solc = ["svm/blocking", "svm-builds", "sha2"]
+
+async = [
+    "tokio/process",
+    "tokio/io-util",
+    "tokio/fs",
+    "tokio/time",
+    "futures-util",
+    "criterion/async_tokio",
+]
+svm-solc = ["svm-builds", "sha2"]
+
 # Utilities for creating and testing project workspaces
 project-util = ["tempfile", "fs_extra", "rand"]
+
 tests = []
 openssl = ["svm/openssl"]
 rustls = ["svm/rustls"]
-asm = ["sha2/asm", "svm/sha2-asm"]
+
+# Deprecated
+asm = []
diff --git a/ethers-solc/src/compile/mod.rs b/ethers-solc/src/compile/mod.rs
index d9a26a03..fd74e697 100644
--- a/ethers-solc/src/compile/mod.rs
+++ b/ethers-solc/src/compile/mod.rs
@@ -70,7 +70,7 @@ pub(crate) fn take_solc_installer_lock() -> std::sync::MutexGuard<'static, ()> {
 /// A list of upstream Solc releases, used to check which version
 /// we should download.
 /// The boolean value marks whether there was an error accessing the release list
-#[cfg(all(feature = "svm-solc"))]
+#[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
 pub static RELEASES: once_cell::sync::Lazy<(svm::Releases, Vec<Version>, bool)> =
     once_cell::sync::Lazy::new(|| {
         match serde_json::from_str::<svm::Releases>(svm_builds::RELEASE_LIST_JSON) {
@@ -240,7 +240,7 @@ impl Solc {
 
     /// Returns the list of all versions that are available to download and marking those which are
     /// already installed.
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn all_versions() -> Vec<SolcVersion> {
         let mut all_versions = Self::installed_versions();
         let mut uniques = all_versions
@@ -324,7 +324,7 @@ impl Solc {
     /// to build it, and returns it.
     ///
     /// If the required compiler version is not installed, it also proceeds to install it.
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn detect_version(source: &Source) -> Result<Version> {
         // detects the required solc version
         let sol_version = Self::source_version_req(source)?;
@@ -335,7 +335,7 @@ impl Solc {
     /// used to build it, and returns it.
     ///
     /// If the required compiler version is not installed, it also proceeds to install it.
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn ensure_installed(sol_version: &VersionReq) -> Result<Version> {
         #[cfg(any(test, feature = "tests"))]
         let _lock = take_solc_installer_lock();
@@ -400,7 +400,7 @@ impl Solc {
     /// # Ok(())
     /// # }
     /// ```
-    #[cfg(feature = "svm-solc")]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub async fn install(version: &Version) -> std::result::Result<Self, svm::SolcVmError> {
         tracing::trace!("installing solc version \"{}\"", version);
         crate::report::solc_installation_start(version);
@@ -410,7 +410,7 @@ impl Solc {
     }
 
     /// Blocking version of `Self::install`
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn blocking_install(version: &Version) -> std::result::Result<Self, svm::SolcVmError> {
         use crate::utils::RuntimeOrHandle;
 
@@ -440,7 +440,7 @@ impl Solc {
 
     /// Verify that the checksum for this version of solc is correct. We check against the SHA256
     /// checksum from the build information published by [binaries.soliditylang.org](https://binaries.soliditylang.org/)
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn verify_checksum(&self) -> Result<()> {
         let version = self.version_short()?;
         let mut version_path = svm::version_path(version.to_string().as_str());
@@ -817,7 +817,7 @@ mod tests {
 
     #[test]
     // This test might be a bit hard to maintain
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     fn test_detect_version() {
         for (pragma, expected) in [
             // pinned
@@ -862,7 +862,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg(feature = "svm-solc")]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     fn can_install_solc_in_tokio_rt() {
         let version = Version::from_str("0.8.6").unwrap();
         let rt = tokio::runtime::Runtime::new().unwrap();
diff --git a/ethers-solc/src/compile/project.rs b/ethers-solc/src/compile/project.rs
index 7a792286..2010f5fb 100644
--- a/ethers-solc/src/compile/project.rs
+++ b/ethers-solc/src/compile/project.rs
@@ -140,7 +140,7 @@ impl<'a, T: ArtifactOutput> ProjectCompiler<'a, T> {
     /// let project = Project::builder().build().unwrap();
     /// let output = project.compile().unwrap();
     /// ```
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn new(project: &'a Project<T>) -> Result<Self> {
         Self::with_sources(project, project.paths.read_input_files()?)
     }
@@ -151,7 +151,7 @@ impl<'a, T: ArtifactOutput> ProjectCompiler<'a, T> {
     ///
     /// Multiple (`Solc` -> `Sources`) pairs can be compiled in parallel if the `Project` allows
     /// multiple `jobs`, see [`crate::Project::set_solc_jobs()`].
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn with_sources(project: &'a Project<T>, sources: Sources) -> Result<Self> {
         let graph = Graph::resolve_sources(&project.paths, sources)?;
         let (versions, edges) = graph.into_sources_by_version(project.offline)?;
diff --git a/ethers-solc/src/error.rs b/ethers-solc/src/error.rs
index 0b77fde3..d91fbc34 100644
--- a/ethers-solc/src/error.rs
+++ b/ethers-solc/src/error.rs
@@ -40,7 +40,7 @@ pub enum SolcError {
         {2:?}"#
     )]
     FailedResolveImport(Box<SolcError>, PathBuf, PathBuf),
-    #[cfg(feature = "svm-solc")]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     #[error(transparent)]
     SvmError(#[from] svm::SolcVmError),
     #[error("No contracts found at \"{0}\"")]
diff --git a/ethers-solc/src/lib.rs b/ethers-solc/src/lib.rs
index 6390e80e..d0976954 100644
--- a/ethers-solc/src/lib.rs
+++ b/ethers-solc/src/lib.rs
@@ -267,7 +267,7 @@ impl<T: ArtifactOutput> Project<T> {
         let sources = self.paths.read_input_files()?;
         tracing::trace!("found {} sources to compile: {:?}", sources.len(), sources.keys());
 
-        #[cfg(all(feature = "svm-solc"))]
+        #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
         if self.auto_detect {
             tracing::trace!("using solc auto detection to compile sources");
             return self.svm_compile(sources)
@@ -299,7 +299,7 @@ impl<T: ArtifactOutput> Project<T> {
     /// let output = project.svm_compile(sources).unwrap();
     /// # }
     /// ```
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn svm_compile(&self, sources: Sources) -> Result<ProjectCompileOutput<T>> {
         project::ProjectCompiler::with_sources(self, sources)?.compile()
     }
@@ -316,7 +316,7 @@ impl<T: ArtifactOutput> Project<T> {
     /// let output = project.compile_file("example/Greeter.sol").unwrap();
     /// # }
     /// ```
-    #[cfg(all(feature = "svm-solc"))]
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn compile_file(&self, file: impl Into<PathBuf>) -> Result<ProjectCompileOutput<T>> {
         let file = file.into();
         let source = Source::read(&file)?;
@@ -345,7 +345,7 @@ impl<T: ArtifactOutput> Project<T> {
     {
         let sources = Source::read_all(files)?;
 
-        #[cfg(all(feature = "svm-solc"))]
+        #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
         if self.auto_detect {
             return project::ProjectCompiler::with_sources(self, sources)?.compile()
         }
@@ -392,7 +392,7 @@ impl<T: ArtifactOutput> Project<T> {
             Source::read_all(self.paths.input_files().into_iter().filter(|p| filter.is_match(p)))?;
         let filter: Box<dyn FileFilter> = Box::new(filter);
 
-        #[cfg(all(feature = "svm-solc"))]
+        #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
         if self.auto_detect {
             return project::ProjectCompiler::with_sources(self, sources)?
                 .with_sparse_output(filter)
@@ -963,7 +963,7 @@ impl<T: ArtifactOutput> ArtifactOutput for Project<T> {
 }
 
 #[cfg(test)]
-#[cfg(all(feature = "svm-solc"))]
+#[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
 mod tests {
     use crate::remappings::Remapping;
 
diff --git a/ethers-solc/src/project_util/mod.rs b/ethers-solc/src/project_util/mod.rs
index a7653731..8b05095f 100644
--- a/ethers-solc/src/project_util/mod.rs
+++ b/ethers-solc/src/project_util/mod.rs
@@ -9,7 +9,7 @@ use crate::{
     utils,
     utils::tempdir,
     Artifact, ArtifactOutput, Artifacts, ConfigurableArtifacts, ConfigurableContractArtifact,
-    FileFilter, PathStyle, Project, ProjectCompileOutput, ProjectPathsConfig, SolFilesCache, Solc,
+    FileFilter, PathStyle, Project, ProjectCompileOutput, ProjectPathsConfig, SolFilesCache,
     SolcIoError,
 };
 use fs_extra::{dir, file};
@@ -69,8 +69,9 @@ impl<T: ArtifactOutput> TempProject<T> {
     }
 
     /// Explicitly sets the solc version for the project
+    #[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
     pub fn set_solc(&mut self, solc: impl AsRef<str>) -> &mut Self {
-        self.inner.solc = Solc::find_or_install_svm_version(solc).unwrap();
+        self.inner.solc = crate::Solc::find_or_install_svm_version(solc).unwrap();
         self.inner.auto_detect = false;
         self
     }
diff --git a/ethers-solc/src/resolver/mod.rs b/ethers-solc/src/resolver/mod.rs
index 0610b71d..06a971db 100644
--- a/ethers-solc/src/resolver/mod.rs
+++ b/ethers-solc/src/resolver/mod.rs
@@ -437,7 +437,7 @@ impl Graph {
     }
 }
 
-#[cfg(all(feature = "svm-solc"))]
+#[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
 impl Graph {
     /// Consumes the nodes of the graph and returns all input files together with their appropriate
     /// version and the edges of the graph
@@ -759,7 +759,7 @@ impl<'a> Iterator for NodesIter<'a> {
 }
 
 /// Container type for solc versions and their compatible sources
-#[cfg(all(feature = "svm-solc"))]
+#[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
 #[derive(Debug)]
 pub struct VersionedSources {
     resolved_solc_include_paths: IncludePaths,
@@ -767,7 +767,7 @@ pub struct VersionedSources {
     offline: bool,
 }
 
-#[cfg(all(feature = "svm-solc"))]
+#[cfg(all(feature = "svm-solc", not(target_arch = "wasm32")))]
 impl VersionedSources {
     /// Resolves or installs the corresponding `Solc` installation.
     ///
diff --git a/ethers/Cargo.toml b/ethers/Cargo.toml
new file mode 100644
index 00000000..7dff1300
--- /dev/null
+++ b/ethers/Cargo.toml
@@ -0,0 +1,89 @@
+[package]
+name = "ethers"
+authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
+readme = "../README.md"
+description = "A complete Ethereum and Celo Rust library"
+
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+documentation.workspace = true
+repository.workspace = true
+homepage.workspace = true
+categories.workspace = true
+keywords.workspace = true
+exclude.workspace = true
+
+[package.metadata.docs.rs]
+all-features = true
+rustc-args = ["--cfg", "docsrs"]
+rustdoc-args = ["--cfg", "docsrs"]
+
+[package.metadata.playground]
+all-features = true
+
+[features]
+default = ["abigen", "rustls"]
+
+celo = [
+    "ethers-core/celo",
+    "ethers-providers/celo",
+    "ethers-signers/celo",
+    "ethers-contract/celo",
+    "ethers-middleware/celo",
+    "legacy",
+]
+
+legacy = ["ethers-core/legacy", "ethers-contract/legacy"]
+
+# individual features per sub-crate
+## core
+eip712 = ["ethers-contract/eip712", "ethers-core/eip712"]
+## providers
+ws = ["ethers-providers/ws"]
+ipc = ["ethers-providers/ipc"]
+rustls = [
+    "ethers-middleware/rustls",
+    "ethers-providers/rustls",
+    "ethers-etherscan/rustls",
+    "ethers-contract/rustls",
+    "ethers-solc/rustls",
+]
+openssl = [
+    "ethers-middleware/openssl",
+    "ethers-providers/openssl",
+    "ethers-etherscan/openssl",
+    "ethers-contract/openssl",
+    "ethers-solc/openssl",
+]
+dev-rpc = ["ethers-providers/dev-rpc"]
+## signers
+ledger = ["ethers-signers/ledger"]
+trezor = ["ethers-signers/trezor"]
+yubi = ["ethers-signers/yubi"]
+## contracts
+abigen = ["ethers-contract/abigen"]
+### abigen without reqwest
+abigen-offline = ["ethers-contract/abigen-offline"]
+## solc
+ethers-solc = ["dep:ethers-solc", "ethers-etherscan/ethers-solc"]
+solc-full = ["ethers-solc?/full"]
+solc-tests = ["ethers-solc?/tests"]
+
+# Deprecated
+solc-sha2-asm = []
+
+[dependencies]
+ethers-addressbook.workspace = true
+ethers-contract.workspace = true
+ethers-core.workspace = true
+ethers-etherscan.workspace = true
+ethers-middleware.workspace = true
+ethers-providers.workspace = true
+ethers-signers.workspace = true
+
+ethers-solc = { workspace = true, optional = true }
+
+[dev-dependencies]
+tokio = { workspace = true, features = ["macros", "rt"] }
diff --git a/examples/anvil/Cargo.toml b/examples/anvil/Cargo.toml
index 5bed2fb9..13b0ed18 100644
--- a/examples/anvil/Cargo.toml
+++ b/examples/anvil/Cargo.toml
@@ -1,10 +1,14 @@
 [package]
 name = "examples-anvil"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
 [dev-dependencies]
-ethers = { path = "../..", version = "2.0.0" }
-eyre = "0.6"
-tokio = { version = "1.18", features = ["full"] }
+ethers.workspace = true
+tokio = { workspace = true, features = ["macros"] }
+eyre.workspace = true
diff --git a/examples/big-numbers/Cargo.toml b/examples/big-numbers/Cargo.toml
index 2b1ca01a..832ff472 100644
--- a/examples/big-numbers/Cargo.toml
+++ b/examples/big-numbers/Cargo.toml
@@ -1,10 +1,12 @@
 [package]
 name = "examples-big-numbers"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
 
-[dev-dependencies]
-#ethers-core = { version = "^1.0.0", path = "../../ethers-core" }
-ethers = { path = "../..", version = "2.0.0" }
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
+[dev-dependencies]
+ethers.workspace = true
diff --git a/examples/contracts/Cargo.toml b/examples/contracts/Cargo.toml
index 2bf81407..6e9ca761 100644
--- a/examples/contracts/Cargo.toml
+++ b/examples/contracts/Cargo.toml
@@ -1,19 +1,23 @@
 [package]
 name = "examples-contracts"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
 [features]
 default = ["legacy"]
-legacy = []
+legacy = ["ethers/legacy"]
 
 [dev-dependencies]
-ethers = { path = "../..", version = "2.0.0", features = ["abigen", "ethers-solc", "legacy", "rustls", "ws"] }
+ethers = { workspace = true, features = ["abigen", "ethers-solc", "rustls", "ws"] }
 
-eyre = "0.6"
-serde = { version = "1.0.144", features = ["derive"] }
-serde_json = "1.0.64"
-tokio = { version = "1.18", features = ["macros"] }
+tokio = { workspace = true, features = ["macros"] }
 
+serde.workspace = true
+serde_json.workspace = true
 
+eyre.workspace = true
diff --git a/examples/ethers-wasm/Cargo.toml b/examples/ethers-wasm/Cargo.toml
index 7e5dd152..83925955 100644
--- a/examples/ethers-wasm/Cargo.toml
+++ b/examples/ethers-wasm/Cargo.toml
@@ -1,15 +1,11 @@
 [package]
 name = "ethers-wasm"
-version = "0.1.0"
-edition = "2021"
-rust-version = "1.64"
+version = "2.0.0"
 authors = ["Matthias Seitz <matthias.seitz@outlook.de>"]
 license = "MIT OR Apache-2.0"
-readme = "README.md"
-documentation = "https://docs.rs/ethers"
-repository = "https://github.com/gakonst/ethers-rs"
-homepage = "https://docs.rs/ethers"
-description = "How to use ethers in the browser with WASM."
+
+rust-version.workspace = true
+edition.workspace = true
 
 [lib]
 crate-type = ["cdylib", "rlib"]
@@ -18,31 +14,23 @@ crate-type = ["cdylib", "rlib"]
 default = ["console_error_panic_hook"]
 
 [dependencies]
-ethers = { path = "../..", version = "2.0.0", features = ["abigen", "legacy", "ws"] }
+ethers = { workspace = true, features = ["abigen", "ws"] }
 
-wasm-bindgen-futures = "0.4.34"
-wasm-bindgen = { version = "0.2.83", features = ["serde-serialize"] }
+serde.workspace = true
+serde_json.workspace = true
+serde-wasm-bindgen = "0.5.0"
+hex.workspace = true
 
-serde = { version = "1.0.144", features = ["derive"] }
-serde_json = "1.0.85"
-serde-wasm-bindgen = "0.4.5"
+wasm-bindgen-futures = "0.4.34"
+wasm-bindgen = { version = "0.2.84", features = ["serde-serialize"] }
 
 # The `console_error_panic_hook` crate provides better debugging of panics by
 # logging them with `console.error`. This is great for development, but requires
 # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
 # code size when deploying.
-console_error_panic_hook = { version = "0.1.6", optional = true }
-
-# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
-# compared to the default allocator's ~10K. It is slower than the default
-# allocator, however.
-#
-# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
-wee_alloc = { version = "0.4.5", optional = true }
+console_error_panic_hook = { version = "0.1.7", optional = true }
 
 web-sys = { version = "0.3.61", features = ["console"] }
 
-hex = "0.4.3"
-
 [dev-dependencies]
 wasm-bindgen-test = "0.3.34"
diff --git a/examples/ethers-wasm/abi/contract.json b/examples/ethers-wasm/abi/contract.json
new file mode 100644
index 00000000..f0b01965
--- /dev/null
+++ b/examples/ethers-wasm/abi/contract.json
@@ -0,0 +1,1 @@
+{"abi":[{"inputs":[{"internalType":"string","name":"value","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"author","type":"address"},{"indexed":false,"internalType":"string","name":"oldValue","type":"string"},{"indexed":false,"internalType":"string","name":"newValue","type":"string"}],"name":"ValueChanged","type":"event"},{"inputs":[],"name":"getValue","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"value","type":"string"}],"name":"setValue","outputs":[],"stateMutability":"nonpayable","type":"function"}],"bytecode":"608060405234801561001057600080fd5b5060405161073b38038061073b8339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b8382019150602082018581111561006957600080fd5b825186600182028301116401000000008211171561008657600080fd5b8083526020830192505050908051906020019080838360005b838110156100ba57808201518184015260208101905061009f565b50505050905090810190601f1680156100e75780820380516001836020036101000a031916815260200191505b506040525050503373ffffffffffffffffffffffffffffffffffffffff167fe826f71647b8486f2bae59832124c70792fba044036720a54ec8dacdd5df4fcb6000836040518080602001806020018381038352858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156101b65780601f1061018b576101008083540402835291602001916101b6565b820191906000526020600020905b81548152906001019060200180831161019957829003601f168201915b5050838103825284818151815260200191508051906020019080838360005b838110156101f05780820151818401526020810190506101d5565b50505050905090810190601f16801561021d5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a28060009080519060200190610242929190610249565b50506102e6565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061028a57805160ff19168380011785556102b8565b828001600101855582156102b8579182015b828111156102b757825182559160200191906001019061029c565b5b5090506102c591906102c9565b5090565b5b808211156102e25760008160009055506001016102ca565b5090565b610446806102f56000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063209652551461003b57806393a09352146100be575b600080fd5b610043610179565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610083578082015181840152602081019050610068565b50505050905090810190601f1680156100b05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610177600480360360208110156100d457600080fd5b81019080803590602001906401000000008111156100f157600080fd5b82018360208201111561010357600080fd5b8035906020019184600183028401116401000000008311171561012557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061021b565b005b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102115780601f106101e657610100808354040283529160200191610211565b820191906000526020600020905b8154815290600101906020018083116101f457829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff167fe826f71647b8486f2bae59832124c70792fba044036720a54ec8dacdd5df4fcb6000836040518080602001806020018381038352858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156102e35780601f106102b8576101008083540402835291602001916102e3565b820191906000526020600020905b8154815290600101906020018083116102c657829003601f168201915b5050838103825284818151815260200191508051906020019080838360005b8381101561031d578082015181840152602081019050610302565b50505050905090810190601f16801561034a5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2806000908051906020019061036f929190610373565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106103b457805160ff19168380011785556103e2565b828001600101855582156103e2579182015b828111156103e15782518255916020019190600101906103c6565b5b5090506103ef91906103f3565b5090565b5b8082111561040c5760008160009055506001016103f4565b509056fea26469706673582212202d397d3d0e6cf9afdeed7d5192e3abff386699395df0409eb5c3ec494832c57a64736f6c63430007000033"}
diff --git a/examples/ethers-wasm/abi/contract_abi.json b/examples/ethers-wasm/abi/contract_abi.json
deleted file mode 100644
index 12de10c8..00000000
--- a/examples/ethers-wasm/abi/contract_abi.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[{"inputs":[{"internalType":"string","name":"value","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"author","type":"address"},{"indexed":false,"internalType":"string","name":"oldValue","type":"string"},{"indexed":false,"internalType":"string","name":"newValue","type":"string"}],"name":"ValueChanged","type":"event"},{"inputs":[],"name":"getValue","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"value","type":"string"}],"name":"setValue","outputs":[],"stateMutability":"nonpayable","type":"function"}]
diff --git a/examples/ethers-wasm/index.js b/examples/ethers-wasm/index.js
index b075993e..6dd314e7 100644
--- a/examples/ethers-wasm/index.js
+++ b/examples/ethers-wasm/index.js
@@ -1,4 +1,4 @@
-const ethers = import('./pkg');
+const ethers = import("./pkg");
 
 ethers
     .then(m => {
diff --git a/examples/ethers-wasm/package.json b/examples/ethers-wasm/package.json
index 9cc884c7..7dceecec 100644
--- a/examples/ethers-wasm/package.json
+++ b/examples/ethers-wasm/package.json
@@ -12,8 +12,8 @@
         "@wasm-tool/wasm-pack-plugin": "^1.6",
         "html-webpack-plugin": "^5.5",
         "text-encoding": "^0.7",
-        "webpack": "^5.74",
-        "webpack-cli": "^4.10",
+        "webpack": "^5.75",
+        "webpack-cli": "^5.0",
         "webpack-dev-server": "^4.11",
         "ganache-cli": "^6.12"
     }
diff --git a/examples/ethers-wasm/src/lib.rs b/examples/ethers-wasm/src/lib.rs
index 273836ce..e34c75ad 100644
--- a/examples/ethers-wasm/src/lib.rs
+++ b/examples/ethers-wasm/src/lib.rs
@@ -1,8 +1,8 @@
-use crate::utils::SIMPLECONTRACT_BIN;
 use ethers::{
     contract::abigen,
-    prelude::{ContractFactory, Provider, SignerMiddleware},
-    providers::Ws,
+    prelude::{Provider, SignerMiddleware},
+    providers::{Middleware, Ws},
+    signers::Signer,
 };
 use std::sync::Arc;
 use wasm_bindgen::prelude::*;
@@ -10,23 +10,13 @@ use web_sys::console;
 
 pub mod utils;
 
-// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
-// allocator.
-#[cfg(feature = "wee_alloc")]
-#[global_allocator]
-static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
-
 macro_rules! log {
     ( $( $t:tt )* ) => {
         web_sys::console::log_1(&format!( $( $t )* ).into());
     }
 }
 
-abigen!(
-    SimpleContract,
-    "./abi/contract_abi.json",
-    event_derives(serde::Deserialize, serde::Serialize)
-);
+abigen!(SimpleContract, "./abi/contract.json", derives(serde::Deserialize, serde::Serialize));
 
 #[wasm_bindgen]
 pub async fn deploy() {
@@ -37,24 +27,21 @@ pub async fn deploy() {
         &serde_wasm_bindgen::to_value(&*SIMPLECONTRACT_ABI).unwrap(),
     );
 
-    let wallet = utils::key(0);
-    log!("Wallet: {:?}", wallet);
-
     let endpoint = "ws://127.0.0.1:8545";
     let provider = Provider::<Ws>::connect(endpoint).await.unwrap();
-    let client = Arc::new(SignerMiddleware::new(provider, wallet));
-    log!("Connected to: `{}`", endpoint);
+    log!("Connected to: `{endpoint}`");
 
-    let bytecode = hex::decode(SIMPLECONTRACT_BIN).unwrap();
-    let factory = ContractFactory::new(SIMPLECONTRACT_ABI.clone(), bytecode.into(), client.clone());
+    let chain_id = provider.get_chainid().await.unwrap();
+    let wallet = utils::key(0).with_chain_id(chain_id.as_u64());
+    log!("Wallet: {wallet:?}");
+    let client = Arc::new(SignerMiddleware::new(provider, wallet));
 
     log!("Deploying contract...");
-    let contract = factory.deploy("hello WASM!".to_string()).unwrap().send().await.unwrap();
+    let deploy_tx = SimpleContract::deploy(client.clone(), "hello WASM!".to_string()).unwrap();
+    let contract: SimpleContract<_> = deploy_tx.send().await.unwrap();
     let addr = contract.address();
     log!("Deployed contract with address: {:?}", addr);
 
-    let contract = SimpleContract::new(addr, client.clone());
-
     let value = "bye from WASM!";
     log!("Setting value... `{}`", value);
     let receipt = contract.set_value(value.to_owned()).send().await.unwrap().await.unwrap();
diff --git a/examples/ethers-wasm/src/utils.rs b/examples/ethers-wasm/src/utils.rs
index 70bdd53e..2eec88ec 100644
--- a/examples/ethers-wasm/src/utils.rs
+++ b/examples/ethers-wasm/src/utils.rs
@@ -21,6 +21,3 @@ pub const PHRASE: &str =
 pub fn key(index: u32) -> LocalWallet {
     MnemonicBuilder::<English>::default().phrase(PHRASE).index(index).unwrap().build().unwrap()
 }
-
-/// Bytecode of the `SimpleContract`
-pub const SIMPLECONTRACT_BIN: &str = "608060405234801561001057600080fd5b5060405161073b38038061073b8339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b8382019150602082018581111561006957600080fd5b825186600182028301116401000000008211171561008657600080fd5b8083526020830192505050908051906020019080838360005b838110156100ba57808201518184015260208101905061009f565b50505050905090810190601f1680156100e75780820380516001836020036101000a031916815260200191505b506040525050503373ffffffffffffffffffffffffffffffffffffffff167fe826f71647b8486f2bae59832124c70792fba044036720a54ec8dacdd5df4fcb6000836040518080602001806020018381038352858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156101b65780601f1061018b576101008083540402835291602001916101b6565b820191906000526020600020905b81548152906001019060200180831161019957829003601f168201915b5050838103825284818151815260200191508051906020019080838360005b838110156101f05780820151818401526020810190506101d5565b50505050905090810190601f16801561021d5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a28060009080519060200190610242929190610249565b50506102e6565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061028a57805160ff19168380011785556102b8565b828001600101855582156102b8579182015b828111156102b757825182559160200191906001019061029c565b5b5090506102c591906102c9565b5090565b5b808211156102e25760008160009055506001016102ca565b5090565b610446806102f56000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063209652551461003b57806393a09352146100be575b600080fd5b610043610179565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610083578082015181840152602081019050610068565b50505050905090810190601f1680156100b05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610177600480360360208110156100d457600080fd5b81019080803590602001906401000000008111156100f157600080fd5b82018360208201111561010357600080fd5b8035906020019184600183028401116401000000008311171561012557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061021b565b005b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102115780601f106101e657610100808354040283529160200191610211565b820191906000526020600020905b8154815290600101906020018083116101f457829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff167fe826f71647b8486f2bae59832124c70792fba044036720a54ec8dacdd5df4fcb6000836040518080602001806020018381038352858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156102e35780601f106102b8576101008083540402835291602001916102e3565b820191906000526020600020905b8154815290600101906020018083116102c657829003601f168201915b5050838103825284818151815260200191508051906020019080838360005b8381101561031d578082015181840152602081019050610302565b50505050905090810190601f16801561034a5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2806000908051906020019061036f929190610373565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106103b457805160ff19168380011785556103e2565b828001600101855582156103e2579182015b828111156103e15782518255916020019190600101906103c6565b5b5090506103ef91906103f3565b5090565b5b8082111561040c5760008160009055506001016103f4565b509056fea26469706673582212202d397d3d0e6cf9afdeed7d5192e3abff386699395df0409eb5c3ec494832c57a64736f6c63430007000033";
diff --git a/examples/ethers-wasm/yarn.lock b/examples/ethers-wasm/yarn.lock
index 8a798a56..33828e7d 100644
--- a/examples/ethers-wasm/yarn.lock
+++ b/examples/ethers-wasm/yarn.lock
@@ -350,22 +350,20 @@
     "@webassemblyjs/ast" "1.11.1"
     "@xtuc/long" "4.2.2"
 
-"@webpack-cli/configtest@^1.2.0":
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5"
-  integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==
+"@webpack-cli/configtest@^2.0.1":
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.0.1.tgz#a69720f6c9bad6aef54a8fa6ba9c3533e7ef4c7f"
+  integrity sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==
 
-"@webpack-cli/info@^1.5.0":
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1"
-  integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==
-  dependencies:
-    envinfo "^7.7.3"
+"@webpack-cli/info@^2.0.1":
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.1.tgz#eed745799c910d20081e06e5177c2b2569f166c0"
+  integrity sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==
 
-"@webpack-cli/serve@^1.7.0":
-  version "1.7.0"
-  resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1"
-  integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==
+"@webpack-cli/serve@^2.0.1":
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.1.tgz#34bdc31727a1889198855913db2f270ace6d7bf8"
+  integrity sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==
 
 "@xtuc/ieee754@^1.2.0":
   version "1.2.0"
@@ -740,16 +738,16 @@ commander@^2.20.0:
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
 
-commander@^7.0.0:
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
-  integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
-
 commander@^8.3.0:
   version "8.3.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
   integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
 
+commander@^9.4.1:
+  version "9.5.0"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
+  integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
+
 compressible@~2.0.16:
   version "2.0.18"
   resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
@@ -1564,10 +1562,10 @@ inherits@2.0.3:
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
   integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
 
-interpret@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
-  integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
+interpret@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
+  integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
 
 invert-kv@^2.0.0:
   version "2.0.0"
@@ -2243,12 +2241,12 @@ readdirp@~3.6.0:
   dependencies:
     picomatch "^2.2.1"
 
-rechoir@^0.7.0:
-  version "0.7.1"
-  resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686"
-  integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==
+rechoir@^0.8.0:
+  version "0.8.0"
+  resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22"
+  integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==
   dependencies:
-    resolve "^1.9.0"
+    resolve "^1.20.0"
 
 relateurl@^0.2.7:
   version "0.2.7"
@@ -2298,7 +2296,7 @@ resolve-from@^5.0.0:
   resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
   integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
 
-resolve@^1.9.0:
+resolve@^1.20.0:
   version "1.22.1"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
   integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@@ -2783,22 +2781,23 @@ wbuf@^1.1.0, wbuf@^1.7.3:
   dependencies:
     minimalistic-assert "^1.0.0"
 
-webpack-cli@^4.10:
-  version "4.10.0"
-  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31"
-  integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==
+webpack-cli@^5.0:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.0.1.tgz#95fc0495ac4065e9423a722dec9175560b6f2d9a"
+  integrity sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==
   dependencies:
     "@discoveryjs/json-ext" "^0.5.0"
-    "@webpack-cli/configtest" "^1.2.0"
-    "@webpack-cli/info" "^1.5.0"
-    "@webpack-cli/serve" "^1.7.0"
+    "@webpack-cli/configtest" "^2.0.1"
+    "@webpack-cli/info" "^2.0.1"
+    "@webpack-cli/serve" "^2.0.1"
     colorette "^2.0.14"
-    commander "^7.0.0"
+    commander "^9.4.1"
     cross-spawn "^7.0.3"
+    envinfo "^7.7.3"
     fastest-levenshtein "^1.0.12"
     import-local "^3.0.2"
-    interpret "^2.2.0"
-    rechoir "^0.7.0"
+    interpret "^3.1.1"
+    rechoir "^0.8.0"
     webpack-merge "^5.7.3"
 
 webpack-dev-middleware@^5.3.1:
@@ -2860,10 +2859,10 @@ webpack-sources@^3.2.3:
   resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
   integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
 
-webpack@^5.74:
-  version "5.74.0"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980"
-  integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==
+webpack@^5.75:
+  version "5.75.0"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152"
+  integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==
   dependencies:
     "@types/eslint-scope" "^3.7.3"
     "@types/estree" "^0.0.51"
diff --git a/examples/events/Cargo.toml b/examples/events/Cargo.toml
index f8935bc0..b1730d52 100644
--- a/examples/events/Cargo.toml
+++ b/examples/events/Cargo.toml
@@ -1,13 +1,19 @@
 [package]
 name = "examples-events"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
 [dev-dependencies]
-ethers = { path = "../..", version = "2.0.0" }
+ethers = { workspace = true, features = ["rustls"] }
+
+tokio = { workspace = true, features = ["macros"] }
+
+serde.workspace = true
+serde_json.workspace = true
 
-eyre = "0.6"
-serde = { version = "1.0.144", features = ["derive"] }
-serde_json = "1.0.64"
-tokio = { version = "1.18", features = ["macros"] }
+eyre.workspace = true
diff --git a/examples/geth/Cargo.toml b/examples/geth/Cargo.toml
new file mode 100644
index 00000000..eef9e3a1
--- /dev/null
+++ b/examples/geth/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "examples-geth"
+version = "0.0.0"
+publish = false
+authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
+
+[dev-dependencies]
+ethers.workspace = true
+
+tokio = { workspace = true, features = ["macros"] }
+
+serde.workspace = true
+serde_json.workspace = true
+
+eyre.workspace = true
+tempfile.workspace = true
diff --git a/examples/geth_clique.rs b/examples/geth/examples/clique.rs
similarity index 100%
rename from examples/geth_clique.rs
rename to examples/geth/examples/clique.rs
diff --git a/examples/middleware/Cargo.toml b/examples/middleware/Cargo.toml
index c3396571..b11c82d3 100644
--- a/examples/middleware/Cargo.toml
+++ b/examples/middleware/Cargo.toml
@@ -1,15 +1,18 @@
 [package]
 name = "examples-middleware"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
 
-[dev-dependencies]
-ethers = { path = "../..", version = "2.0.0", features = ["rustls", "ws"] }
-
-async-trait = { version = "0.1.50", default-features = false }
-eyre = "0.6"
-serde_json = "1.0.61"
-thiserror = { version = "1.0", default-features = false }
-tokio = { version = "1.18", features = ["macros", "rt", "rt-multi-thread"] }
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
+[dev-dependencies]
+ethers = { workspace = true, features = ["rustls"] }
+serde.workspace = true
+serde_json.workspace = true
+tokio = { workspace = true, features = ["macros"] }
+async-trait.workspace = true
+thiserror.workspace = true
+eyre.workspace = true
diff --git a/examples/providers/Cargo.toml b/examples/providers/Cargo.toml
index 80cf4446..964e2c4c 100644
--- a/examples/providers/Cargo.toml
+++ b/examples/providers/Cargo.toml
@@ -1,18 +1,23 @@
 [package]
 name = "examples-providers"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
 [dev-dependencies]
-ethers = { path = "../..", version = "2.0.0", features = ["abigen", "ipc", "rustls", "ws"] }
+ethers = { workspace = true, features = ["abigen", "ipc", "rustls", "ws"] }
+
+tokio = { workspace = true, features = ["macros"] }
+async-trait.workspace = true
+reqwest.workspace = true
+url.workspace = true
 
-eyre = "0.6"
-reqwest = { version = "0.11.14", default-features = false }
-serde = { version = "1.0.144", features = ["derive"] }
-serde_json = "1.0.64"
-tokio = { version = "1.18", features = ["macros"] }
+serde.workspace = true
+serde_json.workspace = true
 
-async-trait = "0.1"
-url = "2.3"
-thiserror = "1.0"
+thiserror.workspace = true
+eyre.workspace = true
diff --git a/examples/queries/Cargo.toml b/examples/queries/Cargo.toml
index 27fe8d8a..71b01a4d 100644
--- a/examples/queries/Cargo.toml
+++ b/examples/queries/Cargo.toml
@@ -1,13 +1,19 @@
 [package]
 name = "examples-queries"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
 [dev-dependencies]
-ethers = { path = "../..", version = "2.0.0", features = ["abigen", "rustls", "ws"] }
+ethers = { workspace = true, features = ["abigen", "ws", "rustls"] }
+
+tokio = { workspace = true, features = ["macros"] }
+
+serde.workspace = true
+serde_json.workspace = true
 
-eyre = "0.6"
-serde = { version = "1.0.144", features = ["derive"] }
-serde_json = "1.0.64"
-tokio = { version = "1.18", features = ["macros"] }
+eyre.workspace = true
diff --git a/examples/subscriptions/Cargo.toml b/examples/subscriptions/Cargo.toml
index b90a1af1..76ca8499 100644
--- a/examples/subscriptions/Cargo.toml
+++ b/examples/subscriptions/Cargo.toml
@@ -1,13 +1,19 @@
 [package]
 name = "examples-subscriptions"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
 [dev-dependencies]
-ethers = { path = "../..", version = "2.0.0", features = ["abigen", "rustls", "ws"] }
+ethers = { workspace = true, features = ["abigen", "ws", "rustls"] }
+
+tokio = { workspace = true, features = ["macros"] }
+
+serde.workspace = true
+serde_json.workspace = true
 
-eyre = "0.6"
-serde = { version = "1.0.144", features = ["derive"] }
-serde_json = "1.0.64"
-tokio = { version = "1.18", features = ["macros"] }
+eyre.workspace = true
diff --git a/examples/transactions/Cargo.toml b/examples/transactions/Cargo.toml
index ec152a53..70bc415d 100644
--- a/examples/transactions/Cargo.toml
+++ b/examples/transactions/Cargo.toml
@@ -1,13 +1,19 @@
 [package]
 name = "examples-transactions"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
 [dev-dependencies]
-ethers = { path = "../..", version = "2.0.0", features = ["abigen", "rustls", "ws"] }
+ethers = { workspace = true, features = ["abigen", "ws", "rustls"] }
+
+tokio = { workspace = true, features = ["macros"] }
+
+serde.workspace = true
+serde_json.workspace = true
 
-eyre = "0.6"
-serde = { version = "1.0.144", features = ["derive"] }
-serde_json = "1.0.64"
-tokio = { version = "1.18", features = ["macros"] }
+eyre.workspace = true
diff --git a/examples/wallets/Cargo.toml b/examples/wallets/Cargo.toml
index 937663ed..0d37ab5b 100644
--- a/examples/wallets/Cargo.toml
+++ b/examples/wallets/Cargo.toml
@@ -1,20 +1,25 @@
 [package]
 name = "examples-wallets"
 version = "2.0.0"
+publish = false
 authors = ["Andrea Simeoni <andreasimeoni84@gmail.com>"]
-edition = "2021"
+
+license.workspace = true
+rust-version.workspace = true
+edition.workspace = true
 
 [features]
 default = ["ledger", "trezor", "yubi"]
-ledger = []
-trezor = []
-yubi = []
+ledger = ["ethers/ledger"]
+trezor = ["ethers/trezor"]
+yubi = ["ethers/yubi"]
 
 [dev-dependencies]
-ethers = { path = "../..", version = "2.0.0", features = ["abigen", "eip712", "ledger", "rustls", "trezor", "ws", "yubi"] }
+ethers = { workspace = true, features = ["abigen", "eip712", "ws", "rustls"] }
+
+tokio = { workspace = true, features = ["macros"] }
 
-eyre = "0.6"
-serde = { version = "1.0.144", features = ["derive"] }
-serde_json = "1.0.64"
-tokio = { version = "1.18", features = ["macros"] }
+serde.workspace = true
+serde_json.workspace = true
 
+eyre.workspace = true
diff --git a/release.toml b/release.toml
deleted file mode 100644
index d55f4e95..00000000
--- a/release.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-consolidate-commits = false
-consolidate-pushes = true


Test patch:
diff --git a/ethers-contract/tests/it/contract.rs b/ethers-contract/tests/it/contract.rs
index 89dcb926..8d4dd44e 100644
--- a/ethers-contract/tests/it/contract.rs
+++ b/ethers-contract/tests/it/contract.rs
@@ -11,10 +11,9 @@ use ethers_core::{
     },
     utils::{keccak256, Anvil},
 };
-use ethers_derive_eip712::*;
 use ethers_providers::{Http, Middleware, MiddlewareError, Provider, StreamExt};
 use ethers_signers::{LocalWallet, Signer};
-use std::{convert::TryFrom, iter::FromIterator, sync::Arc, time::Duration};
+use std::{sync::Arc, time::Duration};
 
 #[derive(Debug)]
 pub struct NonClone<M> {
@@ -787,7 +786,10 @@ async fn multicall_aggregate() {
 }
 
 #[tokio::test]
+#[cfg(feature = "eip712")]
 async fn test_derive_eip712() {
+    use ethers_derive_eip712::*;
+
     // Generate Contract ABI Bindings
     abigen!(
         DeriveEip712Test,
diff --git a/ethers-etherscan/tests/it/contract.rs b/ethers-etherscan/tests/it/contract.rs
index 3ba30edc..a0ff3cd3 100644
--- a/ethers-etherscan/tests/it/contract.rs
+++ b/ethers-etherscan/tests/it/contract.rs
@@ -4,7 +4,7 @@ use ethers_etherscan::contract::SourceCodeMetadata;
 use serial_test::serial;
 
 /// Abi of [0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413](https://api.etherscan.io/api?module=contract&action=getsourcecode&address=0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413).
-const DAO_ABI: &str = include!("../../../tests/testdata/the_dao_abi.expr");
+const DAO_ABI: &str = include!("../../../testdata/the_dao_abi.expr");
 
 #[tokio::test]
 #[serial]
diff --git a/ethers-middleware/tests/it/transformer.rs b/ethers-middleware/tests/it/transformer.rs
index 87bdfcc0..a3cbb3f1 100644
--- a/ethers-middleware/tests/it/transformer.rs
+++ b/ethers-middleware/tests/it/transformer.rs
@@ -12,7 +12,7 @@ use std::sync::Arc;
 
 type HttpWallet = SignerMiddleware<Provider<Http>, LocalWallet>;
 
-abigen!(SimpleStorage, "../tests/testdata/SimpleStorage.json");
+abigen!(SimpleStorage, "../testdata/SimpleStorage.json");
 
 #[tokio::test]
 #[ignore]
diff --git a/src/lib.rs b/ethers/src/lib.rs
similarity index 100%
rename from src/lib.rs
rename to ethers/src/lib.rs
diff --git a/tests/live/celo.rs b/ethers/tests/live/celo.rs
similarity index 100%
rename from tests/live/celo.rs
rename to ethers/tests/live/celo.rs
diff --git a/tests/live/main.rs b/ethers/tests/live/main.rs
similarity index 75%
rename from tests/live/main.rs
rename to ethers/tests/live/main.rs
index 175e4b80..a8828646 100644
--- a/tests/live/main.rs
+++ b/ethers/tests/live/main.rs
@@ -9,5 +9,5 @@
 mod celo;
 
 pub(crate) mod simple_storage {
-    ethers::contract::abigen!(SimpleStorage, "./tests/testdata/SimpleStorage.json");
+    ethers::contract::abigen!(SimpleStorage, "../testdata/SimpleStorage.json");
 }
diff --git a/examples/ethers-wasm/tests/contract_with_abi.rs b/examples/ethers-wasm/tests/contract_with_abi.rs
index df080b38..0050be94 100644
--- a/examples/ethers-wasm/tests/contract_with_abi.rs
+++ b/examples/ethers-wasm/tests/contract_with_abi.rs
@@ -1,51 +1,42 @@
 #![cfg(target_arch = "wasm32")]
 
 use ethers::{
-    prelude::{
-        abigen, ContractFactory, Http, JsonRpcClient, LocalWallet, Provider, SignerMiddleware, Ws,
-    },
+    prelude::{Http, JsonRpcClient, LocalWallet, Provider, SignerMiddleware, Ws},
     signers::Signer,
     types::Chain,
 };
-use std::{convert::TryFrom, sync::Arc};
+use ethers_wasm::{utils, SimpleContract};
+use std::sync::Arc;
 use wasm_bindgen_test::*;
 
 wasm_bindgen_test_configure!(run_in_browser);
 
-// Generate the type-safe contract bindings by providing the ABI
-// definition in human readable format
-abigen!(
-    SimpleContract,
-    "./abi/contract_abi.json",
-    event_derives(serde::Deserialize, serde::Serialize)
-);
-
 #[wasm_bindgen_test]
 async fn http_connect_and_deploy() {
     console_log!("connecting http...");
     let provider = Provider::<Http>::try_from("http://localhost:8545").unwrap();
-    deploy(provider, ethers_wasm::utils::key(0).with_chain_id(Chain::AnvilHardhat)).await;
+    deploy(provider, utils::key(0).with_chain_id(Chain::AnvilHardhat)).await;
 }
 
 #[wasm_bindgen_test]
 async fn ws_connect_and_deploy() {
     console_log!("connecting ws...");
     let provider = Provider::new(Ws::connect("ws://localhost:8545").await.unwrap());
-    deploy(provider, ethers_wasm::utils::key(1).with_chain_id(Chain::AnvilHardhat)).await;
+    deploy(provider, utils::key(1).with_chain_id(Chain::AnvilHardhat)).await;
 }
 
 async fn deploy<T: JsonRpcClient>(provider: Provider<T>, wallet: LocalWallet) {
     let client = Arc::new(SignerMiddleware::new(provider, wallet));
 
-    let bytecode = hex::decode(ethers_wasm::utils::SIMPLECONTRACT_BIN).unwrap();
-    let factory = ContractFactory::new(SIMPLECONTRACT_ABI.clone(), bytecode.into(), client.clone());
-    let contract =
-        factory.deploy("Hello from Contract!".to_string()).unwrap().send().await.unwrap();
+    let expected = "Hello from Contract!";
+    let deploy_tx = SimpleContract::deploy(client, expected.to_string()).unwrap();
+    let contract: SimpleContract<_> = deploy_tx.send().await.unwrap();
     let addr = contract.address();
-    console_log!("deployed to {}", addr);
+    console_log!("deployed to {addr}");
 
-    let contract = SimpleContract::new(addr, client.clone());
     let value = contract.get_value().call().await.unwrap();
 
-    console_log!("value: {:?}", value);
+    console_log!("value: {value:?}");
+
+    assert_eq!(value, expected);
 }