From 39eba149960013afabe0d38a570e55897cebc984 Mon Sep 17 00:00:00 2001
From: PG Herveou <pgherveou@gmail.com>
Date: Fri, 15 Nov 2024 09:31:25 +0100
Subject: [PATCH] [pallet-revive] use evm decimals in call host fn (#6466)

This PR update the pallet to use the EVM 18 decimal balance in contracts
call and host functions instead of the native balance.

It also updates the js example to add the piggy-bank solidity contract
that expose the problem

---------

Co-authored-by: GitHub Action <action@github.com>
---
 .../assets/asset-hub-westend/src/lib.rs       |  17 +-
 prdoc/pr_6466.prdoc                           |  12 +
 substrate/bin/node/runtime/src/lib.rs         |  11 +-
 .../revive/rpc/examples/js/abi/event.json     |  34 +
 .../revive/rpc/examples/js/abi/piggyBank.json |  65 ++
 .../revive/rpc/examples/js/abi/revert.json    |  14 +
 .../frame/revive/rpc/examples/js/bun.lockb    | Bin 23039 -> 45391 bytes
 .../rpc/examples/js/contracts/PiggyBank.sol   |  32 +
 .../revive/rpc/examples/js/evm-contracts.json |  56 --
 .../frame/revive/rpc/examples/js/index.html   |  53 +-
 .../revive/rpc/examples/js/package-lock.json  | 882 +++++++++---------
 .../frame/revive/rpc/examples/js/package.json |   9 +-
 .../revive/rpc/examples/js/pvm-contracts.json |  56 --
 .../revive/rpc/examples/js/pvm/event.polkavm  | Bin 0 -> 5186 bytes
 .../rpc/examples/js/pvm/piggyBank.polkavm     | Bin 0 -> 12334 bytes
 .../revive/rpc/examples/js/pvm/revert.polkavm | Bin 0 -> 2490 bytes
 .../rpc/examples/js/src/build-contracts.ts    |  14 +-
 .../frame/revive/rpc/examples/js/src/event.ts |   4 +-
 .../frame/revive/rpc/examples/js/src/lib.ts   |  24 +-
 .../revive/rpc/examples/js/src/piggy-bank.ts  |  24 +
 .../revive/rpc/examples/js/src/revert.ts      |   4 +-
 .../revive/rpc/examples/js/src/transfer.ts    |  17 +
 .../revive/rpc/examples/js/tsconfig.json      |  38 +-
 .../js/types/ethers-contracts/Event.ts        | 117 +++
 .../js/types/ethers-contracts/PiggyBank.ts    |  96 ++
 .../js/types/ethers-contracts/Revert.ts       |  78 ++
 .../js/types/ethers-contracts/common.ts       | 100 ++
 .../factories/Event__factory.ts               |  51 +
 .../factories/PiggyBank__factory.ts           |  82 ++
 .../factories/Revert__factory.ts              |  31 +
 .../types/ethers-contracts/factories/index.ts |   6 +
 .../js/types/ethers-contracts/index.ts        |  10 +
 .../frame/revive/rpc/examples/package.json    |   1 -
 .../frame/revive/rpc/revive_chain.metadata    | Bin 656635 -> 658056 bytes
 substrate/frame/revive/rpc/src/client.rs      |  36 +-
 substrate/frame/revive/rpc/src/example.rs     |  25 +
 .../frame/revive/rpc/src/subxt_client.rs      |   5 +
 substrate/frame/revive/rpc/src/tests.rs       |  55 +-
 .../frame/revive/src/benchmarking/mod.rs      |   9 +-
 substrate/frame/revive/src/evm/runtime.rs     |   7 +-
 substrate/frame/revive/src/exec.rs            | 163 ++--
 substrate/frame/revive/src/lib.rs             |  69 +-
 42 files changed, 1537 insertions(+), 770 deletions(-)
 create mode 100644 prdoc/pr_6466.prdoc
 create mode 100644 substrate/frame/revive/rpc/examples/js/abi/event.json
 create mode 100644 substrate/frame/revive/rpc/examples/js/abi/piggyBank.json
 create mode 100644 substrate/frame/revive/rpc/examples/js/abi/revert.json
 create mode 100644 substrate/frame/revive/rpc/examples/js/contracts/PiggyBank.sol
 delete mode 100644 substrate/frame/revive/rpc/examples/js/evm-contracts.json
 delete mode 100644 substrate/frame/revive/rpc/examples/js/pvm-contracts.json
 create mode 100644 substrate/frame/revive/rpc/examples/js/pvm/event.polkavm
 create mode 100644 substrate/frame/revive/rpc/examples/js/pvm/piggyBank.polkavm
 create mode 100644 substrate/frame/revive/rpc/examples/js/pvm/revert.polkavm
 create mode 100644 substrate/frame/revive/rpc/examples/js/src/piggy-bank.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/src/transfer.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/Event.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/PiggyBank.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/Revert.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/common.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/Event__factory.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/PiggyBank__factory.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/Revert__factory.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/index.ts
 create mode 100644 substrate/frame/revive/rpc/examples/js/types/ethers-contracts/index.ts
 delete mode 100644 substrate/frame/revive/rpc/examples/package.json

diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
index e66c4f27fbe..2206aea78ec 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
@@ -45,10 +45,7 @@ use frame_support::{
 	ord_parameter_types, parameter_types,
 	traits::{
 		fungible, fungibles,
-		tokens::{
-			imbalance::ResolveAssetTo, nonfungibles_v2::Inspect, Fortitude::Polite,
-			Preservation::Expendable,
-		},
+		tokens::{imbalance::ResolveAssetTo, nonfungibles_v2::Inspect},
 		AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, InstanceFilter,
 		Nothing, TransformOrigin,
 	},
@@ -68,7 +65,7 @@ use parachains_common::{
 	NORMAL_DISPATCH_RATIO,
 };
 use sp_api::impl_runtime_apis;
-use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160};
+use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160, U256};
 use sp_runtime::{
 	generic, impl_opaque_keys,
 	traits::{AccountIdConversion, BlakeTwo256, Block as BlockT, Saturating, Verify},
@@ -127,7 +124,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: alloc::borrow::Cow::Borrowed("westmint"),
 	impl_name: alloc::borrow::Cow::Borrowed("westmint"),
 	authoring_version: 1,
-	spec_version: 1_016_005,
+	spec_version: 1_016_006,
 	impl_version: 0,
 	apis: RUNTIME_API_VERSIONS,
 	transaction_version: 16,
@@ -2080,10 +2077,8 @@ impl_runtime_apis! {
 
 	impl pallet_revive::ReviveApi<Block, AccountId, Balance, Nonce, BlockNumber, EventRecord> for Runtime
 	{
-		fn balance(address: H160) -> Balance {
-			use frame_support::traits::fungible::Inspect;
-			let account = <Runtime as pallet_revive::Config>::AddressMapper::to_account_id(&address);
-			Balances::reducible_balance(&account, Expendable, Polite)
+		fn balance(address: H160) -> U256 {
+			Revive::evm_balance(&address)
 		}
 
 		fn nonce(address: H160) -> Nonce {
@@ -2093,7 +2088,7 @@ impl_runtime_apis! {
 		fn eth_transact(
 			from: H160,
 			dest: Option<H160>,
-			value: Balance,
+			value: U256,
 			input: Vec<u8>,
 			gas_limit: Option<Weight>,
 			storage_deposit_limit: Option<Balance>,
diff --git a/prdoc/pr_6466.prdoc b/prdoc/pr_6466.prdoc
new file mode 100644
index 00000000000..0faa6afc800
--- /dev/null
+++ b/prdoc/pr_6466.prdoc
@@ -0,0 +1,12 @@
+title: '[pallet-revive] add piggy-bank sol example'
+doc:
+- audience: Runtime Dev
+  description: |-
+    This PR update the pallet to use the EVM 18 decimal balance in contracts call and host functions instead of the native balance.
+
+    It also updates the js example to add the piggy-bank solidity contract that expose the problem
+crates:
+- name: pallet-revive-eth-rpc
+  bump: minor
+- name: pallet-revive
+  bump: minor
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 5a2ff3ceb7f..914b51fb562 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -54,7 +54,7 @@ use frame_support::{
 		},
 		tokens::{
 			imbalance::ResolveAssetTo, nonfungibles_v2::Inspect, pay::PayAssetFromAccount,
-			Fortitude::Polite, GetSalary, PayFromAccount, Preservation::Preserve,
+			GetSalary, PayFromAccount,
 		},
 		AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, Contains,
 		Currency, EitherOfDiverse, EnsureOriginWithArg, EqualPrivilegeOnly, Imbalance, InsideBoth,
@@ -86,6 +86,7 @@ use pallet_nis::WithMaximumOf;
 use pallet_nomination_pools::PoolId;
 use pallet_revive::{evm::runtime::EthExtra, AddressMapper};
 use pallet_session::historical as pallet_session_historical;
+use sp_core::U256;
 // Can't use `FungibleAdapter` here until Treasury pallet migrates to fungibles
 // <https://github.com/paritytech/polkadot-sdk/issues/226>
 use pallet_broker::TaskId;
@@ -3205,10 +3206,8 @@ impl_runtime_apis! {
 
 	impl pallet_revive::ReviveApi<Block, AccountId, Balance, Nonce, BlockNumber, EventRecord> for Runtime
 	{
-		fn balance(address: H160) -> Balance {
-			use frame_support::traits::fungible::Inspect;
-			let account = <Runtime as pallet_revive::Config>::AddressMapper::to_account_id(&address);
-			Balances::reducible_balance(&account, Preserve, Polite)
+		fn balance(address: H160) -> U256 {
+			Revive::evm_balance(&address)
 		}
 
 		fn nonce(address: H160) -> Nonce {
@@ -3219,7 +3218,7 @@ impl_runtime_apis! {
 		fn eth_transact(
 			from: H160,
 			dest: Option<H160>,
-			value: Balance,
+			value: U256,
 			input: Vec<u8>,
 			gas_limit: Option<Weight>,
 			storage_deposit_limit: Option<Balance>,
diff --git a/substrate/frame/revive/rpc/examples/js/abi/event.json b/substrate/frame/revive/rpc/examples/js/abi/event.json
new file mode 100644
index 00000000000..d36089fbc84
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/abi/event.json
@@ -0,0 +1,34 @@
+[
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "sender",
+				"type": "address"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "value",
+				"type": "uint256"
+			},
+			{
+				"indexed": false,
+				"internalType": "string",
+				"name": "message",
+				"type": "string"
+			}
+		],
+		"name": "ExampleEvent",
+		"type": "event"
+	},
+	{
+		"inputs": [],
+		"name": "triggerEvent",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	}
+]
diff --git a/substrate/frame/revive/rpc/examples/js/abi/piggyBank.json b/substrate/frame/revive/rpc/examples/js/abi/piggyBank.json
new file mode 100644
index 00000000000..2c2cfd5f753
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/abi/piggyBank.json
@@ -0,0 +1,65 @@
+[
+	{
+		"inputs": [],
+		"stateMutability": "nonpayable",
+		"type": "constructor"
+	},
+	{
+		"inputs": [],
+		"name": "deposit",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "payable",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "getDeposit",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "owner",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "withdrawAmount",
+				"type": "uint256"
+			}
+		],
+		"name": "withdraw",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "remainingBal",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	}
+]
diff --git a/substrate/frame/revive/rpc/examples/js/abi/revert.json b/substrate/frame/revive/rpc/examples/js/abi/revert.json
new file mode 100644
index 00000000000..be2945fcc0a
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/abi/revert.json
@@ -0,0 +1,14 @@
+[
+	{
+		"inputs": [],
+		"stateMutability": "nonpayable",
+		"type": "constructor"
+	},
+	{
+		"inputs": [],
+		"name": "doRevert",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	}
+]
diff --git a/substrate/frame/revive/rpc/examples/js/bun.lockb b/substrate/frame/revive/rpc/examples/js/bun.lockb
index 8bf47d7eb8b82734467165627413c33adede6fd6..700dca51da2ad3f843e890258b59c16fd4df6457 100755
GIT binary patch
literal 45391
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%0DALZ~bv?cJO=LC2l@6M`;bKNw0vD4}1
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

delta 4427
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
MU3@bKPv6`B1XQ9;6951J

diff --git a/substrate/frame/revive/rpc/examples/js/contracts/PiggyBank.sol b/substrate/frame/revive/rpc/examples/js/contracts/PiggyBank.sol
new file mode 100644
index 00000000000..1906c465888
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/contracts/PiggyBank.sol
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+contract PiggyBank {
+
+    uint private balance;
+    address public owner;
+
+    constructor() {
+        owner = msg.sender;
+        balance = 0;
+    }
+
+    function deposit() public payable returns (uint) {
+        balance += msg.value;
+        return balance;
+    }
+
+    function getDeposit() public view returns (uint) {
+        return balance;
+    }
+
+    function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
+        require(msg.sender == owner);
+        balance -= withdrawAmount;
+        (bool success, ) = payable(msg.sender).call{value: withdrawAmount}("");
+        require(success, "Transfer failed");
+
+        return balance;
+    }
+}
+
diff --git a/substrate/frame/revive/rpc/examples/js/evm-contracts.json b/substrate/frame/revive/rpc/examples/js/evm-contracts.json
deleted file mode 100644
index 4d98f5dd814..00000000000
--- a/substrate/frame/revive/rpc/examples/js/evm-contracts.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
-  "event": {
-    "abi": [
-      {
-        "anonymous": false,
-        "inputs": [
-          {
-            "indexed": true,
-            "internalType": "address",
-            "name": "sender",
-            "type": "address"
-          },
-          {
-            "indexed": false,
-            "internalType": "uint256",
-            "name": "value",
-            "type": "uint256"
-          },
-          {
-            "indexed": false,
-            "internalType": "string",
-            "name": "message",
-            "type": "string"
-          }
-        ],
-        "name": "ExampleEvent",
-        "type": "event"
-      },
-      {
-        "inputs": [],
-        "name": "triggerEvent",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-      }
-    ],
-    "bytecode": "6080604052348015600e575f5ffd5b506101b68061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063ede48fb71461002d575b5f5ffd5b610035610037565b005b5f61303990505f6040518060400160405280600b81526020017f48656c6c6f20776f726c6400000000000000000000000000000000000000000081525090503373ffffffffffffffffffffffffffffffffffffffff167f1585375487296ff2f0370daeec4214074a032b31af827c12622fa9a58c16c7d083836040516100be929190610152565b60405180910390a25050565b5f819050919050565b6100dc816100ca565b82525050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610124826100e2565b61012e81856100ec565b935061013e8185602086016100fc565b6101478161010a565b840191505092915050565b5f6040820190506101655f8301856100d3565b8181036020830152610177818461011a565b9050939250505056fea2646970667358221220a159f2cdba512e018377f5822cfd8ef04769755d98c3e494275605d96d7d13e864736f6c634300081c0033"
-  },
-  "revert": {
-    "abi": [
-      {
-        "inputs": [],
-        "stateMutability": "nonpayable",
-        "type": "constructor"
-      },
-      {
-        "inputs": [],
-        "name": "doRevert",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-      }
-    ],
-    "bytecode": "6080604052348015600e575f5ffd5b506101138061001c5f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c8063afc874d214602a575b5f5ffd5b60306032565b005b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040160629060c1565b60405180910390fd5b5f82825260208201905092915050565b7f726576657274206d6573736167650000000000000000000000000000000000005f82015250565b5f60ad600e83606b565b915060b682607b565b602082019050919050565b5f6020820190508181035f83015260d68160a3565b905091905056fea264697066735822122084f7096e030faf779d12b20184187708d335e4bcd4208a52c0651700fe8dde6a64736f6c634300081c0033"
-  }
-}
\ No newline at end of file
diff --git a/substrate/frame/revive/rpc/examples/js/index.html b/substrate/frame/revive/rpc/examples/js/index.html
index 052daf2787f..97efebe180e 100644
--- a/substrate/frame/revive/rpc/examples/js/index.html
+++ b/substrate/frame/revive/rpc/examples/js/index.html
@@ -1,29 +1,38 @@
 <!doctype html>
 <html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <link rel="icon" href="https://polkadot.com/favicon.ico">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>MetaMask Playground</title>
-    <style>
-	  input { width: 300px; margin-right: 10px; }
+	<head>
+		<meta charset="UTF-8" />
+		<link rel="icon" href="https://polkadot.com/favicon.ico" />
+		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+		<title>MetaMask Playground</title>
+		<style>
+			input {
+				width: 300px;
+				margin-right: 10px;
+			}
 
-      button {
-        display: block;
-        margin-bottom: 10px;
-      }
-    </style>
-  </head>
-  <body>
-    <input id="transferInput" type="text" style="float: left" placeholder="Destination address" value="0x3cd0a705a2dc65e5b1e1205896baa2be8a07c6e0" />
-    <button id="transferButton">Transfer coins</button>
+			button {
+				display: block;
+				margin-bottom: 10px;
+			}
+		</style>
+	</head>
+	<body>
+		<input
+			id="transferInput"
+			type="text"
+			style="float: left"
+			placeholder="Destination address"
+			value="0x3cd0a705a2dc65e5b1e1205896baa2be8a07c6e0"
+		/>
+		<button id="transferButton">Transfer coins</button>
 
-    <button id="deployButton">Deploy Contract</button>
+		<button id="deployButton">Deploy Contract</button>
 
-    <input id="callInput" type="text" style="float: left" placeholder="Contract address" />
-    <button id="callButton">Call Contract</button>
+		<input id="callInput" type="text" style="float: left" placeholder="Contract address" />
+		<button id="callButton">Call Contract</button>
 
-    <button id="deployAndCallButton">Deploy and Call Contract</button>
-    <script type="module" src="src/web.ts"></script>
-  </body>
+		<button id="deployAndCallButton">Deploy and Call Contract</button>
+		<script type="module" src="src/web.ts"></script>
+	</body>
 </html>
diff --git a/substrate/frame/revive/rpc/examples/js/package-lock.json b/substrate/frame/revive/rpc/examples/js/package-lock.json
index f1453eae64c..5c7db0abc93 100644
--- a/substrate/frame/revive/rpc/examples/js/package-lock.json
+++ b/substrate/frame/revive/rpc/examples/js/package-lock.json
@@ -1,443 +1,443 @@
 {
-  "name": "demo",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "demo",
-      "version": "0.0.0",
-      "dependencies": {
-        "ethers": "^6.13.1",
-        "solc": "^0.8.28"
-      },
-      "devDependencies": {
-        "typescript": "^5.5.3",
-        "vite": "^5.4.8"
-      }
-    },
-    "node_modules/@adraffy/ens-normalize": {
-      "version": "1.10.1",
-      "license": "MIT"
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.21.5",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@noble/curves": {
-      "version": "1.2.0",
-      "license": "MIT",
-      "dependencies": {
-        "@noble/hashes": "1.3.2"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      }
-    },
-    "node_modules/@noble/hashes": {
-      "version": "1.3.2",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 16"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      }
-    },
-    "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.24.0",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.24.0",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@types/estree": {
-      "version": "1.0.6",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@types/node": {
-      "version": "18.15.13",
-      "license": "MIT"
-    },
-    "node_modules/aes-js": {
-      "version": "4.0.0-beta.5",
-      "license": "MIT"
-    },
-    "node_modules/command-exists": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
-      "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==",
-      "license": "MIT"
-    },
-    "node_modules/commander": {
-      "version": "8.3.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
-      "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 12"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.21.5",
-      "dev": true,
-      "hasInstallScript": true,
-      "license": "MIT",
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.21.5",
-        "@esbuild/android-arm": "0.21.5",
-        "@esbuild/android-arm64": "0.21.5",
-        "@esbuild/android-x64": "0.21.5",
-        "@esbuild/darwin-arm64": "0.21.5",
-        "@esbuild/darwin-x64": "0.21.5",
-        "@esbuild/freebsd-arm64": "0.21.5",
-        "@esbuild/freebsd-x64": "0.21.5",
-        "@esbuild/linux-arm": "0.21.5",
-        "@esbuild/linux-arm64": "0.21.5",
-        "@esbuild/linux-ia32": "0.21.5",
-        "@esbuild/linux-loong64": "0.21.5",
-        "@esbuild/linux-mips64el": "0.21.5",
-        "@esbuild/linux-ppc64": "0.21.5",
-        "@esbuild/linux-riscv64": "0.21.5",
-        "@esbuild/linux-s390x": "0.21.5",
-        "@esbuild/linux-x64": "0.21.5",
-        "@esbuild/netbsd-x64": "0.21.5",
-        "@esbuild/openbsd-x64": "0.21.5",
-        "@esbuild/sunos-x64": "0.21.5",
-        "@esbuild/win32-arm64": "0.21.5",
-        "@esbuild/win32-ia32": "0.21.5",
-        "@esbuild/win32-x64": "0.21.5"
-      }
-    },
-    "node_modules/ethers": {
-      "version": "6.13.3",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/ethers-io/"
-        },
-        {
-          "type": "individual",
-          "url": "https://www.buymeacoffee.com/ricmoo"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "@adraffy/ens-normalize": "1.10.1",
-        "@noble/curves": "1.2.0",
-        "@noble/hashes": "1.3.2",
-        "@types/node": "18.15.13",
-        "aes-js": "4.0.0-beta.5",
-        "tslib": "2.4.0",
-        "ws": "8.17.1"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.9",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
-      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/js-sha3": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
-      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
-      "license": "MIT"
-    },
-    "node_modules/memorystream": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
-      "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
-      "engines": {
-        "node": ">= 0.10.0"
-      }
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.7",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/picocolors": {
-      "version": "1.1.0",
-      "dev": true,
-      "license": "ISC"
-    },
-    "node_modules/postcss": {
-      "version": "8.4.47",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "nanoid": "^3.3.7",
-        "picocolors": "^1.1.0",
-        "source-map-js": "^1.2.1"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "4.24.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/estree": "1.0.6"
-      },
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=18.0.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.24.0",
-        "@rollup/rollup-android-arm64": "4.24.0",
-        "@rollup/rollup-darwin-arm64": "4.24.0",
-        "@rollup/rollup-darwin-x64": "4.24.0",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.24.0",
-        "@rollup/rollup-linux-arm-musleabihf": "4.24.0",
-        "@rollup/rollup-linux-arm64-gnu": "4.24.0",
-        "@rollup/rollup-linux-arm64-musl": "4.24.0",
-        "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0",
-        "@rollup/rollup-linux-riscv64-gnu": "4.24.0",
-        "@rollup/rollup-linux-s390x-gnu": "4.24.0",
-        "@rollup/rollup-linux-x64-gnu": "4.24.0",
-        "@rollup/rollup-linux-x64-musl": "4.24.0",
-        "@rollup/rollup-win32-arm64-msvc": "4.24.0",
-        "@rollup/rollup-win32-ia32-msvc": "4.24.0",
-        "@rollup/rollup-win32-x64-msvc": "4.24.0",
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/semver": {
-      "version": "5.7.2",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
-      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/solc": {
-      "version": "0.8.28",
-      "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.28.tgz",
-      "integrity": "sha512-AFCiJ+b4RosyyNhnfdVH4ZR1+TxiL91iluPjw0EJslIu4LXGM9NYqi2z5y8TqochC4tcH9QsHfwWhOIC9jPDKA==",
-      "license": "MIT",
-      "dependencies": {
-        "command-exists": "^1.2.8",
-        "commander": "^8.1.0",
-        "follow-redirects": "^1.12.1",
-        "js-sha3": "0.8.0",
-        "memorystream": "^0.3.1",
-        "semver": "^5.5.0",
-        "tmp": "0.0.33"
-      },
-      "bin": {
-        "solcjs": "solc.js"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.1",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/tmp": {
-      "version": "0.0.33",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-      "license": "MIT",
-      "dependencies": {
-        "os-tmpdir": "~1.0.2"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/tslib": {
-      "version": "2.4.0",
-      "license": "0BSD"
-    },
-    "node_modules/typescript": {
-      "version": "5.6.3",
-      "dev": true,
-      "license": "Apache-2.0",
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/vite": {
-      "version": "5.4.8",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "esbuild": "^0.21.3",
-        "postcss": "^8.4.43",
-        "rollup": "^4.20.0"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^18.0.0 || >=20.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.3"
-      },
-      "peerDependencies": {
-        "@types/node": "^18.0.0 || >=20.0.0",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "sass-embedded": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "sass-embedded": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/ws": {
-      "version": "8.17.1",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10.0.0"
-      },
-      "peerDependencies": {
-        "bufferutil": "^4.0.1",
-        "utf-8-validate": ">=5.0.2"
-      },
-      "peerDependenciesMeta": {
-        "bufferutil": {
-          "optional": true
-        },
-        "utf-8-validate": {
-          "optional": true
-        }
-      }
-    }
-  }
+	"name": "demo",
+	"version": "0.0.0",
+	"lockfileVersion": 3,
+	"requires": true,
+	"packages": {
+		"": {
+			"name": "demo",
+			"version": "0.0.0",
+			"dependencies": {
+				"ethers": "^6.13.1",
+				"solc": "^0.8.28"
+			},
+			"devDependencies": {
+				"typescript": "^5.5.3",
+				"vite": "^5.4.8"
+			}
+		},
+		"node_modules/@adraffy/ens-normalize": {
+			"version": "1.10.1",
+			"license": "MIT"
+		},
+		"node_modules/@esbuild/linux-x64": {
+			"version": "0.21.5",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/@noble/curves": {
+			"version": "1.2.0",
+			"license": "MIT",
+			"dependencies": {
+				"@noble/hashes": "1.3.2"
+			},
+			"funding": {
+				"url": "https://paulmillr.com/funding/"
+			}
+		},
+		"node_modules/@noble/hashes": {
+			"version": "1.3.2",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 16"
+			},
+			"funding": {
+				"url": "https://paulmillr.com/funding/"
+			}
+		},
+		"node_modules/@rollup/rollup-linux-x64-gnu": {
+			"version": "4.24.0",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			]
+		},
+		"node_modules/@rollup/rollup-linux-x64-musl": {
+			"version": "4.24.0",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			]
+		},
+		"node_modules/@types/estree": {
+			"version": "1.0.6",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@types/node": {
+			"version": "18.15.13",
+			"license": "MIT"
+		},
+		"node_modules/aes-js": {
+			"version": "4.0.0-beta.5",
+			"license": "MIT"
+		},
+		"node_modules/command-exists": {
+			"version": "1.2.9",
+			"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz",
+			"integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==",
+			"license": "MIT"
+		},
+		"node_modules/commander": {
+			"version": "8.3.0",
+			"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+			"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 12"
+			}
+		},
+		"node_modules/esbuild": {
+			"version": "0.21.5",
+			"dev": true,
+			"hasInstallScript": true,
+			"license": "MIT",
+			"bin": {
+				"esbuild": "bin/esbuild"
+			},
+			"engines": {
+				"node": ">=12"
+			},
+			"optionalDependencies": {
+				"@esbuild/aix-ppc64": "0.21.5",
+				"@esbuild/android-arm": "0.21.5",
+				"@esbuild/android-arm64": "0.21.5",
+				"@esbuild/android-x64": "0.21.5",
+				"@esbuild/darwin-arm64": "0.21.5",
+				"@esbuild/darwin-x64": "0.21.5",
+				"@esbuild/freebsd-arm64": "0.21.5",
+				"@esbuild/freebsd-x64": "0.21.5",
+				"@esbuild/linux-arm": "0.21.5",
+				"@esbuild/linux-arm64": "0.21.5",
+				"@esbuild/linux-ia32": "0.21.5",
+				"@esbuild/linux-loong64": "0.21.5",
+				"@esbuild/linux-mips64el": "0.21.5",
+				"@esbuild/linux-ppc64": "0.21.5",
+				"@esbuild/linux-riscv64": "0.21.5",
+				"@esbuild/linux-s390x": "0.21.5",
+				"@esbuild/linux-x64": "0.21.5",
+				"@esbuild/netbsd-x64": "0.21.5",
+				"@esbuild/openbsd-x64": "0.21.5",
+				"@esbuild/sunos-x64": "0.21.5",
+				"@esbuild/win32-arm64": "0.21.5",
+				"@esbuild/win32-ia32": "0.21.5",
+				"@esbuild/win32-x64": "0.21.5"
+			}
+		},
+		"node_modules/ethers": {
+			"version": "6.13.3",
+			"funding": [
+				{
+					"type": "individual",
+					"url": "https://github.com/sponsors/ethers-io/"
+				},
+				{
+					"type": "individual",
+					"url": "https://www.buymeacoffee.com/ricmoo"
+				}
+			],
+			"license": "MIT",
+			"dependencies": {
+				"@adraffy/ens-normalize": "1.10.1",
+				"@noble/curves": "1.2.0",
+				"@noble/hashes": "1.3.2",
+				"@types/node": "18.15.13",
+				"aes-js": "4.0.0-beta.5",
+				"tslib": "2.4.0",
+				"ws": "8.17.1"
+			},
+			"engines": {
+				"node": ">=14.0.0"
+			}
+		},
+		"node_modules/follow-redirects": {
+			"version": "1.15.9",
+			"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+			"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+			"funding": [
+				{
+					"type": "individual",
+					"url": "https://github.com/sponsors/RubenVerborgh"
+				}
+			],
+			"license": "MIT",
+			"engines": {
+				"node": ">=4.0"
+			},
+			"peerDependenciesMeta": {
+				"debug": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/js-sha3": {
+			"version": "0.8.0",
+			"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+			"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
+			"license": "MIT"
+		},
+		"node_modules/memorystream": {
+			"version": "0.3.1",
+			"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+			"integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
+			"engines": {
+				"node": ">= 0.10.0"
+			}
+		},
+		"node_modules/nanoid": {
+			"version": "3.3.7",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
+			"license": "MIT",
+			"bin": {
+				"nanoid": "bin/nanoid.cjs"
+			},
+			"engines": {
+				"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+			}
+		},
+		"node_modules/os-tmpdir": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+			"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/picocolors": {
+			"version": "1.1.0",
+			"dev": true,
+			"license": "ISC"
+		},
+		"node_modules/postcss": {
+			"version": "8.4.47",
+			"dev": true,
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/postcss/"
+				},
+				{
+					"type": "tidelift",
+					"url": "https://tidelift.com/funding/github/npm/postcss"
+				},
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
+			"license": "MIT",
+			"dependencies": {
+				"nanoid": "^3.3.7",
+				"picocolors": "^1.1.0",
+				"source-map-js": "^1.2.1"
+			},
+			"engines": {
+				"node": "^10 || ^12 || >=14"
+			}
+		},
+		"node_modules/rollup": {
+			"version": "4.24.0",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@types/estree": "1.0.6"
+			},
+			"bin": {
+				"rollup": "dist/bin/rollup"
+			},
+			"engines": {
+				"node": ">=18.0.0",
+				"npm": ">=8.0.0"
+			},
+			"optionalDependencies": {
+				"@rollup/rollup-android-arm-eabi": "4.24.0",
+				"@rollup/rollup-android-arm64": "4.24.0",
+				"@rollup/rollup-darwin-arm64": "4.24.0",
+				"@rollup/rollup-darwin-x64": "4.24.0",
+				"@rollup/rollup-linux-arm-gnueabihf": "4.24.0",
+				"@rollup/rollup-linux-arm-musleabihf": "4.24.0",
+				"@rollup/rollup-linux-arm64-gnu": "4.24.0",
+				"@rollup/rollup-linux-arm64-musl": "4.24.0",
+				"@rollup/rollup-linux-powerpc64le-gnu": "4.24.0",
+				"@rollup/rollup-linux-riscv64-gnu": "4.24.0",
+				"@rollup/rollup-linux-s390x-gnu": "4.24.0",
+				"@rollup/rollup-linux-x64-gnu": "4.24.0",
+				"@rollup/rollup-linux-x64-musl": "4.24.0",
+				"@rollup/rollup-win32-arm64-msvc": "4.24.0",
+				"@rollup/rollup-win32-ia32-msvc": "4.24.0",
+				"@rollup/rollup-win32-x64-msvc": "4.24.0",
+				"fsevents": "~2.3.2"
+			}
+		},
+		"node_modules/semver": {
+			"version": "5.7.2",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+			"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+			"license": "ISC",
+			"bin": {
+				"semver": "bin/semver"
+			}
+		},
+		"node_modules/solc": {
+			"version": "0.8.28",
+			"resolved": "https://registry.npmjs.org/solc/-/solc-0.8.28.tgz",
+			"integrity": "sha512-AFCiJ+b4RosyyNhnfdVH4ZR1+TxiL91iluPjw0EJslIu4LXGM9NYqi2z5y8TqochC4tcH9QsHfwWhOIC9jPDKA==",
+			"license": "MIT",
+			"dependencies": {
+				"command-exists": "^1.2.8",
+				"commander": "^8.1.0",
+				"follow-redirects": "^1.12.1",
+				"js-sha3": "0.8.0",
+				"memorystream": "^0.3.1",
+				"semver": "^5.5.0",
+				"tmp": "0.0.33"
+			},
+			"bin": {
+				"solcjs": "solc.js"
+			},
+			"engines": {
+				"node": ">=10.0.0"
+			}
+		},
+		"node_modules/source-map-js": {
+			"version": "1.2.1",
+			"dev": true,
+			"license": "BSD-3-Clause",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/tmp": {
+			"version": "0.0.33",
+			"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+			"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+			"license": "MIT",
+			"dependencies": {
+				"os-tmpdir": "~1.0.2"
+			},
+			"engines": {
+				"node": ">=0.6.0"
+			}
+		},
+		"node_modules/tslib": {
+			"version": "2.4.0",
+			"license": "0BSD"
+		},
+		"node_modules/typescript": {
+			"version": "5.6.3",
+			"dev": true,
+			"license": "Apache-2.0",
+			"bin": {
+				"tsc": "bin/tsc",
+				"tsserver": "bin/tsserver"
+			},
+			"engines": {
+				"node": ">=14.17"
+			}
+		},
+		"node_modules/vite": {
+			"version": "5.4.8",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"esbuild": "^0.21.3",
+				"postcss": "^8.4.43",
+				"rollup": "^4.20.0"
+			},
+			"bin": {
+				"vite": "bin/vite.js"
+			},
+			"engines": {
+				"node": "^18.0.0 || >=20.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/vitejs/vite?sponsor=1"
+			},
+			"optionalDependencies": {
+				"fsevents": "~2.3.3"
+			},
+			"peerDependencies": {
+				"@types/node": "^18.0.0 || >=20.0.0",
+				"less": "*",
+				"lightningcss": "^1.21.0",
+				"sass": "*",
+				"sass-embedded": "*",
+				"stylus": "*",
+				"sugarss": "*",
+				"terser": "^5.4.0"
+			},
+			"peerDependenciesMeta": {
+				"@types/node": {
+					"optional": true
+				},
+				"less": {
+					"optional": true
+				},
+				"lightningcss": {
+					"optional": true
+				},
+				"sass": {
+					"optional": true
+				},
+				"sass-embedded": {
+					"optional": true
+				},
+				"stylus": {
+					"optional": true
+				},
+				"sugarss": {
+					"optional": true
+				},
+				"terser": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/ws": {
+			"version": "8.17.1",
+			"license": "MIT",
+			"engines": {
+				"node": ">=10.0.0"
+			},
+			"peerDependencies": {
+				"bufferutil": "^4.0.1",
+				"utf-8-validate": ">=5.0.2"
+			},
+			"peerDependenciesMeta": {
+				"bufferutil": {
+					"optional": true
+				},
+				"utf-8-validate": {
+					"optional": true
+				}
+			}
+		}
+	}
 }
diff --git a/substrate/frame/revive/rpc/examples/js/package.json b/substrate/frame/revive/rpc/examples/js/package.json
index ec05cb74f7d..3ae1f0fbd79 100644
--- a/substrate/frame/revive/rpc/examples/js/package.json
+++ b/substrate/frame/revive/rpc/examples/js/package.json
@@ -6,11 +6,14 @@
   "scripts": {
     "dev": "vite",
     "build": "tsc && vite build",
-    "preview": "vite preview"
+    "preview": "vite preview",
+	"generate-types": "typechain --target=ethers-v6 'abi/*.json'"
   },
   "dependencies": {
-    "ethers": "^6.13.1",
-    "solc": "^0.8.28"
+    "@typechain/ethers-v6": "^0.5.1",
+    "ethers": "^6.13.4",
+    "solc": "^0.8.28",
+    "typechain": "^8.3.2"
   },
   "devDependencies": {
     "typescript": "^5.5.3",
diff --git a/substrate/frame/revive/rpc/examples/js/pvm-contracts.json b/substrate/frame/revive/rpc/examples/js/pvm-contracts.json
deleted file mode 100644
index be58e88a9a6..00000000000
--- a/substrate/frame/revive/rpc/examples/js/pvm-contracts.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
-  "event": {
-    "abi": [
-      {
-        "anonymous": false,
-        "inputs": [
-          {
-            "indexed": true,
-            "internalType": "address",
-            "name": "sender",
-            "type": "address"
-          },
-          {
-            "indexed": false,
-            "internalType": "uint256",
-            "name": "value",
-            "type": "uint256"
-          },
-          {
-            "indexed": false,
-            "internalType": "string",
-            "name": "message",
-            "type": "string"
-          }
-        ],
-        "name": "ExampleEvent",
-        "type": "event"
-      },
-      {
-        "inputs": [],
-        "name": "triggerEvent",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-      }
-    ],
-    "bytecode": "50564d00014214000000000000010700c13004c00040045f0600000000060000001300000018000000230000003500000063616c6c65726465706f7369745f6576656e74696e7075747365616c5f72657475726e7365745f696d6d757461626c655f6461746176616c75655f7472616e73666572726564051102912c0463616c6c9133066465706c6f790693b42602913cc8000c0111013001cb010a0327034303570374030c05270530054b055605d505e905f7050b062f06a7075d09e109460a9c0b400c730cdf0c710e800ef70ed20f2610bb10e710131133113b1152790e7a1004070f0a41040a0000012f8a3908890802871f1277e03b370000010a040713000a08000002297814160700000252780407100002088707130004071000020887071300130018875e08970a14a80b099c0128cc29bc1d29873107094a5279110b8b028801029c01109b52c91eacf405350709335279110b8b028801029c01109b52c91eacf4051e07091c027aff0288ff1108980b0bbb029cff089a09109b52c90f0cf113000211e003101c0315180316140215201211e0127601040704080610023dff16070800020d010004040710000352184e0211011726032c040326032804032603240403260320040326031c0403260318040326031404031607100403070607061004090610064b020211c003103c0315380316340215401211e05216040740040820061008d5fe070716020408080002260364000200000080260360000226035c000226035800022603540002260350000226034c000203681826034800020217e01277e003671c52710d171c0d17180d17140d17100d170c0d17080d17040d074e051101681c0182100183018914018a1c018b0c018c040187180188080cba0a0cc9090ca9090c87070c23080c87070c97070f077e0104074004082006100a3afe07077b01016718017450017040017b58017c48017a5401724c0173440e2808128800ff000e29180c9808122900ff000999080922180c92090c980803681c0e3808128800ff000e39180c9808123900ff000999080933180c93090c89030ea808128800ff000ea9180c980812a900ff0009990809aa180ca9090c89020ec808128800ff000ec9180c980812c900ff0009990809cc180cc9090c890c0eb808128800ff000eb9180c980812b900ff0009990809bb180cb9090c98080e0908129900ff000e0b180cb909120b00ff0009bb080900180cb00b0cb9090e4b0812bb00ff000e4a180cba0a124b00ff0009bb080944180cb40b0cba0a0ca9090cc8080c98080c3209016a1c0ca9090c98080f086e01681801885c0e8908129900ff000e8a180ca909128700ff000977080988180c87070c970703671c040806100cfbfc07073c0a080c000207080b04073004034e041101671c040806100edefc07071f01681801671c087808040704094e031104070408061010c2fc0f070400040808000204070104090400124e03110211a003105c0315580316540215601211e004074004082006101491fc0f07040004061004030a0710040303171c0a041404030a031804030a092c04030a082804030a002004030a0c2404032797278a54970a27cb270754cb070c980b54ba070316180a0b1c04032742011a1c1baa041faa0154420a27b2273654b2060cb30b54b60a0cc9090c80080c980854870a0409080002260364000200000080260360000226035c000226035800022603540002260350000226034c00022603480002070a0b010a071000030f47ede48fb7020103191c0d113c0d11380d11340d11300d112c0d11280d11240d11200217204e0511011230011820011934011a3c011b2c011c240116380117280cba0a0cc9090ca9090c67070c28080c87070c97070f07b10001171801721c017318017414017a100178017c0c017604017708028bfc248b0808860b02bbff1c6b09246b0b53980b0278ff08b8092479002489081b7601146c060868081cc80624c8085360081c97070c6707537b0802a7ff0878082478071ba8011484080878092489085377080c4a071b77011473090898082498082473071472070887072d074604070408061016f9fa07076bfe040808000204070104094e0304001805ca00061018c7000407040806101ad5fa070747fe040808000204070104094e0304001c05c80006101cc50004074004082006101eaffa070721fe011b1c01b24c01b34401ba5401b94801bc4001b65001b8580c6c0c0c98080cc8080c3a090c29090c98080e8908129900ff000e8a180ca909098a18128800ff000988080ca8080c98080f08d4fd01b85c0e8908129900ff000e8a180ca909128700ff000977080988180c87070c9707031718040852b606102030fa0707a2fd011818086808040704090400224e03110211fc0310040704080610240efa0f070400040808000204070104090400264e0311021140ff0310bc000315b8000316b4000215c0001211e05216040740040820061028d6f90707e70a04040800020a036400020a084800020a0a6000020a025000020a0c4c00020e8b0812b900ff000e8b180cb909128b00ff0009bb080988180cb8080c98080368780ec808128800ff000ec9180c980812c900ff0009990809cc180cc9090c89000ea808128800ff000ea9180c980812a900ff0009990809aa180ca9090c890a0e3808128800ff000e39180c9808123900ff000999080933180c93090c890902a801036a6c1baaff0369741b99c0548a090e2808128800ff000e2a180ca808122a00ff0009aa080a0b5400020922180ca20a0c8a020eb808128800ff000eba180ca80812ba00ff0009aa080a0c58000209bb180cba0a0c8a030ec808128800ff000eca180ca80812ca00ff0009aa0803647c0a0b5c000209cc180cca0a0c8a0c0eb808128800ff000eba180ca80812b700ff0009770809bb180cb7070c870a0362680167780c72070360700363640c03080c8707036c60036a5c0cca08036854568903675856790709190904074004082006102a5ef807076f0901677402784003685024780701686c08780903694824890b53770b01675c08b70024700701686008780224820c53770c53bb0c016764087c0c247c0b01676808b70424740853bb0801677008870a247a080163780883030e3708127700ff000e38180c7808123700ff000977080933180c73070c870703674c0ea708127700ff000ea9180c970712a900ff0009990809aa180ca9090c97070367440e4708127700ff000e49180c9707124900ff000999080944180c94090c79040ec708127700ff000ec9180c970712c900ff0009990809cc180cc9090c79030e2708127700ff000e29180c9707122900ff000999080922180c92090c79020e0908129900ff000e0a180ca909120a00ff0009aa080900180ca00a0ca9090167480e7a0812aa00ff000e78180ca808127a00ff0009aa08097c180cca0a0ca8080167500e7a0812aa00ff000e7c180cca0a127b00ff0009bb08097c180ccb0b0cba0a016b7c03ba5c03b85803b95403b25003b34c03b44801674403b74401676c0168680c87070168600169780c98080c870701685c0169700c98080169640c98080c870701684c03b8400f07c80704082001677406102ca8f60707b9070162741b27e01f770101696c279854980701685c2788016a6027a953a8090168545387090167642777016a6827a853a708016c7027c7016b7827ba53b70a0cbc0753780a01675853790a01677c0827080d181c0000000b0d18180d18140d18100d180c0d18080d18040368440d080f0a470702272004082003676006102e24f60707350701687c0167600878080d181c0d18180d18140d18100d180c0d1808726c640d18046f20776f0368340d0848656c6c026780004e0167900003671401678c000367180167880003671c0167840003672001678000036724040740040820061030bff50707d00601677c017250017340017458017048017c54017b4c0179440eb808128800ff000eba180ca80812ba00ff0009aa0809bb180cba0a0ca8080368700e9808128800ff000e9a180ca808129a00ff0009aa080999180ca9090c98080368680ec808128800ff000ec9180c980812c900ff0009990809cc180cc9090c890b0e0808128800ff000e09180c9808120900ff000999080900180c90090c89000e4808128800ff000e49180c9808124900ff000999080944180c94090c890c0e3808128800ff000e39180c9808123900ff000999080933180c93090c890a0e2808128800ff000e29180c9808122900ff000999080922180c92090c9808036a5c0368540ca808036058036c6c0c0c090c9808036b640169680cb909016a700ca9090c98080f08ae0501687c01885c0e8908129900ff000e8a180ca909128700ff000977080988180c87070c970704082003677806103269f407077a05016a7c016778087a0a527b0d1a1c000030390d1a180d1a140d1a100d1a0c0d1a080d1a0401686c27891bb7e01f7c0103694854890c01676427780160542704530804016770277801635827325338020169682798016b5c27b753b8070cb9085382070168700c98080cb3090c98080169640c090903694c03644054940c03685003673c54870c036a100d0a0168780f0ce804028720040820036738061034c5f30707d60401677c0168380887070d171c000000400d17180d17140d17100d170c0d17080d17040d0704082001677406103692f30707a3040169781b97c01f770101686c016a48548a0701684c016a40548a07016850016a3c548a070f077b0401674401781c03684801781803687401781403684001781003683c01780c03683801780803683001780403682c017703674402974004082003672806103826f3070737040167781b77a001686c568701684c5687016850568701687c016928089808016c2c038c04016a44038a016b30038b0801643803840c01623c03821001604003801401697403891801694803891c0707e6030ea808128800ff000ea9180c980812a900ff0009990809aa180ca9090c98080368500ec808128800ff000ec9180c980812c900ff0009990809ca180ca9090c890c0eb808128800ff000eb9180c980812b900ff0009990809ba180ca9090c89030e4808128800ff000e49180c9808124900ff00099908094a180ca9090c89040e2808128800ff000e29180c9808122900ff00099908092a180ca9090c89020e0808128800ff000e09180c9808120900ff00099908090a180ca9090c8900016a740ea808128800ff000ea9180c980812a900ff0009990809aa180ca9090c980803684403633c0c38080362300169500c92090c9808036c4003602c0cc0090364380c49090c98080f08dc02016a480ea808128800ff000ea9180c980812a700ff0009770809a9180c97070c780801677802776003674c03687406103a94f10707a50201676001687406103c85f10707960201677801684c247807528b01686c08780903690c24890853770801676408870903692824790701695408790a036a48249a0953770953880901677008790903696024790701685808780903696424890853770801676808780803686c24780703676801677c08b70701683401697406103e58f101684c016974089808016a4401670c08a7070368702498080887021ca20924a20a53980a01682c016928088909016730016c48087c0c24890b08cb0b08a904249409089b031c730c24730b24840753c70b1c84070cc707537a0b01683801676008870724870a01683c016c64088c0c08ac0c1c8c09248c08539a08087b0b247b07087c0024c00953770901675c016a5008a707016a6808a707016a40016c6c08ac0c24ac0a08a70708c80824c80a08a7070889092489080887070cb4080c98080c73070c02090c98080c87070f07530104082001677006104033f00707440101687c0167700878080d181c0d18180d18140d18100d180c0d18080d180401697402971f249709016a4408a909129901127be01bbaa01faa0154990a0d080167780f0aff0002b86003687c061042dfef0707f0000217c01277e052710d171c8c16c7d00d1718622fa9a50d1714af827c120d17104a032b310d170cec4214070d1708f0370dae0d170487296ff20d071585375401681403783c01681803783801681c03783401682003783001682403782c0d17280d17240d1720040802016910016a7c4e01025140ff0110bc000115b8000116b4000211c000130004082004070610444aef07075b01687c0d181c0d18180d18140d18100d180c0d18080d18040d084e487b710407040408200610461eef07072f01687c0d1820000000410d181c0d18180d18140d18100d180c0d18080d18040408240407061048f2ee0f07040004080800020407010409244e03040704004a0581ef040706104a7cef04070106104c74ef00a58424092a241452482549495a52292da994644a2a2549920a21422d8410420821119224290911028410420809494a92243529499224491249882449928424244912929024094948928424244942129224210949929084244992244912929024292424348524a956c890d2244992902124841042a854928492a492244908104208218408014992244993244992244924494a9224499224499224499224499224a9102195840a115249484224499224499290242489242421495221924a53850c298d8888948408218410129290244948429224242149129290244992242421214942121292242421094912929024499224494a91844892244992244992244992242421499290842449421292242109499290842449484292242109499284242449922449922449922449242192a4a49424a5a4942449024992a448122249922408248891482412494224499224242149929084244942129224210949929084244948429224242149922449922491242421499210490a2449929224a5a494949224499224494a2409912490244949882449922489244992244952928448524a4992942449922491908424494212922421094992908424494842922424214992908424499224499244129290244912220991a424499224499224499224499284244992244992244992244992244992244992244992244992248924449224499224499294484224050281402010089224499224498a8888524892244990842490244952c8905452480800"
-  },
-  "revert": {
-    "abi": [
-      {
-        "inputs": [],
-        "stateMutability": "nonpayable",
-        "type": "constructor"
-      },
-      {
-        "inputs": [],
-        "name": "doRevert",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-      }
-    ],
-    "bytecode": "50564d0001ba09000000000000010700c13004c0004004440400000000050000001000000022000000696e7075747365616c5f72657475726e7365745f696d6d757461626c655f6461746176616c75655f7472616e7366657272656405110288020463616c6c8809066465706c6f79068947170288126700aa00af00ce006901a802c502e102f5021303ab04c604cf04eb043d06d50632078f07c907dc07ea070908110852790e7a1004070f0a41040a0000012f8a3908890802871f1277e03b370000010a040713000a0800000229781416070000025278040710000208870713000407100002088707130013000211e003101c0315180316140215201211e0127601040704080610029d16070400020d010004040710000352184e11011726032c040326032804032603240403260320040326031c0403260318040326031404031607100403070607061004090610064b020211c003103c0315380316340215401211e0521604074004082006100837ff07071602040804000226036000020000008026035c000226035800022603540002260350000226034c0002260348000203681826034400020217e01277e003671c52710d171c0d17180d17140d17100d170c0d17080d17040d074e031101681c0182100183018914018a1c018b0c018c040187180188080cba0a0cc9090ca9090c87070c23080c87070c97070f077e0104074004082006100a9cfe07077b01016718017450017040017b58017c48017a5401724c0173440e2808128800ff000e29180c9808122900ff000999080922180c92090c980803681c0e3808128800ff000e39180c9808123900ff000999080933180c93090c89030ea808128800ff000ea9180c980812a900ff0009990809aa180ca9090c89020ec808128800ff000ec9180c980812c900ff0009990809cc180cc9090c890c0eb808128800ff000eb9180c980812b900ff0009990809bb180cb9090c98080e0908129900ff000e0b180cb909120b00ff0009bb080900180cb00b0cb9090e4b0812bb00ff000e4a180cba0a124b00ff0009bb080944180cb40b0cba0a0ca9090cc8080c98080c3209016a1c0ca9090c98080f086e01681801885c0e8908129900ff000e8a180ca909128700ff000977080988180c87070c970703671c040806100c5dfd07073c0a0808000207080b04073004034e021101671c040806100e40fd07071f01681801671c087808040704094e01110407040806101024fd0f070400040804000204070104090400124e011102118003107c031578031674021580001211e0040740040820061014f2fc0f07040004061004030a0710040303173c0a041404030a031804030a092c04030a082804030a002004030a0c2404032797278a54970a27cb270754cb070c980b54ba070316380a0b1c04032742011a3c1baa041faa0154420a27b2273654b2060cb30b54b60a0cc9090c80080c980854870a040904000226036000020000008026035c000226035800022603540002260350000226034c000226034800022603440002070a0b010a071000030f47afc874d2020103193c0d115c0d11580d11540d11500d114c0d11480d11440d11400217404e0311011250011840011954011a5c011b4c011c440116580117480cba0a0cc9090ca9090c67070c28080c87070c97070f07b10001173801721c017318017414017a100178017c0c017604017708028bfc248b0808860b02bbff1c6b09246b0b53980b0278ff08b8092479002489081b7601146c060868081cc80624c8085360081c97070c6707537b0802a7ff0878082478071ba8011484080878092489085377080c4a071b77011473090898082498082473071472070887072d0741040704080610165afb07076bfe040804000204070104094e01040018051e030610181b030407040806101a36fb070747fe040804000204070104094e011104074004082006101c1afb07072bfe01103c010250010340010458010b48010c54010a4c0108440ea608126600ff000ea9180c690912a600ff0009660809aa180c6a0a0ca9090319380e8908129900ff000e8a180ca909128a00ff0009aa080988180ca8080c98080318340ec808128800ff000ec9180c980812c900ff0009990809cc180cc9090c890c0eb808128800ff000eb9180c980812b900ff0009990809bb180cb9090c890a0e4808128800ff000e49180c9808124900ff000999080944180c94090c89040e3808128800ff000e39180c9808123900ff000999080933180c93090c89030e2808128800ff000e29180c9808122900ff000999080922180c92060c860b0c3b080ca4090c98080119340cc9090116380c69090c98080f0818fd52b6031320031a24031c2803142c01085c0e8908129900ff000e8a180ca909128700ff000977080988180c87070c970704082003173006101ec8f90707d9fc011230011a3c082a0a0d0a08c379a00113382737011424274b53470b011c3427c701182027895387090c8c07537b09011b2827b727605367000cb6060cc3070d1a1c0d1a180d1a140d1a100d1a0c0d1a080c8408011b2c27bc0c78081b27fc1f770154bc070316385460075489070d1a040f0764fc031c20031824031028031934031a1c011730027704040820527606102030f9070741fc01173c0867070d171c000000200d17180d17140d17100d170c0d17080d17040118301b88dc1f880101192c011a20549a08011928011a3854a908011934011a2454a9080d070f08f8fb0117300276240408205267061022d3f80707e4fb01173c0867070d171c0000000e0d17180d17140d17100d170c0d17080d17040118301b88bc1f880101192c011a20549a08011928011a3854a908011934011a2454a9080d070f089bfb011730027644040820526706102476f8070787fb01173c0867070d171c0d17180d17140d17100d170c67650d1708657373610d17047274206d0d07726576650408640117300610263cf807074dfb04070104096401181c0400284e01110211fc03100407040806102a1bf80f070400040804000204070104094e01040704002c054bf8040706102c46f804070106102e3ef800a58424092a241452482549928a10a10b21841042488424494a4284002184104242929224494d4a9224499244122249922421094992842424494212922421094992908424494842922424214992244992842424490a09094d2149aa1532a434492249c81012420821542a494249524992240408218410428480244992a449922449922492242549922449922449922449922449925488904a428508a9498824499284242449129290244948429224242149129290240949489284242449922449942449484292242192042925a524a924499224254992449224492192409224499224495224294412489224499224498a24854892240402411222499a2a64489514120200"
-  }
-}
\ No newline at end of file
diff --git a/substrate/frame/revive/rpc/examples/js/pvm/event.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/event.polkavm
new file mode 100644
index 0000000000000000000000000000000000000000..859c1cdf5d3e97c7df8cbad6a0dc0cbd5f8d6388
GIT binary patch
literal 5186
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
PI4Am)*gBU=#F+HI@tB`4

literal 0
HcmV?d00001

diff --git a/substrate/frame/revive/rpc/examples/js/pvm/piggyBank.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/piggyBank.polkavm
new file mode 100644
index 0000000000000000000000000000000000000000..1a45c15d53f68431b7e5c1dff297c768e1160e97
GIT binary patch
literal 12334
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
JpgkTJ{s(-6RoDOk

literal 0
HcmV?d00001

diff --git a/substrate/frame/revive/rpc/examples/js/pvm/revert.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/revert.polkavm
new file mode 100644
index 0000000000000000000000000000000000000000..7505c402f21b7f8a16914f1f067f94eebb9b3c96
GIT binary patch
literal 2490
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

literal 0
HcmV?d00001

diff --git a/substrate/frame/revive/rpc/examples/js/src/build-contracts.ts b/substrate/frame/revive/rpc/examples/js/src/build-contracts.ts
index 3e9d036d1b7..c6b7700d1cc 100644
--- a/substrate/frame/revive/rpc/examples/js/src/build-contracts.ts
+++ b/substrate/frame/revive/rpc/examples/js/src/build-contracts.ts
@@ -25,11 +25,10 @@ function evmCompile(sources: CompileInput) {
 
 console.log('Compiling contracts...')
 
-let pvmContracts: Map<string, { abi: Abi; bytecode: string }> = new Map()
-let evmContracts: Map<string, { abi: Abi; bytecode: string }> = new Map()
 const input = [
 	{ file: 'Event.sol', contract: 'EventExample', keypath: 'event' },
 	{ file: 'Revert.sol', contract: 'RevertExample', keypath: 'revert' },
+	{ file: 'PiggyBank.sol', contract: 'PiggyBank', keypath: 'piggyBank' },
 ]
 
 for (const { keypath, contract, file } of input) {
@@ -41,16 +40,17 @@ for (const { keypath, contract, file } of input) {
 		console.log(`Compile with solc ${file}`)
 		const out = JSON.parse(evmCompile(input))
 		const entry = out.contracts[file][contract]
-		evmContracts.set(keypath, { abi: entry.abi, bytecode: entry.evm.bytecode.object })
+		writeFileSync(join('evm', `${keypath}.bin`), Buffer.from(entry.evm.bytecode.object, 'hex'))
+		writeFileSync(join('abi', `${keypath}.json`), JSON.stringify(entry.abi, null, 2))
 	}
 
 	{
 		console.log(`Compile with revive ${file}`)
 		const out = await compile(input)
 		const entry = out.contracts[file][contract]
-		pvmContracts.set(keypath, { abi: entry.abi, bytecode: entry.evm.bytecode.object })
+		writeFileSync(
+			join('pvm', `${keypath}.polkavm`),
+			Buffer.from(entry.evm.bytecode.object, 'hex')
+		)
 	}
 }
-
-writeFileSync('pvm-contracts.json', JSON.stringify(Object.fromEntries(pvmContracts), null, 2))
-writeFileSync('evm-contracts.json', JSON.stringify(Object.fromEntries(evmContracts), null, 2))
diff --git a/substrate/frame/revive/rpc/examples/js/src/event.ts b/substrate/frame/revive/rpc/examples/js/src/event.ts
index 95e630a4346..94cc2560272 100644
--- a/substrate/frame/revive/rpc/examples/js/src/event.ts
+++ b/substrate/frame/revive/rpc/examples/js/src/event.ts
@@ -3,8 +3,8 @@ import { call, getContract, deploy } from './lib.ts'
 
 try {
 	const { abi, bytecode } = getContract('event')
-	const address = await deploy(bytecode, abi)
-	const receipt = await call('triggerEvent', address, abi)
+	const contract = await deploy(bytecode, abi)
+	const receipt = await call('triggerEvent', await contract.getAddress(), abi)
 	if (receipt) {
 		for (const log of receipt.logs) {
 			console.log('Event log:', JSON.stringify(log, null, 2))
diff --git a/substrate/frame/revive/rpc/examples/js/src/lib.ts b/substrate/frame/revive/rpc/examples/js/src/lib.ts
index 40f2d6f0582..975d8faf15b 100644
--- a/substrate/frame/revive/rpc/examples/js/src/lib.ts
+++ b/substrate/frame/revive/rpc/examples/js/src/lib.ts
@@ -10,6 +10,7 @@ import { readFileSync } from 'node:fs'
 import type { compile } from '@parity/revive'
 import { spawn } from 'node:child_process'
 import { parseArgs } from 'node:util'
+import { BaseContract } from 'ethers'
 
 type CompileOutput = Awaited<ReturnType<typeof compile>>
 type Abi = CompileOutput['contracts'][string][string]['abi']
@@ -41,7 +42,7 @@ if (geth) {
 			'--http.api',
 			'web3,eth,debug,personal,net',
 			'--http.port',
-			'8545',
+			'8546',
 			'--dev',
 			'--verbosity',
 			'0',
@@ -55,10 +56,14 @@ if (geth) {
 }
 
 export const provider = new JsonRpcProvider(
-	westend ? 'https://westend-asset-hub-eth-rpc.polkadot.io' : 'http://localhost:8545'
+	westend
+		? 'https://westend-asset-hub-eth-rpc.polkadot.io'
+		: geth
+			? 'http://localhost:8546'
+			: 'http://localhost:8545'
 )
 
-const signer = privateKey ? new Wallet(privateKey, provider) : await provider.getSigner()
+export const signer = privateKey ? new Wallet(privateKey, provider) : await provider.getSigner()
 console.log(`Signer address: ${await signer.getAddress()}, Nonce: ${await signer.getNonce()}`)
 
 /**
@@ -66,18 +71,16 @@ console.log(`Signer address: ${await signer.getAddress()}, Nonce: ${await signer
  * @param name - the contract name
  */
 export function getContract(name: string): { abi: Abi; bytecode: string } {
-	const file = geth
-		? readFileSync('evm-contracts.json', 'utf8')
-		: readFileSync('pvm-contracts.json', 'utf8')
-	const contracts = JSON.parse(file) as Record<string, { abi: Abi; bytecode: string }>
-	return contracts[name]
+	const bytecode = geth ? readFileSync(`evm/${name}.bin`) : readFileSync(`pvm/${name}.polkavm`)
+	const abi = JSON.parse(readFileSync(`abi/${name}.json`, 'utf8')) as Abi
+	return { abi, bytecode: Buffer.from(bytecode).toString('hex') }
 }
 
 /**
  * Deploy a contract
  * @returns the contract address
  **/
-export async function deploy(bytecode: string, abi: Abi, args: any[] = []): Promise<string> {
+export async function deploy(bytecode: string, abi: Abi, args: any[] = []): Promise<BaseContract> {
 	console.log('Deploying contract with', args)
 	const contractFactory = new ContractFactory(abi, bytecode, signer)
 
@@ -85,7 +88,8 @@ export async function deploy(bytecode: string, abi: Abi, args: any[] = []): Prom
 	await contract.waitForDeployment()
 	const address = await contract.getAddress()
 	console.log(`Contract deployed: ${address}`)
-	return address
+
+	return contract
 }
 
 /**
diff --git a/substrate/frame/revive/rpc/examples/js/src/piggy-bank.ts b/substrate/frame/revive/rpc/examples/js/src/piggy-bank.ts
new file mode 100644
index 00000000000..7a8edbde366
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/src/piggy-bank.ts
@@ -0,0 +1,24 @@
+import { provider, call, getContract, deploy } from './lib.ts'
+import { parseEther } from 'ethers'
+import { PiggyBank } from '../types/ethers-contracts/PiggyBank'
+
+try {
+	const { abi, bytecode } = getContract('piggyBank')
+	const contract = (await deploy(bytecode, abi)) as PiggyBank
+	const address = await contract.getAddress()
+
+	let receipt = await call('deposit', address, abi, [], {
+		value: parseEther('10.0'),
+	})
+	console.log('Deposit receipt:', receipt?.status)
+	console.log(`Contract balance: ${await provider.getBalance(address)}`)
+
+	console.log('deposit: ', await contract.getDeposit())
+
+	receipt = await call('withdraw', address, abi, [parseEther('5.0')])
+	console.log('Withdraw receipt:', receipt?.status)
+	console.log(`Contract balance: ${await provider.getBalance(address)}`)
+	console.log('deposit: ', await contract.getDeposit())
+} catch (err) {
+	console.error(err)
+}
diff --git a/substrate/frame/revive/rpc/examples/js/src/revert.ts b/substrate/frame/revive/rpc/examples/js/src/revert.ts
index 5fb3ccde6fa..ea1bf4eceeb 100644
--- a/substrate/frame/revive/rpc/examples/js/src/revert.ts
+++ b/substrate/frame/revive/rpc/examples/js/src/revert.ts
@@ -3,8 +3,8 @@ import { call, getContract, deploy } from './lib.ts'
 
 try {
 	const { abi, bytecode } = getContract('revert')
-	const address = await deploy(bytecode, abi)
-	await call('doRevert', address, abi)
+	const contract = await deploy(bytecode, abi)
+	await call('doRevert', await contract.getAddress(), abi)
 } catch (err) {
 	console.error(err)
 }
diff --git a/substrate/frame/revive/rpc/examples/js/src/transfer.ts b/substrate/frame/revive/rpc/examples/js/src/transfer.ts
new file mode 100644
index 00000000000..ae2dd50f2af
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/src/transfer.ts
@@ -0,0 +1,17 @@
+import { parseEther } from 'ethers'
+import { provider, signer } from './lib.ts'
+
+const recipient = '0x75E480dB528101a381Ce68544611C169Ad7EB342'
+try {
+	console.log(`Signer balance:    ${await provider.getBalance(signer.address)}`)
+	console.log(`Recipient balance: ${await provider.getBalance(recipient)}`)
+	await signer.sendTransaction({
+		to: recipient,
+		value: parseEther('1.0'),
+	})
+	console.log(`Sent:              ${parseEther('1.0')}`)
+	console.log(`Signer balance:    ${await provider.getBalance(signer.address)}`)
+	console.log(`Recipient balance: ${await provider.getBalance(recipient)}`)
+} catch (err) {
+	console.error(err)
+}
diff --git a/substrate/frame/revive/rpc/examples/js/tsconfig.json b/substrate/frame/revive/rpc/examples/js/tsconfig.json
index 0511b9f0e04..55cb8379e88 100644
--- a/substrate/frame/revive/rpc/examples/js/tsconfig.json
+++ b/substrate/frame/revive/rpc/examples/js/tsconfig.json
@@ -1,23 +1,23 @@
 {
-  "compilerOptions": {
-    "target": "ES2020",
-    "useDefineForClassFields": true,
-    "module": "ESNext",
-    "lib": ["ES2020", "DOM", "DOM.Iterable"],
-    "skipLibCheck": true,
+	"compilerOptions": {
+		"target": "ES2020",
+		"useDefineForClassFields": true,
+		"module": "ESNext",
+		"lib": ["ES2020", "DOM", "DOM.Iterable"],
+		"skipLibCheck": true,
 
-    /* Bundler mode */
-    "moduleResolution": "bundler",
-    "allowImportingTsExtensions": true,
-    "isolatedModules": true,
-    "moduleDetection": "force",
-    "noEmit": true,
+		/* Bundler mode */
+		"moduleResolution": "bundler",
+		"allowImportingTsExtensions": true,
+		"isolatedModules": true,
+		"moduleDetection": "force",
+		"noEmit": true,
 
-    /* Linting */
-    "strict": true,
-    "noUnusedLocals": true,
-    "noUnusedParameters": true,
-    "noFallthroughCasesInSwitch": true
-  },
-  "include": ["src"]
+		/* Linting */
+		"strict": true,
+		"noUnusedLocals": true,
+		"noUnusedParameters": true,
+		"noFallthroughCasesInSwitch": true
+	},
+	"include": ["src"]
 }
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/Event.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/Event.ts
new file mode 100644
index 00000000000..d65f953969f
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/Event.ts
@@ -0,0 +1,117 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+import type {
+	BaseContract,
+	BigNumberish,
+	BytesLike,
+	FunctionFragment,
+	Result,
+	Interface,
+	EventFragment,
+	AddressLike,
+	ContractRunner,
+	ContractMethod,
+	Listener,
+} from 'ethers'
+import type {
+	TypedContractEvent,
+	TypedDeferredTopicFilter,
+	TypedEventLog,
+	TypedLogDescription,
+	TypedListener,
+	TypedContractMethod,
+} from './common'
+
+export interface EventInterface extends Interface {
+	getFunction(nameOrSignature: 'triggerEvent'): FunctionFragment
+
+	getEvent(nameOrSignatureOrTopic: 'ExampleEvent'): EventFragment
+
+	encodeFunctionData(functionFragment: 'triggerEvent', values?: undefined): string
+
+	decodeFunctionResult(functionFragment: 'triggerEvent', data: BytesLike): Result
+}
+
+export namespace ExampleEventEvent {
+	export type InputTuple = [sender: AddressLike, value: BigNumberish, message: string]
+	export type OutputTuple = [sender: string, value: bigint, message: string]
+	export interface OutputObject {
+		sender: string
+		value: bigint
+		message: string
+	}
+	export type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>
+	export type Filter = TypedDeferredTopicFilter<Event>
+	export type Log = TypedEventLog<Event>
+	export type LogDescription = TypedLogDescription<Event>
+}
+
+export interface Event extends BaseContract {
+	connect(runner?: ContractRunner | null): Event
+	waitForDeployment(): Promise<this>
+
+	interface: EventInterface
+
+	queryFilter<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		fromBlockOrBlockhash?: string | number | undefined,
+		toBlock?: string | number | undefined
+	): Promise<Array<TypedEventLog<TCEvent>>>
+	queryFilter<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		fromBlockOrBlockhash?: string | number | undefined,
+		toBlock?: string | number | undefined
+	): Promise<Array<TypedEventLog<TCEvent>>>
+
+	on<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+	on<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+
+	once<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+	once<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+
+	listeners<TCEvent extends TypedContractEvent>(
+		event: TCEvent
+	): Promise<Array<TypedListener<TCEvent>>>
+	listeners(eventName?: string): Promise<Array<Listener>>
+	removeAllListeners<TCEvent extends TypedContractEvent>(event?: TCEvent): Promise<this>
+
+	triggerEvent: TypedContractMethod<[], [void], 'nonpayable'>
+
+	getFunction<T extends ContractMethod = ContractMethod>(key: string | FunctionFragment): T
+
+	getFunction(nameOrSignature: 'triggerEvent'): TypedContractMethod<[], [void], 'nonpayable'>
+
+	getEvent(
+		key: 'ExampleEvent'
+	): TypedContractEvent<
+		ExampleEventEvent.InputTuple,
+		ExampleEventEvent.OutputTuple,
+		ExampleEventEvent.OutputObject
+	>
+
+	filters: {
+		'ExampleEvent(address,uint256,string)': TypedContractEvent<
+			ExampleEventEvent.InputTuple,
+			ExampleEventEvent.OutputTuple,
+			ExampleEventEvent.OutputObject
+		>
+		ExampleEvent: TypedContractEvent<
+			ExampleEventEvent.InputTuple,
+			ExampleEventEvent.OutputTuple,
+			ExampleEventEvent.OutputObject
+		>
+	}
+}
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/PiggyBank.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/PiggyBank.ts
new file mode 100644
index 00000000000..ca137fcc8b3
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/PiggyBank.ts
@@ -0,0 +1,96 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+import type {
+	BaseContract,
+	BigNumberish,
+	BytesLike,
+	FunctionFragment,
+	Result,
+	Interface,
+	ContractRunner,
+	ContractMethod,
+	Listener,
+} from 'ethers'
+import type {
+	TypedContractEvent,
+	TypedDeferredTopicFilter,
+	TypedEventLog,
+	TypedListener,
+	TypedContractMethod,
+} from './common'
+
+export interface PiggyBankInterface extends Interface {
+	getFunction(nameOrSignature: 'deposit' | 'getDeposit' | 'owner' | 'withdraw'): FunctionFragment
+
+	encodeFunctionData(functionFragment: 'deposit', values?: undefined): string
+	encodeFunctionData(functionFragment: 'getDeposit', values?: undefined): string
+	encodeFunctionData(functionFragment: 'owner', values?: undefined): string
+	encodeFunctionData(functionFragment: 'withdraw', values: [BigNumberish]): string
+
+	decodeFunctionResult(functionFragment: 'deposit', data: BytesLike): Result
+	decodeFunctionResult(functionFragment: 'getDeposit', data: BytesLike): Result
+	decodeFunctionResult(functionFragment: 'owner', data: BytesLike): Result
+	decodeFunctionResult(functionFragment: 'withdraw', data: BytesLike): Result
+}
+
+export interface PiggyBank extends BaseContract {
+	connect(runner?: ContractRunner | null): PiggyBank
+	waitForDeployment(): Promise<this>
+
+	interface: PiggyBankInterface
+
+	queryFilter<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		fromBlockOrBlockhash?: string | number | undefined,
+		toBlock?: string | number | undefined
+	): Promise<Array<TypedEventLog<TCEvent>>>
+	queryFilter<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		fromBlockOrBlockhash?: string | number | undefined,
+		toBlock?: string | number | undefined
+	): Promise<Array<TypedEventLog<TCEvent>>>
+
+	on<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+	on<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+
+	once<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+	once<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+
+	listeners<TCEvent extends TypedContractEvent>(
+		event: TCEvent
+	): Promise<Array<TypedListener<TCEvent>>>
+	listeners(eventName?: string): Promise<Array<Listener>>
+	removeAllListeners<TCEvent extends TypedContractEvent>(event?: TCEvent): Promise<this>
+
+	deposit: TypedContractMethod<[], [bigint], 'payable'>
+
+	getDeposit: TypedContractMethod<[], [bigint], 'view'>
+
+	owner: TypedContractMethod<[], [string], 'view'>
+
+	withdraw: TypedContractMethod<[withdrawAmount: BigNumberish], [bigint], 'nonpayable'>
+
+	getFunction<T extends ContractMethod = ContractMethod>(key: string | FunctionFragment): T
+
+	getFunction(nameOrSignature: 'deposit'): TypedContractMethod<[], [bigint], 'payable'>
+	getFunction(nameOrSignature: 'getDeposit'): TypedContractMethod<[], [bigint], 'view'>
+	getFunction(nameOrSignature: 'owner'): TypedContractMethod<[], [string], 'view'>
+	getFunction(
+		nameOrSignature: 'withdraw'
+	): TypedContractMethod<[withdrawAmount: BigNumberish], [bigint], 'nonpayable'>
+
+	filters: {}
+}
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/Revert.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/Revert.ts
new file mode 100644
index 00000000000..ad6e23b38a6
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/Revert.ts
@@ -0,0 +1,78 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+import type {
+	BaseContract,
+	BytesLike,
+	FunctionFragment,
+	Result,
+	Interface,
+	ContractRunner,
+	ContractMethod,
+	Listener,
+} from 'ethers'
+import type {
+	TypedContractEvent,
+	TypedDeferredTopicFilter,
+	TypedEventLog,
+	TypedListener,
+	TypedContractMethod,
+} from './common'
+
+export interface RevertInterface extends Interface {
+	getFunction(nameOrSignature: 'doRevert'): FunctionFragment
+
+	encodeFunctionData(functionFragment: 'doRevert', values?: undefined): string
+
+	decodeFunctionResult(functionFragment: 'doRevert', data: BytesLike): Result
+}
+
+export interface Revert extends BaseContract {
+	connect(runner?: ContractRunner | null): Revert
+	waitForDeployment(): Promise<this>
+
+	interface: RevertInterface
+
+	queryFilter<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		fromBlockOrBlockhash?: string | number | undefined,
+		toBlock?: string | number | undefined
+	): Promise<Array<TypedEventLog<TCEvent>>>
+	queryFilter<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		fromBlockOrBlockhash?: string | number | undefined,
+		toBlock?: string | number | undefined
+	): Promise<Array<TypedEventLog<TCEvent>>>
+
+	on<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+	on<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+
+	once<TCEvent extends TypedContractEvent>(
+		event: TCEvent,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+	once<TCEvent extends TypedContractEvent>(
+		filter: TypedDeferredTopicFilter<TCEvent>,
+		listener: TypedListener<TCEvent>
+	): Promise<this>
+
+	listeners<TCEvent extends TypedContractEvent>(
+		event: TCEvent
+	): Promise<Array<TypedListener<TCEvent>>>
+	listeners(eventName?: string): Promise<Array<Listener>>
+	removeAllListeners<TCEvent extends TypedContractEvent>(event?: TCEvent): Promise<this>
+
+	doRevert: TypedContractMethod<[], [void], 'nonpayable'>
+
+	getFunction<T extends ContractMethod = ContractMethod>(key: string | FunctionFragment): T
+
+	getFunction(nameOrSignature: 'doRevert'): TypedContractMethod<[], [void], 'nonpayable'>
+
+	filters: {}
+}
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/common.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/common.ts
new file mode 100644
index 00000000000..247b9468ece
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/common.ts
@@ -0,0 +1,100 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+import type {
+	FunctionFragment,
+	Typed,
+	EventFragment,
+	ContractTransaction,
+	ContractTransactionResponse,
+	DeferredTopicFilter,
+	EventLog,
+	TransactionRequest,
+	LogDescription,
+} from 'ethers'
+
+export interface TypedDeferredTopicFilter<_TCEvent extends TypedContractEvent>
+	extends DeferredTopicFilter {}
+
+export interface TypedContractEvent<
+	InputTuple extends Array<any> = any,
+	OutputTuple extends Array<any> = any,
+	OutputObject = any,
+> {
+	(
+		...args: Partial<InputTuple>
+	): TypedDeferredTopicFilter<TypedContractEvent<InputTuple, OutputTuple, OutputObject>>
+	name: string
+	fragment: EventFragment
+	getFragment(...args: Partial<InputTuple>): EventFragment
+}
+
+type __TypechainAOutputTuple<T> = T extends TypedContractEvent<infer _U, infer W> ? W : never
+type __TypechainOutputObject<T> =
+	T extends TypedContractEvent<infer _U, infer _W, infer V> ? V : never
+
+export interface TypedEventLog<TCEvent extends TypedContractEvent> extends Omit<EventLog, 'args'> {
+	args: __TypechainAOutputTuple<TCEvent> & __TypechainOutputObject<TCEvent>
+}
+
+export interface TypedLogDescription<TCEvent extends TypedContractEvent>
+	extends Omit<LogDescription, 'args'> {
+	args: __TypechainAOutputTuple<TCEvent> & __TypechainOutputObject<TCEvent>
+}
+
+export type TypedListener<TCEvent extends TypedContractEvent> = (
+	...listenerArg: [...__TypechainAOutputTuple<TCEvent>, TypedEventLog<TCEvent>, ...undefined[]]
+) => void
+
+export type MinEthersFactory<C, ARGS> = {
+	deploy(...a: ARGS[]): Promise<C>
+}
+
+export type GetContractTypeFromFactory<F> = F extends MinEthersFactory<infer C, any> ? C : never
+export type GetARGsTypeFromFactory<F> =
+	F extends MinEthersFactory<any, any> ? Parameters<F['deploy']> : never
+
+export type StateMutability = 'nonpayable' | 'payable' | 'view'
+
+export type BaseOverrides = Omit<TransactionRequest, 'to' | 'data'>
+export type NonPayableOverrides = Omit<BaseOverrides, 'value' | 'blockTag' | 'enableCcipRead'>
+export type PayableOverrides = Omit<BaseOverrides, 'blockTag' | 'enableCcipRead'>
+export type ViewOverrides = Omit<TransactionRequest, 'to' | 'data'>
+export type Overrides<S extends StateMutability> = S extends 'nonpayable'
+	? NonPayableOverrides
+	: S extends 'payable'
+		? PayableOverrides
+		: ViewOverrides
+
+export type PostfixOverrides<A extends Array<any>, S extends StateMutability> =
+	| A
+	| [...A, Overrides<S>]
+export type ContractMethodArgs<A extends Array<any>, S extends StateMutability> = PostfixOverrides<
+	{ [I in keyof A]-?: A[I] | Typed },
+	S
+>
+
+export type DefaultReturnType<R> = R extends Array<any> ? R[0] : R
+
+// export interface ContractMethod<A extends Array<any> = Array<any>, R = any, D extends R | ContractTransactionResponse = R | ContractTransactionResponse> {
+export interface TypedContractMethod<
+	A extends Array<any> = Array<any>,
+	R = any,
+	S extends StateMutability = 'payable',
+> {
+	(
+		...args: ContractMethodArgs<A, S>
+	): S extends 'view' ? Promise<DefaultReturnType<R>> : Promise<ContractTransactionResponse>
+
+	name: string
+
+	fragment: FunctionFragment
+
+	getFragment(...args: ContractMethodArgs<A, S>): FunctionFragment
+
+	populateTransaction(...args: ContractMethodArgs<A, S>): Promise<ContractTransaction>
+	staticCall(...args: ContractMethodArgs<A, 'view'>): Promise<DefaultReturnType<R>>
+	send(...args: ContractMethodArgs<A, S>): Promise<ContractTransactionResponse>
+	estimateGas(...args: ContractMethodArgs<A, S>): Promise<bigint>
+	staticCallResult(...args: ContractMethodArgs<A, 'view'>): Promise<R>
+}
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/Event__factory.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/Event__factory.ts
new file mode 100644
index 00000000000..2e16b18a7ed
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/Event__factory.ts
@@ -0,0 +1,51 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+
+import { Contract, Interface, type ContractRunner } from 'ethers'
+import type { Event, EventInterface } from '../Event'
+
+const _abi = [
+	{
+		anonymous: false,
+		inputs: [
+			{
+				indexed: true,
+				internalType: 'address',
+				name: 'sender',
+				type: 'address',
+			},
+			{
+				indexed: false,
+				internalType: 'uint256',
+				name: 'value',
+				type: 'uint256',
+			},
+			{
+				indexed: false,
+				internalType: 'string',
+				name: 'message',
+				type: 'string',
+			},
+		],
+		name: 'ExampleEvent',
+		type: 'event',
+	},
+	{
+		inputs: [],
+		name: 'triggerEvent',
+		outputs: [],
+		stateMutability: 'nonpayable',
+		type: 'function',
+	},
+] as const
+
+export class Event__factory {
+	static readonly abi = _abi
+	static createInterface(): EventInterface {
+		return new Interface(_abi) as EventInterface
+	}
+	static connect(address: string, runner?: ContractRunner | null): Event {
+		return new Contract(address, _abi, runner) as unknown as Event
+	}
+}
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/PiggyBank__factory.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/PiggyBank__factory.ts
new file mode 100644
index 00000000000..0efea80ed2d
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/PiggyBank__factory.ts
@@ -0,0 +1,82 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+
+import { Contract, Interface, type ContractRunner } from 'ethers'
+import type { PiggyBank, PiggyBankInterface } from '../PiggyBank'
+
+const _abi = [
+	{
+		inputs: [],
+		stateMutability: 'nonpayable',
+		type: 'constructor',
+	},
+	{
+		inputs: [],
+		name: 'deposit',
+		outputs: [
+			{
+				internalType: 'uint256',
+				name: '',
+				type: 'uint256',
+			},
+		],
+		stateMutability: 'payable',
+		type: 'function',
+	},
+	{
+		inputs: [],
+		name: 'getDeposit',
+		outputs: [
+			{
+				internalType: 'uint256',
+				name: '',
+				type: 'uint256',
+			},
+		],
+		stateMutability: 'view',
+		type: 'function',
+	},
+	{
+		inputs: [],
+		name: 'owner',
+		outputs: [
+			{
+				internalType: 'address',
+				name: '',
+				type: 'address',
+			},
+		],
+		stateMutability: 'view',
+		type: 'function',
+	},
+	{
+		inputs: [
+			{
+				internalType: 'uint256',
+				name: 'withdrawAmount',
+				type: 'uint256',
+			},
+		],
+		name: 'withdraw',
+		outputs: [
+			{
+				internalType: 'uint256',
+				name: 'remainingBal',
+				type: 'uint256',
+			},
+		],
+		stateMutability: 'nonpayable',
+		type: 'function',
+	},
+] as const
+
+export class PiggyBank__factory {
+	static readonly abi = _abi
+	static createInterface(): PiggyBankInterface {
+		return new Interface(_abi) as PiggyBankInterface
+	}
+	static connect(address: string, runner?: ContractRunner | null): PiggyBank {
+		return new Contract(address, _abi, runner) as unknown as PiggyBank
+	}
+}
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/Revert__factory.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/Revert__factory.ts
new file mode 100644
index 00000000000..ece1c6b5426
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/Revert__factory.ts
@@ -0,0 +1,31 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+
+import { Contract, Interface, type ContractRunner } from 'ethers'
+import type { Revert, RevertInterface } from '../Revert'
+
+const _abi = [
+	{
+		inputs: [],
+		stateMutability: 'nonpayable',
+		type: 'constructor',
+	},
+	{
+		inputs: [],
+		name: 'doRevert',
+		outputs: [],
+		stateMutability: 'nonpayable',
+		type: 'function',
+	},
+] as const
+
+export class Revert__factory {
+	static readonly abi = _abi
+	static createInterface(): RevertInterface {
+		return new Interface(_abi) as RevertInterface
+	}
+	static connect(address: string, runner?: ContractRunner | null): Revert {
+		return new Contract(address, _abi, runner) as unknown as Revert
+	}
+}
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/index.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/index.ts
new file mode 100644
index 00000000000..67370dba411
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/factories/index.ts
@@ -0,0 +1,6 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+export { Event__factory } from './Event__factory'
+export { PiggyBank__factory } from './PiggyBank__factory'
+export { Revert__factory } from './Revert__factory'
diff --git a/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/index.ts b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/index.ts
new file mode 100644
index 00000000000..3e324e80dcb
--- /dev/null
+++ b/substrate/frame/revive/rpc/examples/js/types/ethers-contracts/index.ts
@@ -0,0 +1,10 @@
+/* Autogenerated file. Do not edit manually. */
+/* tslint:disable */
+/* eslint-disable */
+export type { Event } from './Event'
+export type { PiggyBank } from './PiggyBank'
+export type { Revert } from './Revert'
+export * as factories from './factories'
+export { Event__factory } from './factories/Event__factory'
+export { PiggyBank__factory } from './factories/PiggyBank__factory'
+export { Revert__factory } from './factories/Revert__factory'
diff --git a/substrate/frame/revive/rpc/examples/package.json b/substrate/frame/revive/rpc/examples/package.json
deleted file mode 100644
index 37d819aaa48..00000000000
--- a/substrate/frame/revive/rpc/examples/package.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "dependencies": { "@parity/revive": "^0.0.5" } }
\ No newline at end of file
diff --git a/substrate/frame/revive/rpc/revive_chain.metadata b/substrate/frame/revive/rpc/revive_chain.metadata
index e5bfa0820b100bce59107541915f9352fce1c99a..3560b3b90407acce7f602ce91ac089843be8dea8 100644
GIT binary patch
delta 20100
zcmb_^3tUvy_W#*u&YTC#FoOc})ImidfxsuIsHmuzsHpfx9bwc-V0fyOXqI-RG9MEz
zDM`6E@6BIQ8JA90mQ>!*!bfRpX=-U@<*V}Eyk-5r=gg=>^!t4Npa192htKSN_FjAK
zwbx#It+m(Q=loI~yS64)EOeCHE$eoR9Yl809VYf*r`^NEd)YP0{!R*UpA+LKX#@*r
zKiz&F$bP2ZzLPq;Q>7lv=$<D{V2b-?<ip%2q+}N5R^&b`#+@c7uw?gQIiB@%Z;_K(
zj{Bh8ljXX9knd#<cUR?JR^pz7-wOA`N)oGdH{y4V`-0Mgt#kYPC9sX|RQ%St7y2c!
z9quiD@ocAizu!Hq!F|ndEZdFW6dHC-GWti3bCs7nN-G7f$^D4`J#4T0Mf~n>Jmqgl
zWLEc?)RdLXT5MnFurljJBpkCAIhK{Tu%rpa<xW@8V6AWnXA)+xbeop9xfa;U%I%9C
zrDe8K$5MM~ewoc)>aZ<zl$Se;7TSvK&iq8%JPpY_o3qR|Z@jC>f!qR{y`TWK3mqQ#
zyaKzk(2<`w(mixw68q3yJn$qt)|feH40C_h+8qTO2Pd*4?tOzJr6U|CzQ-MNe>r#(
zJ4wGcu}<!+w8L)7=-7DgkOhpLYur54Y+x5?*4r%7y>IxJ?0a{=k;B{<MoiRmb@=^w
zWD<Ub3^zOH-jY!P;O3=bCwI)KIQ9+MP6?xU?i)|hi=)hdd~;N3<Mna-jr7qZF|5&)
z^}Lb)*+jp0;=|oXCdIK|8~;0LyfN@sj^i2Q@XrY{7s?qMr%gY`FyrwvhcUCeaORsq
zX4LV4jKe=*f>{z5%;@(Xz%y-D7e0(p+9ola!rn8Q8lRnY!pKK4+E61#(swtEihHZQ
zAB%Q>WG@YhW~}=t=Q2lrPIB)Qj+u%aOQYS>=O^*ejOx;*2=|Wpo%k3=u2ep(@x=Un
z0w2f7k}CFXY+aZxusFA+pfgKwCl>VN6BunA&Vt<q1tyl<SXt1OhY)Tp8qHGO7mA)?
zY3_$yPa<zA9@Q~TBR-vR_}2!Q!MF_fqT>ENG8u~;ZZEJG<w0OfuBAn73PN4wiy$6Z
zG~FR4Su@dA4CS&kRN0Knb_*qw0({}Q9Cv<6GMnMvTyoho17HR#$8j>3>t0{l-8?-$
zGv85E?kumI>?n8F$AmO~QkrMzFl=(gd~b!*QHCnhrlp-CQi>`H=Q~R0x)#hWtC(MA
zWu}Tgy*U;SZc*S4DRh)9yqR8Pv*+cxDvHW`me~N6;Pl`J8rxC_B)QB{Zi{sm+2&Ui
zERIVYbGM_)Nsb~rWL9=(E$MZiB1B_JEOah$6zOR0BDI&5x$>O$a!0;RgSRcUm)Y_b
z*^3sUV1A{|S+4b4>?pn6bEP|F$qeS_-n68S`MZ;r{zEVc%hRd3l<(-ivNT073#+|P
zY0FXr?Tp3elsQT@)PtuC;R4)$SvH>8-JdK=VivblS&n7BymECrxIlN{0}r+<?clC^
zU}L+|j_#okw(ltjr6KNZ4|eVNM;d~K0(bg@LGEuJj0Giu%SZ4IMlY@8J2e(AA7x-p
zD$ZjejR#j&^Q^FO%EP%#c533lafR+ZkE~`TjYC$iHL!}t_y6(`<0~0`{{|oCo?rb6
zt8)MTL=U#gJ@~Pyck-`4w(3qk@9`OT@)sUob|=63i3jfFd#wBCojm`f-LDE=3$oS9
zt#TJW8N;t(l>I*6$^F8Ub*$Q*xqcyjcduWB-|!8^e6_y3qTLM}EKt3BH(cX4GCF#c
z4|cz|@dZ}nF5c9G)i%<m5scMP^f5l(Ej{J9ovnQ;g|G3hwr`$FlWWnlQQ+#_2{osM
zdd7;W_&Yw*9k+Q~o2NeR2&!sR(%bzljbruh0b3@s9gUA~i4@q*#^<+2@{Rc~{LMs1
zuZx`;KY#X76KiTTzGh`?k2_?~Sie2`KxLWR+j#$;<veR{{Q8X<3`zRlZy4Xq=vFBU
zcW1mE3VSf;?dcLbKvzc!UENpS@96&iUuW+=e#Khd$6Lx-i#z#X7_(FK0HKHb@dMBK
z7Ibmne{d}dqCXFB4EW$7o*mHSKyKCM*~%T&9vVj+x@lxBG$BEVY@B)QaRF$*I!PWZ
z?iW9ecJDd$spqNj#ZSX|FSZM(2Qk*t82x#&L9YyUKlDY8`>pdYc%B*``r>~y(By-`
zjp-L3m07L3<+206iC2m+HFZ~N7?M8M25L#s_0>Fj{qe`AgK8O*t(tLyvawEf6*>g2
zwz2-FpA}Y1>pnBqHxBy!E8dfTUOmXOQt(Gj^JDKNN@!}TNbXNZ_wv2eKB?@rt}Iji
zeinP4u}rGTWhx%C=CH0t=2Rj1<y!H@e6|}2IoKA|CM{sRA6U`1m_@S|by_j2)cQJF
z%CcFl+O3T3<Jqrtp@QWCc=!@l%OgF#jCI!1Umjpt68liie3)G|dlpx)I(`GYf}yEt
zZZ^dLpiP@uX=hX#o7ho2o@ipl0t==wud|gbRc(2l#b~ImyvYi9c0q;Z92EgV{`M(z
z8`$^ifX`Wf0j*!YCWNR%PYYK%Q0WaevTey5GC$Z`LIDad0$;Gg&ksZyMjfoK3+G$>
z#b72(Wr4J+C*KqOKhlH$8OidVd_0n!J^A;*l<1Czj_&)PHq*9BLzw!HSiV+3X?g-b
z#VajpV*-CsVbN4OfUjlIYM&IIG^Rc|hL51L1NqrBA%nM2_CUVWTdJZ|^aYuv&K}IK
zkUiDqD&U7`YyyTBqo=Tp05M24PT+U)K`>B%l#WdGooxOGe>7^!<#%X}XW99|9kCv^
zl=HioUCpS#oZ@lf68-@sA1vX2*OI0DNmM?!j1Mrd8EWH${NKCZ=34P~w5U}d+|KXo
zqU)$`>fC+&X``O+N^}0jp9rdIPe~PJzR%CWbnSefpU7A>{kMhR#;Vn)5AX&a>9Zg3
z56i4Zg+4leTQ8~ie!^$)9?g_M!yXqzbiDH<|D+)d3nXdEz=0D>UCSz`R2IXe2RV!K
z9m{IfiKqGdOzw3*g;Ucv{P^3mAAX5fG--X}M?U=aNcR574^-EG$Nws|tx!>MKf3Y-
z4(MJE*RR;+EGoaF1l33W%liwFc>W{X>!CsL-_PiNVoNAJ_KCqvhkxTkF=v|CsK5Ni
zkHK7M4?*g5-mpWtT@z?BSR~96YX0Jd=%~IKVpyq7;oz=@C@pQSG<47wLgBrJOIrHY
z3d0lH)ZX{7;eeLDm}>Z{Bhp`M4O1bM>i5}(_cf#ue>WVrs@3-!!nD%=57-vP@|nzS
zd)=n)IAmyHo`-04!x6*##-Qf*Y-v^(e`45c#)^--VCWL0D?lIJ+*RH6v%#wuy~SPB
zjlURfu)As<+_+_^7JLgH<OM$gxS++=dQrIC3HaA{7TyYgut9A<s(2JFxrPW+)L{dJ
zU=0|W*Hf@>kg&z8id8_gpcODhs8h0pU(iy`o+i|ok$#geyb6_0+ZVux(vwc=rwato
z)}kI=B(!#fXl`3BEP;@zAuEO1(A;X-L&AOuzysF`7m-9)3+uyLgvl`F+zlfOo$AQb
zoFU|4Z(7t3s)fBFn3(GALZvp1hUbLi;lMI4#n>RIkG?CMFyLv<`+{sly6{7xT<h!f
zA>o*|EOs9kmWsEf9onxr$ny||MAvLzUK3n?Ks)&t;i#teVt6ADX`&~r#tOC0Y=kDx
zRPg|>z^NVyG_Hq}p!Izgt3w?&%vhF;A!ue$Jz8Qs51Xj|bE)wSjg;al<7*lzaSs`b
zELb-8yCs|Y+InLEctG!OFn){Vm5s*vNUm&_I#Zub#tvvcdXupc&9t&8HMGX~24e!T
zr;Q!y#%AL{ao8kBfxVKF$Qb3#tK-SoQ|o9+tufQU4$!`>#!z-ZJ+;+%P?PBA>WwdA
z5SoS^jK>Yn8R5s>ex#u1F|<|c^yiKDcy%m*Xx~m_3QBM8G;V@QRiAjtxGwk)jLX_@
zR6Br99|Nl*-wdlw6D}A_LC`xFjI%5dyUsru(*xKln#YS>yR2etuy;c`0-kh{qhJWf
zY{jKcS1EP|E$Ux+@qQR?)oc=nXnYtKAkN0)&Hyo7Q$FtniLjySpkUD-h9g$&<ach$
zA_w-b;EMZ!HzH_7Cox8=2nm;Cm{wKbC|X#)$cAlz4y5_-^lm4yH%n6g-AO#5&BmcH
zaV(IAg^M*BBVURX&HhOD_7oen>XJBdFOqxj5jP=uM^Dt8UgC5O_{9YAUlz}PjJBqU
zvse}VoF>jo9y!9bbZ}4Xugjfz@z`gVLZqW*!GvN#n8IRYh&z5b{m002akP90Mw&pU
zv?Q7O4@HO~nR17Ui7EYL&cs5CT&0Eff_^d+reGuF!nOmrT}5|_x)<7u^6llW(n=2u
z*N@&ED%P`9atssiVQI8sm>7;kLrJHGiG5f)nbXC=EQ7|TiwS-Hgksj+Sy)^!SKFXO
z%d9;B{WV>@5At#)T^tgdd3SVK+UW4Z=|6n7%;6ud`YOT7<)~AJi~j=yO221_MJ$)L
zXNd!2?XpJ$IOMw;z^=Ec;*&TBay%ZLvYQ=B+B{m61{eAO7HZW3S0W3c9?{Y`Tp_nJ
zKox+40ji)Onb?=l9W8cZm9%uU*b~CJZL}EA*3gHe#YhzD0LC%m?2c73OPX4`V6t;z
zk-fa46h3AZm5&jpQCg-LMc<4ObI=OlReu6mO@}f?JHJk+y5~mk5NmuW->45U$;#De
zL%>t5Ov6U8Aa(0laT_z$Y1Jk!)W+4z?(tD!>b!B{P{wxXJnOL2i*WZHgfwTo7(vo_
zaa=%y%pxZ_>}9T^GLCB?`*?An-)^mwoif*?6BNA1+kWqz_8hlIgA65pf;ii6uLizH
z=9)d=`@P^deZcqAy;H^HjtAu1K?D}cf$z@z19W|Y7|tJ%^#}!ZohWvpEfd8wPmt{>
z)lL+%*m3%LqL{!=QE)cq;0&c@LnzNvNwzpbxG1wNbfj7cr;oD5?!qORZFO62Mo{o1
z(Z()o?FR?;8Nv<bY?JK^99gb>c>UMukx61Nc7t955Otg^j@E)c>HKk7kET%RWN{>a
zN_M}sA(W0x79-H*_mjnBblG`|IGVpG)1hji8$C8fjOH)NwEJ11I~|=Oc13?jCW#~X
z>oO%V#CRs>h+WXjZ+*m0^xY)UpK5Z%`}}Td?AkALw{&)eFvTO$X63F#Gli0-ib+96
z<&XR_D)eTo6l&m*(PBFE+*C0R;D@G)@w}o?agk)B$Z29X#jKzkrf`Akm}%lngCSUv
z$?}C1LHlNcGhuXorZ|H|(V$u4Ts}&n<gsEhwayYd!sk9eOPpwqQ7}WHOI(O0mL<@T
z*<$BtCu1p^*-iIEQ!?|Rs{p2nUQ(RG#VOjVqvA4A3IXUH3!R`*0=Q(ozGpx0fKz=2
z+)u~yGPdZc8ZaKyC^}bcf$BjLOC77FK(*T(Q4*kqdd(L{K$*Dai<(ckcD`7S<ko!g
z9zIj=A;{|CXsZtmSyY&Zg&Rjt=ZW)JHvN((4(^bnuz0VHsp#JqgUO-Hd@;svhDMEy
zm{cw;%NGZ9@Qq!0f?w2}FQ)k0b*inLm2;5b5Qhf00c;Z#gH^0{h?7_$opy*Z0}2(v
zHhfB{!;xh#mWBHmhaHm@y08Qo^&h@M;qVVKfV~nKzDj{cNm(E|#a~%IW`TBpf(7{Y
z0?`k+4=xaU$g6bt_d;p?La42vg`zVEEa<DvSVpNmQ*-b!#%kKQ5SC+|dS#)Qu0(Cr
zaMvgt{<Y3p4P33Bt5Z_AIvQ6Z_TuXmJp`+6D1j2^cj!Fsv(r0^4L-BDQ)_9m_CuJb
zK|_n@-8!-+C6sHrD;)v8(y>QD=rxq;%EV!8FMVDnIw`OMi|3O;QXrL<i@EF^9Vr(R
zLYftpG6f;!%E8`1BnH#$Y22#<hIv2jTMCXmSs{*wck@YwIG#VQ(65<NXa1Bzkz=K9
z<Xj@o`9mSL>>PK%Bblw<F&*_8Q>#7z>jmzpHX=M7_jI{(Dd;_=bvZNmj1JR}KgXT-
zKsPDeMfKigVwI7<<QewoRbofeWxbZWuHc`poq!W?gJ!G{UE$!z9~Ty)^7hIyCw;L(
z?8)C$=;$OdT%G-}*vj*_?xOT#e)_bn<&0|j!{Rr*pMnD3?8lk?=(kRMBu!W&&gKL4
zhX`s}182cWSJ#NChG4%t(QQQ?|ESnm;KTgxEZ{a%6y@ihK0T5SKPGO3cCbG#Ze}s`
z^W$PZ)>G~iVoz%e>+W4g<1s05epH_&riKJEuV(XEhY5b}gqdOLttZ4UdAKd-*NfGB
zKfT*OTeYe5@&@q=e35M%VQ$mt&5hy|sD!{x@KZ9>!JEWMnybIQM(oD;EDg(W+DKv$
z`H|QkIw76Ji7bbf*TUE}5HK8|gCw4UOYz(mF^iv}wFsu)XGuLMu~zgC&h=v{w^!xh
z`{Hd=F_>H$Un_R%WCvS0?T2^xarnnt=^M&9HQWxq(9`u(Ps7p=e;VFG1<iaKs=tyR
zcp8$N`wYr=KP~P;!JKEr5oD+XjZM#po#9U$dq(#s*j8A!YKq$`4iVP*v11g!75aGV
zR?*5fQo~j;5&QVl8q6v>Unlm&o`>Vsc(S3$R_j^Tmv+~Qz38Pn(Mad&#8_hz>T0yQ
zUhqhfbR^reqQ&1E&f>T_Ki%S~lb;on0$Dw+en~9kcX;NnbE<d#cKY4b<vTSNq%y9-
z&s|p(K@ruGLPal&OZnZNMr7M9%E3)OEt<3zM-A{8(sqjj$Kzl@W;jw>;DA0VO=rwD
z!JFq;_fo_NN;QLn1)=M$N!|iX#9p20Ggu1O>|wu^+ph}_X={r=;79XT@SQ076)}Ug
z(!y6n7vHMa_de?9k;CIYR2|iEST70Oah*Ot?v!2<dd81C<3X$0u{O)#yk0)!q8Hs|
zA9N`5aVanPwR0&i0Xr1UB`=l2KgGp<m$jZR`f=Aayu<k$-nwJ|6esgHy${2h#L=O*
z{MbmuYL?*KqSQzE-J)$x;zBd?*R(EYz2(Ol{oNZ%!_|aW#d{<;1=IJ6+00D;vsa9Z
zGyD5e80g=Q!a$$_g@N?zUU48Cive$m{op1Pz9mL=2=iyL6YZ6*it;j86OIe>*Azw1
zD1Q%Qqy6s+NR&p6Yz^h2k>T+aqr(Qrd0~@%VB;v|ZE+O#GArN4J}ZG<d0Q-0lC^em
z{@9ho?h_|?Ds8l7pBRE2%1is;Wu?+b`^0g6X?jl(@N|l876<YfT1UgN?Eld$y3AQx
zt%>7O{kd#^{bWKN_>S0Bf<DMS0RLeI)gKVkkeodrhTL5cGjwWoAI9u!rE+QHLA}-5
zgJMd+41X3ms?-S)hSO|U4;>We3B1G8blzbs0H@C=o!WqmMy`;m4nuF1sLvmUuf|vC
z;Axd!zO3?TfifRys%k%1RX~Zks-h7eK?$#-=RXpkQdVjGRQf|LWPB{<^VR<Pp^Ez6
z$Ko8uuk+W>JZR8y@hmh-#3$k;oMTeaCt@lzOQIx2(}7RK4ue|mdPIGCW5*5k(S{h-
zJ}$)og#TI!J|XrCuLHI5IYp(8k_tx|4#eO?VrRS9QC?5^C!pMR__G2^mZXlf=Y-g`
zWBdN<=;{e^cHeq!{$#GspWD%ffco~_&_F@JPJRCQ27mbN;p&-_Vij-Ntz&8Ohx?(k
zJ9v+m-Fto5y@y`-OdJ3<eEFH!S3qpEyZgMmBPE^|1A_KyOx@$pHS37>1JQmDq61z;
ztv-kjP|ay^g<q@I=72wU)L%b0qReHYznXSNjOG1~>uBKUog&v+ajH<y*mUhkD40G!
zi<xMm&~sueJENwb6XyunZ*0FHzQ``pgo|+UFRGOnH3#gHXPlS)5grYvZ?20bHR)^d
zFwd@U{#L}<iWX$+L@$3U8ryh^AAgI${0;Tew_*^_-vnvb#9%e(G8_WSEq@lDUWQZ9
z$p}MKl+lJOVi?W8A|^pXj$9K%Xy+AiR)o>S`g%Qo4;;rrOZA<jLS3$6ziHHfLuu(%
zT$fNh4fkFZpOMX2hHwixYP|-$mDj|nP%i+@5W-Ac5beG!MvCxu3LRlI=(-pNrIT}A
z?8k?h^z|I29=<M46>$cjr+kc7oJ24FhGiCqaEIpJYH`3g^unJqa0%)Mzlj$#=i+51
zJ<Iyh1YX*1O4VqPt!XAMO>ZBy$7|fueNd!pC~$_Bp^h;~?;#?qgNFQ>n#<Cwg0oE?
z4VdGDC7YT>DTo@3(g-O>!<cQNw?(NF1&C5AYo;-xl!#=hC}kq50oa_-W}NU&bd;7<
zAVBUcC_p$KC+v<=ePLpoq0`=s4T3{0ktBcZnC6OE>ZCs9FUicmP^*Uiw{j(VF}-Dy
zo}|lWDU|ZfQVyJ+?IBVZ?TnA-Dm91&K1I=7mEPRiVrSecy`!Vpo3GJxp}V+hlY8#l
zVIC<v6d=V4w6CKSO#U6ECa96-j#6}3jS2EBvy>68f&xdL7HXR0DnR_BMyn1YOOTWd
z=OaBx>ffo()IGhp7?#XlP{!&_h*s$XrQgnqVKMb4cDI&ek@>LwWzO<C6N?<_$--aJ
z@I=tpLDE#dUYi1s`!-(NKec$KVuz`{6Su?Ee!JBIs&`_T`VZe=;_$C&oEC1khw!t(
z(jwXyg3-<nkvj2vOmr()3T1of$q=bGlI9R;RoGswk=5FA24`+uvyR~u+i&9bdvFwY
zlJ4gZ+#%GmIaKQ0tJTEfbvF~27<AEXy-gkpw2%}~a@uh@cT^j0FwF^-s<5ulgi4bT
z3(=S!dP-w@66-q=8zM*fD2F%Zbjs6hRhX0xE%J7l1ao_yu6LJIXb~h`+{3<6DD<zA
zS^YdlQW(2L-}I0^Lg3<!o|2tir>Iyd63M_=sgA#a4MG`C1FyzP0S5l2Y12=k)G1yn
zFyGS0Y32iY4(`SEN}-GTQoJ<Rz#Gll+U%s5JyT&e-(8-HS*F9)LIjm2Nt+b28S6qZ
zBRFABmOkU54=(kQ>ap@4?<>t$qO{s1F52vV;YNfmdlc0Vq8>v%`bl$<JlapP8{*8e
z+wyD3=Kd1FOW4w1N;D*Ris)>A=?qI&_YROoGH8H#L!@wuOvU8Y(t|FkFF8}CE>;|~
zg+@*&T8LArg#wpqrq5l{O6)FH4U}S$qz{yawt4DFol2yzKNJlb1gySodeXNgC`#2j
z4Wr0XDZ;l?6Rsk}v!L=)d*0$&${sAO5z@>sh#QL`)q~2Uj-HNV{cQP;JZC;A%b-<d
zQXJ){N!?f$9V)}cvNR9wmNaQ}cDmWuRRFF(9;T&%mk_0lHgK8k;W9mNnHug{9wQRc
zkIQP)EW3TPY)>;SfqKR0a&!^s@n<@727vfnGlzcw*D|}A9vX&mR}RIXVrctN>22nq
zdBda-lf%q{MpTq8ff_-H#>r=fN$)`K%}JL+Vx4AY)2~Kl_V3FvTP1G)EP(ZDQ;Zmd
zleVTyaUBZH%;W?hSBQR%Ca%OxbCZo>>a}#K$-q~b>DFsT1X41jT2rM?8HZaNRc2~9
zC3K-jMoHu0V0|=7%D_B^j+T1!tGrc<M@z#H)7>>%8Ut1MOQzHXE=0swsXM<$=Rs_>
zcNwhnSq9a557vGnw+=ZTj~jJ#;nXlj8bwnx;fMugO2heDZ!b$TrAPjNzRrWb-iv;R
z5Bho?eJwQj4h=mXcY4v+?H45V^|8_#18Y!+jhAW|zgx%S**-OyeIpEe^qQz_(X)<m
z=y=D>?$z*Si(E5Jnk)_F_j_=(+bbQ=%R4*07+QTWv}zcfB6rkGzrSk?SBFiJj)>4}
zfwQD?gcly2C3Qz&<%L;N8h=W|qO161#9)(WOC39(F}GFaR%rfE=)!1tR@`|FNjNQ^
zEp>&y+csMo4PEy2Y#5-6T1^D?&6S2j=Pk{ZwBYa-?a6a2M?dER_!149BgLR*!5pb4
z^_hzn&(Dz_N0>%$Jz*{^cQmb-EA3@BJzY(mCv{@CsA!%P!LtB*d>-WF79E`@<-&JL
z|C<z|g%|D_cgs6hIMr(xVK4@?AJHu{hNJ{wNZJo?4&d;wtuRzjQIXVDJ!6+l60Tf)
zyGUAXg#L6DNhgUf#pokap`~<1H`&rw$3@W@m-J8@b@l(Q;`pclvJZiiaaYGp{(n?&
z<8EuVXpLpbAyr=AEX?NwAtu0Q)f(agWU5~Vwa{ak6w(FZ4C^F&(PEBE(7A;5%O!hr
zR%|4JbOf%zY+EM1%|m<6eNfV(NJzrfLk~*JB*c_QKOzmp*74y-q!B_^0Nb!RPlQkY
z2tts3R!hBuaJZ@;JpX!kA!O;a2LDN{IXi&-e>8U1gClDFYUx*oP3OkHzyoZ0RB~d=
z+2t=%X55SbU(KBx&`xvbVgwjSuGTak*GhB@=C#stD9OjxO7Tdvf$`1&T0hGerG`~Y
zj~n>H0LuE+7*6}1kY3|U0<?pOFhZ5T`s_OCIzwn`!+L2wB2gNrqi%TDXH~%6fmNYj
z{)Wh{(m_Jj1bBvC?E|tVfOc;-2GhX}Qi@--2EQhNTc;O>P}hyR%^R{&+Qx760{*lS
zf~lWQM{bg=e{woa_id6Eb;d+?AK@x>=&@>!_02=ROw;bTrJ0Y*Qk!(i{%(^rIIt}!
zSL5v{%MJfUKSYn_YrSQEbxXrT>jK!Y5iXok!cMq~yc-y<&I=Owlr)B~*B?Tt<SD7h
zv_qF4D@19h2WE4PG>&iZg5=l0#_y)>HBvZY#buS)=@#mb5z1~fH2QN*Ud*Rzq^)ok
zb-CW_Wo5GuEBAWgKH98v4afPZO0&k%y#d^QHHoB=e!_tO(?ojt-*Bd%sD~)Ds@Lmr
z%bdYG)CBuDt@)cY3c`zUXIHxNHz^7XFg+)Q``roiouZ`Yq`rO!;PFgB*djBZj=W-w
zqQ{?u7e9m2cStEvuR5~x8e}L@EduHnDf;hFq%YIlXT_Up+CQX;meCVO!Y{$`^2Ac4
zW#HsES6LYsD;yhTcNXBbYq`so=PFv_C@r_yi)<NFvuyJ{w}!PEJ8s98<NB;^K0W#>
z%w-(?{Z;8Db`MQerPo<63VcnP9DYe-eD})%*8^?@+zhxCV6-R}vnANVU8d|kkfJTG
zNlDP^dj8ATq+T>}57czr9;qjEGD-(S|LT>`?~!`=GYd1}@B=H!;y%I$sh9UiTdj2D
zAeuaP5Nim5^@CXXW-@&sWkhD;UX=H6VZs8<HD@+l?RAvTb>;_B;RjIlfwblWDTaRh
z0CxI=52ViiVHRf9P8AUpqZdBF;akv$`1#w1(EMXR1oxt;5J^ak#S`JrSXN%@EGl#6
zVaFP+lSF$ylqPh*s0A(s`aZ^jxsSGRaTMMvjfG?DXqDooCR==!MS`WBvPeKPD2sl8
zo8%~~C@7b)k60~auvEax6BY~HY9Qypi&FTy9^h1R9hSP1cu4mt6AppebeebwTD9n~
z)ScEHlFp+5FeOls=MTd$W|DM7x+gi)($-?F5@3W=Fn}x|)_?eH3x|JLtW`n^mqYW9
zNRv8dSXfeK5iW}3cK1koIVNR>hk{E-r2a{{ZAiCUd}+69c-s<hrwK=~adFVEA7Ls+
zd?Y0&INM+-)G(CX9(|z?h7#l%-TVk+-2ai(pOt7h=0G#f`dEsCW?b{J6cbm~hT|3O
zIbNY*;h-fy{#Ysl9ixw7W4(r6JcbpjKaG+@u@n|K7gm$~xD*jr-3H^j_88ZBFs`E=
z$05ZVX~Ri4E;W?&xilN0`I1khG)s+z36l_aao`SmdD#xS_PG?5Skq?Qwc5BBc_+Qr
zXV{B$dTTYbovFtODV$+9eL{*xl6OKHgf39ih2A<LjY-_mhSr_!Y2E3eRZIAZ^yEp%
z{FIYGvfD#-QyZ$A{*3CTHdOENrFu_0s`q%Pjynq@`rRq4!&)+YDkUWDZG)uQ7fEwF
zB+VWq%RiN7Chc$2@RA6g9k?wkm&Ci$cEB^v1D>YcKa(c+Z?(vSaSy4`sj0HL<+wgs
zX3go{uRo-nJ8EIJSvX4`Wb2!Y?K>J91RzV|juZPF&Lb4DHk-J+fZ2qC{or#ryPj!8
z9Y7*z`)SM!w6QibXXwmnDP=PznR=hWv|MaM^(o)so@zJTOCEgho<UESJ>6e#)BTM$
z-Cy^BgT-Az%DA&qx5OK5y1VY%-Su|e-K4s+(80GnXwIF5hkcRQIcY-wi~98AJtJS;
zWVHH-sZo3X!@IscVrsOK<t()Q_H)vdWTj0@eX`6}uY~(fmKkWUB+cHoL(fZt>6I_A
z%(tDF3gIK0zko&!qv>Brz2m}w^X?^}D4_ep)$k|}vM8-pH~QoYDSu{kn>I1++r)U<
zXo(<)hH`Oj8YHxDkl<;MK<onIJUhRXdci0j*OFwdD1)!CP~E=__i5?3|1xw>?AL}B
zeZj-j+nm4-_cjkxJ!n(u>kHDGE7RJvN%C!z)UHi>8{iCWmhSYB0knVULMsyFOl!84
z%S4vXvT|8gd1P7f+`_`rx%x7pu3tf|X4AN@plhS(k*}om#GE$0to7|=ZM!~Z&<|fp
znH_VjENQZ%OmjLWF0z-w;^J)fYsr;jZ-dOCkz9D2DGnc!3z3I-Xhpo!$~o!A*AR<B
z%KJu|wz33B?#e?&`>Cq%wAK>75_d9?3UW#vZe_ITUK>jct~Tj5*Jmu+9X`!mwCP3z
z^oU*fomUdPfNQjVkgv9C_k2Rgc?lk84n2GcPRk5>=@LYwmOj&xdXm1C?uBPE;9F_9
zkgnhzI%|A)s{a;_;5vHyTd19Sy7Dc&ri;|&J0v%0;&;+a-sq>j!Z?(^`%VhP;<)u4
z#0@9?c6cr`zlTSdK<@8>H-p~&9(E{`ZhSBGfvt$UEF}Qpw96o*fmUBeosnL>49INy
zN=xh%as^2Vjk<!)s%fc~tfS|(!Uj5d1<j9=cooSR>U&j6^1JNMmKW=BOgi#|6z+b*
zPr;6R(^csnlCDXq?pXg0aHIBKmGn0p%^+<2HFTaq4_=e*fvx?!mQ>?F1I#!>x2{Pk
z{6&*{s41GJU&n^w29;iy`to=??`2a2y?b4X5dzKZdC#RW@dv33k3i$S=3pB9gR~m!
zuK5RP0I0wD1L&=wxE~?4J89mJ@Ddy7nIEMAJYppp<Gk0((hCZl+G}x8{?z>^X@C$I
zz_!xSsn~Wc`$_5|#00RP=vQ<@hrW{(x53&A!NIFPA$F8bNjG3Jv#H>Qlp;8>>!gjd
zj6w9~4a{62eR>0YD<S`XLw{FL=D+c@pC0%(V$TPt;onk*&>FyYk>vxp>jD3PH+@k}
z{Evj`kE<z`aj06O%I~752bugbdWz@exwta%1TQbuuBr-xd>PX8gCNg<G>tRL_pw}c
zi&1{TfOMoHKZ9$`bj}a8B{a}q-hmL<Ie+;Et5QEP$#~VLnx<Lg2gGU_k^cmmZIL7C
zM~nO*ZWXz#@-qVNyZQ&qRs+N(GE}Z$_3EZjIZJ@0I~OVc7sp(mMaj?O3}kg@ycK&(
zeWkNJP~Za<_f;X74Bg~7Om{*zxw~JmqFGP2MVLqRF><I{)=iE#LW6IQl^?)?P(++u
zDIm^UlOX?<u{1U1UO7U+V5g+WpWqsHuT;5@0fU}9SYE~O_RRS-c{O8M>Vly%E|zDj
z@uTIl%rHaAPy;gMLM@l8t{5wC<MlFImfX`|uqzIA>_oi9iLzFjpDo`&=0kPnB=Cee
zU!5Xj%WzB`n<L}prApN?O}1)~t7zGDd7U&v2^BcOPF2(8Fp8NWPlkV3IYaJmtWc_z
zhiKJ*B%69{hK#LTtJ-~*+{=VzGI62Y6}&H7DE|Z(aM2?9Z>TgmWn8<ir2+SYizhiO
zzqR+vE5J@^u{@RSR_81RlZ|`8EfY0NQxZumlqVbZD<`!+`m37?WdwrGs8*LOF?L=J
zE!NWSRa*(z&rYl3OXX@2+Tr9f85bHA+Gba(;4(BXmw(3UdA&+r0E(hl$Zw$V%nG?&
zyN{G?h0d@oM}u3Q20Zhl&hwT3v}y4cWdGa>xdbX=(n`4-wp&Y9%5#t$Un#%IepNR;
zBu`_8K)=-*q0wZ1SYF6}Rx2KsXNW+5c&$7@4D$mITWI&&auC_7<>^LT*n%0Us+OZ5
zCeKvMsfZmPuf`NtsnZ^lZ}PC9+3UbBMP0s5{)({#HE+Ef!VJlN0<B*!@1}%}@?(a6
zx1SbolB=;!ZfHput#r#zv2-=)DcQ<H!^CWs@jfoi+AROW7=?bZ0V25<?ix|?E@d=i
zXgSGK1!E3qG?Ar2=|wXK%Ka&2tK1Q*^w|dG2JiHvnirMFsI?A66w-w{SvAM7zP8DE
ziyZkC1rFQ?cvd#atcsfc4svU0>p#HnIx;*j4>cyE&w6$A^YT(2v;Fq}$k~7kd_i7>
zRr|mT@}oH1V7ugxpqY;Cl6%AZmKx+fNCq{?;}CUN+aQ<YQr)cvc?wqhq!%%mW?K8A
zyck%1dJzNOPb*%6pdFyHm*vm!&eDY4GOh)jqDimFAHqxR(kP!dT=%;{hJVUA20Oc{
z&ibePFca*I`K#xfv^8K?|DtNbnXA6?ntYED6MbecB)IU^x8(o9d(rg5+wv@gDW!d~
zOM6_}EI)?%;@^SP_oGSgV1=gnr_<VZ<ndtliFf2IT<D5<7gB+kVAXrF3#%!euD&M^
zGCNpzypOIOcV*_Ms{{7Sy$#Tv_qWKg7@NCAo&!v|>Q61QKVv1Y9+Xu9rs%apAjUzT
z9RfcJDfTebUj=PHjKxzzU5?0uv|Zm3*<q-{(tP)bJQIxRd{l10TK@2;>|lx2{x&Xh
zbU{UVxvPlX&ICnjk)(=p2ji-lP4ic@KWj9j=;LxHTJo{{W`J)6Ud+}jrX7>_;$^Mi
z<MK3vaSf(+9hIDvdtjY!IVlgt)So;lr&^o+cKSo@u_z;32bczmJ|%a?oDMrBzlZ5F
zekzY-8`ZI&%FhWfq*p(edl-)UpQ6ySaw4l!N1v7Rd6>an=P}FYDfA0@ka!9Bgoo(O
z93_lOzmUVg`6s>rmL2NRFXX;L#AW{&&N{_eT*mZYS^wpjVC;KcwSA2RVc5w+>He?e
zr`7CB@_!hXc;<JY=_bASgWOY?p)eDj`a#Yzm`#B&nDR|SFalOs(LrkJPcmLROjGCn
z8&gSZf56KY|97oodFZvstMdH@tiRTqau-O=<(p8`G3u=U$|ZQ|NImqcjJGrs)Y{)6
z<%VR_%UYN5G?*#rcb|4K<yEnt2@KdpxfZz_J<coP2nPS1SMYvl8l5*N<>n@4@)521
zf>Ob{W|-nR(|BhY(|)Y+*%gio#}rq&c5=;Snhxad7E~rGi#pMU|46dxj8Y;sk$tqY
zGTJc1v|S@5mVWN648|FMzb?v5^IjI~)5q2>$~y+utj_JGB=V5cCu5ZSt`1WI7nxJ!
z)UM93+nLy)5d{cBVLEuLlPcqt8VIr_L8+u}J(UicG$$yJ(wjXMe+Y32y_l$^k|9<J
zMon0(G602@lya}qLo)F^Uu9ZF55+3Ib$M@!RaP4IGn+anSy{%@OTCnxFzhqpl`as>
zyB%%t^syByaU%^)R0`0zR_kXngc4nJq3C;+AQU!f{q!>IH8tPu<C%Mv6jb3p?!C$}
zWR6lpl2QOw9iFVbE+BS!yq}URoH5<Yk*&WHOkMgbJpguI9n)X&$3*(s7T~P3+)2Mb
z0zFVSK(RncHw;ixkbE^jSput-n*!Efq6boxe(bXPa*8sNhk)J~s4Rr2;js%XAEX4q
z&Dc0d8N=WQ;_Yc{wyq6UdNQLLnx-sZ&{`{pC>ijf_YYBGVR^0$QTCySmxe0KS(F+-
zOmPNiUZTq!tnM1Gd}mx4Ic&rtXF>jO?W+QnBeY+p-N3*fMASAiW8$QY5$RJhMh>*$
z3S)si524YePP|?;Zz4XOQB<xA(p?Pr62UyY`{OFrKDXgSEZMf$;V9NVu95G^cjoCI
z7SKOnP?p1N3tXkPl@5E}B79pz!)2SV6Om{euYU?b`&>u4CZ~9V2^4y2(LthZ8m^Yu
z=4&rO6}pyyAiV07Wv{gLPU_t+ah!*)HYDND!)Wym>O&vwm=D@?N$f!89A(^q|8+z@
z&4qO4(_W{Jew(612gQSkyn+htpc`>xJv#58@i|Io$Uq#qa+G^w^Y7ABInq&<SL)P1
zQ&KiHnPaliSj9B$W`c@^dh4;$rXL-6KD#h4*25q~Z{t18KrU`xB8M58vIt))(K(Gf
zr`r6K+3*Pq+r0m!vp>wvf>KwZ4nH;N&a@%sUFKZrDoUI<HED`#YO)WeOk5Mxc!_f@
zE+|*)++i!U7wZ$O%@!W>?#@-E&519p=v~|v2_3hq$Tn|k(mXAYuC>4yF7TW@&*rVv
zhqY2etwU)z=3|$fZ$rCw@=ytGLuPHWd<U$H@x0u5i8_J4xHXC}g?I7&kzx<FV#mtT
zwnB*x{#Sv|O>}rzp-%&DK4~|C^KE6gJXBDrOL<-au2`0P4it)z&2!*T0iW1#mD?(`
zkwJhpPI&f?__jx$OUBnc3S0}FdFuHbd`t(sxxi@(!QSnh2BT05N8$1`<qK?2j!ai9
z0-UIGvz67sCFTJf!sdnc(#0H$6IqVLLFZNGDp|%#bCucSMH8E&JOcw;H%GzSe><s<
z9R{R<itOlTH$7`tR{W_4{061uLrpc&OZm!^aLI-^lm`sW=Kb`BL%E3J`UT3v?10*R
zp|TezI_ejTlmkYn#a%_pKVZJ6xReLk4fTjiiD2-)zAskt3~)~;mMbF-&{j1|K~fkc
zFH_P5yd@t%SEecFJ)?V&sUJU}JjHv*s9Db{WdIa+%nD_N7#9G8xK(qigXygmN;LM=
z=T<01;Mate%6?e%brQW%CHJPW4=Ei2`T?3_J499u#-!5y4=Kqo>02LCW`Y>{&m+oM
zB*RxL-LctPxLU!x*V%OSF96D+=(S2c*0NpQzg9`b*AeLVb;=^xyG2ien4Pr!Nf?`*
zwC_n}B|NWT>y=Jntym;n-<%>%t3e*{f(*XrA~0(!6|aZoZl%Z9D>qo7x@v<W;y6=X
zyHP2@XCl;Jo>H(0EK#4`tiTPepaah+^I`hpx1zsQRI?S+w2t;~RVKjQ3a(S;8)^b-
z>47@sG3=&{&nn~LUr%{fv4caeJ`1Mrq~6<<S(xA_w<(J;PygMf;9XTJ+zvCbhZ?sl
zUtu1eu2=Ay?ta?&SJ;v&I{H^-Cgw8!Z|D*xuI4$VQ3Ao4yObChKG!Z~41YX;sz@G8
zH+I27pCbPTpgTj^4azv!NNv9W)A!ViN}z=MF^Cv(ux|}bn4e2@xJe0KbU9!x438sk
z@#JDh-c(KFxQea^SX1<}Da*ViHv+6lddX-<k)zC6b~B)_2O<l%>+J=2fA&^D-&h?2
zpTo#=7%gk#^`~hL=fXwhie)V&e;@_Nn=NZc>g8FEaywobwU4ovEef`*VhL=XRXe9O
zMS7JFmqF`Zg|8Du2VaG4jw6GrGztk8;R*U(RYK^9s%Rn2UsWu=RyzBda?lWM=|{Wv
zD2ELhmKa*`x^ll?l*Oubl3_t$;&tV6&<u-QzAV}jJHNn{w|Fi>evA6%sz1J=jNmN}
zOLy&+Sw|uC!+yz08E+|HGqalTw(<@$R9Gri^_UXDllfhxk0BUSapkJ=G*i#Kr{JCD
zShahLGD95Ex7g(>nCtzBPni&@KRWZRY5qb2gW1MgoJAh1FyEzXCNHS2gFGL?qI2{4
zFn?VKX}FyE>heQM6Em;Ez`Yo3<uuoVRW|vEGDlcr5#FQ!98tQ_$s>^EHT2^VWdnRJ
zkT*&_cvSh8H>~pz@8VgL+Vh0+1cUqg&y&i_kXqLnWv8XV!=w~znZ2MqWj95AsyvP@
z-q5p3mBg7AJ1SH5s|laMfi<>Tgk(lLPAdaC#zS9fCRRI-)h?Fd0GB>Hjn{~d>qxDa
ze37ogE+1IOQt9VPWZ+Fp5N>N$I9e_EL<IIcDRlJ=7WyrE_jBbzo>^(wS>+L4v8sum
zDN`9moL73rMO#dGo7x&^<wnAlEv=lpz~Pvi4;gY6l*y)wW#wLgV0H0%Wi5{p{`4i3
zVIX~aL3se1#hi=EKeev~_<xOM(Lyu6hN~Gz4PPsdikMrAErVV^ru0(tzflJBp~=?4
z81-EJ!Yl&LF4qDbCd~u$<+sXK-qR}AQ}Xg<C5`upL<fVhrOF~_(DkcI5QYB;1r1B_
zqtYMyf^$DYQ?ydjPf8fyl1}4(QvT(iX${gl$hPLFQ8$#etWC+w|5jdOP`A#XmEq8E
zyM9(iAi4IlG7Yh)F*lVp0^IXMx0HHxUi_PayBMpQ=KIYxur=yC2EYEyP;KS@4>1A%
A?*IS*

delta 19111
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

diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs
index b7efae15c4a..1ca1a6d37c5 100644
--- a/substrate/frame/revive/rpc/src/client.rs
+++ b/substrate/frame/revive/rpc/src/client.rs
@@ -236,7 +236,6 @@ struct ClientInner {
 	cache: Shared<BlockCache<CACHE_SIZE>>,
 	chain_id: u64,
 	max_block_weight: Weight,
-	native_to_evm_ratio: U256,
 }
 
 impl ClientInner {
@@ -252,20 +251,10 @@ impl ClientInner {
 
 		let rpc = LegacyRpcMethods::<SrcChainConfig>::new(RpcClient::new(rpc_client.clone()));
 
-		let (native_to_evm_ratio, chain_id, max_block_weight) =
-			tokio::try_join!(native_to_evm_ratio(&api), chain_id(&api), max_block_weight(&api))?;
+		let (chain_id, max_block_weight) =
+			tokio::try_join!(chain_id(&api), max_block_weight(&api))?;
 
-		Ok(Self { api, rpc_client, rpc, cache, chain_id, max_block_weight, native_to_evm_ratio })
-	}
-
-	/// Convert a native balance to an EVM balance.
-	fn native_to_evm_decimals(&self, value: U256) -> U256 {
-		value.saturating_mul(self.native_to_evm_ratio)
-	}
-
-	/// Convert an evm balance to a native balance.
-	fn evm_to_native_decimals(&self, value: U256) -> U256 {
-		value / self.native_to_evm_ratio
+		Ok(Self { api, rpc_client, rpc, cache, chain_id, max_block_weight })
 	}
 
 	/// Get the receipt infos from the extrinsics in a block.
@@ -368,13 +357,6 @@ async fn max_block_weight(api: &OnlineClient<SrcChainConfig>) -> Result<Weight,
 	Ok(max_block.0)
 }
 
-/// Fetch the native to EVM ratio from the substrate chain.
-async fn native_to_evm_ratio(api: &OnlineClient<SrcChainConfig>) -> Result<U256, ClientError> {
-	let query = subxt_client::constants().revive().native_to_eth_ratio();
-	let ratio = api.constants().at(&query)?;
-	Ok(U256::from(ratio))
-}
-
 /// Extract the block timestamp.
 async fn extract_block_timestamp(block: &SubstrateBlock) -> Option<u64> {
 	let extrinsics = block.extrinsics().await.ok()?;
@@ -607,8 +589,9 @@ impl Client {
 
 		let runtime_api = self.runtime_api(at).await?;
 		let payload = subxt_client::apis().revive_api().balance(address);
-		let balance = runtime_api.call(payload).await?.into();
-		Ok(self.inner.native_to_evm_decimals(balance))
+		let balance = runtime_api.call(payload).await?;
+
+		Ok(*balance)
 	}
 
 	/// Get the contract storage for the given contract address and key.
@@ -659,13 +642,8 @@ impl Client {
 	) -> Result<EthContractResult<Balance, Vec<u8>>, ClientError> {
 		let runtime_api = self.runtime_api(&block).await?;
 
-		let value = self
-			.inner
-			.evm_to_native_decimals(tx.value.unwrap_or_default())
-			.try_into()
-			.map_err(|_| ClientError::ConversionFailed)?;
-
 		// TODO: remove once subxt is updated
+		let value = subxt::utils::Static(tx.value.unwrap_or_default());
 		let from = tx.from.map(|v| v.0.into());
 		let to = tx.to.map(|v| v.0.into());
 
diff --git a/substrate/frame/revive/rpc/src/example.rs b/substrate/frame/revive/rpc/src/example.rs
index d2f9b509f4d..20f00465b14 100644
--- a/substrate/frame/revive/rpc/src/example.rs
+++ b/substrate/frame/revive/rpc/src/example.rs
@@ -105,6 +105,30 @@ impl TransactionBuilder {
 		self
 	}
 
+	/// Call eth_call to get the result of a view function
+	pub async fn eth_call(
+		self,
+		client: &(impl EthRpcClient + Send + Sync),
+	) -> anyhow::Result<Vec<u8>> {
+		let TransactionBuilder { signer, value, input, to, .. } = self;
+
+		let from = signer.address();
+		let result = client
+			.call(
+				GenericTransaction {
+					from: Some(from),
+					input: Some(input.clone()),
+					value: Some(value),
+					to,
+					..Default::default()
+				},
+				None,
+			)
+			.await
+			.with_context(|| "eth_call failed")?;
+		Ok(result.0)
+	}
+
 	/// Send the transaction.
 	pub async fn send(self, client: &(impl EthRpcClient + Send + Sync)) -> anyhow::Result<H256> {
 		let TransactionBuilder { signer, value, input, to, mutate } = self;
@@ -156,6 +180,7 @@ impl TransactionBuilder {
 		Ok(hash)
 	}
 
+	/// Send the transaction and wait for the receipt.
 	pub async fn send_and_wait_for_receipt(
 		self,
 		client: &(impl EthRpcClient + Send + Sync),
diff --git a/substrate/frame/revive/rpc/src/subxt_client.rs b/substrate/frame/revive/rpc/src/subxt_client.rs
index 11a0d51ed03..a232b231bc7 100644
--- a/substrate/frame/revive/rpc/src/subxt_client.rs
+++ b/substrate/frame/revive/rpc/src/subxt_client.rs
@@ -21,6 +21,11 @@ use subxt::config::{signed_extensions, Config, PolkadotConfig};
 
 #[subxt::subxt(
 	runtime_metadata_path = "revive_chain.metadata",
+	// TODO remove once subxt use the same U256 type
+	substitute_type(
+		path = "primitive_types::U256",
+		with = "::subxt::utils::Static<::sp_core::U256>"
+	),
 	substitute_type(
 		path = "pallet_revive::primitives::EthContractResult<A, B>",
 		with = "::subxt::utils::Static<::pallet_revive::EthContractResult<A, B>>"
diff --git a/substrate/frame/revive/rpc/src/tests.rs b/substrate/frame/revive/rpc/src/tests.rs
index 3d2cbe42be8..eb23bd7583a 100644
--- a/substrate/frame/revive/rpc/src/tests.rs
+++ b/substrate/frame/revive/rpc/src/tests.rs
@@ -22,6 +22,7 @@ use crate::{
 	EthRpcClient,
 };
 use clap::Parser;
+use ethabi::Token;
 use jsonrpsee::ws_client::{WsClient, WsClientBuilder};
 use pallet_revive::{
 	create1,
@@ -48,15 +49,12 @@ async fn ws_client_with_retry(url: &str) -> WsClient {
 }
 
 fn get_contract(name: &str) -> anyhow::Result<(Vec<u8>, ethabi::Contract)> {
-	const PVM_CONTRACTS: &str = include_str!("../examples/js/pvm-contracts.json");
-	let pvm_contract: serde_json::Value = serde_json::from_str(PVM_CONTRACTS)?;
-	let pvm_contract = pvm_contract[name].as_object().unwrap();
-	let bytecode = pvm_contract["bytecode"].as_str().unwrap();
-	let bytecode = hex::decode(bytecode)?;
+	let pvm_dir: std::path::PathBuf = "./examples/js/pvm".into();
+	let abi_dir: std::path::PathBuf = "./examples/js/abi".into();
+	let bytecode = std::fs::read(pvm_dir.join(format!("{}.polkavm", name)))?;
 
-	let abi = pvm_contract["abi"].clone();
-	let abi = serde_json::to_string(&abi)?;
-	let contract = ethabi::Contract::load(abi.as_bytes())?;
+	let abi = std::fs::read(abi_dir.join(format!("{}.json", name)))?;
+	let contract = ethabi::Contract::load(abi.as_slice())?;
 
 	Ok((bytecode, contract))
 }
@@ -280,3 +278,44 @@ async fn invalid_transaction() -> anyhow::Result<()> {
 
 	Ok(())
 }
+
+#[tokio::test]
+async fn native_evm_ratio_works() -> anyhow::Result<()> {
+	let _lock = SHARED_RESOURCES.write();
+	let client = SharedResources::client().await;
+	let (bytecode, contract) = get_contract("piggyBank")?;
+	let contract_address = TransactionBuilder::default()
+		.input(bytecode)
+		.send_and_wait_for_receipt(&client)
+		.await?
+		.contract_address
+		.unwrap();
+
+	let value = 10_000_000_000_000_000_000u128; // 10 eth
+	TransactionBuilder::default()
+		.to(contract_address)
+		.input(contract.function("deposit")?.encode_input(&[])?.to_vec())
+		.value(value.into())
+		.send_and_wait_for_receipt(&client)
+		.await?;
+
+	let contract_value = client.get_balance(contract_address, BlockTag::Latest.into()).await?;
+	assert_eq!(contract_value, value.into());
+
+	let withdraw_value = 1_000_000_000_000_000_000u128; // 1 eth
+	TransactionBuilder::default()
+		.to(contract_address)
+		.input(
+			contract
+				.function("withdraw")?
+				.encode_input(&[Token::Uint(withdraw_value.into())])?
+				.to_vec(),
+		)
+		.send_and_wait_for_receipt(&client)
+		.await?;
+
+	let contract_value = client.get_balance(contract_address, BlockTag::Latest.into()).await?;
+	assert_eq!(contract_value, (value - withdraw_value).into());
+
+	Ok(())
+}
diff --git a/substrate/frame/revive/src/benchmarking/mod.rs b/substrate/frame/revive/src/benchmarking/mod.rs
index 593c16cbb2d..40ad3a3aed1 100644
--- a/substrate/frame/revive/src/benchmarking/mod.rs
+++ b/substrate/frame/revive/src/benchmarking/mod.rs
@@ -1516,7 +1516,7 @@ mod benchmarks {
 		let callee_bytes = callee.encode();
 		let callee_len = callee_bytes.len() as u32;
 
-		let value: BalanceOf<T> = t.into();
+		let value: BalanceOf<T> = (1_000_000 * t).into();
 		let value_bytes = Into::<U256>::into(value).encode();
 
 		let deposit: BalanceOf<T> = (u32::MAX - 100).into();
@@ -1591,7 +1591,7 @@ mod benchmarks {
 		let hash_bytes = hash.encode();
 		let hash_len = hash_bytes.len() as u32;
 
-		let value: BalanceOf<T> = 1u32.into();
+		let value: BalanceOf<T> = 1_000_000u32.into();
 		let value_bytes = Into::<U256>::into(value).encode();
 		let value_len = value_bytes.len() as u32;
 
@@ -1645,7 +1645,10 @@ mod benchmarks {
 
 		assert_ok!(result);
 		assert!(ContractInfoOf::<T>::get(&addr).is_some());
-		assert_eq!(T::Currency::balance(&account_id), Pallet::<T>::min_balance() + value);
+		assert_eq!(
+			T::Currency::balance(&account_id),
+			Pallet::<T>::min_balance() + Pallet::<T>::convert_evm_to_native(value.into()).unwrap()
+		);
 		Ok(())
 	}
 
diff --git a/substrate/frame/revive/src/evm/runtime.rs b/substrate/frame/revive/src/evm/runtime.rs
index c27edac9350..21294fdf6ba 100644
--- a/substrate/frame/revive/src/evm/runtime.rs
+++ b/substrate/frame/revive/src/evm/runtime.rs
@@ -313,9 +313,10 @@ pub trait EthExtra {
 			return Err(InvalidTransaction::Call);
 		}
 
-		let value = (value / U256::from(<Self::Config as crate::Config>::NativeToEthRatio::get()))
-			.try_into()
-			.map_err(|_| InvalidTransaction::Call)?;
+		let value = crate::Pallet::<Self::Config>::convert_evm_to_native(value).map_err(|err| {
+			log::debug!(target: LOG_TARGET, "Failed to convert value to native: {err:?}");
+			InvalidTransaction::Call
+		})?;
 
 		let call = if let Some(dest) = to {
 			crate::Call::call::<Self::Config> {
diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs
index 4f90b41b0de..fdb45f045bb 100644
--- a/substrate/frame/revive/src/exec.rs
+++ b/substrate/frame/revive/src/exec.rs
@@ -569,8 +569,8 @@ struct Frame<T: Config> {
 	account_id: T::AccountId,
 	/// The cached in-storage data of the contract.
 	contract_info: CachedContract<T>,
-	/// The amount of balance transferred by the caller as part of the call.
-	value_transferred: BalanceOf<T>,
+	/// The EVM balance transferred by the caller as part of the call.
+	value_transferred: U256,
 	/// Determines whether this is a call or instantiate frame.
 	entry_point: ExportedFunction,
 	/// The gas meter capped to the supplied gas limit.
@@ -757,7 +757,7 @@ where
 		dest: H160,
 		gas_meter: &'a mut GasMeter<T>,
 		storage_meter: &'a mut storage::meter::Meter<T>,
-		value: BalanceOf<T>,
+		value: U256,
 		input_data: Vec<u8>,
 		debug_message: Option<&'a mut DebugBuffer>,
 	) -> ExecResult {
@@ -791,7 +791,7 @@ where
 		executable: E,
 		gas_meter: &'a mut GasMeter<T>,
 		storage_meter: &'a mut storage::meter::Meter<T>,
-		value: BalanceOf<T>,
+		value: U256,
 		input_data: Vec<u8>,
 		salt: Option<&[u8; 32]>,
 		debug_message: Option<&'a mut DebugBuffer>,
@@ -834,7 +834,7 @@ where
 			origin,
 			gas_meter,
 			storage_meter,
-			value,
+			value.into(),
 			debug_message,
 		)
 		.unwrap()
@@ -843,14 +843,14 @@ where
 
 	/// Create a new call stack.
 	///
-	/// Returns `None` when calling a non existant contract. This is not an error case
+	/// Returns `None` when calling a non existent contract. This is not an error case
 	/// since this will result in a value transfer.
 	fn new(
 		args: FrameArgs<T, E>,
 		origin: Origin<T>,
 		gas_meter: &'a mut GasMeter<T>,
 		storage_meter: &'a mut storage::meter::Meter<T>,
-		value: BalanceOf<T>,
+		value: U256,
 		debug_message: Option<&'a mut DebugBuffer>,
 	) -> Result<Option<(Self, E)>, ExecError> {
 		origin.ensure_mapped()?;
@@ -890,7 +890,7 @@ where
 	/// not initialized, yet.
 	fn new_frame<S: storage::meter::State + Default + Debug>(
 		frame_args: FrameArgs<T, E>,
-		value_transferred: BalanceOf<T>,
+		value_transferred: U256,
 		gas_meter: &mut GasMeter<T>,
 		gas_limit: Weight,
 		storage_meter: &mut storage::meter::GenericMeter<T, S>,
@@ -975,7 +975,7 @@ where
 	fn push_frame(
 		&mut self,
 		frame_args: FrameArgs<T, E>,
-		value_transferred: BalanceOf<T>,
+		value_transferred: U256,
 		gas_limit: Weight,
 		deposit_limit: BalanceOf<T>,
 		read_only: bool,
@@ -1282,8 +1282,9 @@ where
 		origin: &Origin<T>,
 		from: &T::AccountId,
 		to: &T::AccountId,
-		value: BalanceOf<T>,
+		value: U256,
 	) -> ExecResult {
+		let value = crate::Pallet::<T>::convert_evm_to_native(value)?;
 		if value.is_zero() {
 			return Ok(Default::default());
 		}
@@ -1311,7 +1312,7 @@ where
 		origin: &Origin<T>,
 		from: &Origin<T>,
 		to: &T::AccountId,
-		value: BalanceOf<T>,
+		value: U256,
 	) -> ExecResult {
 		// If the from address is root there is no account to transfer from, and therefore we can't
 		// take any `value` other than 0.
@@ -1358,7 +1359,11 @@ where
 
 	/// Returns the *free* balance of the supplied AccountId.
 	fn account_balance(&self, who: &T::AccountId) -> U256 {
-		T::Currency::reducible_balance(who, Preservation::Preserve, Fortitude::Polite).into()
+		crate::Pallet::<T>::convert_native_to_evm(T::Currency::reducible_balance(
+			who,
+			Preservation::Preserve,
+			Fortitude::Polite,
+		))
 	}
 
 	/// Certain APIs, e.g. `{set,get}_immutable_data` behave differently depending
@@ -2066,7 +2071,7 @@ mod tests {
 					BOB_ADDR,
 					&mut gas_meter,
 					&mut storage_meter,
-					value,
+					value.into(),
 					vec![],
 					None,
 				),
@@ -2086,7 +2091,7 @@ mod tests {
 			set_balance(&BOB, 0);
 
 			let origin = Origin::from_account_id(ALICE);
-			MockStack::transfer(&origin, &ALICE, &BOB, 55).unwrap();
+			MockStack::transfer(&origin, &ALICE, &BOB, 55u64.into()).unwrap();
 
 			let min_balance = <Test as Config>::Currency::minimum_balance();
 			assert_eq!(get_balance(&ALICE), 45 - min_balance);
@@ -2107,7 +2112,12 @@ mod tests {
 			set_balance(&ALICE, ed * 2);
 			set_balance(&BOB, ed + value);
 
-			assert_ok!(MockStack::transfer(&Origin::from_account_id(ALICE), &BOB, &CHARLIE, value));
+			assert_ok!(MockStack::transfer(
+				&Origin::from_account_id(ALICE),
+				&BOB,
+				&CHARLIE,
+				value.into()
+			));
 			assert_eq!(get_balance(&ALICE), ed);
 			assert_eq!(get_balance(&BOB), ed);
 			assert_eq!(get_balance(&CHARLIE), ed + value);
@@ -2116,7 +2126,7 @@ mod tests {
 			set_balance(&ALICE, ed);
 			set_balance(&BOB, ed + value);
 			assert_err!(
-				MockStack::transfer(&Origin::from_account_id(ALICE), &BOB, &DJANGO, value),
+				MockStack::transfer(&Origin::from_account_id(ALICE), &BOB, &DJANGO, value.into()),
 				<Error<Test>>::TransferFailed
 			);
 
@@ -2124,7 +2134,7 @@ mod tests {
 			set_balance(&ALICE, ed * 2);
 			set_balance(&BOB, value);
 			assert_err!(
-				MockStack::transfer(&Origin::from_account_id(ALICE), &BOB, &EVE, value),
+				MockStack::transfer(&Origin::from_account_id(ALICE), &BOB, &EVE, value.into()),
 				<Error<Test>>::TransferFailed
 			);
 			// The ED transfer would work. But it should only be executed with the actual transfer
@@ -2153,7 +2163,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				value,
+				value.into(),
 				vec![],
 				None,
 			)
@@ -2191,7 +2201,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				value,
+				value.into(),
 				vec![],
 				None,
 			)
@@ -2223,7 +2233,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				55,
+				55u64.into(),
 				vec![],
 				None,
 			)
@@ -2246,7 +2256,7 @@ mod tests {
 		ExtBuilder::default().build().execute_with(|| {
 			set_balance(&from, 0);
 
-			let result = MockStack::transfer(&origin, &from, &dest, 100);
+			let result = MockStack::transfer(&origin, &from, &dest, 100u64.into());
 
 			assert_eq!(result, Err(Error::<Test>::TransferFailed.into()));
 			assert_eq!(get_balance(&from), 0);
@@ -2272,7 +2282,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			);
@@ -2301,7 +2311,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			);
@@ -2330,7 +2340,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![1, 2, 3, 4],
 				None,
 			);
@@ -2365,7 +2375,7 @@ mod tests {
 					executable,
 					&mut gas_meter,
 					&mut storage_meter,
-					min_balance,
+					min_balance.into(),
 					vec![1, 2, 3, 4],
 					Some(&[0; 32]),
 					None,
@@ -2420,7 +2430,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				value,
+				value.into(),
 				vec![],
 				None,
 			);
@@ -2484,7 +2494,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			);
@@ -2549,7 +2559,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			);
@@ -2581,7 +2591,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			);
@@ -2618,7 +2628,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -2644,7 +2654,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -2688,7 +2698,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -2714,7 +2724,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -2740,7 +2750,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				1,
+				1u64.into(),
 				vec![0],
 				None,
 			);
@@ -2784,7 +2794,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -2829,7 +2839,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			);
@@ -2854,7 +2864,7 @@ mod tests {
 					executable,
 					&mut gas_meter,
 					&mut storage_meter,
-					0, // <- zero value
+					U256::zero(), // <- zero value
 					vec![],
 					Some(&[0; 32]),
 					None,
@@ -2889,8 +2899,7 @@ mod tests {
 						executable,
 						&mut gas_meter,
 						&mut storage_meter,
-
-						min_balance,
+						min_balance.into(),
 						vec![],
 						Some(&[0 ;32]),
 						None,
@@ -2945,7 +2954,7 @@ mod tests {
 						&mut gas_meter,
 						&mut storage_meter,
 
-						min_balance,
+						min_balance.into(),
 						vec![],
 						Some(&[0; 32]),
 						None,
@@ -3010,7 +3019,7 @@ mod tests {
 						BOB_ADDR,
 						&mut GasMeter::<Test>::new(GAS_LIMIT),
 						&mut storage_meter,
-						min_balance * 10,
+						(min_balance * 10).into(),
 						vec![],
 						None,
 					),
@@ -3090,7 +3099,7 @@ mod tests {
 						BOB_ADDR,
 						&mut GasMeter::<Test>::new(GAS_LIMIT),
 						&mut storage_meter,
-						0,
+						U256::zero(),
 						vec![],
 						None,
 					),
@@ -3132,7 +3141,7 @@ mod tests {
 						executable,
 						&mut gas_meter,
 						&mut storage_meter,
-						100,
+						100u64.into(),
 						vec![],
 						Some(&[0; 32]),
 						None,
@@ -3197,7 +3206,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -3258,7 +3267,7 @@ mod tests {
 					executable,
 					&mut gas_meter,
 					&mut storage_meter,
-					10,
+					10u64.into(),
 					vec![],
 					Some(&[0; 32]),
 					None,
@@ -3305,7 +3314,7 @@ mod tests {
 					BOB_ADDR,
 					&mut gas_meter,
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					vec![],
 					None,
 				)
@@ -3336,7 +3345,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				Some(&mut debug_buffer),
 			)
@@ -3369,7 +3378,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				Some(&mut debug_buffer),
 			);
@@ -3402,7 +3411,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				Some(&mut debug_buf_after),
 			)
@@ -3435,7 +3444,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				CHARLIE_ADDR.as_bytes().to_vec(),
 				None,
 			));
@@ -3447,7 +3456,7 @@ mod tests {
 					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					BOB_ADDR.as_bytes().to_vec(),
 					None,
 				)
@@ -3497,7 +3506,7 @@ mod tests {
 					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					vec![0],
 					None,
 				)
@@ -3531,7 +3540,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			)
@@ -3615,7 +3624,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			)
@@ -3740,7 +3749,7 @@ mod tests {
 					fail_executable,
 					&mut gas_meter,
 					&mut storage_meter,
-					min_balance * 100,
+					(min_balance * 100).into(),
 					vec![],
 					Some(&[0; 32]),
 					None,
@@ -3753,7 +3762,7 @@ mod tests {
 					success_executable,
 					&mut gas_meter,
 					&mut storage_meter,
-					min_balance * 100,
+					(min_balance * 100).into(),
 					vec![],
 					Some(&[0; 32]),
 					None,
@@ -3765,7 +3774,7 @@ mod tests {
 					succ_fail_executable,
 					&mut gas_meter,
 					&mut storage_meter,
-					min_balance * 200,
+					(min_balance * 200).into(),
 					vec![],
 					Some(&[0; 32]),
 					None,
@@ -3777,7 +3786,7 @@ mod tests {
 					succ_succ_executable,
 					&mut gas_meter,
 					&mut storage_meter,
-					min_balance * 200,
+					(min_balance * 200).into(),
 					vec![],
 					Some(&[0; 32]),
 					None,
@@ -3846,7 +3855,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			));
@@ -3957,7 +3966,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			));
@@ -3996,7 +4005,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			));
@@ -4035,7 +4044,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			));
@@ -4088,7 +4097,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			));
@@ -4144,7 +4153,7 @@ mod tests {
 				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			));
@@ -4219,7 +4228,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			));
@@ -4289,7 +4298,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -4327,7 +4336,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			));
@@ -4389,7 +4398,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -4422,7 +4431,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			);
@@ -4505,7 +4514,7 @@ mod tests {
 					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					vec![],
 					None,
 				)
@@ -4573,7 +4582,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![0],
 				None,
 			);
@@ -4639,7 +4648,7 @@ mod tests {
 				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
-				0,
+				U256::zero(),
 				vec![],
 				None,
 			);
@@ -4690,7 +4699,7 @@ mod tests {
 					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					vec![],
 					None,
 				)
@@ -4761,7 +4770,7 @@ mod tests {
 					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					vec![],
 					None,
 				)
@@ -4807,7 +4816,7 @@ mod tests {
 					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					vec![],
 					None,
 				)
@@ -4851,7 +4860,7 @@ mod tests {
 					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					vec![],
 					None,
 				)
@@ -4906,7 +4915,7 @@ mod tests {
 					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
-					0,
+					U256::zero(),
 					vec![0],
 					None,
 				),
diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs
index 5ca0042d929..caecf07c407 100644
--- a/substrate/frame/revive/src/lib.rs
+++ b/substrate/frame/revive/src/lib.rs
@@ -59,6 +59,7 @@ use frame_support::{
 	pallet_prelude::DispatchClass,
 	traits::{
 		fungible::{Inspect, Mutate, MutateHold},
+		tokens::{Fortitude::Polite, Preservation::Preserve},
 		ConstU32, ConstU64, Contains, EnsureOrigin, Get, IsType, OriginTrait, Time,
 	},
 	weights::{Weight, WeightMeter},
@@ -73,7 +74,7 @@ use pallet_transaction_payment::OnChargeTransaction;
 use scale_info::TypeInfo;
 use sp_core::{H160, H256, U256};
 use sp_runtime::{
-	traits::{BadOrigin, Convert, Dispatchable, Saturating},
+	traits::{BadOrigin, Convert, Dispatchable, Saturating, Zero},
 	DispatchError,
 };
 
@@ -379,7 +380,7 @@ pub mod pallet {
 			type RuntimeMemory = ConstU32<{ 128 * 1024 * 1024 }>;
 			type PVFMemory = ConstU32<{ 512 * 1024 * 1024 }>;
 			type ChainId = ConstU64<0>;
-			type NativeToEthRatio = ConstU32<1_000_000>;
+			type NativeToEthRatio = ConstU32<1>;
 		}
 	}
 
@@ -561,6 +562,8 @@ pub mod pallet {
 		ExecutionFailed,
 		/// Failed to convert a U256 to a Balance.
 		BalanceConversionFailed,
+		/// Failed to convert an EVM balance to a native balance.
+		DecimalPrecisionLoss,
 		/// Immutable data can only be set during deploys and only be read during calls.
 		/// Additionally, it is only valid to set the data once and it must not be empty.
 		InvalidImmutableAccess,
@@ -1115,7 +1118,7 @@ where
 				dest,
 				&mut gas_meter,
 				&mut storage_meter,
-				value,
+				Self::convert_native_to_evm(value),
 				data,
 				debug_message.as_mut(),
 			)?;
@@ -1180,7 +1183,7 @@ where
 				executable,
 				&mut gas_meter,
 				&mut storage_meter,
-				value,
+				Self::convert_native_to_evm(value),
 				data,
 				salt.as_ref(),
 				debug_message.as_mut(),
@@ -1214,7 +1217,7 @@ where
 	///
 	/// - `origin`: The origin of the call.
 	/// - `dest`: The destination address of the call.
-	/// - `value`: The value to transfer.
+	/// - `value`: The EVM value to transfer.
 	/// - `input`: The input data.
 	/// - `gas_limit`: The gas limit enforced during contract execution.
 	/// - `storage_deposit_limit`: The maximum balance that can be charged to the caller for storage
@@ -1226,7 +1229,7 @@ where
 	pub fn bare_eth_transact(
 		origin: T::AccountId,
 		dest: Option<H160>,
-		value: BalanceOf<T>,
+		value: U256,
 		input: Vec<u8>,
 		gas_limit: Weight,
 		storage_deposit_limit: BalanceOf<T>,
@@ -1250,6 +1253,18 @@ where
 		// Get the nonce to encode in the tx.
 		let nonce: T::Nonce = <System<T>>::account_nonce(&origin);
 
+		// Convert the value to the native balance type.
+		let native_value = match Self::convert_evm_to_native(value) {
+			Ok(v) => v,
+			Err(err) =>
+				return EthContractResult {
+					gas_required: Default::default(),
+					storage_deposit: Default::default(),
+					fee: Default::default(),
+					result: Err(err.into()),
+				},
+		};
+
 		// Dry run the call
 		let (mut result, dispatch_info) = match dest {
 			// A contract call.
@@ -1258,13 +1273,14 @@ where
 				let result = crate::Pallet::<T>::bare_call(
 					T::RuntimeOrigin::signed(origin),
 					dest,
-					value,
+					native_value,
 					gas_limit,
 					storage_deposit_limit,
 					input.clone(),
 					debug,
 					collect_events,
 				);
+
 				let result = EthContractResult {
 					gas_required: result.gas_required,
 					storage_deposit: result.storage_deposit.charge_or_zero(),
@@ -1274,7 +1290,7 @@ where
 				// Get the dispatch info of the call.
 				let dispatch_call: <T as Config>::RuntimeCall = crate::Call::<T>::call {
 					dest,
-					value,
+					value: native_value,
 					gas_limit: result.gas_required,
 					storage_deposit_limit: result.storage_deposit,
 					data: input.clone(),
@@ -1300,7 +1316,7 @@ where
 				// Dry run the call.
 				let result = crate::Pallet::<T>::bare_instantiate(
 					T::RuntimeOrigin::signed(origin),
-					value,
+					native_value,
 					gas_limit,
 					storage_deposit_limit,
 					Code::Upload(code.to_vec()),
@@ -1320,7 +1336,7 @@ where
 				// Get the dispatch info of the call.
 				let dispatch_call: <T as Config>::RuntimeCall =
 					crate::Call::<T>::instantiate_with_code {
-						value,
+						value: native_value,
 						gas_limit: result.gas_required,
 						storage_deposit_limit: result.storage_deposit,
 						code: code.to_vec(),
@@ -1333,7 +1349,7 @@ where
 		};
 
 		let mut tx = TransactionLegacyUnsigned {
-			value: value.into().saturating_mul(T::NativeToEthRatio::get().into()),
+			value,
 			input: input.into(),
 			nonce: nonce.into(),
 			chain_id: Some(T::ChainId::get().into()),
@@ -1372,6 +1388,12 @@ where
 		result
 	}
 
+	/// Get the balance with EVM decimals of the given `address`.
+	pub fn evm_balance(address: &H160) -> U256 {
+		let account = T::AddressMapper::to_account_id(&address);
+		Self::convert_native_to_evm(T::Currency::reducible_balance(&account, Preserve, Polite))
+	}
+
 	/// A generalized version of [`Self::upload_code`].
 	///
 	/// It is identical to [`Self::upload_code`] and only differs in the information it returns.
@@ -1424,6 +1446,25 @@ where
 				.and_then(|r| r)
 		})
 	}
+
+	/// Convert a native balance to EVM balance.
+	fn convert_native_to_evm(value: BalanceOf<T>) -> U256 {
+		value.into().saturating_mul(T::NativeToEthRatio::get().into())
+	}
+
+	/// Convert an EVM balance to a native balance.
+	fn convert_evm_to_native(value: U256) -> Result<BalanceOf<T>, Error<T>> {
+		if value.is_zero() {
+			return Ok(Zero::zero())
+		}
+		let ratio = T::NativeToEthRatio::get().into();
+		let res = value.checked_div(ratio).expect("divisor is non-zero; qed");
+		if res.saturating_mul(ratio) == value {
+			res.try_into().map_err(|_| Error::<T>::BalanceConversionFailed)
+		} else {
+			Err(Error::<T>::DecimalPrecisionLoss)
+		}
+	}
 }
 
 impl<T: Config> Pallet<T> {
@@ -1451,8 +1492,8 @@ sp_api::decl_runtime_apis! {
 		BlockNumber: Codec,
 		EventRecord: Codec,
 	{
-		/// Returns the free balance of the given `[H160]` address.
-		fn balance(address: H160) -> Balance;
+		/// Returns the free balance of the given `[H160]` address, using EVM decimals.
+		fn balance(address: H160) -> U256;
 
 		/// Returns the nonce of the given `[H160]` address.
 		fn nonce(address: H160) -> Nonce;
@@ -1489,7 +1530,7 @@ sp_api::decl_runtime_apis! {
 		fn eth_transact(
 			origin: H160,
 			dest: Option<H160>,
-			value: Balance,
+			value: U256,
 			input: Vec<u8>,
 			gas_limit: Option<Weight>,
 			storage_deposit_limit: Option<Balance>,
-- 
GitLab