From 9c54d96f4ccfe03dac71a89c7bc59cf3e20333b4 Mon Sep 17 00:00:00 2001 From: vpanchal-supra Date: Tue, 11 Nov 2025 20:37:56 +0530 Subject: [PATCH 1/7] [WIP] --- Cargo.lock | 73 +- .../src/aptos_framework_sdk_builder.rs | 222 ++ .../framework/supra-framework/doc/genesis.md | 48 +- .../doc/microchain_registry.md | 953 +++++ .../framework/supra-framework/doc/overview.md | 1 + .../supra-framework/sources/genesis.move | 39 +- .../sources/microchain_registry.move | 314 ++ .../sources/microchain_registry.spec.move | 5 + .../tests/microchain_registry_tests.move | 301 ++ aptos-move/vm-genesis/src/lib.rs | 25 +- .../evm/hardhat-examples/package-lock.json | 3334 ++++++++++++++--- .../on_chain_config/microchain_registry.rs | 47 + types/src/on_chain_config/mod.rs | 9 +- 13 files changed, 4717 insertions(+), 654 deletions(-) create mode 100644 aptos-move/framework/supra-framework/doc/microchain_registry.md create mode 100644 aptos-move/framework/supra-framework/sources/microchain_registry.move create mode 100644 aptos-move/framework/supra-framework/sources/microchain_registry.spec.move create mode 100644 aptos-move/framework/supra-framework/tests/microchain_registry_tests.move create mode 100644 types/src/on_chain_config/microchain_registry.rs diff --git a/Cargo.lock b/Cargo.lock index 8e4aa24a6aadb..41e7b96d4edfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5923,7 +5923,7 @@ dependencies = [ "bitflags 1.3.2", "strsim 0.8.0", "textwrap 0.11.0", - "unicode-width 0.1.11", + "unicode-width", "vec_map", ] @@ -6076,7 +6076,7 @@ checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "serde", "termcolor", - "unicode-width 0.1.11", + "unicode-width", ] [[package]] @@ -6146,7 +6146,7 @@ dependencies = [ "encode_unicode 0.3.6", "lazy_static", "libc", - "unicode-width 0.1.11", + "unicode-width", "windows-sys 0.45.0", ] @@ -6651,15 +6651,16 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", + "platforms", "rustc_version", "subtle", "zeroize", @@ -7350,7 +7351,7 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.3", + "curve25519-dalek 4.1.2", "ed25519 2.2.3", "serde", "sha2 0.10.8", @@ -7837,9 +7838,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" [[package]] name = "field_count" @@ -9283,15 +9284,15 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.11" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" dependencies = [ "console", + "instant", "number_prefix 0.4.0", "portable-atomic", - "unicode-width 0.2.0", - "web-time", + "unicode-width", ] [[package]] @@ -11835,7 +11836,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" dependencies = [ - "unicode-width 0.1.11", + "unicode-width", ] [[package]] @@ -12332,6 +12333,12 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + [[package]] name = "plotters" version = "0.3.5" @@ -12533,9 +12540,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" [[package]] name = "poseidon-ark" @@ -12699,7 +12706,7 @@ dependencies = [ "is-terminal", "lazy_static", "term", - "unicode-width 0.1.11", + "unicode-width", ] [[package]] @@ -14018,9 +14025,9 @@ dependencies = [ [[package]] name = "self-replace" -version = "1.4.0" +version = "1.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7828a58998685d8bf5a3c5e7a3379a5867289c20828c3ee436280b44b598515" +checksum = "525db198616b2bcd0f245daf7bfd8130222f7ee6af9ff9984c19a61bf1160c55" dependencies = [ "fastrand 1.9.0", "tempfile", @@ -14033,7 +14040,7 @@ version = "0.39.0" source = "git+https://github.com/banool/self_update.git?rev=8306158ad0fd5b9d4766a3c6bf967e7ef0ea5c4b#8306158ad0fd5b9d4766a3c6bf967e7ef0ea5c4b" dependencies = [ "hyper", - "indicatif 0.17.11", + "indicatif 0.17.7", "log", "quick-xml 0.23.1", "regex", @@ -15226,7 +15233,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width 0.1.11", + "unicode-width", ] [[package]] @@ -15236,7 +15243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd05616119e612a8041ef58f2b578906cc2531a6069047ae092cfb86a325d835" dependencies = [ "smawk", - "unicode-width 0.1.11", + "unicode-width", ] [[package]] @@ -15247,7 +15254,7 @@ checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" dependencies = [ "smawk", "unicode-linebreak", - "unicode-width 0.1.11", + "unicode-width", ] [[package]] @@ -15913,7 +15920,7 @@ dependencies = [ "cassowary", "crossterm 0.25.0", "unicode-segmentation", - "unicode-width 0.1.11", + "unicode-width", ] [[package]] @@ -16130,12 +16137,6 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" -[[package]] -name = "unicode-width" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" - [[package]] name = "unicode-xid" version = "0.2.4" @@ -16492,16 +16493,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "webpki" version = "0.22.4" @@ -16982,9 +16973,9 @@ dependencies = [ [[package]] name = "zipsign-api" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6413a546ada9dbcd0b9a3e0b0880581279e35047bce9797e523b3408e1df607c" +checksum = "2ba5aa1827d6b1a35a29b3413ec69ce5f796e4d897e3e5b38f461bef41d225ea" dependencies = [ "ed25519-dalek 2.1.1", "thiserror", diff --git a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs index 345dc79fcdeb5..227490988b2e4 100644 --- a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs +++ b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs @@ -328,6 +328,34 @@ pub enum EntryFunctionCall { coin_type: TypeTag, }, + /// Adds a reserved chain ID range. + MicrochainRegistryAddReservedRange { + start: u8, + end: u8, + }, + + /// Deactivates the already registered microchain. + MicrochainRegistryDeactivateMicrochain { + chain_id: u8, + }, + + /// Reactivates the deactivated microchain. + MicrochainRegistryReactivateMicrochain { + chain_id: u8, + }, + + /// Registeres a new microchain. + MicrochainRegistryRegisterMicrochain { + chain_id: u8, + metadata_link: Vec, + }, + + /// Updates metadata link of a registered microchain. + MicrochainRegistryUpdateMicrochainMetadataLink { + chain_id: u8, + new_metadata_link: Vec, + }, + /// Similar to add_owners, but only allow adding one owner. MultisigAccountAddOwner { new_owner: AccountAddress, @@ -1433,6 +1461,23 @@ impl EntryFunctionCall { amount, } => managed_coin_mint(coin_type, dst_addr, amount), ManagedCoinRegister { coin_type } => managed_coin_register(coin_type), + MicrochainRegistryAddReservedRange { start, end } => { + microchain_registry_add_reserved_range(start, end) + }, + MicrochainRegistryDeactivateMicrochain { chain_id } => { + microchain_registry_deactivate_microchain(chain_id) + }, + MicrochainRegistryReactivateMicrochain { chain_id } => { + microchain_registry_reactivate_microchain(chain_id) + }, + MicrochainRegistryRegisterMicrochain { + chain_id, + metadata_link, + } => microchain_registry_register_microchain(chain_id, metadata_link), + MicrochainRegistryUpdateMicrochainMetadataLink { + chain_id, + new_metadata_link, + } => microchain_registry_update_microchain_metadata_link(chain_id, new_metadata_link), MultisigAccountAddOwner { new_owner } => multisig_account_add_owner(new_owner), MultisigAccountAddOwners { new_owners } => multisig_account_add_owners(new_owners), MultisigAccountAddOwnersAndUpdateSignaturesRequired { @@ -2825,6 +2870,98 @@ pub fn managed_coin_register(coin_type: TypeTag) -> TransactionPayload { )) } +/// Adds a reserved chain ID range. +pub fn microchain_registry_add_reserved_range(start: u8, end: u8) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ]), + ident_str!("microchain_registry").to_owned(), + ), + ident_str!("add_reserved_range").to_owned(), + vec![], + vec![bcs::to_bytes(&start).unwrap(), bcs::to_bytes(&end).unwrap()], + )) +} + +/// Deactivates the already registered microchain. +pub fn microchain_registry_deactivate_microchain(chain_id: u8) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ]), + ident_str!("microchain_registry").to_owned(), + ), + ident_str!("deactivate_microchain").to_owned(), + vec![], + vec![bcs::to_bytes(&chain_id).unwrap()], + )) +} + +/// Reactivates the deactivated microchain. +pub fn microchain_registry_reactivate_microchain(chain_id: u8) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ]), + ident_str!("microchain_registry").to_owned(), + ), + ident_str!("reactivate_microchain").to_owned(), + vec![], + vec![bcs::to_bytes(&chain_id).unwrap()], + )) +} + +/// Registeres a new microchain. +pub fn microchain_registry_register_microchain( + chain_id: u8, + metadata_link: Vec, +) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ]), + ident_str!("microchain_registry").to_owned(), + ), + ident_str!("register_microchain").to_owned(), + vec![], + vec![ + bcs::to_bytes(&chain_id).unwrap(), + bcs::to_bytes(&metadata_link).unwrap(), + ], + )) +} + +/// Updates metadata link of a registered microchain. +pub fn microchain_registry_update_microchain_metadata_link( + chain_id: u8, + new_metadata_link: Vec, +) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ]), + ident_str!("microchain_registry").to_owned(), + ), + ident_str!("update_microchain_metadata_link").to_owned(), + vec![], + vec![ + bcs::to_bytes(&chain_id).unwrap(), + bcs::to_bytes(&new_metadata_link).unwrap(), + ], + )) +} + /// Similar to add_owners, but only allow adding one owner. pub fn multisig_account_add_owner(new_owner: AccountAddress) -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( @@ -6023,6 +6160,71 @@ mod decoder { } } + pub fn microchain_registry_add_reserved_range( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::MicrochainRegistryAddReservedRange { + start: bcs::from_bytes(script.args().get(0)?).ok()?, + end: bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } + } + + pub fn microchain_registry_deactivate_microchain( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::MicrochainRegistryDeactivateMicrochain { + chain_id: bcs::from_bytes(script.args().get(0)?).ok()?, + }) + } else { + None + } + } + + pub fn microchain_registry_reactivate_microchain( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::MicrochainRegistryReactivateMicrochain { + chain_id: bcs::from_bytes(script.args().get(0)?).ok()?, + }) + } else { + None + } + } + + pub fn microchain_registry_register_microchain( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::MicrochainRegistryRegisterMicrochain { + chain_id: bcs::from_bytes(script.args().get(0)?).ok()?, + metadata_link: bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } + } + + pub fn microchain_registry_update_microchain_metadata_link( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some( + EntryFunctionCall::MicrochainRegistryUpdateMicrochainMetadataLink { + chain_id: bcs::from_bytes(script.args().get(0)?).ok()?, + new_metadata_link: bcs::from_bytes(script.args().get(1)?).ok()?, + }, + ) + } else { + None + } + } + pub fn multisig_account_add_owner(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { Some(EntryFunctionCall::MultisigAccountAddOwner { @@ -7806,6 +8008,26 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazyuse 0x1::features; use 0x1::fixed_point32; use 0x1::gas_schedule; +use 0x1::microchain_registry; use 0x1::multisig_account; use 0x1::option; use 0x1::pbo_delegation_pool; @@ -705,8 +707,7 @@ Deprecated in favoor of initialize_supra_native_automation_v2. _congestion_base_fee_in_quants_per_sec: u64, _congestion_exponent: u8, _task_capacity: u16, -) { -} +) {} @@ -764,6 +765,42 @@ Genesis step 3: Initialize Supra Native Automation. + + + + +## Function `initialize_microchain_registry` + +Genesis step 4: Initialize Microchain Registry. + +This method allows to initialize the microchain registry either during the genesis initialization +or after it has been completed. + +Because it is publicly accessible, it can be invoked via a move-script. Since it requires +the supra_framework as the signer, the invocation must go through the governance process. + + +
public fun initialize_microchain_registry(supra_framework: &signer, reserved_ranges: vector<microchain_registry::ReservedRange>)
+
+ + + +
+Implementation + + +
public fun initialize_microchain_registry(
+    supra_framework: &signer,
+    reserved_ranges: vector<ReservedRange>
+) {
+    microchain_registry::initialize(
+        supra_framework, reserved_ranges
+    )
+}
+
+ + +
@@ -1550,7 +1587,7 @@ The last step of genesis.
#[verify_only]
-fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, evm_genesis_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
+fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, _evm_genesis_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
 
@@ -1566,7 +1603,7 @@ The last step of genesis. consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, - evm_genesis_config: vector<u8>, + _evm_genesis_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, @@ -1603,7 +1640,6 @@ The last step of genesis. rewards_rate_denominator, voting_power_increase_limit, 0, - ); features::change_feature_flags_for_verification(supra_framework, vector[1, 2, 11], vector[]); initialize_supra_coin(supra_framework); @@ -1961,7 +1997,7 @@ The last step of genesis.
#[verify_only]
-fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, evm_genesis_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
+fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, _evm_genesis_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
 
diff --git a/aptos-move/framework/supra-framework/doc/microchain_registry.md b/aptos-move/framework/supra-framework/doc/microchain_registry.md new file mode 100644 index 0000000000000..4b9ba4404dab1 --- /dev/null +++ b/aptos-move/framework/supra-framework/doc/microchain_registry.md @@ -0,0 +1,953 @@ + + + +# Module `0x1::microchain_registry` + +Copyright (c) 2025 Supra +Microchain Registry Module +This module manages the registration and lifecycle of microchains on the Supra-L1. + + +- [Struct `ReservedRange`](#0x1_microchain_registry_ReservedRange) +- [Struct `MicrochainInfo`](#0x1_microchain_registry_MicrochainInfo) +- [Resource `MicrochainRegistry`](#0x1_microchain_registry_MicrochainRegistry) +- [Struct `MicrochainRegistered`](#0x1_microchain_registry_MicrochainRegistered) +- [Struct `MicrochainDeactivated`](#0x1_microchain_registry_MicrochainDeactivated) +- [Struct `MicrochainReactivated`](#0x1_microchain_registry_MicrochainReactivated) +- [Struct `MicrochainMetadataLinkUpdated`](#0x1_microchain_registry_MicrochainMetadataLinkUpdated) +- [Constants](#@Constants_0) +- [Function `initialize`](#0x1_microchain_registry_initialize) +- [Function `register_microchain`](#0x1_microchain_registry_register_microchain) +- [Function `deactivate_microchain`](#0x1_microchain_registry_deactivate_microchain) +- [Function `reactivate_microchain`](#0x1_microchain_registry_reactivate_microchain) +- [Function `update_microchain_metadata_link`](#0x1_microchain_registry_update_microchain_metadata_link) +- [Function `add_reserved_range`](#0x1_microchain_registry_add_reserved_range) +- [Function `new_reserved_range`](#0x1_microchain_registry_new_reserved_range) +- [Function `microchain_state`](#0x1_microchain_registry_microchain_state) +- [Function `is_microchain_active`](#0x1_microchain_registry_is_microchain_active) +- [Function `active_microchains`](#0x1_microchain_registry_active_microchains) +- [Function `microchain_metadata_link`](#0x1_microchain_registry_microchain_metadata_link) +- [Function `microchain_info`](#0x1_microchain_registry_microchain_info) +- [Function `is_chain_id_reserved`](#0x1_microchain_registry_is_chain_id_reserved) +- [Function `borrow_global_microchain_registry`](#0x1_microchain_registry_borrow_global_microchain_registry) +- [Function `borrow_global_mut_microchain_registry`](#0x1_microchain_registry_borrow_global_mut_microchain_registry) +- [Function `assert_microchain_registered`](#0x1_microchain_registry_assert_microchain_registered) +- [Function `is_chain_id_reserved_internal`](#0x1_microchain_registry_is_chain_id_reserved_internal) +- [Specification](#@Specification_1) + + +
use 0x1::error;
+use 0x1::event;
+use 0x1::simple_map;
+use 0x1::string;
+use 0x1::system_addresses;
+
+ + + + + +## Struct `ReservedRange` + +Represents reserved chain ID range. + + +
struct ReservedRange has copy, drop, store
+
+ + + +
+Fields + + +
+
+start: u8 +
+
+ +
+
+end: u8 +
+
+ +
+
+ + +
+ + + +## Struct `MicrochainInfo` + +Represents information about the registered microchain. + + +
struct MicrochainInfo has copy, drop, store
+
+ + + +
+Fields + + +
+
+state: u8 +
+
+ +
+
+metadata_link: string::String +
+
+ +
+
+ + +
+ + + +## Resource `MicrochainRegistry` + +Global microchain registry resource. + + +
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
+struct MicrochainRegistry has key
+
+ + + +
+Fields + + +
+
+microchains: simple_map::SimpleMap<u8, microchain_registry::MicrochainInfo> +
+
+ Map from chain ID to microchain info. +
+
+reserved_ranges: vector<microchain_registry::ReservedRange> +
+
+ Reserved chain ID ranges. +
+
+ + +
+ + + +## Struct `MicrochainRegistered` + + + +
#[event]
+struct MicrochainRegistered has drop, store
+
+ + + +
+Fields + + +
+
+chain_id: u8 +
+
+ +
+
+metadata_link: string::String +
+
+ +
+
+ + +
+ + + +## Struct `MicrochainDeactivated` + + + +
#[event]
+struct MicrochainDeactivated has drop, store
+
+ + + +
+Fields + + +
+
+chain_id: u8 +
+
+ +
+
+ + +
+ + + +## Struct `MicrochainReactivated` + + + +
#[event]
+struct MicrochainReactivated has drop, store
+
+ + + +
+Fields + + +
+
+chain_id: u8 +
+
+ +
+
+ + +
+ + + +## Struct `MicrochainMetadataLinkUpdated` + + + +
#[event]
+struct MicrochainMetadataLinkUpdated has drop, store
+
+ + + +
+Fields + + +
+
+chain_id: u8 +
+
+ +
+
+old_metadata_link: string::String +
+
+ +
+
+new_metadata_link: string::String +
+
+ +
+
+ + +
+ + + +## Constants + + + + +The provided range is invalid, start value must be less than or equal to end value. + + +
const EINVALID_RANGE: u64 = 7;
+
+ + + + + +The chain ID falls within a reserved range and cannot be used for registration. + + +
const ECHAIN_ID_RESERVED: u64 = 3;
+
+ + + + + +The microchain is already in the ACTIVE state and connot be reactivated. + + +
const EMICROCHAIN_ALREADY_ACTIVE: u64 = 5;
+
+ + + + + +The microchain is already in the INACTIVE state and cannot be deactivated again. + + +
const EMICROCHAIN_ALREADY_DEACTIVATED: u64 = 4;
+
+ + + + + +The microchain with the given chain ID is already registered in the microchain registry. + + +
const EMICROCHAIN_ALREADY_REGISTERED: u64 = 1;
+
+ + + + + +The microchain with the given chain ID is not found in the microchain registry. + + +
const EMICROCHAIN_NOT_REGISTERED: u64 = 2;
+
+ + + + + +The MicrochainRegistry resource has not been initialized at @supra_framework. + + +
const EREGISTRY_NOT_INITIALIZED: u64 = 6;
+
+ + + + + +Registered as a microchain and actively working. + + +
const STATE_ACTIVE: u8 = 1;
+
+ + + + + +Registered as a microchain, but decommissioned from the Supra-L1. + + +
const STATE_INACTIVE: u8 = 2;
+
+ + + + + +Never registered as a mirochain. + + +
const STATE_UNKNOWN: u8 = 0;
+
+ + + + + +## Function `initialize` + +Initializes the microchain registry. + + +
public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector<microchain_registry::ReservedRange>)
+
+ + + +
+Implementation + + +
public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector<ReservedRange>) {
+    system_addresses::assert_supra_framework(supra_framework);
+
+    move_to(supra_framework, MicrochainRegistry {
+        microchains: simple_map::new(),
+        reserved_ranges,
+    });
+}
+
+ + + +
+ + + +## Function `register_microchain` + +Registeres a new microchain. + + +
public entry fun register_microchain(supra_framework: &signer, chain_id: u8, metadata_link: string::String)
+
+ + + +
+Implementation + + +
public entry fun register_microchain(
+    supra_framework: &signer,
+    chain_id: u8,
+    metadata_link: String,
+) acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
+
+    // Checks if given chain ID is reserved.
+    assert!(
+        !is_chain_id_reserved_internal(chain_id, &microchain_registry.reserved_ranges),
+        error::invalid_argument(ECHAIN_ID_RESERVED)
+    );
+    // Checks if a microchain is already registered.
+    assert!(
+        !simple_map::contains_key(&microchain_registry.microchains, &chain_id),
+        error::already_exists(EMICROCHAIN_ALREADY_REGISTERED)
+    );
+
+    let microchain_info = MicrochainInfo {
+        state: STATE_ACTIVE,
+        metadata_link,
+    };
+    simple_map::add(&mut microchain_registry.microchains, chain_id, microchain_info);
+
+    event::emit(MicrochainRegistered {
+        chain_id,
+        metadata_link,
+    });
+}
+
+ + + +
+ + + +## Function `deactivate_microchain` + +Deactivates the already registered microchain. + + +
public entry fun deactivate_microchain(supra_framework: &signer, chain_id: u8)
+
+ + + +
+Implementation + + +
public entry fun deactivate_microchain(
+    supra_framework: &signer,
+    chain_id: u8,
+) acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
+    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
+
+    let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id);
+    assert!(microchain_infp.state == STATE_ACTIVE, error::invalid_state(EMICROCHAIN_ALREADY_DEACTIVATED));
+
+    microchain_infp.state = STATE_INACTIVE;
+
+    event::emit(MicrochainDeactivated {
+        chain_id,
+    });
+}
+
+ + + +
+ + + +## Function `reactivate_microchain` + +Reactivates the deactivated microchain. + + +
public entry fun reactivate_microchain(supra_framework: &signer, chain_id: u8)
+
+ + + +
+Implementation + + +
public entry fun reactivate_microchain(
+    supra_framework: &signer,
+    chain_id: u8,
+) acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
+    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
+
+    let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id);
+    assert!(microchain_infp.state == STATE_INACTIVE, error::invalid_state(EMICROCHAIN_ALREADY_ACTIVE));
+
+    microchain_infp.state = STATE_ACTIVE;
+
+    event::emit(MicrochainReactivated {
+        chain_id,
+    });
+}
+
+ + + +
+ + + +## Function `update_microchain_metadata_link` + +Updates metadata link of a registered microchain. + + +
public entry fun update_microchain_metadata_link(supra_framework: &signer, chain_id: u8, new_metadata_link: string::String)
+
+ + + +
+Implementation + + +
public entry fun update_microchain_metadata_link(
+    supra_framework: &signer,
+    chain_id: u8,
+    new_metadata_link: String,
+) acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
+    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
+
+    let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id);
+    let old_metadata_link = microchain_infp.metadata_link;
+    microchain_infp.metadata_link = new_metadata_link;
+
+    event::emit(MicrochainMetadataLinkUpdated {
+        chain_id,
+        old_metadata_link,
+        new_metadata_link,
+    });
+}
+
+ + + +
+ + + +## Function `add_reserved_range` + +Adds a reserved chain ID range. + + +
public entry fun add_reserved_range(supra_framework: &signer, start: u8, end: u8)
+
+ + + +
+Implementation + + +
public entry fun add_reserved_range(
+    supra_framework: &signer,
+    start: u8,
+    end: u8,
+) acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
+    assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
+
+    vector::push_back(&mut microchain_registry.reserved_ranges, ReservedRange { start, end });
+}
+
+ + + +
+ + + +## Function `new_reserved_range` + +Constructor to create an instance of the ReservedRange. +This will be utilsed in move-script to initialize the microchain registry with reserved ranges. + + +
public fun new_reserved_range(start: u8, end: u8): microchain_registry::ReservedRange
+
+ + + +
+Implementation + + +
public fun new_reserved_range(
+    start: u8,
+    end: u8,
+): ReservedRange {
+    assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
+    ReservedRange { start, end }
+}
+
+ + + +
+ + + +## Function `microchain_state` + +Get the state of a microchain. + + +
#[view]
+public fun microchain_state(chain_id: u8): u8
+
+ + + +
+Implementation + + +
public fun microchain_state(chain_id: u8): u8 acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_microchain_registry();
+    if (simple_map::contains_key(&microchain_registry.microchains, &chain_id)) {
+        return simple_map::borrow(&microchain_registry.microchains, &chain_id).state;
+    };
+
+    STATE_UNKNOWN
+}
+
+ + + +
+ + + +## Function `is_microchain_active` + +Check if a microchain is active. + + +
#[view]
+public fun is_microchain_active(chain_id: u8): bool
+
+ + + +
+Implementation + + +
public fun is_microchain_active(chain_id: u8): bool acquires MicrochainRegistry {
+    microchain_state(chain_id) == STATE_ACTIVE
+}
+
+ + + +
+ + + +## Function `active_microchains` + +Get chain IDs of all mirochains with Active state. + + +
#[view]
+public fun active_microchains(): vector<u8>
+
+ + + +
+Implementation + + +
public fun active_microchains(): vector<u8> acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_microchain_registry();
+    let microchains_chain_id = simple_map::keys(&microchain_registry.microchains);
+    let microchains_info = simple_map::values(&microchain_registry.microchains);
+    let active_microchains_chain_id = vector::empty<u8>();
+    vector::zip_reverse<u8, MicrochainInfo>(microchains_chain_id, microchains_info, |chain_id, microchain_info|{
+        // New helper variable with explicit type annotation is required due to Move's lambda type inference
+        // limitations. When I don't use this new variable with explicit type declaration, compiler throws error
+        // and ask to infer the type.
+        let info: MicrochainInfo = microchain_info;
+        if (info.state == STATE_ACTIVE) {
+            vector::push_back(&mut active_microchains_chain_id, chain_id);
+        }
+    });
+    active_microchains_chain_id
+}
+
+ + + +
+ + + +## Function `microchain_metadata_link` + +Get microchain metadata link. + + +
#[view]
+public fun microchain_metadata_link(chain_id: u8): string::String
+
+ + + +
+Implementation + + +
public fun microchain_metadata_link(chain_id: u8): String acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_microchain_registry();
+    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
+
+    simple_map::borrow(&microchain_registry.microchains, &chain_id).metadata_link
+}
+
+ + + +
+ + + +## Function `microchain_info` + +Get microchain info. + + +
#[view]
+public fun microchain_info(chain_id: u8): (u8, string::String)
+
+ + + +
+Implementation + + +
public fun microchain_info(chain_id: u8): (u8, String) acquires MicrochainRegistry {
+    let microchain_registry = borrow_global_microchain_registry();
+    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
+
+    let microchain = simple_map::borrow(&microchain_registry.microchains, &chain_id);
+    (microchain.state, microchain.metadata_link)
+}
+
+ + + +
+ + + +## Function `is_chain_id_reserved` + +Check if a chain ID falls within reserved ranges. + + +
#[view]
+public fun is_chain_id_reserved(chain_id: u8): bool
+
+ + + +
+Implementation + + +
public fun is_chain_id_reserved(chain_id: u8): bool acquires MicrochainRegistry {
+    is_chain_id_reserved_internal(chain_id, &borrow_global_microchain_registry().reserved_ranges)
+}
+
+ + + +
+ + + +## Function `borrow_global_microchain_registry` + + + +
fun borrow_global_microchain_registry(): &microchain_registry::MicrochainRegistry
+
+ + + +
+Implementation + + +
inline fun borrow_global_microchain_registry(): &MicrochainRegistry acquires MicrochainRegistry {
+    assert!(exists<MicrochainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
+    borrow_global<MicrochainRegistry>(@supra_framework)
+}
+
+ + + +
+ + + +## Function `borrow_global_mut_microchain_registry` + + + +
fun borrow_global_mut_microchain_registry(supra_framework: &signer): &mut microchain_registry::MicrochainRegistry
+
+ + + +
+Implementation + + +
inline fun borrow_global_mut_microchain_registry(
+    supra_framework: &signer
+): &mut MicrochainRegistry acquires MicrochainRegistry {
+    system_addresses::assert_supra_framework(supra_framework);
+    assert!(exists<MicrochainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
+    borrow_global_mut<MicrochainRegistry>(@supra_framework)
+}
+
+ + + +
+ + + +## Function `assert_microchain_registered` + + + +
fun assert_microchain_registered(microchains: &simple_map::SimpleMap<u8, microchain_registry::MicrochainInfo>, chain_id: &u8)
+
+ + + +
+Implementation + + +
inline fun assert_microchain_registered(microchains: &SimpleMap<u8, MicrochainInfo>, chain_id: &u8) {
+    assert!(
+        simple_map::contains_key(microchains, chain_id),
+        error::not_found(EMICROCHAIN_NOT_REGISTERED)
+    );
+}
+
+ + + +
+ + + +## Function `is_chain_id_reserved_internal` + + + +
fun is_chain_id_reserved_internal(chain_id: u8, reserved_ranges: &vector<microchain_registry::ReservedRange>): bool
+
+ + + +
+Implementation + + +
fun is_chain_id_reserved_internal(
+    chain_id: u8,
+    reserved_ranges: &vector<ReservedRange>
+): bool {
+    let i = 0;
+    let total_ranges = vector::length(reserved_ranges);
+    while (i < total_ranges) {
+        let range = vector::borrow(reserved_ranges, i);
+        if (chain_id >= range.start && chain_id <= range.end) {
+            return true
+        };
+        i = i + 1;
+    };
+
+    false
+}
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md index 202e9563f6480..5998fa9328fb5 100644 --- a/aptos-move/framework/supra-framework/doc/overview.md +++ b/aptos-move/framework/supra-framework/doc/overview.md @@ -41,6 +41,7 @@ This is the reference documentation of the Supra framework. - [`0x1::jwks`](jwks.md#0x1_jwks) - [`0x1::keyless_account`](keyless_account.md#0x1_keyless_account) - [`0x1::managed_coin`](managed_coin.md#0x1_managed_coin) +- [`0x1::microchain_registry`](microchain_registry.md#0x1_microchain_registry) - [`0x1::multisig_account`](multisig_account.md#0x1_multisig_account) - [`0x1::multisig_voting`](multisig_voting.md#0x1_multisig_voting) - [`0x1::object`](object.md#0x1_object) diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index a13f985ba3823..84d3685457888 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -36,6 +36,7 @@ module supra_framework::genesis { use supra_framework::version; use supra_framework::vesting; use supra_framework::vesting_without_staking; + use supra_framework::microchain_registry::{Self, ReservedRange}; #[test_only] use aptos_std::ed25519; @@ -225,8 +226,7 @@ module supra_framework::genesis { _congestion_base_fee_in_quants_per_sec: u64, _congestion_exponent: u8, _task_capacity: u16, - ) { - } + ) {} /// Genesis step 3: Initialize Supra Native Automation. public fun initialize_supra_native_automation_v2( @@ -261,6 +261,22 @@ module supra_framework::genesis { ) } + /// Genesis step 4: Initialize Microchain Registry. + /// + /// This method allows to initialize the microchain registry either during the genesis initialization + /// or after it has been completed. + /// + /// Because it is publicly accessible, it can be invoked via a move-script. Since it requires + /// the `supra_framework` as the signer, the invocation must go through the governance process. + public fun initialize_microchain_registry( + supra_framework: &signer, + reserved_ranges: vector + ) { + microchain_registry::initialize( + supra_framework, reserved_ranges + ) + } + /// Only called for testnets and e2e tests. fun initialize_core_resources_and_supra_coin( @@ -731,7 +747,7 @@ module supra_framework::genesis { consensus_config: vector, execution_config: vector, supra_config: vector, - evm_genesis_config: vector, + _evm_genesis_config: vector, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, @@ -768,7 +784,6 @@ module supra_framework::genesis { rewards_rate_denominator, voting_power_increase_limit, 0, - ); features::change_feature_flags_for_verification(supra_framework, vector[1, 2, 11], vector[]); initialize_supra_coin(supra_framework); @@ -1159,14 +1174,14 @@ module supra_framework::genesis { let cliff_period_in_seconds = 100; let period_duration_in_seconds = 200; let pool_config = VestingPoolsMap { - admin_address: admin_address, - vpool_locking_percentage: vpool_locking_percentage, - vesting_numerators: vesting_numerators, - vesting_denominator: vesting_denominator, - withdrawal_address: withdrawal_address, - shareholders: shareholders, - cliff_period_in_seconds: cliff_period_in_seconds, - period_duration_in_seconds: period_duration_in_seconds, + admin_address, + vpool_locking_percentage, + vesting_numerators, + vesting_denominator, + withdrawal_address, + shareholders, + cliff_period_in_seconds, + period_duration_in_seconds, }; let vesting_pool_map = vector[pool_config]; create_vesting_without_staking_pools(vesting_pool_map); diff --git a/aptos-move/framework/supra-framework/sources/microchain_registry.move b/aptos-move/framework/supra-framework/sources/microchain_registry.move new file mode 100644 index 0000000000000..66eadb4ac1943 --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/microchain_registry.move @@ -0,0 +1,314 @@ +/// Copyright (c) 2025 Supra +/// Microchain Registry Module +/// This module manages the registration and lifecycle of microchains on the Supra-L1. +module supra_framework::microchain_registry { + use std::error; + use std::string::String; + use std::vector; + + use aptos_std::simple_map::{Self, SimpleMap}; + + use supra_framework::event; + use supra_framework::system_addresses; + + friend supra_framework::genesis; + #[test_only] + friend supra_framework::microchain_registry_tests; + + + /// The microchain with the given chain ID is already registered in the microchain registry. + const EMICROCHAIN_ALREADY_REGISTERED: u64 = 1; + + /// The microchain with the given chain ID is not found in the microchain registry. + const EMICROCHAIN_NOT_REGISTERED: u64 = 2; + + /// The chain ID falls within a reserved range and cannot be used for registration. + const ECHAIN_ID_RESERVED: u64 = 3; + + /// The microchain is already in the `INACTIVE` state and cannot be deactivated again. + const EMICROCHAIN_ALREADY_DEACTIVATED: u64 = 4; + + /// The microchain is already in the `ACTIVE` state and connot be reactivated. + const EMICROCHAIN_ALREADY_ACTIVE: u64 = 5; + + /// The `MicrochainRegistry` resource has not been initialized at @supra_framework. + const EREGISTRY_NOT_INITIALIZED: u64 = 6; + + /// The provided range is invalid, start value must be less than or equal to end value. + const EINVALID_RANGE: u64 = 7; + + + /// Never registered as a mirochain. + const STATE_UNKNOWN: u8 = 0; + /// Registered as a microchain and actively working. + const STATE_ACTIVE: u8 = 1; + /// Registered as a microchain, but decommissioned from the Supra-L1. + const STATE_INACTIVE: u8 = 2; + + + /// Represents reserved chain ID range. + struct ReservedRange has store, copy, drop { + start: u8, + end: u8 + } + + /// Represents information about the registered microchain. + struct MicrochainInfo has store, copy, drop { + state: u8, + metadata_link: String, + } + + #[resource_group_member(group = supra_framework::object::ObjectGroup)] + /// Global microchain registry resource. + struct MicrochainRegistry has key { + /// Map from chain ID to microchain info. + microchains: SimpleMap, + /// Reserved chain ID ranges. + reserved_ranges: vector, + } + + + #[event] + struct MicrochainRegistered has store, drop { + chain_id: u8, + metadata_link: String, + } + + #[event] + struct MicrochainDeactivated has store, drop { + chain_id: u8, + } + + #[event] + struct MicrochainReactivated has store, drop { + chain_id: u8, + } + + #[event] + struct MicrochainMetadataLinkUpdated has store, drop { + chain_id: u8, + old_metadata_link: String, + new_metadata_link: String, + } + + /// Initializes the microchain registry. + public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector) { + system_addresses::assert_supra_framework(supra_framework); + + move_to(supra_framework, MicrochainRegistry { + microchains: simple_map::new(), + reserved_ranges, + }); + } + + /// Registeres a new microchain. + public entry fun register_microchain( + supra_framework: &signer, + chain_id: u8, + metadata_link: String, + ) acquires MicrochainRegistry { + let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); + + // Checks if given chain ID is reserved. + assert!( + !is_chain_id_reserved_internal(chain_id, µchain_registry.reserved_ranges), + error::invalid_argument(ECHAIN_ID_RESERVED) + ); + // Checks if a microchain is already registered. + assert!( + !simple_map::contains_key(µchain_registry.microchains, &chain_id), + error::already_exists(EMICROCHAIN_ALREADY_REGISTERED) + ); + + let microchain_info = MicrochainInfo { + state: STATE_ACTIVE, + metadata_link, + }; + simple_map::add(&mut microchain_registry.microchains, chain_id, microchain_info); + + event::emit(MicrochainRegistered { + chain_id, + metadata_link, + }); + } + + /// Deactivates the already registered microchain. + public entry fun deactivate_microchain( + supra_framework: &signer, + chain_id: u8, + ) acquires MicrochainRegistry { + let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); + assert_microchain_registered(µchain_registry.microchains, &chain_id); + + let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id); + assert!(microchain_infp.state == STATE_ACTIVE, error::invalid_state(EMICROCHAIN_ALREADY_DEACTIVATED)); + + microchain_infp.state = STATE_INACTIVE; + + event::emit(MicrochainDeactivated { + chain_id, + }); + } + + /// Reactivates the deactivated microchain. + public entry fun reactivate_microchain( + supra_framework: &signer, + chain_id: u8, + ) acquires MicrochainRegistry { + let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); + assert_microchain_registered(µchain_registry.microchains, &chain_id); + + let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id); + assert!(microchain_infp.state == STATE_INACTIVE, error::invalid_state(EMICROCHAIN_ALREADY_ACTIVE)); + + microchain_infp.state = STATE_ACTIVE; + + event::emit(MicrochainReactivated { + chain_id, + }); + } + + /// Updates metadata link of a registered microchain. + public entry fun update_microchain_metadata_link( + supra_framework: &signer, + chain_id: u8, + new_metadata_link: String, + ) acquires MicrochainRegistry { + let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); + assert_microchain_registered(µchain_registry.microchains, &chain_id); + + let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id); + let old_metadata_link = microchain_infp.metadata_link; + microchain_infp.metadata_link = new_metadata_link; + + event::emit(MicrochainMetadataLinkUpdated { + chain_id, + old_metadata_link, + new_metadata_link, + }); + } + + /// Adds a reserved chain ID range. + public entry fun add_reserved_range( + supra_framework: &signer, + start: u8, + end: u8, + ) acquires MicrochainRegistry { + let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); + assert!(start <= end, error::invalid_argument(EINVALID_RANGE)); + + vector::push_back(&mut microchain_registry.reserved_ranges, ReservedRange { start, end }); + } + + + /// Constructor to create an instance of the `ReservedRange`. + /// This will be utilsed in move-script to initialize the microchain registry with reserved ranges. + public fun new_reserved_range( + start: u8, + end: u8, + ): ReservedRange { + assert!(start <= end, error::invalid_argument(EINVALID_RANGE)); + ReservedRange { start, end } + } + + + #[view] + /// Get the state of a microchain. + public fun microchain_state(chain_id: u8): u8 acquires MicrochainRegistry { + let microchain_registry = borrow_global_microchain_registry(); + if (simple_map::contains_key(µchain_registry.microchains, &chain_id)) { + return simple_map::borrow(µchain_registry.microchains, &chain_id).state; + }; + + STATE_UNKNOWN + } + + #[view] + /// Check if a microchain is active. + public fun is_microchain_active(chain_id: u8): bool acquires MicrochainRegistry { + microchain_state(chain_id) == STATE_ACTIVE + } + + #[view] + /// Get chain IDs of all mirochains with `Active` state. + public fun active_microchains(): vector acquires MicrochainRegistry { + let microchain_registry = borrow_global_microchain_registry(); + let microchains_chain_id = simple_map::keys(µchain_registry.microchains); + let microchains_info = simple_map::values(µchain_registry.microchains); + let active_microchains_chain_id = vector::empty(); + vector::zip_reverse(microchains_chain_id, microchains_info, |chain_id, microchain_info|{ + // New helper variable with explicit type annotation is required due to Move's lambda type inference + // limitations. When I don't use this new variable with explicit type declaration, compiler throws error + // and ask to infer the type. + let info: MicrochainInfo = microchain_info; + if (info.state == STATE_ACTIVE) { + vector::push_back(&mut active_microchains_chain_id, chain_id); + } + }); + active_microchains_chain_id + } + + #[view] + /// Get microchain metadata link. + public fun microchain_metadata_link(chain_id: u8): String acquires MicrochainRegistry { + let microchain_registry = borrow_global_microchain_registry(); + assert_microchain_registered(µchain_registry.microchains, &chain_id); + + simple_map::borrow(µchain_registry.microchains, &chain_id).metadata_link + } + + #[view] + /// Get microchain info. + public fun microchain_info(chain_id: u8): (u8, String) acquires MicrochainRegistry { + let microchain_registry = borrow_global_microchain_registry(); + assert_microchain_registered(µchain_registry.microchains, &chain_id); + + let microchain = simple_map::borrow(µchain_registry.microchains, &chain_id); + (microchain.state, microchain.metadata_link) + } + + #[view] + /// Check if a chain ID falls within reserved ranges. + public fun is_chain_id_reserved(chain_id: u8): bool acquires MicrochainRegistry { + is_chain_id_reserved_internal(chain_id, &borrow_global_microchain_registry().reserved_ranges) + } + + + inline fun borrow_global_microchain_registry(): &MicrochainRegistry acquires MicrochainRegistry { + assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED)); + borrow_global(@supra_framework) + } + + inline fun borrow_global_mut_microchain_registry( + supra_framework: &signer + ): &mut MicrochainRegistry acquires MicrochainRegistry { + system_addresses::assert_supra_framework(supra_framework); + assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED)); + borrow_global_mut(@supra_framework) + } + + inline fun assert_microchain_registered(microchains: &SimpleMap, chain_id: &u8) { + assert!( + simple_map::contains_key(microchains, chain_id), + error::not_found(EMICROCHAIN_NOT_REGISTERED) + ); + } + + + fun is_chain_id_reserved_internal( + chain_id: u8, + reserved_ranges: &vector + ): bool { + let i = 0; + let total_ranges = vector::length(reserved_ranges); + while (i < total_ranges) { + let range = vector::borrow(reserved_ranges, i); + if (chain_id >= range.start && chain_id <= range.end) { + return true + }; + i = i + 1; + }; + + false + } +} diff --git a/aptos-move/framework/supra-framework/sources/microchain_registry.spec.move b/aptos-move/framework/supra-framework/sources/microchain_registry.spec.move new file mode 100644 index 0000000000000..c592b65d6fa3a --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/microchain_registry.spec.move @@ -0,0 +1,5 @@ +spec supra_framework::microchain_registry { + spec module { + pragma verify = false; + } +} diff --git a/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move b/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move new file mode 100644 index 0000000000000..2a034f906580f --- /dev/null +++ b/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move @@ -0,0 +1,301 @@ +/// Copywrite (c) 2025 Supra +/// Microchain Registry Module testcases. +#[test_only] +module supra_framework::microchain_registry_tests { + use std::string; + use std::vector; + + use supra_framework::account; + use supra_framework::microchain_registry; + + + /// Never registered as a mirochain. + const STATE_UNKNOWN: u8 = 0; + /// Registered as a microchain and actively working. + const STATE_ACTIVE: u8 = 1; + /// Registered as a microchain, but decommissioned from the Supra-L1. + const STATE_INACTIVE: u8 = 2; + + // Test constants + const TEST_CHAIN_ID_1: u8 = 10; + const TEST_CHAIN_ID_2: u8 = 20; + const TEST_CHAIN_ID_3: u8 = 30; + const RESERVED_CHAIN_ID: u8 = 5; + + + fun setup_test(): signer { + let supra_framework = account::create_account_for_test(@supra_framework); + microchain_registry::initialize(&supra_framework, vector::empty()); + supra_framework + } + + fun create_metadata_link(suffix: vector): string::String { + let base = b"https://temp.com/temp/"; + vector::append(&mut base, suffix); + string::utf8(base) + } + + // Module Initialization Tests. + + #[test] + fun test_initialize() { + let supra_framework = account::create_account_for_test(@supra_framework); + microchain_registry::initialize( + &supra_framework, + vector[ + microchain_registry::new_reserved_range(0, 0), + microchain_registry::new_reserved_range(1, 10) + ] + ); + assert!(microchain_registry::microchain_state(TEST_CHAIN_ID_1) == STATE_UNKNOWN, 1); + assert!(microchain_registry::is_chain_id_reserved(6), 2) + } + + #[test] + #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] + fun test_initialize_with_non_supra_framework() { + let non_supra_framework = account::create_account_for_test(@0x123); + microchain_registry::initialize(&non_supra_framework, vector::empty()); + } + + + // Register Microchain Tests. + + #[test] + fun test_register_microchain() { + let supra_framework = setup_test(); + let metadata = create_metadata_link(b"chain1"); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + metadata + ); + assert!(microchain_registry::microchain_state(TEST_CHAIN_ID_1) == STATE_ACTIVE, 1); + assert!(microchain_registry::is_microchain_active(TEST_CHAIN_ID_1), 2); + assert!(microchain_registry::microchain_metadata_link(TEST_CHAIN_ID_1) == metadata, 3); + + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_2, + create_metadata_link(b"chain2") + ); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_3, + create_metadata_link(b"chain3") + ); + assert!(microchain_registry::is_microchain_active(TEST_CHAIN_ID_2), 4); + assert!(microchain_registry::is_microchain_active(TEST_CHAIN_ID_3), 5); + assert!(microchain_registry::active_microchains() == vector[30, 20, 10], 6) + } + + + #[test] + #[expected_failure(abort_code = 0x60006, location = supra_framework::microchain_registry)] + fun test_register_microchain_without_initialization() { + let supra_framework = account::create_account_for_test(@supra_framework); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + } + + #[test] + #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] + fun test_register_microchain_with_non_supra_framework_signer() { + let _ = setup_test(); + let non_supra_framework = account::create_account_for_test(@0x123); + microchain_registry::register_microchain( + &non_supra_framework, + RESERVED_CHAIN_ID, + create_metadata_link(b"reserved") + ); + } + + #[test] + #[expected_failure(abort_code = 0x80001, location = supra_framework::microchain_registry)] + fun test_register_microchain_with_already_registered_microchain() { + let supra_framework = setup_test(); + let metadata = create_metadata_link(b"chain1"); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + metadata + ); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1_duplicate") + ); + } + + #[test] + #[expected_failure(abort_code = 0x10003, location = supra_framework::microchain_registry)] + fun test_register_microchain_with_reserved_chain_id() { + let supra_framework = setup_test(); + microchain_registry::add_reserved_range(&supra_framework, 1, 10); + + microchain_registry::register_microchain( + &supra_framework, + RESERVED_CHAIN_ID, + create_metadata_link(b"reserved") + ); + } + + + // Deactivate Microchain Tests. + + #[test] + fun test_deactivate_microchain_success() { + let supra_framework = setup_test(); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); + + assert!(microchain_registry::microchain_state(TEST_CHAIN_ID_1) == STATE_INACTIVE, 1); + assert!(!microchain_registry::is_microchain_active(TEST_CHAIN_ID_1), 2); + } + + #[test] + #[expected_failure(abort_code = 0x60002, location = supra_framework::microchain_registry)] + fun test_deactivate_microchain_with_unregistered_microchain() { + let supra_framework = setup_test(); + microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); + } + + #[test] + #[expected_failure(abort_code = 0x30004, location = supra_framework::microchain_registry)] + fun test_deactivate_microchain_with_already_deactivated_microchain() { + let supra_framework = setup_test(); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + // Here, we are deactivating it first time. + microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); + // Now, again we are trying to deactivate the microchain and this should cause failure. + microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); + } + + + // Reactivate Microchain Tests. + + #[test] + fun test_reactivate_microchain() { + let supra_framework = setup_test(); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); + microchain_registry::reactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); + + assert!(microchain_registry::microchain_state(TEST_CHAIN_ID_1) == STATE_ACTIVE, 1); + assert!(microchain_registry::is_microchain_active(TEST_CHAIN_ID_1), 2); + } + + #[test] + #[expected_failure(abort_code = 0x60002, location = supra_framework::microchain_registry)] + fun test_reactivate_microchain_with_unregistered_microchain() { + let supra_framework = setup_test(); + microchain_registry::reactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); + } + + #[test] + #[expected_failure(abort_code = 0x30005, location = supra_framework::microchain_registry)] + fun test_reactivate_microchain_with_already_active_microchain() { + let supra_framework = setup_test(); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + microchain_registry::reactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); + } + + + // Update Microchain Metadata Link Tests. + + #[test] + fun test_update_microchain_metadata_link() { + let supra_framework = setup_test(); + let initial_metadata = create_metadata_link(b"chain1"); + let new_metadata = create_metadata_link(b"chain1_updated"); + microchain_registry::register_microchain( + &supra_framework, + TEST_CHAIN_ID_1, + initial_metadata + ); + assert!(microchain_registry::microchain_metadata_link(TEST_CHAIN_ID_1) == initial_metadata, 1); + + // Now, Updating the metadata link. + microchain_registry::update_microchain_metadata_link( + &supra_framework, + TEST_CHAIN_ID_1, + new_metadata + ); + assert!(microchain_registry::microchain_metadata_link(TEST_CHAIN_ID_1) == new_metadata, 2); + } + + #[test] + #[expected_failure(abort_code = 0x60002, location = supra_framework::microchain_registry)] + fun test_update_microchain_metadata_link_with_unregistered_microchain() { + let supra_framework = setup_test(); + microchain_registry::update_microchain_metadata_link( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + } + + + // Add Reserved Ranges Tests. + + #[test] + fun test_add_reserved_range() { + let supra_framework = setup_test(); + microchain_registry::add_reserved_range(&supra_framework, 1, 10); + microchain_registry::add_reserved_range(&supra_framework, 200, 255); + + // Verify reserved ranges + assert!(microchain_registry::is_chain_id_reserved(1), 1); + assert!(microchain_registry::is_chain_id_reserved(5), 2); + assert!(microchain_registry::is_chain_id_reserved(10), 3); + assert!(!microchain_registry::is_chain_id_reserved(50), 4); + assert!(microchain_registry::is_chain_id_reserved(220), 5); + assert!(!microchain_registry::is_chain_id_reserved(0), 6); + + // Reserving single range, trying 0-0. + microchain_registry::add_reserved_range(&supra_framework, 0, 0); + assert!(microchain_registry::is_chain_id_reserved(0), 7); + } + + #[test] + fun test_overlapping_reserved_ranges() { + let supra_framework = setup_test(); + + microchain_registry::add_reserved_range(&supra_framework, 10, 20); + microchain_registry::add_reserved_range(&supra_framework, 15, 25); + microchain_registry::add_reserved_range(&supra_framework, 20, 30); + + // All overlapping IDs should be reserved + assert!(microchain_registry::is_chain_id_reserved(10), 1); + assert!(microchain_registry::is_chain_id_reserved(15), 2); + assert!(microchain_registry::is_chain_id_reserved(20), 3); + assert!(microchain_registry::is_chain_id_reserved(25), 4); + assert!(microchain_registry::is_chain_id_reserved(30), 5); + } + + #[test] + #[expected_failure(abort_code = 0x10007, location = supra_framework::microchain_registry)] + fun test_add_reserved_range_with_invalid_range() { + let supra_framework = setup_test(); + microchain_registry::add_reserved_range(&supra_framework, 20, 10); + } +} \ No newline at end of file diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index a8aeddc99eee3..af5c16f187b10 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -32,9 +32,10 @@ use aptos_types::{ move_utils::as_move_value::AsMoveValue, on_chain_config::{ randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit}, - AutomationRegistryConfig, FeatureFlag, Features, GasScheduleV2, OnChainConsensusConfig, - OnChainEvmGenesisConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, - OnChainRandomnessConfig, RandomnessConfigMoveStruct, APTOS_MAX_KNOWN_VERSION, + AutomationRegistryConfig, FeatureFlag, Features, GasScheduleV2, MicrochainRegistryConfig, + OnChainConsensusConfig, OnChainEvmGenesisConfig, OnChainExecutionConfig, + OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct, + APTOS_MAX_KNOWN_VERSION, }, transaction::{authenticator::AuthenticationKey, ChangeSet, Transaction, WriteSetPayload}, write_set::TransactionWrite, @@ -108,6 +109,7 @@ pub struct GenesisConfiguration { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub automation_registry_config: Option, + pub microchain_registry_config: Option, } pub static GENESIS_KEYPAIR: Lazy<(Ed25519PrivateKey, Ed25519PublicKey)> = Lazy::new(|| { @@ -174,6 +176,7 @@ pub fn encode_supra_mainnet_genesis_transaction( ); initialize_supra_coin(&mut session); initialize_supra_native_automation(&mut session, genesis_config); + initialize_microchain_registry(&mut session, genesis_config); initialize_on_chain_governance(&mut session, genesis_config); create_accounts(&mut session, accounts); @@ -326,6 +329,7 @@ pub fn encode_genesis_change_set_for_testnet( initialize_supra_coin(&mut session); } initialize_supra_native_automation(&mut session, genesis_config); + initialize_microchain_registry(&mut session, genesis_config); initialize_config_buffer(&mut session); initialize_dkg(&mut session); initialize_reconfiguration_state(&mut session); @@ -584,6 +588,19 @@ fn initialize_supra_native_automation( ); } +fn initialize_microchain_registry(session: &mut SessionExt, genesis_config: &GenesisConfiguration) { + let Some(config) = &genesis_config.microchain_registry_config else { + return; + }; + exec_function( + session, + GENESIS_MODULE_NAME, + "initialize_microchain_registry", + vec![], + config.serialize_into_move_values(), + ); +} + fn initialize_evm_genesis_config( session: &mut SessionExt, evm_genesis_config: &OnChainEvmGenesisConfig, @@ -1242,6 +1259,7 @@ pub fn generate_test_genesis( randomness_config_override: None, jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), + microchain_registry_config: Some(MicrochainRegistryConfig::default()), }, &OnChainConsensusConfig::default_for_genesis(), &OnChainExecutionConfig::default_for_genesis(), @@ -1310,6 +1328,7 @@ fn mainnet_genesis_config() -> GenesisConfiguration { randomness_config_override: None, jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), + microchain_registry_config: Some(MicrochainRegistryConfig::default()), } } diff --git a/third_party/move/evm/hardhat-examples/package-lock.json b/third_party/move/evm/hardhat-examples/package-lock.json index c10b7f6cd7097..d0cf82e998fe9 100644 --- a/third_party/move/evm/hardhat-examples/package-lock.json +++ b/third_party/move/evm/hardhat-examples/package-lock.json @@ -26,6 +26,23 @@ "web3": "^1.7.1" } }, + "../hardhat-move": { + "version": "0.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^9.1.0", + "neverthrow": "^4.3.1", + "typescript": "^4.6.3" + }, + "devDependencies": { + "hardhat": "^2.9.3", + "mocha": "^7.1.2" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, "node_modules/@babel/runtime": { "version": "7.17.8", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", @@ -358,23 +375,118 @@ } }, "node_modules/@ethereumjs/common": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.3.tgz", - "integrity": "sha512-mQwPucDL7FDYIg9XQ8DL31CnIYZwGhU5hyOO5E+BMmT71G0+RHvIT5rIkLBirJEKxV6+Rcf9aEIY0kXInxUWpQ==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.4" + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" } }, "node_modules/@ethereumjs/tx": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", - "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", + "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dev": true, + "license": "MIT", "dependencies": { - "@ethereumjs/common": "^2.6.3", - "ethereumjs-util": "^7.1.4" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, "node_modules/@ethersproject/abi": { @@ -1116,6 +1228,32 @@ "rlp": "^2.2.3" } }, + "node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@noble/hashes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.0.0.tgz", @@ -4304,14 +4442,28 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/chai": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", @@ -4336,6 +4488,23 @@ "@types/node": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4351,12 +4520,6 @@ "@types/node": "*" } }, - "node_modules/@types/mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", - "dev": true - }, "node_modules/@types/node": { "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", @@ -4403,6 +4566,16 @@ "@types/node": "*" } }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/secp256k1": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", @@ -4471,6 +4644,13 @@ "node": ">=6.5" } }, + "node_modules/abortcontroller-polyfill": { + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.8.tgz", + "integrity": "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ==", + "dev": true, + "license": "MIT" + }, "node_modules/abstract-level": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", @@ -5327,6 +5507,16 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", + "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, "node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -6016,6 +6206,16 @@ "sha.js": "^2.4.8" } }, + "node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -6537,6 +6737,13 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true, + "license": "MIT" + }, "node_modules/es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", @@ -7357,10 +7564,11 @@ } }, "node_modules/ethereumjs-util": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", - "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", "dev": true, + "license": "MPL-2.0", "dependencies": { "@types/bn.js": "^5.1.0", "bn.js": "^5.1.2", @@ -7829,6 +8037,13 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", + "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", + "dev": true, + "license": "MIT" + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -18320,18 +18535,8 @@ } }, "node_modules/hardhat-move": { - "version": "0.0.1", - "resolved": "file:../hardhat-move", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mocha": "^9.1.0", - "neverthrow": "^4.3.1", - "typescript": "^4.6.3" - }, - "peerDependencies": { - "hardhat": "^2.0.0" - } + "resolved": "../hardhat-move", + "link": true }, "node_modules/hardhat/node_modules/@noble/hashes": { "version": "1.2.0", @@ -18736,6 +18941,20 @@ "npm": ">=1.3.7" } }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -19828,6 +20047,13 @@ "node": ">= 0.6" } }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -20290,12 +20516,6 @@ "node": ">= 0.6" } }, - "node_modules/neverthrow": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/neverthrow/-/neverthrow-4.4.2.tgz", - "integrity": "sha512-QVY0ylzBF71pUdLshRrqtweMgqKnE3R37/T82Z5bhO/z8P9z96PC/5pEl2FmiZSy0p+3lsjKerh6jmTWM5fv2g==", - "dev": true - }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -20343,10 +20563,11 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -21144,6 +21365,19 @@ } ] }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -21429,6 +21663,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -22668,6 +22909,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -22826,16 +23068,16 @@ "dev": true }, "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", "which-typed-array": "^1.1.2" } }, @@ -22903,356 +23145,308 @@ } }, "node_modules/web3": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.1.tgz", - "integrity": "sha512-RKVdyZ5FuVEykj62C1o2tc0teJciSOh61jpVB9yb344dBHO3ZV4XPPP24s/PPqIMXmVFN00g2GD9M/v1SoHO/A==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.10.4.tgz", + "integrity": "sha512-kgJvQZjkmjOEKimx/tJQsqWfRDPTTcBfYPa9XletxuHLpHcXdx67w8EFn5AW3eVxCutE9dTVHgGa9VYe8vgsEA==", "dev": true, "hasInstallScript": true, + "license": "LGPL-3.0", "dependencies": { - "web3-bzz": "1.7.1", - "web3-core": "1.7.1", - "web3-eth": "1.7.1", - "web3-eth-personal": "1.7.1", - "web3-net": "1.7.1", - "web3-shh": "1.7.1", - "web3-utils": "1.7.1" + "web3-bzz": "1.10.4", + "web3-core": "1.10.4", + "web3-eth": "1.10.4", + "web3-eth-personal": "1.10.4", + "web3-net": "1.10.4", + "web3-shh": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-bzz": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.1.tgz", - "integrity": "sha512-sVeUSINx4a4pfdnT+3ahdRdpDPvZDf4ZT/eBF5XtqGWq1mhGTl8XaQAk15zafKVm6Onq28vN8abgB/l+TrG8kA==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.10.4.tgz", + "integrity": "sha512-ZZ/X4sJ0Uh2teU9lAGNS8EjveEppoHNQiKlOXAjedsrdWuaMErBPdLQjXfcrYvN6WM6Su9PMsAxf3FXXZ+HwQw==", "dev": true, "hasInstallScript": true, + "license": "LGPL-3.0", "dependencies": { "@types/node": "^12.12.6", - "got": "9.6.0", + "got": "12.1.0", "swarm-js": "^0.1.40" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", - "dev": true - }, - "node_modules/web3-core": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.1.tgz", - "integrity": "sha512-HOyDPj+4cNyeNPwgSeUkhtS0F+Pxc2obcm4oRYPW5ku6jnTO34pjaij0us+zoY3QEusR8FfAKVK1kFPZnS7Dzw==", + "node_modules/web3-bzz/node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-requestmanager": "1.7.1", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", + "node_modules/web3-bzz/node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, + "license": "MIT", "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" + "defer-to-connect": "^2.0.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=14.16" } }, - "node_modules/web3-core-helpers/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } + "license": "MIT" }, - "node_modules/web3-core-helpers/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "node_modules/web3-bzz/node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-core-method": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.1.tgz", - "integrity": "sha512-383wu5FMcEphBFl5jCjk502JnEg3ugHj7MQrsX7DY76pg5N5/dEzxeEMIJFCN6kr5Iq32NINOG3VuJIyjxpsEg==", + "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "license": "MIT", "dependencies": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-utils": "1.7.1" + "pump": "^3.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core-method/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-core-method/node_modules/web3-core-promievent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", - "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "node_modules/web3-bzz/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, + "license": "MIT", "dependencies": { - "eventemitter3": "4.0.4" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-method/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "node": ">=10" }, - "engines": { - "node": ">=8.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", + "node_modules/web3-bzz/node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=10" } }, - "node_modules/web3-core-requestmanager": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.1.tgz", - "integrity": "sha512-/EHVTiMShpZKiq0Jka0Vgguxi3vxq1DAHKxg42miqHdUsz4/cDWay2wGALDR2x3ofDB9kqp7pb66HsvQImQeag==", + "node_modules/web3-bzz/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.1", - "web3-providers-http": "1.7.1", - "web3-providers-ipc": "1.7.1", - "web3-providers-ws": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core-requestmanager/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-bzz/node_modules/got": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", + "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", "dev": true, + "license": "MIT", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "@sindresorhus/is": "^4.6.0", + "@szmarczak/http-timer": "^5.0.1", + "@types/cacheable-request": "^6.0.2", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^6.0.4", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "form-data-encoder": "1.7.1", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^2.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "node_modules/web3-core-requestmanager/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-bzz/node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" - } + "license": "MIT" }, - "node_modules/web3-core-subscriptions": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.1.tgz", - "integrity": "sha512-NZBsvSe4J+Wt16xCf4KEtBbxA9TOwSVr8KWfUQ0tC2KMdDYdzNswl0Q9P58xaVuNlJ3/BH+uDFZJJ5E61BSA1Q==", + "node_modules/web3-bzz/node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "json-buffer": "3.0.1" } }, - "node_modules/web3-core-subscriptions/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-bzz/node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core-subscriptions/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-bzz/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "node_modules/web3-bzz/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true, - "dependencies": { - "@types/node": "*" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", - "dev": true - }, - "node_modules/web3-core/node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "node_modules/web3-bzz/node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=12.20" } }, - "node_modules/web3-core/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-bzz/node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, + "license": "MIT", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "lowercase-keys": "^2.0.0" }, - "engines": { - "node": ">=8.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-bzz/node_modules/responselike/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-eth": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.1.tgz", - "integrity": "sha512-Uz3gO4CjTJ+hMyJZAd2eiv2Ur1uurpN7sTMATWKXYR/SgG+SZgncnk/9d8t23hyu4lyi2GiVL1AqVqptpRElxg==", + "node_modules/web3-core": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.10.4.tgz", + "integrity": "sha512-B6elffYm81MYZDTrat7aEhnhdtVE3lDBUZft16Z8awYMZYJDbnykEbJVS+l3mnA7AQTnSDr/1MjWofGDLBJPww==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-eth-accounts": "1.7.1", - "web3-eth-contract": "1.7.1", - "web3-eth-ens": "1.7.1", - "web3-eth-iban": "1.7.1", - "web3-eth-personal": "1.7.1", - "web3-net": "1.7.1", - "web3-utils": "1.7.1" + "@types/bn.js": "^5.1.1", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-requestmanager": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-abi": { + "node_modules/web3-core-helpers": { "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", + "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", "dev": true, "dependencies": { - "@ethersproject/abi": "5.0.7", + "web3-eth-iban": "1.5.3", "web3-utils": "1.5.3" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "node_modules/web3-eth-abi/node_modules/eth-lib": { + "node_modules/web3-core-helpers/node_modules/eth-lib": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", @@ -23263,7 +23457,7 @@ "xhr-request-promise": "^0.1.2" } }, - "node_modules/web3-eth-abi/node_modules/web3-utils": { + "node_modules/web3-core-helpers/node_modules/web3-utils": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", @@ -23281,191 +23475,515 @@ "node": ">=8.0.0" } }, - "node_modules/web3-eth-accounts": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.1.tgz", - "integrity": "sha512-3xGQ2bkTQc7LFoqGWxp5cQDrKndlX05s7m0rAFVoyZZODMqrdSGjMPMqmWqHzJRUswNEMc+oelqSnGBubqhguQ==", + "node_modules/web3-core-method": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.10.4.tgz", + "integrity": "sha512-uZTb7flr+Xl6LaDsyTeE2L1TylokCJwTDrIVfIfnrGmnwLc6bmTWCCrm71sSrQ0hqs6vp/MKbQYIYqUN0J8WyA==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-utils": "1.7.1" + "@ethersproject/transactions": "^5.6.2", + "web3-core-helpers": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "node_modules/web3-core-method/node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" } }, - "node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "node_modules/web3-core-method/node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", "dev": true, - "bin": { - "uuid": "bin/uuid" + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" } }, - "node_modules/web3-eth-accounts/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-core-method/node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-accounts/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-core-method/node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/bignumber": "^5.8.0" } }, - "node_modules/web3-eth-contract": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.1.tgz", - "integrity": "sha512-HpnbkPYkVK3lOyos2SaUjCleKfbF0SP3yjw7l551rAAi5sIz/vwlEzdPWd0IHL7ouxXbO0tDn7jzWBRcD3sTbA==", + "node_modules/web3-core-method/node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-utils": "1.7.1" + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/web3-core-method/node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/web3-core-method/node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-core-method/node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-core-method/node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/web3-core-method/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/web3-core-method/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core-method/node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/web3-core-method/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core-method/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "node_modules/web3-core-method/node_modules/web3-core-promievent": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz", + "integrity": "sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "node_modules/web3-core-method/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@types/node": "*" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-core-promievent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", + "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", "dev": true, "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "eventemitter3": "4.0.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/web3-core-promievent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", - "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "node_modules/web3-core-requestmanager": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.10.4.tgz", + "integrity": "sha512-vqP6pKH8RrhT/2MoaU+DY/OsYK9h7HmEBNCdoMj+4ZwujQtw/Mq2JifjwsJ7gits7Q+HWJwx8q6WmQoVZAWugg==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "eventemitter3": "4.0.4" + "util": "^0.12.5", + "web3-core-helpers": "1.10.4", + "web3-providers-http": "1.10.4", + "web3-providers-ipc": "1.10.4", + "web3-providers-ws": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/web3-eth-abi": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", - "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "node_modules/web3-core-requestmanager/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core-requestmanager/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-core-requestmanager/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-ens": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.1.tgz", - "integrity": "sha512-DVCF76i9wM93DrPQwLrYiCw/UzxFuofBsuxTVugrnbm0SzucajLLNftp3ITK0c4/lV3x9oo5ER/wD6RRMHQnvw==", + "node_modules/web3-core-subscriptions": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.10.4.tgz", + "integrity": "sha512-o0lSQo/N/f7/L76C0HV63+S54loXiE9fUPfHFcTtpJRQNDBVsSDdWRdePbWwR206XlsBqD5VHApck1//jEafTw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-eth-contract": "1.7.1", - "web3-utils": "1.7.1" + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-ens/node_modules/@ethersproject/abi": { + "node_modules/web3-core-subscriptions/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core-subscriptions/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core/node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/web3-core/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.10.4.tgz", + "integrity": "sha512-Sql2kYKmgt+T/cgvg7b9ce24uLS7xbFrxE4kuuor1zSCGrjhTJ5rRNG8gTJUkAJGKJc7KgnWmgW+cOfMBPUDSA==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-eth-accounts": "1.10.4", + "web3-eth-contract": "1.10.4", + "web3-eth-ens": "1.10.4", + "web3-eth-iban": "1.10.4", + "web3-eth-personal": "1.10.4", + "web3-net": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", + "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", @@ -23482,361 +24000,1925 @@ "@ethersproject/strings": "^5.0.4" } }, - "node_modules/web3-eth-ens/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "node_modules/web3-eth-abi/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-abi/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.10.4.tgz", + "integrity": "sha512-ysy5sVTg9snYS7tJjxVoQAH6DTOTkRGR8emEVCWNGLGiB9txj+qDvSeT0izjurS/g7D5xlMAgrEHLK1Vi6I3yg==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/common": "2.6.5", + "@ethereumjs/tx": "3.5.2", + "@ethereumjs/util": "^8.1.0", + "eth-lib": "0.2.8", + "scrypt-js": "^3.0.1", + "uuid": "^9.0.0", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-eth-iban/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-contract": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.10.4.tgz", + "integrity": "sha512-Q8PfolOJ4eV9TvnTj1TGdZ4RarpSLmHnUnzVxZ/6/NiTfe4maJz99R0ISgwZkntLhLRtw0C7LRJuklzGYCNN3A==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/bn.js": "^5.1.1", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-contract/node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/web3-eth-contract/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-contract/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-core-promievent": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz", + "integrity": "sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-eth-abi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz", + "integrity": "sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.10.4.tgz", + "integrity": "sha512-LLrvxuFeVooRVZ9e5T6OWKVflHPFgrVjJ/jtisRWcmI7KN/b64+D/wJzXqgmp6CNsMQcE7rpmf4CQmJCrTdsgg==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-eth-contract": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-ens/node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/web3-eth-ens/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-ens/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-core-promievent": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz", + "integrity": "sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-eth-abi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz", + "integrity": "sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-ens/node_modules/web3-core-promievent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", - "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "node_modules/web3-eth-iban": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", + "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-iban/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.10.4.tgz", + "integrity": "sha512-BRa/hs6jU1hKHz+AC/YkM71RP3f0Yci1dPk4paOic53R4ZZG4MgwKRkJhgt3/GPuPliwS46f/i5A7fEGBT4F9w==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-net": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-personal/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-personal/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/web3-eth/node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-ens/node_modules/web3-eth-abi": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", - "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "node_modules/web3-eth/node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-ens/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-eth/node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", + "node_modules/web3-eth/node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" } }, - "node_modules/web3-eth-iban/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "node_modules/web3-eth/node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-iban/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "node_modules/web3-eth/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" } }, - "node_modules/web3-eth-personal": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.1.tgz", - "integrity": "sha512-02H6nFBNfNmFjMGZL6xcDi0r7tUhxrUP91FTFdoLyR94eIJDadPp4rpXfG7MVES873i1PReh4ep5pSCHbc3+Pg==", + "node_modules/web3-eth/node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-net": "1.7.1", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" } }, - "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", - "dev": true - }, - "node_modules/web3-eth-personal/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-eth/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" - } + "license": "MIT" }, - "node_modules/web3-eth-personal/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-eth/node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dev": true, + "license": "MIT", "dependencies": { "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/web3-eth/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "node_modules/web3-eth/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", "dev": true, - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } + "license": "MIT" }, "node_modules/web3-eth/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-eth/node_modules/web3-eth-abi": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", - "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz", + "integrity": "sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.1" + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-eth/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-net": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.1.tgz", - "integrity": "sha512-8yPNp2gvjInWnU7DCoj4pIPNhxzUjrxKlODsyyXF8j0q3Z2VZuQp+c63gL++r2Prg4fS8t141/HcJw4aMu5sVA==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.10.4.tgz", + "integrity": "sha512-mKINnhOOnZ4koA+yV2OT5s5ztVjIx7IY9a03w6s+yao/BUn+Luuty0/keNemZxTr1E8Ehvtn28vbOtW7Ids+Ow==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-core": "1.7.1", - "web3-core-method": "1.7.1", - "web3-utils": "1.7.1" + "web3-core": "1.10.4", + "web3-core-method": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-http": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.1.tgz", - "integrity": "sha512-dmiO6G4dgAa3yv+2VD5TduKNckgfR97VI9YKXVleWdcpBoKXe2jofhdvtafd42fpIoaKiYsErxQNcOC5gI/7Vg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.10.4.tgz", + "integrity": "sha512-m2P5Idc8hdiO0l60O6DSCPw0kw64Zgi0pMjbEFRmxKIck2Py57RQMu4bxvkxJwkF06SlGaEQF8rFZBmuX7aagQ==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-core-helpers": "1.7.1", - "xhr2-cookies": "1.1.0" + "abortcontroller-polyfill": "^1.7.5", + "cross-fetch": "^4.0.0", + "es6-promise": "^4.2.8", + "web3-core-helpers": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, + "node_modules/web3-providers-http/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, "node_modules/web3-providers-http/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-http/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-ipc": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.1.tgz", - "integrity": "sha512-uNgLIFynwnd5M9ZC0lBvRQU5iLtU75hgaPpc7ZYYR+kjSk2jr2BkEAQhFVJ8dlqisrVmmqoAPXOEU0flYZZgNQ==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.10.4.tgz", + "integrity": "sha512-YRF/bpQk9z3WwjT+A6FI/GmWRCASgd+gC0si7f9zbBWLXjwzYAKG73bQBaFRAHex1hl4CVcM5WUMaQXf3Opeuw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { "oboe": "2.1.5", - "web3-core-helpers": "1.7.1" + "web3-core-helpers": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, + "node_modules/web3-providers-ipc/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, "node_modules/web3-providers-ipc/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-ipc/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-ws": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.1.tgz", - "integrity": "sha512-Uj0n5hdrh0ESkMnTQBsEUS2u6Unqdc7Pe4Zl+iZFb7Yn9cIGsPJBl7/YOP4137EtD5ueXAv+MKwzcelpVhFiFg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.10.4.tgz", + "integrity": "sha512-j3FBMifyuFFmUIPVQR4pj+t5ILhAexAui0opgcpu9R5LxQrLRUZxHSnU+YO25UycSOa/NAX8A+qkqZNpcFAlxA==", "dev": true, + "license": "LGPL-3.0", "dependencies": { "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.1", + "web3-core-helpers": "1.10.4", "websocket": "^1.0.32" }, "engines": { "node": ">=8.0.0" } }, + "node_modules/web3-providers-ws/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, "node_modules/web3-providers-ws/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-ws/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-shh": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.1.tgz", - "integrity": "sha512-NO+jpEjo8kYX6c7GiaAm57Sx93PLYkWYUCWlZmUOW7URdUcux8VVluvTWklGPvdM9H1WfDrol91DjuSW+ykyqg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.10.4.tgz", + "integrity": "sha512-cOH6iFFM71lCNwSQrC3niqDXagMqrdfFW85hC9PFUrAr3PUrIem8TNstTc3xna2bwZeWG6OBy99xSIhBvyIACw==", "dev": true, "hasInstallScript": true, + "license": "LGPL-3.0", "dependencies": { - "web3-core": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-net": "1.7.1" + "web3-core": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-net": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-utils": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.1.tgz", - "integrity": "sha512-fef0EsqMGJUgiHPdX+KN9okVWshbIumyJPmR+btnD1HgvoXijKEkuKBv0OmUqjbeqmLKP2/N9EiXKJel5+E1Dw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", + "ethereum-cryptography": "^2.1.2", "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", @@ -23846,6 +25928,78 @@ "node": ">=8.0.0" } }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/types/src/on_chain_config/microchain_registry.rs b/types/src/on_chain_config/microchain_registry.rs new file mode 100644 index 0000000000000..bbee305b57e3f --- /dev/null +++ b/types/src/on_chain_config/microchain_registry.rs @@ -0,0 +1,47 @@ +use crate::account_config::CORE_CODE_ADDRESS; +use move_core_types::value::{serialize_values, MoveStruct, MoveValue}; + +#[derive(Clone, Debug, Default)] +pub struct MicrochainRegistryConfig { + reserved_ranges: Vec, +} + +impl MicrochainRegistryConfig { + pub fn new(reserved_ranges: Vec) -> Self { + Self { reserved_ranges } + } + + pub fn serialize_into_move_values(&self) -> Vec> { + let reserved_ranges_vec_move_value = self + .reserved_ranges + .iter() + .map(|range| MoveValue::from(range)) + .collect::>(); + let arguments = vec![ + MoveValue::Signer(CORE_CODE_ADDRESS), + MoveValue::Vector(reserved_ranges_vec_move_value), + ]; + serialize_values(&arguments) + } +} + +#[derive(Clone, Debug, Default)] +pub struct ReservedRange { + start: u8, + end: u8, +} + +impl ReservedRange { + pub fn new(start: u8, end: u8) -> Self { + Self { start, end } + } +} + +impl From<&ReservedRange> for MoveValue { + fn from(value: &ReservedRange) -> MoveValue { + MoveValue::Struct(MoveStruct::new(vec![ + MoveValue::U8(value.start), + MoveValue::U8(value.end), + ])) + } +} diff --git a/types/src/on_chain_config/mod.rs b/types/src/on_chain_config/mod.rs index 30fd0b8c79549..f45f9446a95a7 100644 --- a/types/src/on_chain_config/mod.rs +++ b/types/src/on_chain_config/mod.rs @@ -31,6 +31,7 @@ mod evm_genesis_config; mod execution_config; mod gas_schedule; mod jwk_consensus_config; +mod microchain_registry; pub mod randomness_api_v0_config; mod randomness_config; mod timed_features; @@ -46,7 +47,8 @@ pub use self::{ }, automation_registry::{ AutomationCycleDetails, AutomationCycleEvent, AutomationCycleInfo, AutomationCycleState, - AutomationRegistryConfig, AutomationRegistryConfigV1, AutomationRegistryConfigV2, AutomationCycleTransitionState + AutomationCycleTransitionState, AutomationRegistryConfig, AutomationRegistryConfigV1, + AutomationRegistryConfigV2, }, commit_history::CommitHistoryResource, consensus_config::{ @@ -54,6 +56,9 @@ pub use self::{ LeaderReputationType, OnChainConsensusConfig, ProposerAndVoterConfig, ProposerElectionType, ValidatorTxnConfig, }, + evm_genesis_config::{ + GenesisEvmContract, GenesisEvmEOA, OnChainEvmGenesisConfig, EVM_GENESIS_EVENT_MOVE_TYPE_TAG, + }, execution_config::{ BlockGasLimitType, ExecutionConfigV1, ExecutionConfigV2, ExecutionConfigV4, OnChainExecutionConfig, TransactionDeduperType, TransactionShufflerType, @@ -62,6 +67,7 @@ pub use self::{ jwk_consensus_config::{ ConfigV1 as JWKConsensusConfigV1, OIDCProvider, OnChainJWKConsensusConfig, }, + microchain_registry::{MicrochainRegistryConfig, ReservedRange}, randomness_config::{ OnChainRandomnessConfig, RandomnessConfigMoveStruct, RandomnessConfigSeqNum, }, @@ -69,7 +75,6 @@ pub use self::{ timestamp::CurrentTimeMicroseconds, transaction_fee::TransactionFeeBurnCap, validator_set::{ConsensusScheme, ValidatorSet}, - evm_genesis_config::{OnChainEvmGenesisConfig, GenesisEvmContract, GenesisEvmEOA, EVM_GENESIS_EVENT_MOVE_TYPE_TAG}, }; /// To register an on-chain config in Rust: From 2def1811479c335594f1f2f523c72342393b153f Mon Sep 17 00:00:00 2001 From: vpanchal-supra Date: Wed, 12 Nov 2025 17:18:45 +0530 Subject: [PATCH 2/7] Added microchain_registry and funnel_node_registry --- .../src/aptos_framework_sdk_builder.rs | 222 ---------------- .../doc/funnel_node_registry.md | 251 ++++++++++++++++++ .../framework/supra-framework/doc/genesis.md | 38 +++ .../doc/microchain_registry.md | 109 ++++++-- .../framework/supra-framework/doc/overview.md | 1 + .../sources/funnel_node_registry.move | 96 +++++++ .../supra-framework/sources/genesis.move | 18 +- .../sources/microchain_registry.move | 79 +++++- .../tests/funnel_node_registry_tests.move | 88 ++++++ .../tests/microchain_registry_tests.move | 2 - aptos-move/vm-genesis/src/lib.rs | 31 ++- crates/aptos-genesis/src/builder.rs | 8 +- crates/aptos-genesis/src/config.rs | 8 +- crates/aptos-genesis/src/lib.rs | 15 +- crates/aptos-genesis/src/mainnet.rs | 12 +- crates/aptos/src/genesis/mod.rs | 4 + .../on_chain_config/funnel_node_registry.rs | 31 +++ .../on_chain_config/microchain_registry.rs | 7 +- types/src/on_chain_config/mod.rs | 2 + 19 files changed, 746 insertions(+), 276 deletions(-) create mode 100644 aptos-move/framework/supra-framework/doc/funnel_node_registry.md create mode 100644 aptos-move/framework/supra-framework/sources/funnel_node_registry.move create mode 100644 aptos-move/framework/supra-framework/tests/funnel_node_registry_tests.move create mode 100644 types/src/on_chain_config/funnel_node_registry.rs diff --git a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs index 227490988b2e4..345dc79fcdeb5 100644 --- a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs +++ b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs @@ -328,34 +328,6 @@ pub enum EntryFunctionCall { coin_type: TypeTag, }, - /// Adds a reserved chain ID range. - MicrochainRegistryAddReservedRange { - start: u8, - end: u8, - }, - - /// Deactivates the already registered microchain. - MicrochainRegistryDeactivateMicrochain { - chain_id: u8, - }, - - /// Reactivates the deactivated microchain. - MicrochainRegistryReactivateMicrochain { - chain_id: u8, - }, - - /// Registeres a new microchain. - MicrochainRegistryRegisterMicrochain { - chain_id: u8, - metadata_link: Vec, - }, - - /// Updates metadata link of a registered microchain. - MicrochainRegistryUpdateMicrochainMetadataLink { - chain_id: u8, - new_metadata_link: Vec, - }, - /// Similar to add_owners, but only allow adding one owner. MultisigAccountAddOwner { new_owner: AccountAddress, @@ -1461,23 +1433,6 @@ impl EntryFunctionCall { amount, } => managed_coin_mint(coin_type, dst_addr, amount), ManagedCoinRegister { coin_type } => managed_coin_register(coin_type), - MicrochainRegistryAddReservedRange { start, end } => { - microchain_registry_add_reserved_range(start, end) - }, - MicrochainRegistryDeactivateMicrochain { chain_id } => { - microchain_registry_deactivate_microchain(chain_id) - }, - MicrochainRegistryReactivateMicrochain { chain_id } => { - microchain_registry_reactivate_microchain(chain_id) - }, - MicrochainRegistryRegisterMicrochain { - chain_id, - metadata_link, - } => microchain_registry_register_microchain(chain_id, metadata_link), - MicrochainRegistryUpdateMicrochainMetadataLink { - chain_id, - new_metadata_link, - } => microchain_registry_update_microchain_metadata_link(chain_id, new_metadata_link), MultisigAccountAddOwner { new_owner } => multisig_account_add_owner(new_owner), MultisigAccountAddOwners { new_owners } => multisig_account_add_owners(new_owners), MultisigAccountAddOwnersAndUpdateSignaturesRequired { @@ -2870,98 +2825,6 @@ pub fn managed_coin_register(coin_type: TypeTag) -> TransactionPayload { )) } -/// Adds a reserved chain ID range. -pub fn microchain_registry_add_reserved_range(start: u8, end: u8) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("microchain_registry").to_owned(), - ), - ident_str!("add_reserved_range").to_owned(), - vec![], - vec![bcs::to_bytes(&start).unwrap(), bcs::to_bytes(&end).unwrap()], - )) -} - -/// Deactivates the already registered microchain. -pub fn microchain_registry_deactivate_microchain(chain_id: u8) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("microchain_registry").to_owned(), - ), - ident_str!("deactivate_microchain").to_owned(), - vec![], - vec![bcs::to_bytes(&chain_id).unwrap()], - )) -} - -/// Reactivates the deactivated microchain. -pub fn microchain_registry_reactivate_microchain(chain_id: u8) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("microchain_registry").to_owned(), - ), - ident_str!("reactivate_microchain").to_owned(), - vec![], - vec![bcs::to_bytes(&chain_id).unwrap()], - )) -} - -/// Registeres a new microchain. -pub fn microchain_registry_register_microchain( - chain_id: u8, - metadata_link: Vec, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("microchain_registry").to_owned(), - ), - ident_str!("register_microchain").to_owned(), - vec![], - vec![ - bcs::to_bytes(&chain_id).unwrap(), - bcs::to_bytes(&metadata_link).unwrap(), - ], - )) -} - -/// Updates metadata link of a registered microchain. -pub fn microchain_registry_update_microchain_metadata_link( - chain_id: u8, - new_metadata_link: Vec, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("microchain_registry").to_owned(), - ), - ident_str!("update_microchain_metadata_link").to_owned(), - vec![], - vec![ - bcs::to_bytes(&chain_id).unwrap(), - bcs::to_bytes(&new_metadata_link).unwrap(), - ], - )) -} - /// Similar to add_owners, but only allow adding one owner. pub fn multisig_account_add_owner(new_owner: AccountAddress) -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( @@ -6160,71 +6023,6 @@ mod decoder { } } - pub fn microchain_registry_add_reserved_range( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::MicrochainRegistryAddReservedRange { - start: bcs::from_bytes(script.args().get(0)?).ok()?, - end: bcs::from_bytes(script.args().get(1)?).ok()?, - }) - } else { - None - } - } - - pub fn microchain_registry_deactivate_microchain( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::MicrochainRegistryDeactivateMicrochain { - chain_id: bcs::from_bytes(script.args().get(0)?).ok()?, - }) - } else { - None - } - } - - pub fn microchain_registry_reactivate_microchain( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::MicrochainRegistryReactivateMicrochain { - chain_id: bcs::from_bytes(script.args().get(0)?).ok()?, - }) - } else { - None - } - } - - pub fn microchain_registry_register_microchain( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::MicrochainRegistryRegisterMicrochain { - chain_id: bcs::from_bytes(script.args().get(0)?).ok()?, - metadata_link: bcs::from_bytes(script.args().get(1)?).ok()?, - }) - } else { - None - } - } - - pub fn microchain_registry_update_microchain_metadata_link( - payload: &TransactionPayload, - ) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some( - EntryFunctionCall::MicrochainRegistryUpdateMicrochainMetadataLink { - chain_id: bcs::from_bytes(script.args().get(0)?).ok()?, - new_metadata_link: bcs::from_bytes(script.args().get(1)?).ok()?, - }, - ) - } else { - None - } - } - pub fn multisig_account_add_owner(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { Some(EntryFunctionCall::MultisigAccountAddOwner { @@ -8008,26 +7806,6 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy + +# Module `0x1::funnel_node_registry` + +Copyright (c) 2025 Supra + +Funnel Node Registry Module + +This module manages a list of registered funnel nodes' IP/DNS addresses. + + +- [Resource `FunnelNodeRegistry`](#0x1_funnel_node_registry_FunnelNodeRegistry) +- [Struct `FunnelNodesUpdated`](#0x1_funnel_node_registry_FunnelNodesUpdated) +- [Constants](#@Constants_0) +- [Function `initialize`](#0x1_funnel_node_registry_initialize) +- [Function `update_funnel_nodes`](#0x1_funnel_node_registry_update_funnel_nodes) +- [Function `funnel_nodes`](#0x1_funnel_node_registry_funnel_nodes) +- [Function `assert_registry_initialized`](#0x1_funnel_node_registry_assert_registry_initialized) + + +
use 0x1::error;
+use 0x1::event;
+use 0x1::string;
+use 0x1::system_addresses;
+
+ + + + + +## Resource `FunnelNodeRegistry` + +Global funnel node registry resource. + + +
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
+struct FunnelNodeRegistry has key
+
+ + + +
+Fields + + +
+
+funnel_nodes: vector<string::String> +
+
+ +
+
+ + +
+ + + +## Struct `FunnelNodesUpdated` + + + +
#[event]
+struct FunnelNodesUpdated has drop, store
+
+ + + +
+Fields + + +
+
+old_funnel_nodes: vector<string::String> +
+
+ +
+
+new_funnel_nodes: vector<string::String> +
+
+ +
+
+ + +
+ + + +## Constants + + + + +The FunnelNodeRegistry resource has not been initialized at @supra_framework. + + +
const EREGISTRY_NOT_INITIALIZED: u64 = 1;
+
+ + + + + +## Function `initialize` + +Initializes the funnel node registry. + + +
public(friend) fun initialize(supra_framework: &signer, funnel_nodes: vector<string::String>)
+
+ + + +
+Implementation + + +
public(friend) fun initialize(supra_framework: &signer, funnel_nodes: vector<String>) {
+    system_addresses::assert_supra_framework(supra_framework);
+
+    move_to(supra_framework, FunnelNodeRegistry {
+        funnel_nodes,
+    });
+}
+
+ + + +
+ + + +## Function `update_funnel_nodes` + +Updates the funnel nodes in the funnel node registry. + +This method replaces the existing list of funnel nodes with the provided list. Therefore, it is +strongly recommended that the new list contains valid Socket-Addresses for all funnel nodes, and that the nodes +are ordered based on their reputation and trust level. + +Technically, deduplication of new_funnel_nodes is necessary. However, performing it consumes a +significant amount of execution gas. Since this method is expected to be invoked by microchain +governance - which is assumed to perform governance operations carefully - the new_funnel_nodes +list is **not** deduplicated internally. As a result, it is possible to pass a list containing duplicate +entries without triggering an error. Therefore, deduplication should be performed as part of +the validator node's sanity checks. + +This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package), +it can only be invoked through a governance proposal move-script. + +It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure +after invoking this method. While this method could perform the reconfiguration internally, it +intentionally does not. This is because governance proposal move-scripts may need to invoke +additional methods after this one, so the responsibility of reconfiguration is left to the caller. + +Example usage: +``` +supra_framework::funnel_node_registry::update_funnel_nodes(&supra_framework, new_funnel_nodes); +supra_framework::supra_governance::reconfigure(&supra_framework); +``` + + +
public fun update_funnel_nodes(supra_framework: &signer, new_funnel_nodes: vector<string::String>)
+
+ + + +
+Implementation + + +
public fun update_funnel_nodes(
+    supra_framework: &signer,
+    new_funnel_nodes: vector<String>
+) acquires FunnelNodeRegistry {
+    system_addresses::assert_supra_framework(supra_framework);
+    assert_registry_initialized();
+
+    let funnel_node_registry = borrow_global_mut<FunnelNodeRegistry>(@supra_framework);
+    let old_funnel_nodes = funnel_node_registry.funnel_nodes;
+    funnel_node_registry.funnel_nodes = new_funnel_nodes;
+    event::emit(FunnelNodesUpdated {
+        old_funnel_nodes,
+        new_funnel_nodes
+    })
+}
+
+ + + +
+ + + +## Function `funnel_nodes` + +Get funnel nodes list. + + +
#[view]
+public fun funnel_nodes(): vector<string::String>
+
+ + + +
+Implementation + + +
public fun funnel_nodes(): vector<String> acquires FunnelNodeRegistry {
+    assert_registry_initialized();
+    borrow_global_mut<FunnelNodeRegistry>(@supra_framework).funnel_nodes
+}
+
+ + + +
+ + + +## Function `assert_registry_initialized` + + + +
fun assert_registry_initialized()
+
+ + + +
+Implementation + + +
inline fun assert_registry_initialized() {
+    assert!(exists<FunnelNodeRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/genesis.md b/aptos-move/framework/supra-framework/doc/genesis.md index b9d82d1cd7986..79675ca5425e9 100644 --- a/aptos-move/framework/supra-framework/doc/genesis.md +++ b/aptos-move/framework/supra-framework/doc/genesis.md @@ -18,6 +18,7 @@ - [Function `initialize_supra_native_automation`](#0x1_genesis_initialize_supra_native_automation) - [Function `initialize_supra_native_automation_v2`](#0x1_genesis_initialize_supra_native_automation_v2) - [Function `initialize_microchain_registry`](#0x1_genesis_initialize_microchain_registry) +- [Function `initialize_funnel_node_registry`](#0x1_genesis_initialize_funnel_node_registry) - [Function `initialize_core_resources_and_supra_coin`](#0x1_genesis_initialize_core_resources_and_supra_coin) - [Function `initialize_evm_genesis_config`](#0x1_genesis_initialize_evm_genesis_config) - [Function `create_accounts`](#0x1_genesis_create_accounts) @@ -65,6 +66,7 @@ use 0x1::execution_config; use 0x1::features; use 0x1::fixed_point32; +use 0x1::funnel_node_registry; use 0x1::gas_schedule; use 0x1::microchain_registry; use 0x1::multisig_account; @@ -801,6 +803,42 @@ the supra_framework as the signer, the invocation must go through t + + + + +## Function `initialize_funnel_node_registry` + +Genesis step 5: Initialize Funnel Node Registry. + +This method allows to initialize the microchain registry either during the genesis initialization +or after it has been completed. + +Because it is publicly accessible, it can be invoked via a move-script. Since it requires +the supra_framework as the signer, the invocation must go through the governance process. + + +
public fun initialize_funnel_node_registry(supra_framework: &signer, funnel_nodes: vector<string::String>)
+
+ + + +
+Implementation + + +
public fun initialize_funnel_node_registry(
+    supra_framework: &signer,
+    funnel_nodes: vector<String>
+) {
+    funnel_node_registry::initialize(
+        supra_framework, funnel_nodes
+    )
+}
+
+ + +
diff --git a/aptos-move/framework/supra-framework/doc/microchain_registry.md b/aptos-move/framework/supra-framework/doc/microchain_registry.md index 4b9ba4404dab1..11612cb97f460 100644 --- a/aptos-move/framework/supra-framework/doc/microchain_registry.md +++ b/aptos-move/framework/supra-framework/doc/microchain_registry.md @@ -4,8 +4,23 @@ # Module `0x1::microchain_registry` Copyright (c) 2025 Supra + Microchain Registry Module -This module manages the registration and lifecycle of microchains on the Supra-L1. + +This module manages the registration and lifecycle of microchains on Supra-L1. + +1. To enable support for a new microchain on Supra-L1, it must be first registered by Supra Governance +using the register_microchain method of this module. +2. If a registered microchain misbehaves, it can be deactivated by Supra Governance through the deactivate_microchain method. +3. A previously deactivated microchain can be reactivated by Supra Governance using the reactivate_microchain method. +4. Although the registry data is updated immediately, the changes are only considered by Supra-L1 validators +after an epoch change. Therefore, it is strongly recommended to trigger an epoch change by invoking +0x1::supra_governance::reconfigure. +5. Supra-L1 validators consider the updated registry data only after the epoch change. Hence, it is +highly recommended to perform an epoch change whenever the following methods are invoked: +a. register_microchain +b. deactivate_microchain +c. reactivate_microchain - [Struct `ReservedRange`](#0x1_microchain_registry_ReservedRange) @@ -293,6 +308,16 @@ The provided range is invalid, start value must be less than or equal to end val + + +The MicrochainRegistry resource has not been initialized at @supra_framework. + + +
const EREGISTRY_NOT_INITIALIZED: u64 = 6;
+
+ + + The chain ID falls within a reserved range and cannot be used for registration. @@ -305,7 +330,7 @@ The chain ID falls within a reserved range and cannot be used for registration. -The microchain is already in the ACTIVE state and connot be reactivated. +The microchain is already in the ACTIVE state and cannot be reactivated.
const EMICROCHAIN_ALREADY_ACTIVE: u64 = 5;
@@ -343,16 +368,6 @@ The microchain with the given chain ID is not found in the microchain registry.
 
 
 
-
-
-The MicrochainRegistry resource has not been initialized at @supra_framework.
-
-
-
const EREGISTRY_NOT_INITIALIZED: u64 = 6;
-
- - - Registered as a microchain and actively working. @@ -375,7 +390,7 @@ Registered as a microchain, but decommissioned from the Supra-L1. -Never registered as a mirochain. +Never registered as a microchain.
const STATE_UNKNOWN: u8 = 0;
@@ -417,10 +432,24 @@ Initializes the microchain registry.
 
 ## Function `register_microchain`
 
-Registeres a new microchain.
+Registers a new microchain.
+
+This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package),
+it can only be invoked through a governance proposal move-script.
 
+It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure
+after invoking this method. While this method could perform the reconfiguration internally, it
+intentionally does not. This is because governance proposal move-scripts may need to invoke
+additional methods after this one, so the responsibility of reconfiguration is left to the caller.
 
-
public entry fun register_microchain(supra_framework: &signer, chain_id: u8, metadata_link: string::String)
+Example usage:
+```
+supra_framework::microchain_registry::register_microchain(&supra_framework, chain_id, metadata_link);
+supra_framework::supra_governance::reconfigure(&supra_framework);
+```
+
+
+
public fun register_microchain(supra_framework: &signer, chain_id: u8, metadata_link: string::String)
 
@@ -429,7 +458,7 @@ Registeres a new microchain. Implementation -
public entry fun register_microchain(
+
public fun register_microchain(
     supra_framework: &signer,
     chain_id: u8,
     metadata_link: String,
@@ -470,8 +499,22 @@ Registeres a new microchain.
 
 Deactivates the already registered microchain.
 
+This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package),
+it can only be invoked through a governance proposal move-script.
+
+It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure
+after invoking this method. While this method could perform the reconfiguration internally, it
+intentionally does not. This is because governance proposal move-scripts may need to invoke
+additional methods after this one, so the responsibility of reconfiguration is left to the caller.
+
+Example usage:
+```
+supra_framework::microchain_registry::deactivate_microchain(&supra_framework, chain_id);
+supra_framework::supra_governance::reconfigure(&supra_framework);
+```
 
-
public entry fun deactivate_microchain(supra_framework: &signer, chain_id: u8)
+
+
public fun deactivate_microchain(supra_framework: &signer, chain_id: u8)
 
@@ -480,7 +523,7 @@ Deactivates the already registered microchain. Implementation -
public entry fun deactivate_microchain(
+
public fun deactivate_microchain(
     supra_framework: &signer,
     chain_id: u8,
 ) acquires MicrochainRegistry {
@@ -508,8 +551,22 @@ Deactivates the already registered microchain.
 
 Reactivates the deactivated microchain.
 
+This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package),
+it can only be invoked through a governance proposal move-script.
+
+It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure
+after invoking this method. While this method could perform the reconfiguration internally, it
+intentionally does not. This is because governance proposal move-scripts may need to invoke
+additional methods after this one, so the responsibility of reconfiguration is left to the caller.
+
+Example usage:
+```
+supra_framework::microchain_registry::reactivate_microchain(&supra_framework, chain_id);
+supra_framework::supra_governance::reconfigure(&supra_framework);
+```
+
 
-
public entry fun reactivate_microchain(supra_framework: &signer, chain_id: u8)
+
public fun reactivate_microchain(supra_framework: &signer, chain_id: u8)
 
@@ -518,7 +575,7 @@ Reactivates the deactivated microchain. Implementation -
public entry fun reactivate_microchain(
+
public fun reactivate_microchain(
     supra_framework: &signer,
     chain_id: u8,
 ) acquires MicrochainRegistry {
@@ -547,7 +604,7 @@ Reactivates the deactivated microchain.
 Updates metadata link of a registered microchain.
 
 
-
public entry fun update_microchain_metadata_link(supra_framework: &signer, chain_id: u8, new_metadata_link: string::String)
+
public fun update_microchain_metadata_link(supra_framework: &signer, chain_id: u8, new_metadata_link: string::String)
 
@@ -556,7 +613,7 @@ Updates metadata link of a registered microchain. Implementation -
public entry fun update_microchain_metadata_link(
+
public fun update_microchain_metadata_link(
     supra_framework: &signer,
     chain_id: u8,
     new_metadata_link: String,
@@ -587,7 +644,7 @@ Updates metadata link of a registered microchain.
 Adds a reserved chain ID range.
 
 
-
public entry fun add_reserved_range(supra_framework: &signer, start: u8, end: u8)
+
public fun add_reserved_range(supra_framework: &signer, start: u8, end: u8)
 
@@ -596,7 +653,7 @@ Adds a reserved chain ID range. Implementation -
public entry fun add_reserved_range(
+
public fun add_reserved_range(
     supra_framework: &signer,
     start: u8,
     end: u8,
@@ -617,7 +674,7 @@ Adds a reserved chain ID range.
 ## Function `new_reserved_range`
 
 Constructor to create an instance of the ReservedRange.
-This will be utilsed in move-script to initialize the microchain registry with reserved ranges.
+This will be utilized in move-script to initialize the microchain registry with reserved ranges.
 
 
 
public fun new_reserved_range(start: u8, end: u8): microchain_registry::ReservedRange
@@ -703,7 +760,7 @@ Check if a microchain is active.
 
 ## Function `active_microchains`
 
-Get chain IDs of all mirochains with Active state.
+Get chain IDs of all microchain with Active state.
 
 
 
#[view]
diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md
index 5998fa9328fb5..3b02ed79b95b9 100644
--- a/aptos-move/framework/supra-framework/doc/overview.md
+++ b/aptos-move/framework/supra-framework/doc/overview.md
@@ -33,6 +33,7 @@ This is the reference documentation of the Supra framework.
 -  [`0x1::execution_config`](execution_config.md#0x1_execution_config)
 -  [`0x1::function_info`](function_info.md#0x1_function_info)
 -  [`0x1::fungible_asset`](fungible_asset.md#0x1_fungible_asset)
+-  [`0x1::funnel_node_registry`](funnel_node_registry.md#0x1_funnel_node_registry)
 -  [`0x1::gas_schedule`](gas_schedule.md#0x1_gas_schedule)
 -  [`0x1::genesis`](genesis.md#0x1_genesis)
 -  [`0x1::governance_proposal`](governance_proposal.md#0x1_governance_proposal)
diff --git a/aptos-move/framework/supra-framework/sources/funnel_node_registry.move b/aptos-move/framework/supra-framework/sources/funnel_node_registry.move
new file mode 100644
index 0000000000000..1170f3cf1138f
--- /dev/null
+++ b/aptos-move/framework/supra-framework/sources/funnel_node_registry.move
@@ -0,0 +1,96 @@
+/// Copyright (c) 2025 Supra
+///
+/// Funnel Node Registry Module
+///
+/// This module manages a list of registered funnel nodes' IP/DNS addresses.
+module supra_framework::funnel_node_registry {
+    use std::error;
+    use std::string::String;
+
+    use supra_framework::event;
+    use supra_framework::system_addresses;
+
+    friend supra_framework::genesis;
+    #[test_only]
+    friend supra_framework::funnel_node_registry_tests;
+
+
+    /// The `FunnelNodeRegistry` resource has not been initialized at @supra_framework.
+    const EREGISTRY_NOT_INITIALIZED: u64 = 1;
+
+
+    #[resource_group_member(group = supra_framework::object::ObjectGroup)]
+    /// Global funnel node registry resource.
+    struct FunnelNodeRegistry has key {
+        funnel_nodes: vector,
+    }
+
+    #[event]
+    struct FunnelNodesUpdated has store, drop {
+        old_funnel_nodes: vector,
+        new_funnel_nodes: vector,
+    }
+
+
+    /// Initializes the funnel node registry.
+    public(friend) fun initialize(supra_framework: &signer, funnel_nodes: vector) {
+        system_addresses::assert_supra_framework(supra_framework);
+
+        move_to(supra_framework, FunnelNodeRegistry {
+            funnel_nodes,
+        });
+    }
+
+    /// Updates the funnel nodes in the funnel node registry.
+    ///
+    /// This method replaces the existing list of funnel nodes with the provided list. Therefore, it is
+    /// strongly recommended that the new list contains valid Socket-Addresses for all funnel nodes, and that the nodes
+    /// are ordered based on their reputation and trust level.
+    ///
+    /// Technically, deduplication of `new_funnel_nodes` is necessary. However, performing it consumes a
+    /// significant amount of execution gas. Since this method is expected to be invoked by microchain
+    /// governance - which is assumed to perform governance operations carefully - the `new_funnel_nodes`
+    /// list is **not** deduplicated internally. As a result, it is possible to pass a list containing duplicate
+    /// entries without triggering an error. Therefore, deduplication should be performed as part of
+    /// the validator node's sanity checks.
+    ///
+    /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package),
+    /// it can only be invoked through a governance proposal move-script.
+    ///
+    /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure`
+    /// after invoking this method. While this method could perform the reconfiguration internally, it
+    /// intentionally does not. This is because governance proposal move-scripts may need to invoke
+    /// additional methods after this one, so the responsibility of reconfiguration is left to the caller.
+    ///
+    /// Example usage:
+    /// ```
+    /// supra_framework::funnel_node_registry::update_funnel_nodes(&supra_framework, new_funnel_nodes);
+    /// supra_framework::supra_governance::reconfigure(&supra_framework);
+    /// ```
+    public fun update_funnel_nodes(
+        supra_framework: &signer,
+        new_funnel_nodes: vector
+    ) acquires FunnelNodeRegistry {
+        system_addresses::assert_supra_framework(supra_framework);
+        assert_registry_initialized();
+
+        let funnel_node_registry = borrow_global_mut(@supra_framework);
+        let old_funnel_nodes = funnel_node_registry.funnel_nodes;
+        funnel_node_registry.funnel_nodes = new_funnel_nodes;
+        event::emit(FunnelNodesUpdated {
+            old_funnel_nodes,
+            new_funnel_nodes
+        })
+    }
+
+    #[view]
+    /// Get funnel nodes list.
+    public fun funnel_nodes(): vector acquires FunnelNodeRegistry {
+        assert_registry_initialized();
+        borrow_global_mut(@supra_framework).funnel_nodes
+    }
+
+    inline fun assert_registry_initialized() {
+        assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
+    }
+}
diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move
index 84d3685457888..d4d59069ba0f7 100644
--- a/aptos-move/framework/supra-framework/sources/genesis.move
+++ b/aptos-move/framework/supra-framework/sources/genesis.move
@@ -37,6 +37,7 @@ module supra_framework::genesis {
     use supra_framework::vesting;
     use supra_framework::vesting_without_staking;
     use supra_framework::microchain_registry::{Self, ReservedRange};
+    use supra_framework::funnel_node_registry;
 
     #[test_only]
     use aptos_std::ed25519;
@@ -277,6 +278,21 @@ module supra_framework::genesis {
         )
     }
 
+    /// Genesis step 5: Initialize Funnel Node Registry.
+    ///
+    /// This method allows to initialize the microchain registry either during the genesis initialization
+    /// or after it has been completed.
+    ///
+    /// Because it is publicly accessible, it can be invoked via a move-script. Since it requires
+    /// the `supra_framework` as the signer, the invocation must go through the governance process.
+    public fun initialize_funnel_node_registry(
+        supra_framework: &signer,
+        funnel_nodes: vector
+    ) {
+        funnel_node_registry::initialize(
+            supra_framework, funnel_nodes
+        )
+    }
 
     /// Only called for testnets and e2e tests.
     fun initialize_core_resources_and_supra_coin(
@@ -1188,4 +1204,4 @@ module supra_framework::genesis {
         let vesting_contracts = vesting_without_staking::vesting_contracts(admin_address);
         assert!(vector::length(&vesting_contracts) == 1, 0);
     }
-}
+}
\ No newline at end of file
diff --git a/aptos-move/framework/supra-framework/sources/microchain_registry.move b/aptos-move/framework/supra-framework/sources/microchain_registry.move
index 66eadb4ac1943..21ce8d3a077d9 100644
--- a/aptos-move/framework/supra-framework/sources/microchain_registry.move
+++ b/aptos-move/framework/supra-framework/sources/microchain_registry.move
@@ -1,6 +1,21 @@
 /// Copyright (c) 2025 Supra
+///
 /// Microchain Registry Module
-/// This module manages the registration and lifecycle of microchains on the Supra-L1.
+///
+/// This module manages the registration and lifecycle of microchains on Supra-L1.
+///
+/// 1. To enable support for a new microchain on Supra-L1, it must be first registered by Supra Governance
+///    using the `register_microchain` method of this module.
+/// 2. If a registered microchain misbehaves, it can be deactivated by Supra Governance through the `deactivate_microchain` method.
+/// 3. A previously deactivated microchain can be reactivated by Supra Governance using the `reactivate_microchain` method.
+/// 4. Although the registry data is updated immediately, the changes are only considered by Supra-L1 validators
+///    after an epoch change. Therefore, it is strongly recommended to trigger an epoch change by invoking
+///    `0x1::supra_governance::reconfigure`.
+/// 5. Supra-L1 validators consider the updated registry data only after the epoch change. Hence, it is
+///    highly recommended to perform an epoch change whenever the following methods are invoked:
+///     a. `register_microchain`
+///     b. `deactivate_microchain`
+///     c. `reactivate_microchain`
 module supra_framework::microchain_registry {
     use std::error;
     use std::string::String;
@@ -28,7 +43,7 @@ module supra_framework::microchain_registry {
     /// The microchain is already in the `INACTIVE` state and cannot be deactivated again.
     const EMICROCHAIN_ALREADY_DEACTIVATED: u64 = 4;
 
-    /// The microchain is already in the `ACTIVE` state and connot be reactivated.
+    /// The microchain is already in the `ACTIVE` state and cannot be reactivated.
     const EMICROCHAIN_ALREADY_ACTIVE: u64 = 5;
 
     /// The `MicrochainRegistry` resource has not been initialized at @supra_framework.
@@ -38,7 +53,7 @@ module supra_framework::microchain_registry {
     const EINVALID_RANGE: u64 = 7;
 
 
-    /// Never registered as a mirochain.
+    /// Never registered as a microchain.
     const STATE_UNKNOWN: u8 = 0;
     /// Registered as a microchain and actively working.
     const STATE_ACTIVE: u8 = 1;
@@ -101,8 +116,22 @@ module supra_framework::microchain_registry {
         });
     }
 
-    /// Registeres a new microchain.
-    public entry fun register_microchain(
+    /// Registers a new microchain.
+    ///
+    /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package),
+    /// it can only be invoked through a governance proposal move-script.
+    ///
+    /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure`
+    /// after invoking this method. While this method could perform the reconfiguration internally, it
+    /// intentionally does not. This is because governance proposal move-scripts may need to invoke
+    /// additional methods after this one, so the responsibility of reconfiguration is left to the caller.
+    ///
+    /// Example usage:
+    /// ```
+    /// supra_framework::microchain_registry::register_microchain(&supra_framework, chain_id, metadata_link);
+    /// supra_framework::supra_governance::reconfigure(&supra_framework);
+    /// ```
+    public fun register_microchain(
         supra_framework: &signer,
         chain_id: u8,
         metadata_link: String,
@@ -133,7 +162,21 @@ module supra_framework::microchain_registry {
     }
 
     /// Deactivates the already registered microchain.
-    public entry fun deactivate_microchain(
+    ///
+    /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package),
+    /// it can only be invoked through a governance proposal move-script.
+    ///
+    /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure`
+    /// after invoking this method. While this method could perform the reconfiguration internally, it
+    /// intentionally does not. This is because governance proposal move-scripts may need to invoke
+    /// additional methods after this one, so the responsibility of reconfiguration is left to the caller.
+    ///
+    /// Example usage:
+    /// ```
+    /// supra_framework::microchain_registry::deactivate_microchain(&supra_framework, chain_id);
+    /// supra_framework::supra_governance::reconfigure(&supra_framework);
+    /// ```
+    public fun deactivate_microchain(
         supra_framework: &signer,
         chain_id: u8,
     ) acquires MicrochainRegistry {
@@ -151,7 +194,21 @@ module supra_framework::microchain_registry {
     }
 
     /// Reactivates the deactivated microchain.
-    public entry fun reactivate_microchain(
+    ///
+    /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package),
+    /// it can only be invoked through a governance proposal move-script.
+    ///
+    /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure`
+    /// after invoking this method. While this method could perform the reconfiguration internally, it
+    /// intentionally does not. This is because governance proposal move-scripts may need to invoke
+    /// additional methods after this one, so the responsibility of reconfiguration is left to the caller.
+    ///
+    /// Example usage:
+    /// ```
+    /// supra_framework::microchain_registry::reactivate_microchain(&supra_framework, chain_id);
+    /// supra_framework::supra_governance::reconfigure(&supra_framework);
+    /// ```
+    public fun reactivate_microchain(
         supra_framework: &signer,
         chain_id: u8,
     ) acquires MicrochainRegistry {
@@ -169,7 +226,7 @@ module supra_framework::microchain_registry {
     }
 
     /// Updates metadata link of a registered microchain.
-    public entry fun update_microchain_metadata_link(
+    public fun update_microchain_metadata_link(
         supra_framework: &signer,
         chain_id: u8,
         new_metadata_link: String,
@@ -189,7 +246,7 @@ module supra_framework::microchain_registry {
     }
 
     /// Adds a reserved chain ID range.
-    public entry fun add_reserved_range(
+    public fun add_reserved_range(
         supra_framework: &signer,
         start: u8,
         end: u8,
@@ -202,7 +259,7 @@ module supra_framework::microchain_registry {
 
 
     /// Constructor to create an instance of the `ReservedRange`.
-    /// This will be utilsed in move-script to initialize the microchain registry with reserved ranges.
+    /// This will be utilized in move-script to initialize the microchain registry with reserved ranges.
     public fun new_reserved_range(
         start: u8,
         end: u8,
@@ -230,7 +287,7 @@ module supra_framework::microchain_registry {
     }
 
     #[view]
-    /// Get chain IDs of all mirochains with `Active` state.
+    /// Get chain IDs of all microchain with `Active` state.
     public fun active_microchains(): vector acquires MicrochainRegistry {
         let microchain_registry = borrow_global_microchain_registry();
         let microchains_chain_id = simple_map::keys(µchain_registry.microchains);
diff --git a/aptos-move/framework/supra-framework/tests/funnel_node_registry_tests.move b/aptos-move/framework/supra-framework/tests/funnel_node_registry_tests.move
new file mode 100644
index 0000000000000..94d48adc704af
--- /dev/null
+++ b/aptos-move/framework/supra-framework/tests/funnel_node_registry_tests.move
@@ -0,0 +1,88 @@
+#[test_only]
+module supra_framework::funnel_node_registry_tests {
+    use std::string::{Self, String};
+    use std::vector;
+
+    use supra_framework::account;
+    use supra_framework::funnel_node_registry;
+
+
+    // Test helper to create a vector of funnel node Socket-Address
+    fun create_test_funnel_nodes(): vector {
+        let nodes = vector::empty();
+        vector::push_back(&mut nodes, string::utf8(b"1.1.1.1:26000"));
+        vector::push_back(&mut nodes, string::utf8(b"2.1.1.1:26000"));
+        vector::push_back(&mut nodes, string::utf8(b"3.1.1.1:26000"));
+        nodes
+    }
+
+
+    // Test helper to create updated funnel nodes
+    fun create_updated_funnel_nodes(): vector {
+        let nodes = vector::empty();
+        vector::push_back(&mut nodes, string::utf8(b"4.1.1.1:26000"));
+        vector::push_back(&mut nodes, string::utf8(b"5.1.1.1:26000"));
+        nodes
+    }
+
+
+    // Module Initialization Tests.
+
+    #[test]
+    fun test_initialize() {
+        let supra_framework = account::create_account_for_test(@supra_framework);
+        let funnel_nodes = create_test_funnel_nodes();
+        funnel_node_registry::initialize(&supra_framework, funnel_nodes);
+
+        let stored_nodes = funnel_node_registry::funnel_nodes();
+        assert!(vector::length(&stored_nodes) == 3, 1);
+        assert!(vector::borrow(&stored_nodes, 0) == vector::borrow(&funnel_nodes, 0), 2);
+        assert!(vector::borrow(&stored_nodes, 1) == vector::borrow(&funnel_nodes, 1), 3);
+        assert!(vector::borrow(&stored_nodes, 2) == vector::borrow(&funnel_nodes, 2), 4);
+    }
+
+    #[test]
+    #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)]
+    fun test_initialize_fails_non_framework() {
+        let non_supra_framework = account::create_account_for_test(@123);
+        let funnel_nodes = create_test_funnel_nodes();
+        funnel_node_registry::initialize(&non_supra_framework, funnel_nodes);
+    }
+
+
+    // Update Funnel Nodes Tests.
+
+    #[test]
+    fun test_update_funnel_nodes() {
+        let supra_framework = account::create_account_for_test(@supra_framework);
+        let initial_funnel_nodes = create_test_funnel_nodes();
+        funnel_node_registry::initialize(&supra_framework, initial_funnel_nodes);
+
+        let new_funnel_nodes = create_updated_funnel_nodes();
+        funnel_node_registry::update_funnel_nodes(&supra_framework, new_funnel_nodes);
+        let stored_nodes = funnel_node_registry::funnel_nodes();
+        assert!(vector::length(&stored_nodes) == 2, 1);
+        assert!(vector::borrow(&stored_nodes, 0) == vector::borrow(&new_funnel_nodes, 0), 2);
+        assert!(vector::borrow(&stored_nodes, 1) == vector::borrow(&new_funnel_nodes, 1), 3);
+    }
+
+    #[test]
+    #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)]
+    fun test_update_fails_non_framework() {
+        let supra_framework = account::create_account_for_test(@supra_framework);
+        let initial_funnel_nodes = create_test_funnel_nodes();
+        funnel_node_registry::initialize(&supra_framework, initial_funnel_nodes);
+
+        let non_supra_framework = account::create_account_for_test(@123);
+        let new_funnel_nodes = create_updated_funnel_nodes();
+        funnel_node_registry::update_funnel_nodes(&non_supra_framework, new_funnel_nodes);
+    }
+
+    #[test]
+    #[expected_failure(abort_code = 0x60001, location = supra_framework::funnel_node_registry)]
+    fun test_update_fails_not_initialized() {
+        let supra_framework = account::create_account_for_test(@supra_framework);
+        let new_funnel_nodes = create_updated_funnel_nodes();
+        funnel_node_registry::update_funnel_nodes(&supra_framework, new_funnel_nodes);
+    }
+}
\ No newline at end of file
diff --git a/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move b/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move
index 2a034f906580f..0c3f7968f4104 100644
--- a/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move
+++ b/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move
@@ -1,5 +1,3 @@
-/// Copywrite (c) 2025 Supra
-/// Microchain Registry Module testcases.
 #[test_only]
 module supra_framework::microchain_registry_tests {
     use std::string;
diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs
index af5c16f187b10..d680278b267dd 100644
--- a/aptos-move/vm-genesis/src/lib.rs
+++ b/aptos-move/vm-genesis/src/lib.rs
@@ -32,10 +32,10 @@ use aptos_types::{
     move_utils::as_move_value::AsMoveValue,
     on_chain_config::{
         randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit},
-        AutomationRegistryConfig, FeatureFlag, Features, GasScheduleV2, MicrochainRegistryConfig,
-        OnChainConsensusConfig, OnChainEvmGenesisConfig, OnChainExecutionConfig,
-        OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct,
-        APTOS_MAX_KNOWN_VERSION,
+        AutomationRegistryConfig, FeatureFlag, Features, FunnelNodeRegistryConfig, GasScheduleV2,
+        MicrochainRegistryConfig, OnChainConsensusConfig, OnChainEvmGenesisConfig,
+        OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig,
+        RandomnessConfigMoveStruct, APTOS_MAX_KNOWN_VERSION,
     },
     transaction::{authenticator::AuthenticationKey, ChangeSet, Transaction, WriteSetPayload},
     write_set::TransactionWrite,
@@ -110,6 +110,7 @@ pub struct GenesisConfiguration {
     pub jwk_consensus_config_override: Option,
     pub automation_registry_config: Option,
     pub microchain_registry_config: Option,
+    pub funnel_node_registry_config: Option,
 }
 
 pub static GENESIS_KEYPAIR: Lazy<(Ed25519PrivateKey, Ed25519PublicKey)> = Lazy::new(|| {
@@ -177,6 +178,7 @@ pub fn encode_supra_mainnet_genesis_transaction(
     initialize_supra_coin(&mut session);
     initialize_supra_native_automation(&mut session, genesis_config);
     initialize_microchain_registry(&mut session, genesis_config);
+    initialize_funnel_node_registry(&mut session, genesis_config);
     initialize_on_chain_governance(&mut session, genesis_config);
     create_accounts(&mut session, accounts);
 
@@ -236,6 +238,7 @@ pub fn encode_supra_mainnet_genesis_transaction(
     Transaction::GenesisTransaction(WriteSetPayload::Direct(change_set))
 }
 
+#[allow(clippy::too_many_arguments)]
 pub fn encode_genesis_transaction_for_testnet(
     aptos_root_key: Ed25519PublicKey,
     validators: &[Validator],
@@ -276,6 +279,7 @@ pub fn encode_genesis_transaction_for_testnet(
     ))
 }
 
+#[allow(clippy::too_many_arguments)]
 pub fn encode_genesis_change_set_for_testnet(
     core_resources_key: &Ed25519PublicKey,
     accounts: &BTreeSet,
@@ -330,6 +334,7 @@ pub fn encode_genesis_change_set_for_testnet(
     }
     initialize_supra_native_automation(&mut session, genesis_config);
     initialize_microchain_registry(&mut session, genesis_config);
+    initialize_funnel_node_registry(&mut session, genesis_config);
     initialize_config_buffer(&mut session);
     initialize_dkg(&mut session);
     initialize_reconfiguration_state(&mut session);
@@ -601,6 +606,22 @@ fn initialize_microchain_registry(session: &mut SessionExt, genesis_config: &Gen
     );
 }
 
+fn initialize_funnel_node_registry(
+    session: &mut SessionExt,
+    genesis_config: &GenesisConfiguration,
+) {
+    let Some(config) = &genesis_config.funnel_node_registry_config else {
+        return;
+    };
+    exec_function(
+        session,
+        GENESIS_MODULE_NAME,
+        "initialize_funnel_node_registry",
+        vec![],
+        config.serialize_into_move_values(),
+    );
+}
+
 fn initialize_evm_genesis_config(
     session: &mut SessionExt,
     evm_genesis_config: &OnChainEvmGenesisConfig,
@@ -1260,6 +1281,7 @@ pub fn generate_test_genesis(
             jwk_consensus_config_override: None,
             automation_registry_config: Some(AutomationRegistryConfig::default()),
             microchain_registry_config: Some(MicrochainRegistryConfig::default()),
+            funnel_node_registry_config: Some(FunnelNodeRegistryConfig::default()),
         },
         &OnChainConsensusConfig::default_for_genesis(),
         &OnChainExecutionConfig::default_for_genesis(),
@@ -1329,6 +1351,7 @@ fn mainnet_genesis_config() -> GenesisConfiguration {
         jwk_consensus_config_override: None,
         automation_registry_config: Some(AutomationRegistryConfig::default()),
         microchain_registry_config: Some(MicrochainRegistryConfig::default()),
+        funnel_node_registry_config: Some(FunnelNodeRegistryConfig::default()),
     }
 }
 
diff --git a/crates/aptos-genesis/src/builder.rs b/crates/aptos-genesis/src/builder.rs
index bdb84a172d61a..048f7c6e7aecc 100644
--- a/crates/aptos-genesis/src/builder.rs
+++ b/crates/aptos-genesis/src/builder.rs
@@ -24,6 +24,9 @@ use aptos_crypto::{
 use aptos_framework::ReleaseBundle;
 use aptos_keygen::KeyGen;
 use aptos_logger::prelude::*;
+use aptos_types::on_chain_config::{
+    AutomationRegistryConfig, FunnelNodeRegistryConfig, MicrochainRegistryConfig,
+};
 use aptos_types::{
     account_address::AccountAddress,
     chain_id::ChainId,
@@ -45,7 +48,6 @@ use std::{
     path::{Path, PathBuf},
     sync::Arc,
 };
-use aptos_types::on_chain_config::AutomationRegistryConfig;
 
 const VALIDATOR_IDENTITY: &str = "validator-identity.yaml";
 const VFN_IDENTITY: &str = "vfn-identity.yaml";
@@ -438,6 +440,8 @@ pub struct GenesisConfiguration {
     pub randomness_config_override: Option,
     pub jwk_consensus_config_override: Option,
     pub automation_registry_config: Option,
+    pub microchain_registry_config: Option,
+    pub funnel_node_registry_config: Option,
 }
 
 pub type InitConfigFn = Arc;
@@ -662,6 +666,8 @@ impl Builder {
             randomness_config_override: None,
             jwk_consensus_config_override: None,
             automation_registry_config: Some(AutomationRegistryConfig::default()),
+            microchain_registry_config: Some(MicrochainRegistryConfig::default()),
+            funnel_node_registry_config: Some(FunnelNodeRegistryConfig::default()),
         };
         if let Some(init_genesis_config) = &self.init_genesis_config {
             (init_genesis_config)(&mut genesis_config);
diff --git a/crates/aptos-genesis/src/config.rs b/crates/aptos-genesis/src/config.rs
index 5449c46382afe..b2d9e39f12d21 100644
--- a/crates/aptos-genesis/src/config.rs
+++ b/crates/aptos-genesis/src/config.rs
@@ -3,6 +3,9 @@
 
 use aptos_config::config::HANDSHAKE_VERSION;
 use aptos_crypto::{ed25519, ed25519::Ed25519PublicKey, x25519};
+use aptos_types::on_chain_config::{
+    AutomationRegistryConfig, FunnelNodeRegistryConfig, MicrochainRegistryConfig,
+};
 use aptos_types::{
     account_address::{AccountAddress, AccountAddressWithChecks},
     chain_id::ChainId,
@@ -21,7 +24,6 @@ use std::{
     path::Path,
     str::FromStr,
 };
-use aptos_types::on_chain_config::AutomationRegistryConfig;
 
 /// Template for setting up Github for Genesis
 ///
@@ -83,6 +85,8 @@ pub struct Layout {
     pub jwk_consensus_config_override: Option,
     /// An optional supra native automation config.
     pub automation_registry_config: Option,
+    pub microchain_registry_config: Option,
+    pub funnel_node_registry_config: Option,
 }
 
 impl Layout {
@@ -126,6 +130,8 @@ impl Default for Layout {
             on_chain_execution_config: OnChainExecutionConfig::default_for_genesis(),
             jwk_consensus_config_override: None,
             automation_registry_config: Some(AutomationRegistryConfig::default()),
+            microchain_registry_config: Some(MicrochainRegistryConfig::default()),
+            funnel_node_registry_config: Some(FunnelNodeRegistryConfig::default()),
         }
     }
 }
diff --git a/crates/aptos-genesis/src/lib.rs b/crates/aptos-genesis/src/lib.rs
index 1c5b9fd858da2..02c0165a7ff4e 100644
--- a/crates/aptos-genesis/src/lib.rs
+++ b/crates/aptos-genesis/src/lib.rs
@@ -21,11 +21,15 @@ use aptos_db::AptosDB;
 use aptos_framework::ReleaseBundle;
 use aptos_storage_interface::DbReaderWriter;
 use aptos_temppath::TempPath;
+use aptos_types::on_chain_config::{
+    AutomationRegistryConfig, FunnelNodeRegistryConfig, MicrochainRegistryConfig,
+};
 use aptos_types::{
     account_address::AccountAddress,
     chain_id::ChainId,
     on_chain_config::{
-        Features, GasScheduleV2, OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig
+        Features, GasScheduleV2, OnChainConsensusConfig, OnChainExecutionConfig,
+        OnChainJWKConsensusConfig, OnChainRandomnessConfig,
     },
     transaction::Transaction,
     waypoint::Waypoint,
@@ -33,7 +37,6 @@ use aptos_types::{
 use aptos_vm::AptosVM;
 use aptos_vm_genesis::Validator;
 use std::convert::TryInto;
-use aptos_types::on_chain_config::AutomationRegistryConfig;
 
 /// Holder object for all pieces needed to generate a genesis transaction
 #[derive(Clone)]
@@ -82,6 +85,8 @@ pub struct GenesisInfo {
     pub randomness_config_override: Option,
     pub jwk_consensus_config_override: Option,
     pub automation_registry_config: Option,
+    pub microchain_registry_config: Option,
+    pub funnel_node_registry_config: Option,
 }
 
 impl GenesisInfo {
@@ -124,6 +129,8 @@ impl GenesisInfo {
             randomness_config_override: genesis_config.randomness_config_override.clone(),
             jwk_consensus_config_override: genesis_config.jwk_consensus_config_override.clone(),
             automation_registry_config: genesis_config.automation_registry_config.clone(),
+            microchain_registry_config: genesis_config.microchain_registry_config.clone(),
+            funnel_node_registry_config: genesis_config.funnel_node_registry_config.clone(),
         })
     }
 
@@ -152,7 +159,7 @@ impl GenesisInfo {
                 epoch_duration_secs: self.epoch_duration_secs,
                 is_test: true,
                 min_stake: self.min_stake,
-                min_voting_threshold: self.min_voting_threshold as u64,
+                min_voting_threshold: self.min_voting_threshold,
                 max_stake: self.max_stake,
                 recurring_lockup_duration_secs: self.recurring_lockup_duration_secs,
                 required_proposer_stake: self.required_proposer_stake,
@@ -167,6 +174,8 @@ impl GenesisInfo {
                 jwk_consensus_config_override: self.jwk_consensus_config_override.clone(),
                 genesis_timestamp_in_microseconds: self.genesis_timestamp_in_microseconds,
                 automation_registry_config: self.automation_registry_config.clone(),
+                microchain_registry_config: self.microchain_registry_config.clone(),
+                funnel_node_registry_config: self.funnel_node_registry_config.clone(),
             },
             &self.consensus_config,
             &self.execution_config,
diff --git a/crates/aptos-genesis/src/mainnet.rs b/crates/aptos-genesis/src/mainnet.rs
index 1478112f58cf9..8a5d6c4fa7a85 100644
--- a/crates/aptos-genesis/src/mainnet.rs
+++ b/crates/aptos-genesis/src/mainnet.rs
@@ -10,6 +10,9 @@ use aptos_db::AptosDB;
 use aptos_framework::ReleaseBundle;
 use aptos_storage_interface::DbReaderWriter;
 use aptos_temppath::TempPath;
+use aptos_types::on_chain_config::{
+    AutomationRegistryConfig, FunnelNodeRegistryConfig, MicrochainRegistryConfig,
+};
 use aptos_types::{
     account_address::AccountAddress,
     chain_id::ChainId,
@@ -17,7 +20,6 @@ use aptos_types::{
     transaction::Transaction,
     waypoint::Waypoint,
 };
-use aptos_types::on_chain_config::AutomationRegistryConfig;
 use aptos_vm::AptosVM;
 use aptos_vm_genesis::{AccountBalance, EmployeePool, ValidatorWithCommissionRate};
 
@@ -72,6 +74,8 @@ pub struct MainnetGenesisInfo {
     jwk_consensus_config_override: Option,
     /// Supra native automation feature configuration parameters
     automation_registry_config: Option,
+    microchain_registry_config: Option,
+    funnel_node_registry_config: Option,
 }
 
 impl MainnetGenesisInfo {
@@ -117,6 +121,8 @@ impl MainnetGenesisInfo {
             randomness_config_override: genesis_config.randomness_config_override.clone(),
             jwk_consensus_config_override: genesis_config.jwk_consensus_config_override.clone(),
             automation_registry_config: genesis_config.automation_registry_config.clone(),
+            microchain_registry_config: genesis_config.microchain_registry_config.clone(),
+            funnel_node_registry_config: genesis_config.funnel_node_registry_config.clone(),
         })
     }
 
@@ -146,7 +152,7 @@ impl MainnetGenesisInfo {
                 is_test: false,
                 epoch_duration_secs: self.epoch_duration_secs,
                 min_stake: self.min_stake,
-                min_voting_threshold: self.min_voting_threshold as u64,
+                min_voting_threshold: self.min_voting_threshold,
                 max_stake: self.max_stake,
                 recurring_lockup_duration_secs: self.recurring_lockup_duration_secs,
                 required_proposer_stake: self.required_proposer_stake,
@@ -161,6 +167,8 @@ impl MainnetGenesisInfo {
                 randomness_config_override: self.randomness_config_override.clone(),
                 jwk_consensus_config_override: self.jwk_consensus_config_override.clone(),
                 automation_registry_config: self.automation_registry_config.clone(),
+                microchain_registry_config: self.microchain_registry_config.clone(),
+                funnel_node_registry_config: self.funnel_node_registry_config.clone(),
             },
             b"test".to_vec(),
         )
diff --git a/crates/aptos/src/genesis/mod.rs b/crates/aptos/src/genesis/mod.rs
index f893ca4b88fb4..a274012b582fb 100644
--- a/crates/aptos/src/genesis/mod.rs
+++ b/crates/aptos/src/genesis/mod.rs
@@ -260,6 +260,8 @@ pub fn fetch_mainnet_genesis_info(git_options: GitOptions) -> CliTypedResult CliTypedResult,
+}
+
+impl FunnelNodeRegistryConfig {
+    pub fn new(funnel_nodes: Vec) -> Self {
+        Self { funnel_nodes }
+    }
+
+    pub fn serialize_into_move_values(&self) -> Vec> {
+        let funnel_nodes_vec_move_value = self
+            .funnel_nodes
+            .iter()
+            .map(|node_socket_addr| {
+                MoveValue::Struct(MoveStruct::new(vec![MoveValue::vector_u8(
+                    node_socket_addr.to_string().into_bytes(),
+                )]))
+            })
+            .collect::>();
+        let arguments = vec![
+            MoveValue::Signer(CORE_CODE_ADDRESS),
+            MoveValue::Vector(funnel_nodes_vec_move_value),
+        ];
+        serialize_values(&arguments)
+    }
+}
diff --git a/types/src/on_chain_config/microchain_registry.rs b/types/src/on_chain_config/microchain_registry.rs
index bbee305b57e3f..9031f4c13577e 100644
--- a/types/src/on_chain_config/microchain_registry.rs
+++ b/types/src/on_chain_config/microchain_registry.rs
@@ -1,7 +1,8 @@
 use crate::account_config::CORE_CODE_ADDRESS;
 use move_core_types::value::{serialize_values, MoveStruct, MoveValue};
+use serde::{Deserialize, Serialize};
 
-#[derive(Clone, Debug, Default)]
+#[derive(Clone, Debug, Default, Deserialize, Serialize)]
 pub struct MicrochainRegistryConfig {
     reserved_ranges: Vec,
 }
@@ -15,7 +16,7 @@ impl MicrochainRegistryConfig {
         let reserved_ranges_vec_move_value = self
             .reserved_ranges
             .iter()
-            .map(|range| MoveValue::from(range))
+            .map(MoveValue::from)
             .collect::>();
         let arguments = vec![
             MoveValue::Signer(CORE_CODE_ADDRESS),
@@ -25,7 +26,7 @@ impl MicrochainRegistryConfig {
     }
 }
 
-#[derive(Clone, Debug, Default)]
+#[derive(Clone, Debug, Default, Deserialize, Serialize)]
 pub struct ReservedRange {
     start: u8,
     end: u8,
diff --git a/types/src/on_chain_config/mod.rs b/types/src/on_chain_config/mod.rs
index f45f9446a95a7..d88651beb8010 100644
--- a/types/src/on_chain_config/mod.rs
+++ b/types/src/on_chain_config/mod.rs
@@ -29,6 +29,7 @@ mod commit_history;
 mod consensus_config;
 mod evm_genesis_config;
 mod execution_config;
+mod funnel_node_registry;
 mod gas_schedule;
 mod jwk_consensus_config;
 mod microchain_registry;
@@ -63,6 +64,7 @@ pub use self::{
         BlockGasLimitType, ExecutionConfigV1, ExecutionConfigV2, ExecutionConfigV4,
         OnChainExecutionConfig, TransactionDeduperType, TransactionShufflerType,
     },
+    funnel_node_registry::FunnelNodeRegistryConfig,
     gas_schedule::{DiffItem, GasSchedule, GasScheduleV2, StorageGasSchedule},
     jwk_consensus_config::{
         ConfigV1 as JWKConsensusConfigV1, OIDCProvider, OnChainJWKConsensusConfig,

From 024fde293f91e4b81cd10b1c941690dd0d66c5a7 Mon Sep 17 00:00:00 2001
From: vpanchal-supra 
Date: Thu, 13 Nov 2025 14:21:54 +0530
Subject: [PATCH 3/7] impl essential trait and used url instead of socket_addr

---
 .../doc/funnel_node_registry.md               |  2 +-
 .../doc/microchain_registry.md                |  4 +--
 .../sources/funnel_node_registry.move         |  2 +-
 .../sources/microchain_registry.move          |  9 +++---
 .../tests/microchain_registry_tests.move      | 10 +++----
 types/Cargo.toml                              |  9 ++++--
 .../on_chain_config/funnel_node_registry.rs   | 13 ++++----
 .../on_chain_config/microchain_registry.rs    | 30 ++++++++++++++-----
 8 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/aptos-move/framework/supra-framework/doc/funnel_node_registry.md b/aptos-move/framework/supra-framework/doc/funnel_node_registry.md
index 5502a91d98095..72eac051da26c 100644
--- a/aptos-move/framework/supra-framework/doc/funnel_node_registry.md
+++ b/aptos-move/framework/supra-framework/doc/funnel_node_registry.md
@@ -141,7 +141,7 @@ Initializes the funnel node registry.
 Updates the funnel nodes in the funnel node registry.
 
 This method replaces the existing list of funnel nodes with the provided list. Therefore, it is
-strongly recommended that the new list contains valid Socket-Addresses for all funnel nodes, and that the nodes
+strongly recommended that the new list contains valid URLs for all funnel nodes, and that the nodes
 are ordered based on their reputation and trust level.
 
 Technically, deduplication of new_funnel_nodes is necessary. However, performing it consumes a
diff --git a/aptos-move/framework/supra-framework/doc/microchain_registry.md b/aptos-move/framework/supra-framework/doc/microchain_registry.md
index 11612cb97f460..a92159bde0da3 100644
--- a/aptos-move/framework/supra-framework/doc/microchain_registry.md
+++ b/aptos-move/framework/supra-framework/doc/microchain_registry.md
@@ -383,7 +383,7 @@ Registered as a microchain and actively working.
 Registered as a microchain, but decommissioned from the Supra-L1.
 
 
-
const STATE_INACTIVE: u8 = 2;
+
const STATE_INACTIVE: u8 = 0;
 
@@ -393,7 +393,7 @@ Registered as a microchain, but decommissioned from the Supra-L1. Never registered as a microchain. -
const STATE_UNKNOWN: u8 = 0;
+
const STATE_UNKNOWN: u8 = 2;
 
diff --git a/aptos-move/framework/supra-framework/sources/funnel_node_registry.move b/aptos-move/framework/supra-framework/sources/funnel_node_registry.move index 1170f3cf1138f..2e61e07851d3c 100644 --- a/aptos-move/framework/supra-framework/sources/funnel_node_registry.move +++ b/aptos-move/framework/supra-framework/sources/funnel_node_registry.move @@ -44,7 +44,7 @@ module supra_framework::funnel_node_registry { /// Updates the funnel nodes in the funnel node registry. /// /// This method replaces the existing list of funnel nodes with the provided list. Therefore, it is - /// strongly recommended that the new list contains valid Socket-Addresses for all funnel nodes, and that the nodes + /// strongly recommended that the new list contains valid URLs for all funnel nodes, and that the nodes /// are ordered based on their reputation and trust level. /// /// Technically, deduplication of `new_funnel_nodes` is necessary. However, performing it consumes a diff --git a/aptos-move/framework/supra-framework/sources/microchain_registry.move b/aptos-move/framework/supra-framework/sources/microchain_registry.move index 21ce8d3a077d9..d9a8820735f7a 100644 --- a/aptos-move/framework/supra-framework/sources/microchain_registry.move +++ b/aptos-move/framework/supra-framework/sources/microchain_registry.move @@ -53,13 +53,12 @@ module supra_framework::microchain_registry { const EINVALID_RANGE: u64 = 7; - /// Never registered as a microchain. - const STATE_UNKNOWN: u8 = 0; + /// Registered as a microchain, but decommissioned from the Supra-L1. + const STATE_INACTIVE: u8 = 0; /// Registered as a microchain and actively working. const STATE_ACTIVE: u8 = 1; - /// Registered as a microchain, but decommissioned from the Supra-L1. - const STATE_INACTIVE: u8 = 2; - + /// Never registered as a microchain. + const STATE_UNKNOWN: u8 = 2; /// Represents reserved chain ID range. struct ReservedRange has store, copy, drop { diff --git a/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move b/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move index 0c3f7968f4104..4cb8c7f6ae565 100644 --- a/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move +++ b/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move @@ -7,12 +7,12 @@ module supra_framework::microchain_registry_tests { use supra_framework::microchain_registry; - /// Never registered as a mirochain. - const STATE_UNKNOWN: u8 = 0; + /// Registered as a microchain, but decommissioned from the Supra-L1. + const STATE_INACTIVE: u8 = 0; /// Registered as a microchain and actively working. const STATE_ACTIVE: u8 = 1; - /// Registered as a microchain, but decommissioned from the Supra-L1. - const STATE_INACTIVE: u8 = 2; + /// Never registered as a microchain. + const STATE_UNKNOWN: u8 = 2; // Test constants const TEST_CHAIN_ID_1: u8 = 10; @@ -296,4 +296,4 @@ module supra_framework::microchain_registry_tests { let supra_framework = setup_test(); microchain_registry::add_reserved_range(&supra_framework, 20, 10); } -} \ No newline at end of file +} diff --git a/types/Cargo.toml b/types/Cargo.toml index b25532ea0d7d1..e722e32d64d30 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -65,6 +65,7 @@ strum = { workspace = true } strum_macros = { workspace = true } thiserror = { workspace = true } derive_more = { workspace = true } +url = { workspace = true } [dev-dependencies] ahash = { workspace = true } @@ -86,11 +87,15 @@ regex = { workspace = true } reqwest = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true } -url = { workspace = true } [features] default = [] -fuzzing = ["proptest", "proptest-derive", "aptos-crypto/fuzzing", "move-core-types/fuzzing"] +fuzzing = [ + "proptest", + "proptest-derive", + "aptos-crypto/fuzzing", + "move-core-types/fuzzing", +] [[bench]] name = "keyless" diff --git a/types/src/on_chain_config/funnel_node_registry.rs b/types/src/on_chain_config/funnel_node_registry.rs index 3d5ffac88e830..6ea4ea74fcf4b 100644 --- a/types/src/on_chain_config/funnel_node_registry.rs +++ b/types/src/on_chain_config/funnel_node_registry.rs @@ -1,14 +1,15 @@ use crate::account_config::CORE_CODE_ADDRESS; use move_core_types::value::{serialize_values, MoveStruct, MoveValue}; use serde::{Deserialize, Serialize}; -use std::net::SocketAddr; -#[derive(Clone, Debug, Default, Deserialize, Serialize)] +use url::Url; + +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct FunnelNodeRegistryConfig { - funnel_nodes: Vec, + funnel_nodes: Vec, } impl FunnelNodeRegistryConfig { - pub fn new(funnel_nodes: Vec) -> Self { + pub fn new(funnel_nodes: Vec) -> Self { Self { funnel_nodes } } @@ -16,9 +17,9 @@ impl FunnelNodeRegistryConfig { let funnel_nodes_vec_move_value = self .funnel_nodes .iter() - .map(|node_socket_addr| { + .map(|node_endpoint_url| { MoveValue::Struct(MoveStruct::new(vec![MoveValue::vector_u8( - node_socket_addr.to_string().into_bytes(), + node_endpoint_url.to_string().into_bytes(), )])) }) .collect::>(); diff --git a/types/src/on_chain_config/microchain_registry.rs b/types/src/on_chain_config/microchain_registry.rs index 9031f4c13577e..9e449fbe768af 100644 --- a/types/src/on_chain_config/microchain_registry.rs +++ b/types/src/on_chain_config/microchain_registry.rs @@ -2,7 +2,7 @@ use crate::account_config::CORE_CODE_ADDRESS; use move_core_types::value::{serialize_values, MoveStruct, MoveValue}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub struct MicrochainRegistryConfig { reserved_ranges: Vec, } @@ -26,18 +26,12 @@ impl MicrochainRegistryConfig { } } -#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct ReservedRange { start: u8, end: u8, } -impl ReservedRange { - pub fn new(start: u8, end: u8) -> Self { - Self { start, end } - } -} - impl From<&ReservedRange> for MoveValue { fn from(value: &ReservedRange) -> MoveValue { MoveValue::Struct(MoveStruct::new(vec![ @@ -46,3 +40,23 @@ impl From<&ReservedRange> for MoveValue { ])) } } + +impl Default for ReservedRange { + fn default() -> Self { + Self { + start: Self::DEFAULT_START, + end: Self::DEFAULT_END, + } + } +} + +impl ReservedRange { + // Currently, default values are not finalized yet, however, by considering that our production + // networks chain IDs falls between 0-10, according to me the current default values are best. + pub const DEFAULT_START: u8 = 0; + pub const DEFAULT_END: u8 = 10; + + pub fn new(start: u8, end: u8) -> Self { + Self { start, end } + } +} From d7cda8c5bf79953889eeafd3a13b176d592846f2 Mon Sep 17 00:00:00 2001 From: vpanchal-supra Date: Tue, 2 Dec 2025 16:40:38 +0530 Subject: [PATCH 4/7] microchain -> appchain --- .../supra-framework/doc/appchain_registry.md | 1010 +++++++++++++++++ .../doc/funnel_node_registry.md | 2 +- .../framework/supra-framework/doc/genesis.md | 20 +- .../doc/microchain_registry.md | 1010 ----------------- .../framework/supra-framework/doc/overview.md | 2 +- .../sources/appchain_registry.move | 370 ++++++ ....spec.move => appchain_registry.spec.move} | 2 +- .../sources/funnel_node_registry.move | 2 +- .../supra-framework/sources/genesis.move | 14 +- .../sources/microchain_registry.move | 370 ------ .../tests/appchain_registry_tests.move | 299 +++++ .../tests/microchain_registry_tests.move | 299 ----- aptos-move/vm-genesis/src/lib.rs | 18 +- crates/aptos-genesis/src/builder.rs | 6 +- crates/aptos-genesis/src/config.rs | 6 +- crates/aptos-genesis/src/lib.rs | 8 +- crates/aptos-genesis/src/mainnet.rs | 8 +- crates/aptos/src/genesis/mod.rs | 4 +- ...chain_registry.rs => appchain_registry.rs} | 4 +- types/src/on_chain_config/mod.rs | 4 +- 20 files changed, 1729 insertions(+), 1729 deletions(-) create mode 100644 aptos-move/framework/supra-framework/doc/appchain_registry.md delete mode 100644 aptos-move/framework/supra-framework/doc/microchain_registry.md create mode 100644 aptos-move/framework/supra-framework/sources/appchain_registry.move rename aptos-move/framework/supra-framework/sources/{microchain_registry.spec.move => appchain_registry.spec.move} (56%) delete mode 100644 aptos-move/framework/supra-framework/sources/microchain_registry.move create mode 100644 aptos-move/framework/supra-framework/tests/appchain_registry_tests.move delete mode 100644 aptos-move/framework/supra-framework/tests/microchain_registry_tests.move rename types/src/on_chain_config/{microchain_registry.rs => appchain_registry.rs} (96%) diff --git a/aptos-move/framework/supra-framework/doc/appchain_registry.md b/aptos-move/framework/supra-framework/doc/appchain_registry.md new file mode 100644 index 0000000000000..f6c0d3e8715d4 --- /dev/null +++ b/aptos-move/framework/supra-framework/doc/appchain_registry.md @@ -0,0 +1,1010 @@ + + + +# Module `0x1::appchain_registry` + +Copyright (c) 2025 Supra + +Appchain Registry Module + +This module manages the registration and lifecycle of appchains on Supra-L1. + +1. To enable support for a new appchain on Supra-L1, it must be first registered by Supra Governance +using the register_appchain method of this module. +2. If a registered appchain misbehaves, it can be deactivated by Supra Governance through the deactivate_appchain method. +3. A previously deactivated appchain can be reactivated by Supra Governance using the reactivate_appchain method. +4. Although the registry data is updated immediately, the changes are only considered by Supra-L1 validators +after an epoch change. Therefore, it is strongly recommended to trigger an epoch change by invoking +0x1::supra_governance::reconfigure. +5. Supra-L1 validators consider the updated registry data only after the epoch change. Hence, it is +highly recommended to perform an epoch change whenever the following methods are invoked: +a. register_appchain +b. deactivate_appchain +c. reactivate_appchain + + +- [Struct `ReservedRange`](#0x1_appchain_registry_ReservedRange) +- [Struct `AppchainInfo`](#0x1_appchain_registry_AppchainInfo) +- [Resource `AppchainRegistry`](#0x1_appchain_registry_AppchainRegistry) +- [Struct `AppchainRegistered`](#0x1_appchain_registry_AppchainRegistered) +- [Struct `AppchainDeactivated`](#0x1_appchain_registry_AppchainDeactivated) +- [Struct `AppchainReactivated`](#0x1_appchain_registry_AppchainReactivated) +- [Struct `AppchainMetadataLinkUpdated`](#0x1_appchain_registry_AppchainMetadataLinkUpdated) +- [Constants](#@Constants_0) +- [Function `initialize`](#0x1_appchain_registry_initialize) +- [Function `register_appchain`](#0x1_appchain_registry_register_appchain) +- [Function `deactivate_appchain`](#0x1_appchain_registry_deactivate_appchain) +- [Function `reactivate_appchain`](#0x1_appchain_registry_reactivate_appchain) +- [Function `update_appchain_metadata_link`](#0x1_appchain_registry_update_appchain_metadata_link) +- [Function `add_reserved_range`](#0x1_appchain_registry_add_reserved_range) +- [Function `new_reserved_range`](#0x1_appchain_registry_new_reserved_range) +- [Function `appchain_state`](#0x1_appchain_registry_appchain_state) +- [Function `is_appchain_active`](#0x1_appchain_registry_is_appchain_active) +- [Function `active_appchains`](#0x1_appchain_registry_active_appchains) +- [Function `appchain_metadata_link`](#0x1_appchain_registry_appchain_metadata_link) +- [Function `appchain_info`](#0x1_appchain_registry_appchain_info) +- [Function `is_chain_id_reserved`](#0x1_appchain_registry_is_chain_id_reserved) +- [Function `borrow_global_appchain_registry`](#0x1_appchain_registry_borrow_global_appchain_registry) +- [Function `borrow_global_mut_appchain_registry`](#0x1_appchain_registry_borrow_global_mut_appchain_registry) +- [Function `assert_appchain_registered`](#0x1_appchain_registry_assert_appchain_registered) +- [Function `is_chain_id_reserved_internal`](#0x1_appchain_registry_is_chain_id_reserved_internal) +- [Specification](#@Specification_1) + + +
use 0x1::error;
+use 0x1::event;
+use 0x1::simple_map;
+use 0x1::string;
+use 0x1::system_addresses;
+
+ + + + + +## Struct `ReservedRange` + +Represents reserved chain ID range. + + +
struct ReservedRange has copy, drop, store
+
+ + + +
+Fields + + +
+
+start: u8 +
+
+ +
+
+end: u8 +
+
+ +
+
+ + +
+ + + +## Struct `AppchainInfo` + +Represents information about the registered appchain. + + +
struct AppchainInfo has copy, drop, store
+
+ + + +
+Fields + + +
+
+state: u8 +
+
+ +
+
+metadata_link: string::String +
+
+ +
+
+ + +
+ + + +## Resource `AppchainRegistry` + +Global appchain registry resource. + + +
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
+struct AppchainRegistry has key
+
+ + + +
+Fields + + +
+
+appchains: simple_map::SimpleMap<u8, appchain_registry::AppchainInfo> +
+
+ Map from chain ID to appchain info. +
+
+reserved_ranges: vector<appchain_registry::ReservedRange> +
+
+ Reserved chain ID ranges. +
+
+ + +
+ + + +## Struct `AppchainRegistered` + + + +
#[event]
+struct AppchainRegistered has drop, store
+
+ + + +
+Fields + + +
+
+chain_id: u8 +
+
+ +
+
+metadata_link: string::String +
+
+ +
+
+ + +
+ + + +## Struct `AppchainDeactivated` + + + +
#[event]
+struct AppchainDeactivated has drop, store
+
+ + + +
+Fields + + +
+
+chain_id: u8 +
+
+ +
+
+ + +
+ + + +## Struct `AppchainReactivated` + + + +
#[event]
+struct AppchainReactivated has drop, store
+
+ + + +
+Fields + + +
+
+chain_id: u8 +
+
+ +
+
+ + +
+ + + +## Struct `AppchainMetadataLinkUpdated` + + + +
#[event]
+struct AppchainMetadataLinkUpdated has drop, store
+
+ + + +
+Fields + + +
+
+chain_id: u8 +
+
+ +
+
+old_metadata_link: string::String +
+
+ +
+
+new_metadata_link: string::String +
+
+ +
+
+ + +
+ + + +## Constants + + + + +The provided range is invalid, start value must be less than or equal to end value. + + +
const EINVALID_RANGE: u64 = 7;
+
+ + + + + +The appchain is already in the ACTIVE state and cannot be reactivated. + + +
const EAPPCHAIN_ALREADY_ACTIVE: u64 = 5;
+
+ + + + + +The appchain is already in the INACTIVE state and cannot be deactivated again. + + +
const EAPPCHAIN_ALREADY_DEACTIVATED: u64 = 4;
+
+ + + + + +The appchain with the given chain ID is already registered in the appchain registry. + + +
const EAPPCHAIN_ALREADY_REGISTERED: u64 = 1;
+
+ + + + + +The appchain with the given chain ID is not found in the appchain registry. + + +
const EAPPCHAIN_NOT_REGISTERED: u64 = 2;
+
+ + + + + +The chain ID falls within a reserved range and cannot be used for registration. + + +
const ECHAIN_ID_RESERVED: u64 = 3;
+
+ + + + + +The AppchainRegistry resource has not been initialized at @supra_framework. + + +
const EREGISTRY_NOT_INITIALIZED: u64 = 6;
+
+ + + + + +Registered as a appchain and actively working. + + +
const STATE_ACTIVE: u8 = 1;
+
+ + + + + +Registered as a appchain, but decommissioned from the Supra-L1. + + +
const STATE_INACTIVE: u8 = 0;
+
+ + + + + +Never registered as a appchain. + + +
const STATE_UNKNOWN: u8 = 2;
+
+ + + + + +## Function `initialize` + +Initializes the appchain registry. + + +
public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector<appchain_registry::ReservedRange>)
+
+ + + +
+Implementation + + +
public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector<ReservedRange>) {
+    system_addresses::assert_supra_framework(supra_framework);
+
+    move_to(supra_framework, AppchainRegistry {
+        appchains: simple_map::new(),
+        reserved_ranges,
+    });
+}
+
+ + + +
+ + + +## Function `register_appchain` + +Registers a new appchain. + +This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package), +it can only be invoked through a governance proposal move-script. + +It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure +after invoking this method. While this method could perform the reconfiguration internally, it +intentionally does not. This is because governance proposal move-scripts may need to invoke +additional methods after this one, so the responsibility of reconfiguration is left to the caller. + +Example usage: +``` +supra_framework::appchain_registry::register_appchain(&supra_framework, chain_id, metadata_link); +supra_framework::supra_governance::reconfigure(&supra_framework); +``` + + +
public fun register_appchain(supra_framework: &signer, chain_id: u8, metadata_link: string::String)
+
+ + + +
+Implementation + + +
public fun register_appchain(
+    supra_framework: &signer,
+    chain_id: u8,
+    metadata_link: String,
+) acquires AppchainRegistry {
+    let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
+
+    // Checks if given chain ID is reserved.
+    assert!(
+        !is_chain_id_reserved_internal(chain_id, &appchain_registry.reserved_ranges),
+        error::invalid_argument(ECHAIN_ID_RESERVED)
+    );
+    // Checks if a appchain is already registered.
+    assert!(
+        !simple_map::contains_key(&appchain_registry.appchains, &chain_id),
+        error::already_exists(EAPPCHAIN_ALREADY_REGISTERED)
+    );
+
+    let appchain_info = AppchainInfo {
+        state: STATE_ACTIVE,
+        metadata_link,
+    };
+    simple_map::add(&mut appchain_registry.appchains, chain_id, appchain_info);
+
+    event::emit(AppchainRegistered {
+        chain_id,
+        metadata_link,
+    });
+}
+
+ + + +
+ + + +## Function `deactivate_appchain` + +Deactivates the already registered appchain. + +This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package), +it can only be invoked through a governance proposal move-script. + +It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure +after invoking this method. While this method could perform the reconfiguration internally, it +intentionally does not. This is because governance proposal move-scripts may need to invoke +additional methods after this one, so the responsibility of reconfiguration is left to the caller. + +Example usage: +``` +supra_framework::appchain_registry::deactivate_appchain(&supra_framework, chain_id); +supra_framework::supra_governance::reconfigure(&supra_framework); +``` + + +
public fun deactivate_appchain(supra_framework: &signer, chain_id: u8)
+
+ + + +
+Implementation + + +
public fun deactivate_appchain(
+    supra_framework: &signer,
+    chain_id: u8,
+) acquires AppchainRegistry {
+    let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
+    assert_appchain_registered(&appchain_registry.appchains, &chain_id);
+
+    let appchain_info = simple_map::borrow_mut(&mut appchain_registry.appchains, &chain_id);
+    assert!(appchain_info.state == STATE_ACTIVE, error::invalid_state(EAPPCHAIN_ALREADY_DEACTIVATED));
+
+    appchain_info.state = STATE_INACTIVE;
+
+    event::emit(AppchainDeactivated {
+        chain_id,
+    });
+}
+
+ + + +
+ + + +## Function `reactivate_appchain` + +Reactivates the deactivated appchain. + +This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package), +it can only be invoked through a governance proposal move-script. + +It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure +after invoking this method. While this method could perform the reconfiguration internally, it +intentionally does not. This is because governance proposal move-scripts may need to invoke +additional methods after this one, so the responsibility of reconfiguration is left to the caller. + +Example usage: +``` +supra_framework::appchain_registry::reactivate_appchain(&supra_framework, chain_id); +supra_framework::supra_governance::reconfigure(&supra_framework); +``` + + +
public fun reactivate_appchain(supra_framework: &signer, chain_id: u8)
+
+ + + +
+Implementation + + +
public fun reactivate_appchain(
+    supra_framework: &signer,
+    chain_id: u8,
+) acquires AppchainRegistry {
+    let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
+    assert_appchain_registered(&appchain_registry.appchains, &chain_id);
+
+    let appchain_info = simple_map::borrow_mut(&mut appchain_registry.appchains, &chain_id);
+    assert!(appchain_info.state == STATE_INACTIVE, error::invalid_state(EAPPCHAIN_ALREADY_ACTIVE));
+
+    appchain_info.state = STATE_ACTIVE;
+
+    event::emit(AppchainReactivated {
+        chain_id,
+    });
+}
+
+ + + +
+ + + +## Function `update_appchain_metadata_link` + +Updates metadata link of a registered appchain. + + +
public fun update_appchain_metadata_link(supra_framework: &signer, chain_id: u8, new_metadata_link: string::String)
+
+ + + +
+Implementation + + +
public fun update_appchain_metadata_link(
+    supra_framework: &signer,
+    chain_id: u8,
+    new_metadata_link: String,
+) acquires AppchainRegistry {
+    let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
+    assert_appchain_registered(&appchain_registry.appchains, &chain_id);
+
+    let appchain_info = simple_map::borrow_mut(&mut appchain_registry.appchains, &chain_id);
+    let old_metadata_link = appchain_info.metadata_link;
+    appchain_info.metadata_link = new_metadata_link;
+
+    event::emit(AppchainMetadataLinkUpdated {
+        chain_id,
+        old_metadata_link,
+        new_metadata_link,
+    });
+}
+
+ + + +
+ + + +## Function `add_reserved_range` + +Adds a reserved chain ID range. + + +
public fun add_reserved_range(supra_framework: &signer, start: u8, end: u8)
+
+ + + +
+Implementation + + +
public fun add_reserved_range(
+    supra_framework: &signer,
+    start: u8,
+    end: u8,
+) acquires AppchainRegistry {
+    let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
+    assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
+
+    vector::push_back(&mut appchain_registry.reserved_ranges, ReservedRange { start, end });
+}
+
+ + + +
+ + + +## Function `new_reserved_range` + +Constructor to create an instance of the ReservedRange. +This will be utilized in move-script to initialize the appchain registry with reserved ranges. + + +
public fun new_reserved_range(start: u8, end: u8): appchain_registry::ReservedRange
+
+ + + +
+Implementation + + +
public fun new_reserved_range(
+    start: u8,
+    end: u8,
+): ReservedRange {
+    assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
+    ReservedRange { start, end }
+}
+
+ + + +
+ + + +## Function `appchain_state` + +Get the state of a appchain. + + +
#[view]
+public fun appchain_state(chain_id: u8): u8
+
+ + + +
+Implementation + + +
public fun appchain_state(chain_id: u8): u8 acquires AppchainRegistry {
+    let appchain_registry = borrow_global_appchain_registry();
+    if (simple_map::contains_key(&appchain_registry.appchains, &chain_id)) {
+        return simple_map::borrow(&appchain_registry.appchains, &chain_id).state;
+    };
+
+    STATE_UNKNOWN
+}
+
+ + + +
+ + + +## Function `is_appchain_active` + +Check if a appchain is active. + + +
#[view]
+public fun is_appchain_active(chain_id: u8): bool
+
+ + + +
+Implementation + + +
public fun is_appchain_active(chain_id: u8): bool acquires AppchainRegistry {
+    appchain_state(chain_id) == STATE_ACTIVE
+}
+
+ + + +
+ + + +## Function `active_appchains` + +Get chain IDs of all appchain with Active state. + + +
#[view]
+public fun active_appchains(): vector<u8>
+
+ + + +
+Implementation + + +
public fun active_appchains(): vector<u8> acquires AppchainRegistry {
+    let appchain_registry = borrow_global_appchain_registry();
+    let appchains_chain_id = simple_map::keys(&appchain_registry.appchains);
+    let appchains_info = simple_map::values(&appchain_registry.appchains);
+    let active_appchains_chain_id = vector::empty<u8>();
+    vector::zip_reverse<u8, AppchainInfo>(appchains_chain_id, appchains_info, |chain_id, appchain_info|{
+        // New helper variable with explicit type annotation is required due to Move's lambda type inference
+        // limitations. When I don't use this new variable with explicit type declaration, compiler throws error
+        // and ask to infer the type.
+        let info: AppchainInfo = appchain_info;
+        if (info.state == STATE_ACTIVE) {
+            vector::push_back(&mut active_appchains_chain_id, chain_id);
+        }
+    });
+    active_appchains_chain_id
+}
+
+ + + +
+ + + +## Function `appchain_metadata_link` + +Get appchain metadata link. + + +
#[view]
+public fun appchain_metadata_link(chain_id: u8): string::String
+
+ + + +
+Implementation + + +
public fun appchain_metadata_link(chain_id: u8): String acquires AppchainRegistry {
+    let appchain_registry = borrow_global_appchain_registry();
+    assert_appchain_registered(&appchain_registry.appchains, &chain_id);
+
+    simple_map::borrow(&appchain_registry.appchains, &chain_id).metadata_link
+}
+
+ + + +
+ + + +## Function `appchain_info` + +Get appchain info. + + +
#[view]
+public fun appchain_info(chain_id: u8): (u8, string::String)
+
+ + + +
+Implementation + + +
public fun appchain_info(chain_id: u8): (u8, String) acquires AppchainRegistry {
+    let appchain_registry = borrow_global_appchain_registry();
+    assert_appchain_registered(&appchain_registry.appchains, &chain_id);
+
+    let appchain = simple_map::borrow(&appchain_registry.appchains, &chain_id);
+    (appchain.state, appchain.metadata_link)
+}
+
+ + + +
+ + + +## Function `is_chain_id_reserved` + +Check if a chain ID falls within reserved ranges. + + +
#[view]
+public fun is_chain_id_reserved(chain_id: u8): bool
+
+ + + +
+Implementation + + +
public fun is_chain_id_reserved(chain_id: u8): bool acquires AppchainRegistry {
+    is_chain_id_reserved_internal(chain_id, &borrow_global_appchain_registry().reserved_ranges)
+}
+
+ + + +
+ + + +## Function `borrow_global_appchain_registry` + + + +
fun borrow_global_appchain_registry(): &appchain_registry::AppchainRegistry
+
+ + + +
+Implementation + + +
inline fun borrow_global_appchain_registry(): &AppchainRegistry acquires AppchainRegistry {
+    assert!(exists<AppchainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
+    borrow_global<AppchainRegistry>(@supra_framework)
+}
+
+ + + +
+ + + +## Function `borrow_global_mut_appchain_registry` + + + +
fun borrow_global_mut_appchain_registry(supra_framework: &signer): &mut appchain_registry::AppchainRegistry
+
+ + + +
+Implementation + + +
inline fun borrow_global_mut_appchain_registry(
+    supra_framework: &signer
+): &mut AppchainRegistry acquires AppchainRegistry {
+    system_addresses::assert_supra_framework(supra_framework);
+    assert!(exists<AppchainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
+    borrow_global_mut<AppchainRegistry>(@supra_framework)
+}
+
+ + + +
+ + + +## Function `assert_appchain_registered` + + + +
fun assert_appchain_registered(appchains: &simple_map::SimpleMap<u8, appchain_registry::AppchainInfo>, chain_id: &u8)
+
+ + + +
+Implementation + + +
inline fun assert_appchain_registered(appchains: &SimpleMap<u8, AppchainInfo>, chain_id: &u8) {
+    assert!(
+        simple_map::contains_key(appchains, chain_id),
+        error::not_found(EAPPCHAIN_NOT_REGISTERED)
+    );
+}
+
+ + + +
+ + + +## Function `is_chain_id_reserved_internal` + + + +
fun is_chain_id_reserved_internal(chain_id: u8, reserved_ranges: &vector<appchain_registry::ReservedRange>): bool
+
+ + + +
+Implementation + + +
fun is_chain_id_reserved_internal(
+    chain_id: u8,
+    reserved_ranges: &vector<ReservedRange>
+): bool {
+    let i = 0;
+    let total_ranges = vector::length(reserved_ranges);
+    while (i < total_ranges) {
+        let range = vector::borrow(reserved_ranges, i);
+        if (chain_id >= range.start && chain_id <= range.end) {
+            return true
+        };
+        i = i + 1;
+    };
+
+    false
+}
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/funnel_node_registry.md b/aptos-move/framework/supra-framework/doc/funnel_node_registry.md index 72eac051da26c..620bfbef65868 100644 --- a/aptos-move/framework/supra-framework/doc/funnel_node_registry.md +++ b/aptos-move/framework/supra-framework/doc/funnel_node_registry.md @@ -145,7 +145,7 @@ strongly recommended that the new list contains valid URLs for all funnel nodes, are ordered based on their reputation and trust level. Technically, deduplication of new_funnel_nodes is necessary. However, performing it consumes a -significant amount of execution gas. Since this method is expected to be invoked by microchain +significant amount of execution gas. Since this method is expected to be invoked by appchain governance - which is assumed to perform governance operations carefully - the new_funnel_nodes list is **not** deduplicated internally. As a result, it is possible to pass a list containing duplicate entries without triggering an error. Therefore, deduplication should be performed as part of diff --git a/aptos-move/framework/supra-framework/doc/genesis.md b/aptos-move/framework/supra-framework/doc/genesis.md index 79675ca5425e9..7e6bb21aa0917 100644 --- a/aptos-move/framework/supra-framework/doc/genesis.md +++ b/aptos-move/framework/supra-framework/doc/genesis.md @@ -17,7 +17,7 @@ - [Function `initialize_supra_coin`](#0x1_genesis_initialize_supra_coin) - [Function `initialize_supra_native_automation`](#0x1_genesis_initialize_supra_native_automation) - [Function `initialize_supra_native_automation_v2`](#0x1_genesis_initialize_supra_native_automation_v2) -- [Function `initialize_microchain_registry`](#0x1_genesis_initialize_microchain_registry) +- [Function `initialize_appchain_registry`](#0x1_genesis_initialize_appchain_registry) - [Function `initialize_funnel_node_registry`](#0x1_genesis_initialize_funnel_node_registry) - [Function `initialize_core_resources_and_supra_coin`](#0x1_genesis_initialize_core_resources_and_supra_coin) - [Function `initialize_evm_genesis_config`](#0x1_genesis_initialize_evm_genesis_config) @@ -54,6 +54,7 @@
use 0x1::account;
 use 0x1::aggregator_factory;
+use 0x1::appchain_registry;
 use 0x1::automation_registry;
 use 0x1::block;
 use 0x1::chain_id;
@@ -68,7 +69,6 @@
 use 0x1::fixed_point32;
 use 0x1::funnel_node_registry;
 use 0x1::gas_schedule;
-use 0x1::microchain_registry;
 use 0x1::multisig_account;
 use 0x1::option;
 use 0x1::pbo_delegation_pool;
@@ -769,20 +769,20 @@ Genesis step 3: Initialize Supra Native Automation.
 
 
 
-
+
 
-## Function `initialize_microchain_registry`
+## Function `initialize_appchain_registry`
 
-Genesis step 4: Initialize Microchain Registry.
+Genesis step 4: Initialize Appchain Registry.
 
-This method allows to initialize the microchain registry either during the genesis initialization
+This method allows to initialize the appchain registry either during the genesis initialization
 or after it has been completed.
 
 Because it is publicly accessible, it can be invoked via a move-script. Since it requires
 the supra_framework as the signer, the invocation must go through the governance process.
 
 
-
public fun initialize_microchain_registry(supra_framework: &signer, reserved_ranges: vector<microchain_registry::ReservedRange>)
+
public fun initialize_appchain_registry(supra_framework: &signer, reserved_ranges: vector<appchain_registry::ReservedRange>)
 
@@ -791,11 +791,11 @@ the supra_framework as the signer, the invocation must go through t Implementation -
public fun initialize_microchain_registry(
+
public fun initialize_appchain_registry(
     supra_framework: &signer,
     reserved_ranges: vector<ReservedRange>
 ) {
-    microchain_registry::initialize(
+    appchain_registry::initialize(
         supra_framework, reserved_ranges
     )
 }
@@ -811,7 +811,7 @@ the supra_framework as the signer, the invocation must go through t
 
 Genesis step 5: Initialize Funnel Node Registry.
 
-This method allows to initialize the microchain registry either during the genesis initialization
+This method allows to initialize the appchain registry either during the genesis initialization
 or after it has been completed.
 
 Because it is publicly accessible, it can be invoked via a move-script. Since it requires
diff --git a/aptos-move/framework/supra-framework/doc/microchain_registry.md b/aptos-move/framework/supra-framework/doc/microchain_registry.md
deleted file mode 100644
index a92159bde0da3..0000000000000
--- a/aptos-move/framework/supra-framework/doc/microchain_registry.md
+++ /dev/null
@@ -1,1010 +0,0 @@
-
-
-
-# Module `0x1::microchain_registry`
-
-Copyright (c) 2025 Supra
-
-Microchain Registry Module
-
-This module manages the registration and lifecycle of microchains on Supra-L1.
-
-1. To enable support for a new microchain on Supra-L1, it must be first registered by Supra Governance
-using the register_microchain method of this module.
-2. If a registered microchain misbehaves, it can be deactivated by Supra Governance through the deactivate_microchain method.
-3. A previously deactivated microchain can be reactivated by Supra Governance using the reactivate_microchain method.
-4. Although the registry data is updated immediately, the changes are only considered by Supra-L1 validators
-after an epoch change. Therefore, it is strongly recommended to trigger an epoch change by invoking
-0x1::supra_governance::reconfigure.
-5. Supra-L1 validators consider the updated registry data only after the epoch change. Hence, it is
-highly recommended to perform an epoch change whenever the following methods are invoked:
-a. register_microchain
-b. deactivate_microchain
-c. reactivate_microchain
-
-
--  [Struct `ReservedRange`](#0x1_microchain_registry_ReservedRange)
--  [Struct `MicrochainInfo`](#0x1_microchain_registry_MicrochainInfo)
--  [Resource `MicrochainRegistry`](#0x1_microchain_registry_MicrochainRegistry)
--  [Struct `MicrochainRegistered`](#0x1_microchain_registry_MicrochainRegistered)
--  [Struct `MicrochainDeactivated`](#0x1_microchain_registry_MicrochainDeactivated)
--  [Struct `MicrochainReactivated`](#0x1_microchain_registry_MicrochainReactivated)
--  [Struct `MicrochainMetadataLinkUpdated`](#0x1_microchain_registry_MicrochainMetadataLinkUpdated)
--  [Constants](#@Constants_0)
--  [Function `initialize`](#0x1_microchain_registry_initialize)
--  [Function `register_microchain`](#0x1_microchain_registry_register_microchain)
--  [Function `deactivate_microchain`](#0x1_microchain_registry_deactivate_microchain)
--  [Function `reactivate_microchain`](#0x1_microchain_registry_reactivate_microchain)
--  [Function `update_microchain_metadata_link`](#0x1_microchain_registry_update_microchain_metadata_link)
--  [Function `add_reserved_range`](#0x1_microchain_registry_add_reserved_range)
--  [Function `new_reserved_range`](#0x1_microchain_registry_new_reserved_range)
--  [Function `microchain_state`](#0x1_microchain_registry_microchain_state)
--  [Function `is_microchain_active`](#0x1_microchain_registry_is_microchain_active)
--  [Function `active_microchains`](#0x1_microchain_registry_active_microchains)
--  [Function `microchain_metadata_link`](#0x1_microchain_registry_microchain_metadata_link)
--  [Function `microchain_info`](#0x1_microchain_registry_microchain_info)
--  [Function `is_chain_id_reserved`](#0x1_microchain_registry_is_chain_id_reserved)
--  [Function `borrow_global_microchain_registry`](#0x1_microchain_registry_borrow_global_microchain_registry)
--  [Function `borrow_global_mut_microchain_registry`](#0x1_microchain_registry_borrow_global_mut_microchain_registry)
--  [Function `assert_microchain_registered`](#0x1_microchain_registry_assert_microchain_registered)
--  [Function `is_chain_id_reserved_internal`](#0x1_microchain_registry_is_chain_id_reserved_internal)
--  [Specification](#@Specification_1)
-
-
-
use 0x1::error;
-use 0x1::event;
-use 0x1::simple_map;
-use 0x1::string;
-use 0x1::system_addresses;
-
- - - - - -## Struct `ReservedRange` - -Represents reserved chain ID range. - - -
struct ReservedRange has copy, drop, store
-
- - - -
-Fields - - -
-
-start: u8 -
-
- -
-
-end: u8 -
-
- -
-
- - -
- - - -## Struct `MicrochainInfo` - -Represents information about the registered microchain. - - -
struct MicrochainInfo has copy, drop, store
-
- - - -
-Fields - - -
-
-state: u8 -
-
- -
-
-metadata_link: string::String -
-
- -
-
- - -
- - - -## Resource `MicrochainRegistry` - -Global microchain registry resource. - - -
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
-struct MicrochainRegistry has key
-
- - - -
-Fields - - -
-
-microchains: simple_map::SimpleMap<u8, microchain_registry::MicrochainInfo> -
-
- Map from chain ID to microchain info. -
-
-reserved_ranges: vector<microchain_registry::ReservedRange> -
-
- Reserved chain ID ranges. -
-
- - -
- - - -## Struct `MicrochainRegistered` - - - -
#[event]
-struct MicrochainRegistered has drop, store
-
- - - -
-Fields - - -
-
-chain_id: u8 -
-
- -
-
-metadata_link: string::String -
-
- -
-
- - -
- - - -## Struct `MicrochainDeactivated` - - - -
#[event]
-struct MicrochainDeactivated has drop, store
-
- - - -
-Fields - - -
-
-chain_id: u8 -
-
- -
-
- - -
- - - -## Struct `MicrochainReactivated` - - - -
#[event]
-struct MicrochainReactivated has drop, store
-
- - - -
-Fields - - -
-
-chain_id: u8 -
-
- -
-
- - -
- - - -## Struct `MicrochainMetadataLinkUpdated` - - - -
#[event]
-struct MicrochainMetadataLinkUpdated has drop, store
-
- - - -
-Fields - - -
-
-chain_id: u8 -
-
- -
-
-old_metadata_link: string::String -
-
- -
-
-new_metadata_link: string::String -
-
- -
-
- - -
- - - -## Constants - - - - -The provided range is invalid, start value must be less than or equal to end value. - - -
const EINVALID_RANGE: u64 = 7;
-
- - - - - -The MicrochainRegistry resource has not been initialized at @supra_framework. - - -
const EREGISTRY_NOT_INITIALIZED: u64 = 6;
-
- - - - - -The chain ID falls within a reserved range and cannot be used for registration. - - -
const ECHAIN_ID_RESERVED: u64 = 3;
-
- - - - - -The microchain is already in the ACTIVE state and cannot be reactivated. - - -
const EMICROCHAIN_ALREADY_ACTIVE: u64 = 5;
-
- - - - - -The microchain is already in the INACTIVE state and cannot be deactivated again. - - -
const EMICROCHAIN_ALREADY_DEACTIVATED: u64 = 4;
-
- - - - - -The microchain with the given chain ID is already registered in the microchain registry. - - -
const EMICROCHAIN_ALREADY_REGISTERED: u64 = 1;
-
- - - - - -The microchain with the given chain ID is not found in the microchain registry. - - -
const EMICROCHAIN_NOT_REGISTERED: u64 = 2;
-
- - - - - -Registered as a microchain and actively working. - - -
const STATE_ACTIVE: u8 = 1;
-
- - - - - -Registered as a microchain, but decommissioned from the Supra-L1. - - -
const STATE_INACTIVE: u8 = 0;
-
- - - - - -Never registered as a microchain. - - -
const STATE_UNKNOWN: u8 = 2;
-
- - - - - -## Function `initialize` - -Initializes the microchain registry. - - -
public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector<microchain_registry::ReservedRange>)
-
- - - -
-Implementation - - -
public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector<ReservedRange>) {
-    system_addresses::assert_supra_framework(supra_framework);
-
-    move_to(supra_framework, MicrochainRegistry {
-        microchains: simple_map::new(),
-        reserved_ranges,
-    });
-}
-
- - - -
- - - -## Function `register_microchain` - -Registers a new microchain. - -This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package), -it can only be invoked through a governance proposal move-script. - -It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure -after invoking this method. While this method could perform the reconfiguration internally, it -intentionally does not. This is because governance proposal move-scripts may need to invoke -additional methods after this one, so the responsibility of reconfiguration is left to the caller. - -Example usage: -``` -supra_framework::microchain_registry::register_microchain(&supra_framework, chain_id, metadata_link); -supra_framework::supra_governance::reconfigure(&supra_framework); -``` - - -
public fun register_microchain(supra_framework: &signer, chain_id: u8, metadata_link: string::String)
-
- - - -
-Implementation - - -
public fun register_microchain(
-    supra_framework: &signer,
-    chain_id: u8,
-    metadata_link: String,
-) acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
-
-    // Checks if given chain ID is reserved.
-    assert!(
-        !is_chain_id_reserved_internal(chain_id, &microchain_registry.reserved_ranges),
-        error::invalid_argument(ECHAIN_ID_RESERVED)
-    );
-    // Checks if a microchain is already registered.
-    assert!(
-        !simple_map::contains_key(&microchain_registry.microchains, &chain_id),
-        error::already_exists(EMICROCHAIN_ALREADY_REGISTERED)
-    );
-
-    let microchain_info = MicrochainInfo {
-        state: STATE_ACTIVE,
-        metadata_link,
-    };
-    simple_map::add(&mut microchain_registry.microchains, chain_id, microchain_info);
-
-    event::emit(MicrochainRegistered {
-        chain_id,
-        metadata_link,
-    });
-}
-
- - - -
- - - -## Function `deactivate_microchain` - -Deactivates the already registered microchain. - -This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package), -it can only be invoked through a governance proposal move-script. - -It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure -after invoking this method. While this method could perform the reconfiguration internally, it -intentionally does not. This is because governance proposal move-scripts may need to invoke -additional methods after this one, so the responsibility of reconfiguration is left to the caller. - -Example usage: -``` -supra_framework::microchain_registry::deactivate_microchain(&supra_framework, chain_id); -supra_framework::supra_governance::reconfigure(&supra_framework); -``` - - -
public fun deactivate_microchain(supra_framework: &signer, chain_id: u8)
-
- - - -
-Implementation - - -
public fun deactivate_microchain(
-    supra_framework: &signer,
-    chain_id: u8,
-) acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
-    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
-
-    let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id);
-    assert!(microchain_infp.state == STATE_ACTIVE, error::invalid_state(EMICROCHAIN_ALREADY_DEACTIVATED));
-
-    microchain_infp.state = STATE_INACTIVE;
-
-    event::emit(MicrochainDeactivated {
-        chain_id,
-    });
-}
-
- - - -
- - - -## Function `reactivate_microchain` - -Reactivates the deactivated microchain. - -This method requires the supra_framework as a signer. Therefore, externally (out of the supra-framework package), -it can only be invoked through a governance proposal move-script. - -It is strongly recommended to trigger an epoch change by calling 0x1::supra_governance::reconfigure -after invoking this method. While this method could perform the reconfiguration internally, it -intentionally does not. This is because governance proposal move-scripts may need to invoke -additional methods after this one, so the responsibility of reconfiguration is left to the caller. - -Example usage: -``` -supra_framework::microchain_registry::reactivate_microchain(&supra_framework, chain_id); -supra_framework::supra_governance::reconfigure(&supra_framework); -``` - - -
public fun reactivate_microchain(supra_framework: &signer, chain_id: u8)
-
- - - -
-Implementation - - -
public fun reactivate_microchain(
-    supra_framework: &signer,
-    chain_id: u8,
-) acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
-    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
-
-    let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id);
-    assert!(microchain_infp.state == STATE_INACTIVE, error::invalid_state(EMICROCHAIN_ALREADY_ACTIVE));
-
-    microchain_infp.state = STATE_ACTIVE;
-
-    event::emit(MicrochainReactivated {
-        chain_id,
-    });
-}
-
- - - -
- - - -## Function `update_microchain_metadata_link` - -Updates metadata link of a registered microchain. - - -
public fun update_microchain_metadata_link(supra_framework: &signer, chain_id: u8, new_metadata_link: string::String)
-
- - - -
-Implementation - - -
public fun update_microchain_metadata_link(
-    supra_framework: &signer,
-    chain_id: u8,
-    new_metadata_link: String,
-) acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
-    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
-
-    let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id);
-    let old_metadata_link = microchain_infp.metadata_link;
-    microchain_infp.metadata_link = new_metadata_link;
-
-    event::emit(MicrochainMetadataLinkUpdated {
-        chain_id,
-        old_metadata_link,
-        new_metadata_link,
-    });
-}
-
- - - -
- - - -## Function `add_reserved_range` - -Adds a reserved chain ID range. - - -
public fun add_reserved_range(supra_framework: &signer, start: u8, end: u8)
-
- - - -
-Implementation - - -
public fun add_reserved_range(
-    supra_framework: &signer,
-    start: u8,
-    end: u8,
-) acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_mut_microchain_registry(supra_framework);
-    assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
-
-    vector::push_back(&mut microchain_registry.reserved_ranges, ReservedRange { start, end });
-}
-
- - - -
- - - -## Function `new_reserved_range` - -Constructor to create an instance of the ReservedRange. -This will be utilized in move-script to initialize the microchain registry with reserved ranges. - - -
public fun new_reserved_range(start: u8, end: u8): microchain_registry::ReservedRange
-
- - - -
-Implementation - - -
public fun new_reserved_range(
-    start: u8,
-    end: u8,
-): ReservedRange {
-    assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
-    ReservedRange { start, end }
-}
-
- - - -
- - - -## Function `microchain_state` - -Get the state of a microchain. - - -
#[view]
-public fun microchain_state(chain_id: u8): u8
-
- - - -
-Implementation - - -
public fun microchain_state(chain_id: u8): u8 acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_microchain_registry();
-    if (simple_map::contains_key(&microchain_registry.microchains, &chain_id)) {
-        return simple_map::borrow(&microchain_registry.microchains, &chain_id).state;
-    };
-
-    STATE_UNKNOWN
-}
-
- - - -
- - - -## Function `is_microchain_active` - -Check if a microchain is active. - - -
#[view]
-public fun is_microchain_active(chain_id: u8): bool
-
- - - -
-Implementation - - -
public fun is_microchain_active(chain_id: u8): bool acquires MicrochainRegistry {
-    microchain_state(chain_id) == STATE_ACTIVE
-}
-
- - - -
- - - -## Function `active_microchains` - -Get chain IDs of all microchain with Active state. - - -
#[view]
-public fun active_microchains(): vector<u8>
-
- - - -
-Implementation - - -
public fun active_microchains(): vector<u8> acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_microchain_registry();
-    let microchains_chain_id = simple_map::keys(&microchain_registry.microchains);
-    let microchains_info = simple_map::values(&microchain_registry.microchains);
-    let active_microchains_chain_id = vector::empty<u8>();
-    vector::zip_reverse<u8, MicrochainInfo>(microchains_chain_id, microchains_info, |chain_id, microchain_info|{
-        // New helper variable with explicit type annotation is required due to Move's lambda type inference
-        // limitations. When I don't use this new variable with explicit type declaration, compiler throws error
-        // and ask to infer the type.
-        let info: MicrochainInfo = microchain_info;
-        if (info.state == STATE_ACTIVE) {
-            vector::push_back(&mut active_microchains_chain_id, chain_id);
-        }
-    });
-    active_microchains_chain_id
-}
-
- - - -
- - - -## Function `microchain_metadata_link` - -Get microchain metadata link. - - -
#[view]
-public fun microchain_metadata_link(chain_id: u8): string::String
-
- - - -
-Implementation - - -
public fun microchain_metadata_link(chain_id: u8): String acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_microchain_registry();
-    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
-
-    simple_map::borrow(&microchain_registry.microchains, &chain_id).metadata_link
-}
-
- - - -
- - - -## Function `microchain_info` - -Get microchain info. - - -
#[view]
-public fun microchain_info(chain_id: u8): (u8, string::String)
-
- - - -
-Implementation - - -
public fun microchain_info(chain_id: u8): (u8, String) acquires MicrochainRegistry {
-    let microchain_registry = borrow_global_microchain_registry();
-    assert_microchain_registered(&microchain_registry.microchains, &chain_id);
-
-    let microchain = simple_map::borrow(&microchain_registry.microchains, &chain_id);
-    (microchain.state, microchain.metadata_link)
-}
-
- - - -
- - - -## Function `is_chain_id_reserved` - -Check if a chain ID falls within reserved ranges. - - -
#[view]
-public fun is_chain_id_reserved(chain_id: u8): bool
-
- - - -
-Implementation - - -
public fun is_chain_id_reserved(chain_id: u8): bool acquires MicrochainRegistry {
-    is_chain_id_reserved_internal(chain_id, &borrow_global_microchain_registry().reserved_ranges)
-}
-
- - - -
- - - -## Function `borrow_global_microchain_registry` - - - -
fun borrow_global_microchain_registry(): &microchain_registry::MicrochainRegistry
-
- - - -
-Implementation - - -
inline fun borrow_global_microchain_registry(): &MicrochainRegistry acquires MicrochainRegistry {
-    assert!(exists<MicrochainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
-    borrow_global<MicrochainRegistry>(@supra_framework)
-}
-
- - - -
- - - -## Function `borrow_global_mut_microchain_registry` - - - -
fun borrow_global_mut_microchain_registry(supra_framework: &signer): &mut microchain_registry::MicrochainRegistry
-
- - - -
-Implementation - - -
inline fun borrow_global_mut_microchain_registry(
-    supra_framework: &signer
-): &mut MicrochainRegistry acquires MicrochainRegistry {
-    system_addresses::assert_supra_framework(supra_framework);
-    assert!(exists<MicrochainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
-    borrow_global_mut<MicrochainRegistry>(@supra_framework)
-}
-
- - - -
- - - -## Function `assert_microchain_registered` - - - -
fun assert_microchain_registered(microchains: &simple_map::SimpleMap<u8, microchain_registry::MicrochainInfo>, chain_id: &u8)
-
- - - -
-Implementation - - -
inline fun assert_microchain_registered(microchains: &SimpleMap<u8, MicrochainInfo>, chain_id: &u8) {
-    assert!(
-        simple_map::contains_key(microchains, chain_id),
-        error::not_found(EMICROCHAIN_NOT_REGISTERED)
-    );
-}
-
- - - -
- - - -## Function `is_chain_id_reserved_internal` - - - -
fun is_chain_id_reserved_internal(chain_id: u8, reserved_ranges: &vector<microchain_registry::ReservedRange>): bool
-
- - - -
-Implementation - - -
fun is_chain_id_reserved_internal(
-    chain_id: u8,
-    reserved_ranges: &vector<ReservedRange>
-): bool {
-    let i = 0;
-    let total_ranges = vector::length(reserved_ranges);
-    while (i < total_ranges) {
-        let range = vector::borrow(reserved_ranges, i);
-        if (chain_id >= range.start && chain_id <= range.end) {
-            return true
-        };
-        i = i + 1;
-    };
-
-    false
-}
-
- - - -
- - - -## Specification - - - -
pragma verify = false;
-
- - -[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md index 3b02ed79b95b9..19bdab18b3ec3 100644 --- a/aptos-move/framework/supra-framework/doc/overview.md +++ b/aptos-move/framework/supra-framework/doc/overview.md @@ -16,6 +16,7 @@ This is the reference documentation of the Supra framework. - [`0x1::aggregator`](aggregator.md#0x1_aggregator) - [`0x1::aggregator_factory`](aggregator_factory.md#0x1_aggregator_factory) - [`0x1::aggregator_v2`](aggregator_v2.md#0x1_aggregator_v2) +- [`0x1::appchain_registry`](appchain_registry.md#0x1_appchain_registry) - [`0x1::automation_registry`](automation_registry.md#0x1_automation_registry) - [`0x1::block`](block.md#0x1_block) - [`0x1::chain_id`](chain_id.md#0x1_chain_id) @@ -42,7 +43,6 @@ This is the reference documentation of the Supra framework. - [`0x1::jwks`](jwks.md#0x1_jwks) - [`0x1::keyless_account`](keyless_account.md#0x1_keyless_account) - [`0x1::managed_coin`](managed_coin.md#0x1_managed_coin) -- [`0x1::microchain_registry`](microchain_registry.md#0x1_microchain_registry) - [`0x1::multisig_account`](multisig_account.md#0x1_multisig_account) - [`0x1::multisig_voting`](multisig_voting.md#0x1_multisig_voting) - [`0x1::object`](object.md#0x1_object) diff --git a/aptos-move/framework/supra-framework/sources/appchain_registry.move b/aptos-move/framework/supra-framework/sources/appchain_registry.move new file mode 100644 index 0000000000000..b5b29464b16f6 --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/appchain_registry.move @@ -0,0 +1,370 @@ +/// Copyright (c) 2025 Supra +/// +/// Appchain Registry Module +/// +/// This module manages the registration and lifecycle of appchains on Supra-L1. +/// +/// 1. To enable support for a new appchain on Supra-L1, it must be first registered by Supra Governance +/// using the `register_appchain` method of this module. +/// 2. If a registered appchain misbehaves, it can be deactivated by Supra Governance through the `deactivate_appchain` method. +/// 3. A previously deactivated appchain can be reactivated by Supra Governance using the `reactivate_appchain` method. +/// 4. Although the registry data is updated immediately, the changes are only considered by Supra-L1 validators +/// after an epoch change. Therefore, it is strongly recommended to trigger an epoch change by invoking +/// `0x1::supra_governance::reconfigure`. +/// 5. Supra-L1 validators consider the updated registry data only after the epoch change. Hence, it is +/// highly recommended to perform an epoch change whenever the following methods are invoked: +/// a. `register_appchain` +/// b. `deactivate_appchain` +/// c. `reactivate_appchain` +module supra_framework::appchain_registry { + use std::error; + use std::string::String; + use std::vector; + + use aptos_std::simple_map::{Self, SimpleMap}; + + use supra_framework::event; + use supra_framework::system_addresses; + + friend supra_framework::genesis; + #[test_only] + friend supra_framework::appchain_registry_tests; + + + /// The appchain with the given chain ID is already registered in the appchain registry. + const EAPPCHAIN_ALREADY_REGISTERED: u64 = 1; + + /// The appchain with the given chain ID is not found in the appchain registry. + const EAPPCHAIN_NOT_REGISTERED: u64 = 2; + + /// The chain ID falls within a reserved range and cannot be used for registration. + const ECHAIN_ID_RESERVED: u64 = 3; + + /// The appchain is already in the `INACTIVE` state and cannot be deactivated again. + const EAPPCHAIN_ALREADY_DEACTIVATED: u64 = 4; + + /// The appchain is already in the `ACTIVE` state and cannot be reactivated. + const EAPPCHAIN_ALREADY_ACTIVE: u64 = 5; + + /// The `AppchainRegistry` resource has not been initialized at @supra_framework. + const EREGISTRY_NOT_INITIALIZED: u64 = 6; + + /// The provided range is invalid, start value must be less than or equal to end value. + const EINVALID_RANGE: u64 = 7; + + + /// Registered as a appchain, but decommissioned from the Supra-L1. + const STATE_INACTIVE: u8 = 0; + /// Registered as a appchain and actively working. + const STATE_ACTIVE: u8 = 1; + /// Never registered as a appchain. + const STATE_UNKNOWN: u8 = 2; + + /// Represents reserved chain ID range. + struct ReservedRange has store, copy, drop { + start: u8, + end: u8 + } + + /// Represents information about the registered appchain. + struct AppchainInfo has store, copy, drop { + state: u8, + metadata_link: String, + } + + #[resource_group_member(group = supra_framework::object::ObjectGroup)] + /// Global appchain registry resource. + struct AppchainRegistry has key { + /// Map from chain ID to appchain info. + appchains: SimpleMap, + /// Reserved chain ID ranges. + reserved_ranges: vector, + } + + + #[event] + struct AppchainRegistered has store, drop { + chain_id: u8, + metadata_link: String, + } + + #[event] + struct AppchainDeactivated has store, drop { + chain_id: u8, + } + + #[event] + struct AppchainReactivated has store, drop { + chain_id: u8, + } + + #[event] + struct AppchainMetadataLinkUpdated has store, drop { + chain_id: u8, + old_metadata_link: String, + new_metadata_link: String, + } + + /// Initializes the appchain registry. + public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector) { + system_addresses::assert_supra_framework(supra_framework); + + move_to(supra_framework, AppchainRegistry { + appchains: simple_map::new(), + reserved_ranges, + }); + } + + /// Registers a new appchain. + /// + /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package), + /// it can only be invoked through a governance proposal move-script. + /// + /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure` + /// after invoking this method. While this method could perform the reconfiguration internally, it + /// intentionally does not. This is because governance proposal move-scripts may need to invoke + /// additional methods after this one, so the responsibility of reconfiguration is left to the caller. + /// + /// Example usage: + /// ``` + /// supra_framework::appchain_registry::register_appchain(&supra_framework, chain_id, metadata_link); + /// supra_framework::supra_governance::reconfigure(&supra_framework); + /// ``` + public fun register_appchain( + supra_framework: &signer, + chain_id: u8, + metadata_link: String, + ) acquires AppchainRegistry { + let appchain_registry = borrow_global_mut_appchain_registry(supra_framework); + + // Checks if given chain ID is reserved. + assert!( + !is_chain_id_reserved_internal(chain_id, &appchain_registry.reserved_ranges), + error::invalid_argument(ECHAIN_ID_RESERVED) + ); + // Checks if a appchain is already registered. + assert!( + !simple_map::contains_key(&appchain_registry.appchains, &chain_id), + error::already_exists(EAPPCHAIN_ALREADY_REGISTERED) + ); + + let appchain_info = AppchainInfo { + state: STATE_ACTIVE, + metadata_link, + }; + simple_map::add(&mut appchain_registry.appchains, chain_id, appchain_info); + + event::emit(AppchainRegistered { + chain_id, + metadata_link, + }); + } + + /// Deactivates the already registered appchain. + /// + /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package), + /// it can only be invoked through a governance proposal move-script. + /// + /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure` + /// after invoking this method. While this method could perform the reconfiguration internally, it + /// intentionally does not. This is because governance proposal move-scripts may need to invoke + /// additional methods after this one, so the responsibility of reconfiguration is left to the caller. + /// + /// Example usage: + /// ``` + /// supra_framework::appchain_registry::deactivate_appchain(&supra_framework, chain_id); + /// supra_framework::supra_governance::reconfigure(&supra_framework); + /// ``` + public fun deactivate_appchain( + supra_framework: &signer, + chain_id: u8, + ) acquires AppchainRegistry { + let appchain_registry = borrow_global_mut_appchain_registry(supra_framework); + assert_appchain_registered(&appchain_registry.appchains, &chain_id); + + let appchain_info = simple_map::borrow_mut(&mut appchain_registry.appchains, &chain_id); + assert!(appchain_info.state == STATE_ACTIVE, error::invalid_state(EAPPCHAIN_ALREADY_DEACTIVATED)); + + appchain_info.state = STATE_INACTIVE; + + event::emit(AppchainDeactivated { + chain_id, + }); + } + + /// Reactivates the deactivated appchain. + /// + /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package), + /// it can only be invoked through a governance proposal move-script. + /// + /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure` + /// after invoking this method. While this method could perform the reconfiguration internally, it + /// intentionally does not. This is because governance proposal move-scripts may need to invoke + /// additional methods after this one, so the responsibility of reconfiguration is left to the caller. + /// + /// Example usage: + /// ``` + /// supra_framework::appchain_registry::reactivate_appchain(&supra_framework, chain_id); + /// supra_framework::supra_governance::reconfigure(&supra_framework); + /// ``` + public fun reactivate_appchain( + supra_framework: &signer, + chain_id: u8, + ) acquires AppchainRegistry { + let appchain_registry = borrow_global_mut_appchain_registry(supra_framework); + assert_appchain_registered(&appchain_registry.appchains, &chain_id); + + let appchain_info = simple_map::borrow_mut(&mut appchain_registry.appchains, &chain_id); + assert!(appchain_info.state == STATE_INACTIVE, error::invalid_state(EAPPCHAIN_ALREADY_ACTIVE)); + + appchain_info.state = STATE_ACTIVE; + + event::emit(AppchainReactivated { + chain_id, + }); + } + + /// Updates metadata link of a registered appchain. + public fun update_appchain_metadata_link( + supra_framework: &signer, + chain_id: u8, + new_metadata_link: String, + ) acquires AppchainRegistry { + let appchain_registry = borrow_global_mut_appchain_registry(supra_framework); + assert_appchain_registered(&appchain_registry.appchains, &chain_id); + + let appchain_info = simple_map::borrow_mut(&mut appchain_registry.appchains, &chain_id); + let old_metadata_link = appchain_info.metadata_link; + appchain_info.metadata_link = new_metadata_link; + + event::emit(AppchainMetadataLinkUpdated { + chain_id, + old_metadata_link, + new_metadata_link, + }); + } + + /// Adds a reserved chain ID range. + public fun add_reserved_range( + supra_framework: &signer, + start: u8, + end: u8, + ) acquires AppchainRegistry { + let appchain_registry = borrow_global_mut_appchain_registry(supra_framework); + assert!(start <= end, error::invalid_argument(EINVALID_RANGE)); + + vector::push_back(&mut appchain_registry.reserved_ranges, ReservedRange { start, end }); + } + + + /// Constructor to create an instance of the `ReservedRange`. + /// This will be utilized in move-script to initialize the appchain registry with reserved ranges. + public fun new_reserved_range( + start: u8, + end: u8, + ): ReservedRange { + assert!(start <= end, error::invalid_argument(EINVALID_RANGE)); + ReservedRange { start, end } + } + + + #[view] + /// Get the state of a appchain. + public fun appchain_state(chain_id: u8): u8 acquires AppchainRegistry { + let appchain_registry = borrow_global_appchain_registry(); + if (simple_map::contains_key(&appchain_registry.appchains, &chain_id)) { + return simple_map::borrow(&appchain_registry.appchains, &chain_id).state; + }; + + STATE_UNKNOWN + } + + #[view] + /// Check if a appchain is active. + public fun is_appchain_active(chain_id: u8): bool acquires AppchainRegistry { + appchain_state(chain_id) == STATE_ACTIVE + } + + #[view] + /// Get chain IDs of all appchain with `Active` state. + public fun active_appchains(): vector acquires AppchainRegistry { + let appchain_registry = borrow_global_appchain_registry(); + let appchains_chain_id = simple_map::keys(&appchain_registry.appchains); + let appchains_info = simple_map::values(&appchain_registry.appchains); + let active_appchains_chain_id = vector::empty(); + vector::zip_reverse(appchains_chain_id, appchains_info, |chain_id, appchain_info|{ + // New helper variable with explicit type annotation is required due to Move's lambda type inference + // limitations. When I don't use this new variable with explicit type declaration, compiler throws error + // and ask to infer the type. + let info: AppchainInfo = appchain_info; + if (info.state == STATE_ACTIVE) { + vector::push_back(&mut active_appchains_chain_id, chain_id); + } + }); + active_appchains_chain_id + } + + #[view] + /// Get appchain metadata link. + public fun appchain_metadata_link(chain_id: u8): String acquires AppchainRegistry { + let appchain_registry = borrow_global_appchain_registry(); + assert_appchain_registered(&appchain_registry.appchains, &chain_id); + + simple_map::borrow(&appchain_registry.appchains, &chain_id).metadata_link + } + + #[view] + /// Get appchain info. + public fun appchain_info(chain_id: u8): (u8, String) acquires AppchainRegistry { + let appchain_registry = borrow_global_appchain_registry(); + assert_appchain_registered(&appchain_registry.appchains, &chain_id); + + let appchain = simple_map::borrow(&appchain_registry.appchains, &chain_id); + (appchain.state, appchain.metadata_link) + } + + #[view] + /// Check if a chain ID falls within reserved ranges. + public fun is_chain_id_reserved(chain_id: u8): bool acquires AppchainRegistry { + is_chain_id_reserved_internal(chain_id, &borrow_global_appchain_registry().reserved_ranges) + } + + + inline fun borrow_global_appchain_registry(): &AppchainRegistry acquires AppchainRegistry { + assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED)); + borrow_global(@supra_framework) + } + + inline fun borrow_global_mut_appchain_registry( + supra_framework: &signer + ): &mut AppchainRegistry acquires AppchainRegistry { + system_addresses::assert_supra_framework(supra_framework); + assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED)); + borrow_global_mut(@supra_framework) + } + + inline fun assert_appchain_registered(appchains: &SimpleMap, chain_id: &u8) { + assert!( + simple_map::contains_key(appchains, chain_id), + error::not_found(EAPPCHAIN_NOT_REGISTERED) + ); + } + + + fun is_chain_id_reserved_internal( + chain_id: u8, + reserved_ranges: &vector + ): bool { + let i = 0; + let total_ranges = vector::length(reserved_ranges); + while (i < total_ranges) { + let range = vector::borrow(reserved_ranges, i); + if (chain_id >= range.start && chain_id <= range.end) { + return true + }; + i = i + 1; + }; + + false + } +} diff --git a/aptos-move/framework/supra-framework/sources/microchain_registry.spec.move b/aptos-move/framework/supra-framework/sources/appchain_registry.spec.move similarity index 56% rename from aptos-move/framework/supra-framework/sources/microchain_registry.spec.move rename to aptos-move/framework/supra-framework/sources/appchain_registry.spec.move index c592b65d6fa3a..5a39491d44f68 100644 --- a/aptos-move/framework/supra-framework/sources/microchain_registry.spec.move +++ b/aptos-move/framework/supra-framework/sources/appchain_registry.spec.move @@ -1,4 +1,4 @@ -spec supra_framework::microchain_registry { +spec supra_framework::appchain_registry { spec module { pragma verify = false; } diff --git a/aptos-move/framework/supra-framework/sources/funnel_node_registry.move b/aptos-move/framework/supra-framework/sources/funnel_node_registry.move index 2e61e07851d3c..2120a430fc21d 100644 --- a/aptos-move/framework/supra-framework/sources/funnel_node_registry.move +++ b/aptos-move/framework/supra-framework/sources/funnel_node_registry.move @@ -48,7 +48,7 @@ module supra_framework::funnel_node_registry { /// are ordered based on their reputation and trust level. /// /// Technically, deduplication of `new_funnel_nodes` is necessary. However, performing it consumes a - /// significant amount of execution gas. Since this method is expected to be invoked by microchain + /// significant amount of execution gas. Since this method is expected to be invoked by appchain /// governance - which is assumed to perform governance operations carefully - the `new_funnel_nodes` /// list is **not** deduplicated internally. As a result, it is possible to pass a list containing duplicate /// entries without triggering an error. Therefore, deduplication should be performed as part of diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index d4d59069ba0f7..af6ac0b927bf5 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -36,7 +36,7 @@ module supra_framework::genesis { use supra_framework::version; use supra_framework::vesting; use supra_framework::vesting_without_staking; - use supra_framework::microchain_registry::{Self, ReservedRange}; + use supra_framework::appchain_registry::{Self, ReservedRange}; use supra_framework::funnel_node_registry; #[test_only] @@ -262,25 +262,25 @@ module supra_framework::genesis { ) } - /// Genesis step 4: Initialize Microchain Registry. + /// Genesis step 4: Initialize Appchain Registry. /// - /// This method allows to initialize the microchain registry either during the genesis initialization + /// This method allows to initialize the appchain registry either during the genesis initialization /// or after it has been completed. /// /// Because it is publicly accessible, it can be invoked via a move-script. Since it requires /// the `supra_framework` as the signer, the invocation must go through the governance process. - public fun initialize_microchain_registry( + public fun initialize_appchain_registry( supra_framework: &signer, reserved_ranges: vector ) { - microchain_registry::initialize( + appchain_registry::initialize( supra_framework, reserved_ranges ) } /// Genesis step 5: Initialize Funnel Node Registry. /// - /// This method allows to initialize the microchain registry either during the genesis initialization + /// This method allows to initialize the appchain registry either during the genesis initialization /// or after it has been completed. /// /// Because it is publicly accessible, it can be invoked via a move-script. Since it requires @@ -1204,4 +1204,4 @@ module supra_framework::genesis { let vesting_contracts = vesting_without_staking::vesting_contracts(admin_address); assert!(vector::length(&vesting_contracts) == 1, 0); } -} \ No newline at end of file +} diff --git a/aptos-move/framework/supra-framework/sources/microchain_registry.move b/aptos-move/framework/supra-framework/sources/microchain_registry.move deleted file mode 100644 index d9a8820735f7a..0000000000000 --- a/aptos-move/framework/supra-framework/sources/microchain_registry.move +++ /dev/null @@ -1,370 +0,0 @@ -/// Copyright (c) 2025 Supra -/// -/// Microchain Registry Module -/// -/// This module manages the registration and lifecycle of microchains on Supra-L1. -/// -/// 1. To enable support for a new microchain on Supra-L1, it must be first registered by Supra Governance -/// using the `register_microchain` method of this module. -/// 2. If a registered microchain misbehaves, it can be deactivated by Supra Governance through the `deactivate_microchain` method. -/// 3. A previously deactivated microchain can be reactivated by Supra Governance using the `reactivate_microchain` method. -/// 4. Although the registry data is updated immediately, the changes are only considered by Supra-L1 validators -/// after an epoch change. Therefore, it is strongly recommended to trigger an epoch change by invoking -/// `0x1::supra_governance::reconfigure`. -/// 5. Supra-L1 validators consider the updated registry data only after the epoch change. Hence, it is -/// highly recommended to perform an epoch change whenever the following methods are invoked: -/// a. `register_microchain` -/// b. `deactivate_microchain` -/// c. `reactivate_microchain` -module supra_framework::microchain_registry { - use std::error; - use std::string::String; - use std::vector; - - use aptos_std::simple_map::{Self, SimpleMap}; - - use supra_framework::event; - use supra_framework::system_addresses; - - friend supra_framework::genesis; - #[test_only] - friend supra_framework::microchain_registry_tests; - - - /// The microchain with the given chain ID is already registered in the microchain registry. - const EMICROCHAIN_ALREADY_REGISTERED: u64 = 1; - - /// The microchain with the given chain ID is not found in the microchain registry. - const EMICROCHAIN_NOT_REGISTERED: u64 = 2; - - /// The chain ID falls within a reserved range and cannot be used for registration. - const ECHAIN_ID_RESERVED: u64 = 3; - - /// The microchain is already in the `INACTIVE` state and cannot be deactivated again. - const EMICROCHAIN_ALREADY_DEACTIVATED: u64 = 4; - - /// The microchain is already in the `ACTIVE` state and cannot be reactivated. - const EMICROCHAIN_ALREADY_ACTIVE: u64 = 5; - - /// The `MicrochainRegistry` resource has not been initialized at @supra_framework. - const EREGISTRY_NOT_INITIALIZED: u64 = 6; - - /// The provided range is invalid, start value must be less than or equal to end value. - const EINVALID_RANGE: u64 = 7; - - - /// Registered as a microchain, but decommissioned from the Supra-L1. - const STATE_INACTIVE: u8 = 0; - /// Registered as a microchain and actively working. - const STATE_ACTIVE: u8 = 1; - /// Never registered as a microchain. - const STATE_UNKNOWN: u8 = 2; - - /// Represents reserved chain ID range. - struct ReservedRange has store, copy, drop { - start: u8, - end: u8 - } - - /// Represents information about the registered microchain. - struct MicrochainInfo has store, copy, drop { - state: u8, - metadata_link: String, - } - - #[resource_group_member(group = supra_framework::object::ObjectGroup)] - /// Global microchain registry resource. - struct MicrochainRegistry has key { - /// Map from chain ID to microchain info. - microchains: SimpleMap, - /// Reserved chain ID ranges. - reserved_ranges: vector, - } - - - #[event] - struct MicrochainRegistered has store, drop { - chain_id: u8, - metadata_link: String, - } - - #[event] - struct MicrochainDeactivated has store, drop { - chain_id: u8, - } - - #[event] - struct MicrochainReactivated has store, drop { - chain_id: u8, - } - - #[event] - struct MicrochainMetadataLinkUpdated has store, drop { - chain_id: u8, - old_metadata_link: String, - new_metadata_link: String, - } - - /// Initializes the microchain registry. - public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector) { - system_addresses::assert_supra_framework(supra_framework); - - move_to(supra_framework, MicrochainRegistry { - microchains: simple_map::new(), - reserved_ranges, - }); - } - - /// Registers a new microchain. - /// - /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package), - /// it can only be invoked through a governance proposal move-script. - /// - /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure` - /// after invoking this method. While this method could perform the reconfiguration internally, it - /// intentionally does not. This is because governance proposal move-scripts may need to invoke - /// additional methods after this one, so the responsibility of reconfiguration is left to the caller. - /// - /// Example usage: - /// ``` - /// supra_framework::microchain_registry::register_microchain(&supra_framework, chain_id, metadata_link); - /// supra_framework::supra_governance::reconfigure(&supra_framework); - /// ``` - public fun register_microchain( - supra_framework: &signer, - chain_id: u8, - metadata_link: String, - ) acquires MicrochainRegistry { - let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); - - // Checks if given chain ID is reserved. - assert!( - !is_chain_id_reserved_internal(chain_id, µchain_registry.reserved_ranges), - error::invalid_argument(ECHAIN_ID_RESERVED) - ); - // Checks if a microchain is already registered. - assert!( - !simple_map::contains_key(µchain_registry.microchains, &chain_id), - error::already_exists(EMICROCHAIN_ALREADY_REGISTERED) - ); - - let microchain_info = MicrochainInfo { - state: STATE_ACTIVE, - metadata_link, - }; - simple_map::add(&mut microchain_registry.microchains, chain_id, microchain_info); - - event::emit(MicrochainRegistered { - chain_id, - metadata_link, - }); - } - - /// Deactivates the already registered microchain. - /// - /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package), - /// it can only be invoked through a governance proposal move-script. - /// - /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure` - /// after invoking this method. While this method could perform the reconfiguration internally, it - /// intentionally does not. This is because governance proposal move-scripts may need to invoke - /// additional methods after this one, so the responsibility of reconfiguration is left to the caller. - /// - /// Example usage: - /// ``` - /// supra_framework::microchain_registry::deactivate_microchain(&supra_framework, chain_id); - /// supra_framework::supra_governance::reconfigure(&supra_framework); - /// ``` - public fun deactivate_microchain( - supra_framework: &signer, - chain_id: u8, - ) acquires MicrochainRegistry { - let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); - assert_microchain_registered(µchain_registry.microchains, &chain_id); - - let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id); - assert!(microchain_infp.state == STATE_ACTIVE, error::invalid_state(EMICROCHAIN_ALREADY_DEACTIVATED)); - - microchain_infp.state = STATE_INACTIVE; - - event::emit(MicrochainDeactivated { - chain_id, - }); - } - - /// Reactivates the deactivated microchain. - /// - /// This method requires the `supra_framework` as a signer. Therefore, externally (out of the supra-framework package), - /// it can only be invoked through a governance proposal move-script. - /// - /// It is strongly recommended to trigger an epoch change by calling `0x1::supra_governance::reconfigure` - /// after invoking this method. While this method could perform the reconfiguration internally, it - /// intentionally does not. This is because governance proposal move-scripts may need to invoke - /// additional methods after this one, so the responsibility of reconfiguration is left to the caller. - /// - /// Example usage: - /// ``` - /// supra_framework::microchain_registry::reactivate_microchain(&supra_framework, chain_id); - /// supra_framework::supra_governance::reconfigure(&supra_framework); - /// ``` - public fun reactivate_microchain( - supra_framework: &signer, - chain_id: u8, - ) acquires MicrochainRegistry { - let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); - assert_microchain_registered(µchain_registry.microchains, &chain_id); - - let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id); - assert!(microchain_infp.state == STATE_INACTIVE, error::invalid_state(EMICROCHAIN_ALREADY_ACTIVE)); - - microchain_infp.state = STATE_ACTIVE; - - event::emit(MicrochainReactivated { - chain_id, - }); - } - - /// Updates metadata link of a registered microchain. - public fun update_microchain_metadata_link( - supra_framework: &signer, - chain_id: u8, - new_metadata_link: String, - ) acquires MicrochainRegistry { - let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); - assert_microchain_registered(µchain_registry.microchains, &chain_id); - - let microchain_infp = simple_map::borrow_mut(&mut microchain_registry.microchains, &chain_id); - let old_metadata_link = microchain_infp.metadata_link; - microchain_infp.metadata_link = new_metadata_link; - - event::emit(MicrochainMetadataLinkUpdated { - chain_id, - old_metadata_link, - new_metadata_link, - }); - } - - /// Adds a reserved chain ID range. - public fun add_reserved_range( - supra_framework: &signer, - start: u8, - end: u8, - ) acquires MicrochainRegistry { - let microchain_registry = borrow_global_mut_microchain_registry(supra_framework); - assert!(start <= end, error::invalid_argument(EINVALID_RANGE)); - - vector::push_back(&mut microchain_registry.reserved_ranges, ReservedRange { start, end }); - } - - - /// Constructor to create an instance of the `ReservedRange`. - /// This will be utilized in move-script to initialize the microchain registry with reserved ranges. - public fun new_reserved_range( - start: u8, - end: u8, - ): ReservedRange { - assert!(start <= end, error::invalid_argument(EINVALID_RANGE)); - ReservedRange { start, end } - } - - - #[view] - /// Get the state of a microchain. - public fun microchain_state(chain_id: u8): u8 acquires MicrochainRegistry { - let microchain_registry = borrow_global_microchain_registry(); - if (simple_map::contains_key(µchain_registry.microchains, &chain_id)) { - return simple_map::borrow(µchain_registry.microchains, &chain_id).state; - }; - - STATE_UNKNOWN - } - - #[view] - /// Check if a microchain is active. - public fun is_microchain_active(chain_id: u8): bool acquires MicrochainRegistry { - microchain_state(chain_id) == STATE_ACTIVE - } - - #[view] - /// Get chain IDs of all microchain with `Active` state. - public fun active_microchains(): vector acquires MicrochainRegistry { - let microchain_registry = borrow_global_microchain_registry(); - let microchains_chain_id = simple_map::keys(µchain_registry.microchains); - let microchains_info = simple_map::values(µchain_registry.microchains); - let active_microchains_chain_id = vector::empty(); - vector::zip_reverse(microchains_chain_id, microchains_info, |chain_id, microchain_info|{ - // New helper variable with explicit type annotation is required due to Move's lambda type inference - // limitations. When I don't use this new variable with explicit type declaration, compiler throws error - // and ask to infer the type. - let info: MicrochainInfo = microchain_info; - if (info.state == STATE_ACTIVE) { - vector::push_back(&mut active_microchains_chain_id, chain_id); - } - }); - active_microchains_chain_id - } - - #[view] - /// Get microchain metadata link. - public fun microchain_metadata_link(chain_id: u8): String acquires MicrochainRegistry { - let microchain_registry = borrow_global_microchain_registry(); - assert_microchain_registered(µchain_registry.microchains, &chain_id); - - simple_map::borrow(µchain_registry.microchains, &chain_id).metadata_link - } - - #[view] - /// Get microchain info. - public fun microchain_info(chain_id: u8): (u8, String) acquires MicrochainRegistry { - let microchain_registry = borrow_global_microchain_registry(); - assert_microchain_registered(µchain_registry.microchains, &chain_id); - - let microchain = simple_map::borrow(µchain_registry.microchains, &chain_id); - (microchain.state, microchain.metadata_link) - } - - #[view] - /// Check if a chain ID falls within reserved ranges. - public fun is_chain_id_reserved(chain_id: u8): bool acquires MicrochainRegistry { - is_chain_id_reserved_internal(chain_id, &borrow_global_microchain_registry().reserved_ranges) - } - - - inline fun borrow_global_microchain_registry(): &MicrochainRegistry acquires MicrochainRegistry { - assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED)); - borrow_global(@supra_framework) - } - - inline fun borrow_global_mut_microchain_registry( - supra_framework: &signer - ): &mut MicrochainRegistry acquires MicrochainRegistry { - system_addresses::assert_supra_framework(supra_framework); - assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED)); - borrow_global_mut(@supra_framework) - } - - inline fun assert_microchain_registered(microchains: &SimpleMap, chain_id: &u8) { - assert!( - simple_map::contains_key(microchains, chain_id), - error::not_found(EMICROCHAIN_NOT_REGISTERED) - ); - } - - - fun is_chain_id_reserved_internal( - chain_id: u8, - reserved_ranges: &vector - ): bool { - let i = 0; - let total_ranges = vector::length(reserved_ranges); - while (i < total_ranges) { - let range = vector::borrow(reserved_ranges, i); - if (chain_id >= range.start && chain_id <= range.end) { - return true - }; - i = i + 1; - }; - - false - } -} diff --git a/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move b/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move new file mode 100644 index 0000000000000..768881a6af528 --- /dev/null +++ b/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move @@ -0,0 +1,299 @@ +#[test_only] +module supra_framework::appchain_registry_tests { + use std::string; + use std::vector; + + use supra_framework::account; + use supra_framework::appchain_registry; + + + /// Registered as a appchain, but decommissioned from the Supra-L1. + const STATE_INACTIVE: u8 = 0; + /// Registered as a appchain and actively working. + const STATE_ACTIVE: u8 = 1; + /// Never registered as a appchain. + const STATE_UNKNOWN: u8 = 2; + + // Test constants + const TEST_CHAIN_ID_1: u8 = 10; + const TEST_CHAIN_ID_2: u8 = 20; + const TEST_CHAIN_ID_3: u8 = 30; + const RESERVED_CHAIN_ID: u8 = 5; + + + fun setup_test(): signer { + let supra_framework = account::create_account_for_test(@supra_framework); + appchain_registry::initialize(&supra_framework, vector::empty()); + supra_framework + } + + fun create_metadata_link(suffix: vector): string::String { + let base = b"https://temp.com/temp/"; + vector::append(&mut base, suffix); + string::utf8(base) + } + + // Module Initialization Tests. + + #[test] + fun test_initialize() { + let supra_framework = account::create_account_for_test(@supra_framework); + appchain_registry::initialize( + &supra_framework, + vector[ + appchain_registry::new_reserved_range(0, 0), + appchain_registry::new_reserved_range(1, 10) + ] + ); + assert!(appchain_registry::appchain_state(TEST_CHAIN_ID_1) == STATE_UNKNOWN, 1); + assert!(appchain_registry::is_chain_id_reserved(6), 2) + } + + #[test] + #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] + fun test_initialize_with_non_supra_framework() { + let non_supra_framework = account::create_account_for_test(@0x123); + appchain_registry::initialize(&non_supra_framework, vector::empty()); + } + + + // Register Appchain Tests. + + #[test] + fun test_register_appchain() { + let supra_framework = setup_test(); + let metadata = create_metadata_link(b"chain1"); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + metadata + ); + assert!(appchain_registry::appchain_state(TEST_CHAIN_ID_1) == STATE_ACTIVE, 1); + assert!(appchain_registry::is_appchain_active(TEST_CHAIN_ID_1), 2); + assert!(appchain_registry::appchain_metadata_link(TEST_CHAIN_ID_1) == metadata, 3); + + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_2, + create_metadata_link(b"chain2") + ); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_3, + create_metadata_link(b"chain3") + ); + assert!(appchain_registry::is_appchain_active(TEST_CHAIN_ID_2), 4); + assert!(appchain_registry::is_appchain_active(TEST_CHAIN_ID_3), 5); + assert!(appchain_registry::active_appchains() == vector[30, 20, 10], 6) + } + + + #[test] + #[expected_failure(abort_code = 0x60006, location = supra_framework::appchain_registry)] + fun test_register_appchain_without_initialization() { + let supra_framework = account::create_account_for_test(@supra_framework); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + } + + #[test] + #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] + fun test_register_appchain_with_non_supra_framework_signer() { + let _ = setup_test(); + let non_supra_framework = account::create_account_for_test(@0x123); + appchain_registry::register_appchain( + &non_supra_framework, + RESERVED_CHAIN_ID, + create_metadata_link(b"reserved") + ); + } + + #[test] + #[expected_failure(abort_code = 0x80001, location = supra_framework::appchain_registry)] + fun test_register_appchain_with_already_registered_appchain() { + let supra_framework = setup_test(); + let metadata = create_metadata_link(b"chain1"); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + metadata + ); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1_duplicate") + ); + } + + #[test] + #[expected_failure(abort_code = 0x10003, location = supra_framework::appchain_registry)] + fun test_register_appchain_with_reserved_chain_id() { + let supra_framework = setup_test(); + appchain_registry::add_reserved_range(&supra_framework, 1, 10); + + appchain_registry::register_appchain( + &supra_framework, + RESERVED_CHAIN_ID, + create_metadata_link(b"reserved") + ); + } + + + // Deactivate Appchain Tests. + + #[test] + fun test_deactivate_appchain_success() { + let supra_framework = setup_test(); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + appchain_registry::deactivate_appchain(&supra_framework, TEST_CHAIN_ID_1); + + assert!(appchain_registry::appchain_state(TEST_CHAIN_ID_1) == STATE_INACTIVE, 1); + assert!(!appchain_registry::is_appchain_active(TEST_CHAIN_ID_1), 2); + } + + #[test] + #[expected_failure(abort_code = 0x60002, location = supra_framework::appchain_registry)] + fun test_deactivate_appchain_with_unregistered_appchain() { + let supra_framework = setup_test(); + appchain_registry::deactivate_appchain(&supra_framework, TEST_CHAIN_ID_1); + } + + #[test] + #[expected_failure(abort_code = 0x30004, location = supra_framework::appchain_registry)] + fun test_deactivate_appchain_with_already_deactivated_appchain() { + let supra_framework = setup_test(); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + // Here, we are deactivating it first time. + appchain_registry::deactivate_appchain(&supra_framework, TEST_CHAIN_ID_1); + // Now, again we are trying to deactivate the appchain and this should cause failure. + appchain_registry::deactivate_appchain(&supra_framework, TEST_CHAIN_ID_1); + } + + + // Reactivate Appchain Tests. + + #[test] + fun test_reactivate_appchain() { + let supra_framework = setup_test(); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + appchain_registry::deactivate_appchain(&supra_framework, TEST_CHAIN_ID_1); + appchain_registry::reactivate_appchain(&supra_framework, TEST_CHAIN_ID_1); + + assert!(appchain_registry::appchain_state(TEST_CHAIN_ID_1) == STATE_ACTIVE, 1); + assert!(appchain_registry::is_appchain_active(TEST_CHAIN_ID_1), 2); + } + + #[test] + #[expected_failure(abort_code = 0x60002, location = supra_framework::appchain_registry)] + fun test_reactivate_appchain_with_unregistered_appchain() { + let supra_framework = setup_test(); + appchain_registry::reactivate_appchain(&supra_framework, TEST_CHAIN_ID_1); + } + + #[test] + #[expected_failure(abort_code = 0x30005, location = supra_framework::appchain_registry)] + fun test_reactivate_appchain_with_already_active_appchain() { + let supra_framework = setup_test(); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + appchain_registry::reactivate_appchain(&supra_framework, TEST_CHAIN_ID_1); + } + + + // Update Appchain Metadata Link Tests. + + #[test] + fun test_update_appchain_metadata_link() { + let supra_framework = setup_test(); + let initial_metadata = create_metadata_link(b"chain1"); + let new_metadata = create_metadata_link(b"chain1_updated"); + appchain_registry::register_appchain( + &supra_framework, + TEST_CHAIN_ID_1, + initial_metadata + ); + assert!(appchain_registry::appchain_metadata_link(TEST_CHAIN_ID_1) == initial_metadata, 1); + + // Now, Updating the metadata link. + appchain_registry::update_appchain_metadata_link( + &supra_framework, + TEST_CHAIN_ID_1, + new_metadata + ); + assert!(appchain_registry::appchain_metadata_link(TEST_CHAIN_ID_1) == new_metadata, 2); + } + + #[test] + #[expected_failure(abort_code = 0x60002, location = supra_framework::appchain_registry)] + fun test_update_appchain_metadata_link_with_unregistered_appchain() { + let supra_framework = setup_test(); + appchain_registry::update_appchain_metadata_link( + &supra_framework, + TEST_CHAIN_ID_1, + create_metadata_link(b"chain1") + ); + } + + + // Add Reserved Ranges Tests. + + #[test] + fun test_add_reserved_range() { + let supra_framework = setup_test(); + appchain_registry::add_reserved_range(&supra_framework, 1, 10); + appchain_registry::add_reserved_range(&supra_framework, 200, 255); + + // Verify reserved ranges + assert!(appchain_registry::is_chain_id_reserved(1), 1); + assert!(appchain_registry::is_chain_id_reserved(5), 2); + assert!(appchain_registry::is_chain_id_reserved(10), 3); + assert!(!appchain_registry::is_chain_id_reserved(50), 4); + assert!(appchain_registry::is_chain_id_reserved(220), 5); + assert!(!appchain_registry::is_chain_id_reserved(0), 6); + + // Reserving single range, trying 0-0. + appchain_registry::add_reserved_range(&supra_framework, 0, 0); + assert!(appchain_registry::is_chain_id_reserved(0), 7); + } + + #[test] + fun test_overlapping_reserved_ranges() { + let supra_framework = setup_test(); + + appchain_registry::add_reserved_range(&supra_framework, 10, 20); + appchain_registry::add_reserved_range(&supra_framework, 15, 25); + appchain_registry::add_reserved_range(&supra_framework, 20, 30); + + // All overlapping IDs should be reserved + assert!(appchain_registry::is_chain_id_reserved(10), 1); + assert!(appchain_registry::is_chain_id_reserved(15), 2); + assert!(appchain_registry::is_chain_id_reserved(20), 3); + assert!(appchain_registry::is_chain_id_reserved(25), 4); + assert!(appchain_registry::is_chain_id_reserved(30), 5); + } + + #[test] + #[expected_failure(abort_code = 0x10007, location = supra_framework::appchain_registry)] + fun test_add_reserved_range_with_invalid_range() { + let supra_framework = setup_test(); + appchain_registry::add_reserved_range(&supra_framework, 20, 10); + } +} diff --git a/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move b/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move deleted file mode 100644 index 4cb8c7f6ae565..0000000000000 --- a/aptos-move/framework/supra-framework/tests/microchain_registry_tests.move +++ /dev/null @@ -1,299 +0,0 @@ -#[test_only] -module supra_framework::microchain_registry_tests { - use std::string; - use std::vector; - - use supra_framework::account; - use supra_framework::microchain_registry; - - - /// Registered as a microchain, but decommissioned from the Supra-L1. - const STATE_INACTIVE: u8 = 0; - /// Registered as a microchain and actively working. - const STATE_ACTIVE: u8 = 1; - /// Never registered as a microchain. - const STATE_UNKNOWN: u8 = 2; - - // Test constants - const TEST_CHAIN_ID_1: u8 = 10; - const TEST_CHAIN_ID_2: u8 = 20; - const TEST_CHAIN_ID_3: u8 = 30; - const RESERVED_CHAIN_ID: u8 = 5; - - - fun setup_test(): signer { - let supra_framework = account::create_account_for_test(@supra_framework); - microchain_registry::initialize(&supra_framework, vector::empty()); - supra_framework - } - - fun create_metadata_link(suffix: vector): string::String { - let base = b"https://temp.com/temp/"; - vector::append(&mut base, suffix); - string::utf8(base) - } - - // Module Initialization Tests. - - #[test] - fun test_initialize() { - let supra_framework = account::create_account_for_test(@supra_framework); - microchain_registry::initialize( - &supra_framework, - vector[ - microchain_registry::new_reserved_range(0, 0), - microchain_registry::new_reserved_range(1, 10) - ] - ); - assert!(microchain_registry::microchain_state(TEST_CHAIN_ID_1) == STATE_UNKNOWN, 1); - assert!(microchain_registry::is_chain_id_reserved(6), 2) - } - - #[test] - #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] - fun test_initialize_with_non_supra_framework() { - let non_supra_framework = account::create_account_for_test(@0x123); - microchain_registry::initialize(&non_supra_framework, vector::empty()); - } - - - // Register Microchain Tests. - - #[test] - fun test_register_microchain() { - let supra_framework = setup_test(); - let metadata = create_metadata_link(b"chain1"); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - metadata - ); - assert!(microchain_registry::microchain_state(TEST_CHAIN_ID_1) == STATE_ACTIVE, 1); - assert!(microchain_registry::is_microchain_active(TEST_CHAIN_ID_1), 2); - assert!(microchain_registry::microchain_metadata_link(TEST_CHAIN_ID_1) == metadata, 3); - - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_2, - create_metadata_link(b"chain2") - ); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_3, - create_metadata_link(b"chain3") - ); - assert!(microchain_registry::is_microchain_active(TEST_CHAIN_ID_2), 4); - assert!(microchain_registry::is_microchain_active(TEST_CHAIN_ID_3), 5); - assert!(microchain_registry::active_microchains() == vector[30, 20, 10], 6) - } - - - #[test] - #[expected_failure(abort_code = 0x60006, location = supra_framework::microchain_registry)] - fun test_register_microchain_without_initialization() { - let supra_framework = account::create_account_for_test(@supra_framework); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - create_metadata_link(b"chain1") - ); - } - - #[test] - #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] - fun test_register_microchain_with_non_supra_framework_signer() { - let _ = setup_test(); - let non_supra_framework = account::create_account_for_test(@0x123); - microchain_registry::register_microchain( - &non_supra_framework, - RESERVED_CHAIN_ID, - create_metadata_link(b"reserved") - ); - } - - #[test] - #[expected_failure(abort_code = 0x80001, location = supra_framework::microchain_registry)] - fun test_register_microchain_with_already_registered_microchain() { - let supra_framework = setup_test(); - let metadata = create_metadata_link(b"chain1"); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - metadata - ); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - create_metadata_link(b"chain1_duplicate") - ); - } - - #[test] - #[expected_failure(abort_code = 0x10003, location = supra_framework::microchain_registry)] - fun test_register_microchain_with_reserved_chain_id() { - let supra_framework = setup_test(); - microchain_registry::add_reserved_range(&supra_framework, 1, 10); - - microchain_registry::register_microchain( - &supra_framework, - RESERVED_CHAIN_ID, - create_metadata_link(b"reserved") - ); - } - - - // Deactivate Microchain Tests. - - #[test] - fun test_deactivate_microchain_success() { - let supra_framework = setup_test(); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - create_metadata_link(b"chain1") - ); - microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); - - assert!(microchain_registry::microchain_state(TEST_CHAIN_ID_1) == STATE_INACTIVE, 1); - assert!(!microchain_registry::is_microchain_active(TEST_CHAIN_ID_1), 2); - } - - #[test] - #[expected_failure(abort_code = 0x60002, location = supra_framework::microchain_registry)] - fun test_deactivate_microchain_with_unregistered_microchain() { - let supra_framework = setup_test(); - microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); - } - - #[test] - #[expected_failure(abort_code = 0x30004, location = supra_framework::microchain_registry)] - fun test_deactivate_microchain_with_already_deactivated_microchain() { - let supra_framework = setup_test(); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - create_metadata_link(b"chain1") - ); - // Here, we are deactivating it first time. - microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); - // Now, again we are trying to deactivate the microchain and this should cause failure. - microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); - } - - - // Reactivate Microchain Tests. - - #[test] - fun test_reactivate_microchain() { - let supra_framework = setup_test(); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - create_metadata_link(b"chain1") - ); - microchain_registry::deactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); - microchain_registry::reactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); - - assert!(microchain_registry::microchain_state(TEST_CHAIN_ID_1) == STATE_ACTIVE, 1); - assert!(microchain_registry::is_microchain_active(TEST_CHAIN_ID_1), 2); - } - - #[test] - #[expected_failure(abort_code = 0x60002, location = supra_framework::microchain_registry)] - fun test_reactivate_microchain_with_unregistered_microchain() { - let supra_framework = setup_test(); - microchain_registry::reactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); - } - - #[test] - #[expected_failure(abort_code = 0x30005, location = supra_framework::microchain_registry)] - fun test_reactivate_microchain_with_already_active_microchain() { - let supra_framework = setup_test(); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - create_metadata_link(b"chain1") - ); - microchain_registry::reactivate_microchain(&supra_framework, TEST_CHAIN_ID_1); - } - - - // Update Microchain Metadata Link Tests. - - #[test] - fun test_update_microchain_metadata_link() { - let supra_framework = setup_test(); - let initial_metadata = create_metadata_link(b"chain1"); - let new_metadata = create_metadata_link(b"chain1_updated"); - microchain_registry::register_microchain( - &supra_framework, - TEST_CHAIN_ID_1, - initial_metadata - ); - assert!(microchain_registry::microchain_metadata_link(TEST_CHAIN_ID_1) == initial_metadata, 1); - - // Now, Updating the metadata link. - microchain_registry::update_microchain_metadata_link( - &supra_framework, - TEST_CHAIN_ID_1, - new_metadata - ); - assert!(microchain_registry::microchain_metadata_link(TEST_CHAIN_ID_1) == new_metadata, 2); - } - - #[test] - #[expected_failure(abort_code = 0x60002, location = supra_framework::microchain_registry)] - fun test_update_microchain_metadata_link_with_unregistered_microchain() { - let supra_framework = setup_test(); - microchain_registry::update_microchain_metadata_link( - &supra_framework, - TEST_CHAIN_ID_1, - create_metadata_link(b"chain1") - ); - } - - - // Add Reserved Ranges Tests. - - #[test] - fun test_add_reserved_range() { - let supra_framework = setup_test(); - microchain_registry::add_reserved_range(&supra_framework, 1, 10); - microchain_registry::add_reserved_range(&supra_framework, 200, 255); - - // Verify reserved ranges - assert!(microchain_registry::is_chain_id_reserved(1), 1); - assert!(microchain_registry::is_chain_id_reserved(5), 2); - assert!(microchain_registry::is_chain_id_reserved(10), 3); - assert!(!microchain_registry::is_chain_id_reserved(50), 4); - assert!(microchain_registry::is_chain_id_reserved(220), 5); - assert!(!microchain_registry::is_chain_id_reserved(0), 6); - - // Reserving single range, trying 0-0. - microchain_registry::add_reserved_range(&supra_framework, 0, 0); - assert!(microchain_registry::is_chain_id_reserved(0), 7); - } - - #[test] - fun test_overlapping_reserved_ranges() { - let supra_framework = setup_test(); - - microchain_registry::add_reserved_range(&supra_framework, 10, 20); - microchain_registry::add_reserved_range(&supra_framework, 15, 25); - microchain_registry::add_reserved_range(&supra_framework, 20, 30); - - // All overlapping IDs should be reserved - assert!(microchain_registry::is_chain_id_reserved(10), 1); - assert!(microchain_registry::is_chain_id_reserved(15), 2); - assert!(microchain_registry::is_chain_id_reserved(20), 3); - assert!(microchain_registry::is_chain_id_reserved(25), 4); - assert!(microchain_registry::is_chain_id_reserved(30), 5); - } - - #[test] - #[expected_failure(abort_code = 0x10007, location = supra_framework::microchain_registry)] - fun test_add_reserved_range_with_invalid_range() { - let supra_framework = setup_test(); - microchain_registry::add_reserved_range(&supra_framework, 20, 10); - } -} diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index d680278b267dd..42dea35ae55b8 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -33,7 +33,7 @@ use aptos_types::{ on_chain_config::{ randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit}, AutomationRegistryConfig, FeatureFlag, Features, FunnelNodeRegistryConfig, GasScheduleV2, - MicrochainRegistryConfig, OnChainConsensusConfig, OnChainEvmGenesisConfig, + AppchainRegistryConfig, OnChainConsensusConfig, OnChainEvmGenesisConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct, APTOS_MAX_KNOWN_VERSION, }, @@ -109,7 +109,7 @@ pub struct GenesisConfiguration { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub automation_registry_config: Option, - pub microchain_registry_config: Option, + pub appchain_registry_config: Option, pub funnel_node_registry_config: Option, } @@ -177,7 +177,7 @@ pub fn encode_supra_mainnet_genesis_transaction( ); initialize_supra_coin(&mut session); initialize_supra_native_automation(&mut session, genesis_config); - initialize_microchain_registry(&mut session, genesis_config); + initialize_appchain_registry(&mut session, genesis_config); initialize_funnel_node_registry(&mut session, genesis_config); initialize_on_chain_governance(&mut session, genesis_config); create_accounts(&mut session, accounts); @@ -333,7 +333,7 @@ pub fn encode_genesis_change_set_for_testnet( initialize_supra_coin(&mut session); } initialize_supra_native_automation(&mut session, genesis_config); - initialize_microchain_registry(&mut session, genesis_config); + initialize_appchain_registry(&mut session, genesis_config); initialize_funnel_node_registry(&mut session, genesis_config); initialize_config_buffer(&mut session); initialize_dkg(&mut session); @@ -593,14 +593,14 @@ fn initialize_supra_native_automation( ); } -fn initialize_microchain_registry(session: &mut SessionExt, genesis_config: &GenesisConfiguration) { - let Some(config) = &genesis_config.microchain_registry_config else { +fn initialize_appchain_registry(session: &mut SessionExt, genesis_config: &GenesisConfiguration) { + let Some(config) = &genesis_config.appchain_registry_config else { return; }; exec_function( session, GENESIS_MODULE_NAME, - "initialize_microchain_registry", + "initialize_appchain_registry", vec![], config.serialize_into_move_values(), ); @@ -1280,7 +1280,7 @@ pub fn generate_test_genesis( randomness_config_override: None, jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), - microchain_registry_config: Some(MicrochainRegistryConfig::default()), + appchain_registry_config: Some(AppchainRegistryConfig::default()), funnel_node_registry_config: Some(FunnelNodeRegistryConfig::default()), }, &OnChainConsensusConfig::default_for_genesis(), @@ -1350,7 +1350,7 @@ fn mainnet_genesis_config() -> GenesisConfiguration { randomness_config_override: None, jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), - microchain_registry_config: Some(MicrochainRegistryConfig::default()), + appchain_registry_config: Some(AppchainRegistryConfig::default()), funnel_node_registry_config: Some(FunnelNodeRegistryConfig::default()), } } diff --git a/crates/aptos-genesis/src/builder.rs b/crates/aptos-genesis/src/builder.rs index 048f7c6e7aecc..bccb1f44b1fcb 100644 --- a/crates/aptos-genesis/src/builder.rs +++ b/crates/aptos-genesis/src/builder.rs @@ -25,7 +25,7 @@ use aptos_framework::ReleaseBundle; use aptos_keygen::KeyGen; use aptos_logger::prelude::*; use aptos_types::on_chain_config::{ - AutomationRegistryConfig, FunnelNodeRegistryConfig, MicrochainRegistryConfig, + AutomationRegistryConfig, FunnelNodeRegistryConfig, AppchainRegistryConfig, }; use aptos_types::{ account_address::AccountAddress, @@ -440,7 +440,7 @@ pub struct GenesisConfiguration { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub automation_registry_config: Option, - pub microchain_registry_config: Option, + pub appchain_registry_config: Option, pub funnel_node_registry_config: Option, } @@ -666,7 +666,7 @@ impl Builder { randomness_config_override: None, jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), - microchain_registry_config: Some(MicrochainRegistryConfig::default()), + appchain_registry_config: Some(AppchainRegistryConfig::default()), funnel_node_registry_config: Some(FunnelNodeRegistryConfig::default()), }; if let Some(init_genesis_config) = &self.init_genesis_config { diff --git a/crates/aptos-genesis/src/config.rs b/crates/aptos-genesis/src/config.rs index b2d9e39f12d21..e67fdc9ac3606 100644 --- a/crates/aptos-genesis/src/config.rs +++ b/crates/aptos-genesis/src/config.rs @@ -4,7 +4,7 @@ use aptos_config::config::HANDSHAKE_VERSION; use aptos_crypto::{ed25519, ed25519::Ed25519PublicKey, x25519}; use aptos_types::on_chain_config::{ - AutomationRegistryConfig, FunnelNodeRegistryConfig, MicrochainRegistryConfig, + AutomationRegistryConfig, FunnelNodeRegistryConfig, AppchainRegistryConfig, }; use aptos_types::{ account_address::{AccountAddress, AccountAddressWithChecks}, @@ -85,7 +85,7 @@ pub struct Layout { pub jwk_consensus_config_override: Option, /// An optional supra native automation config. pub automation_registry_config: Option, - pub microchain_registry_config: Option, + pub appchain_registry_config: Option, pub funnel_node_registry_config: Option, } @@ -130,7 +130,7 @@ impl Default for Layout { on_chain_execution_config: OnChainExecutionConfig::default_for_genesis(), jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), - microchain_registry_config: Some(MicrochainRegistryConfig::default()), + appchain_registry_config: Some(AppchainRegistryConfig::default()), funnel_node_registry_config: Some(FunnelNodeRegistryConfig::default()), } } diff --git a/crates/aptos-genesis/src/lib.rs b/crates/aptos-genesis/src/lib.rs index 02c0165a7ff4e..c4d38bf386593 100644 --- a/crates/aptos-genesis/src/lib.rs +++ b/crates/aptos-genesis/src/lib.rs @@ -22,7 +22,7 @@ use aptos_framework::ReleaseBundle; use aptos_storage_interface::DbReaderWriter; use aptos_temppath::TempPath; use aptos_types::on_chain_config::{ - AutomationRegistryConfig, FunnelNodeRegistryConfig, MicrochainRegistryConfig, + AutomationRegistryConfig, FunnelNodeRegistryConfig, AppchainRegistryConfig, }; use aptos_types::{ account_address::AccountAddress, @@ -85,7 +85,7 @@ pub struct GenesisInfo { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub automation_registry_config: Option, - pub microchain_registry_config: Option, + pub appchain_registry_config: Option, pub funnel_node_registry_config: Option, } @@ -129,7 +129,7 @@ impl GenesisInfo { randomness_config_override: genesis_config.randomness_config_override.clone(), jwk_consensus_config_override: genesis_config.jwk_consensus_config_override.clone(), automation_registry_config: genesis_config.automation_registry_config.clone(), - microchain_registry_config: genesis_config.microchain_registry_config.clone(), + appchain_registry_config: genesis_config.appchain_registry_config.clone(), funnel_node_registry_config: genesis_config.funnel_node_registry_config.clone(), }) } @@ -174,7 +174,7 @@ impl GenesisInfo { jwk_consensus_config_override: self.jwk_consensus_config_override.clone(), genesis_timestamp_in_microseconds: self.genesis_timestamp_in_microseconds, automation_registry_config: self.automation_registry_config.clone(), - microchain_registry_config: self.microchain_registry_config.clone(), + appchain_registry_config: self.appchain_registry_config.clone(), funnel_node_registry_config: self.funnel_node_registry_config.clone(), }, &self.consensus_config, diff --git a/crates/aptos-genesis/src/mainnet.rs b/crates/aptos-genesis/src/mainnet.rs index 8a5d6c4fa7a85..90460344cdeca 100644 --- a/crates/aptos-genesis/src/mainnet.rs +++ b/crates/aptos-genesis/src/mainnet.rs @@ -11,7 +11,7 @@ use aptos_framework::ReleaseBundle; use aptos_storage_interface::DbReaderWriter; use aptos_temppath::TempPath; use aptos_types::on_chain_config::{ - AutomationRegistryConfig, FunnelNodeRegistryConfig, MicrochainRegistryConfig, + AutomationRegistryConfig, FunnelNodeRegistryConfig, AppchainRegistryConfig, }; use aptos_types::{ account_address::AccountAddress, @@ -74,7 +74,7 @@ pub struct MainnetGenesisInfo { jwk_consensus_config_override: Option, /// Supra native automation feature configuration parameters automation_registry_config: Option, - microchain_registry_config: Option, + appchain_registry_config: Option, funnel_node_registry_config: Option, } @@ -121,7 +121,7 @@ impl MainnetGenesisInfo { randomness_config_override: genesis_config.randomness_config_override.clone(), jwk_consensus_config_override: genesis_config.jwk_consensus_config_override.clone(), automation_registry_config: genesis_config.automation_registry_config.clone(), - microchain_registry_config: genesis_config.microchain_registry_config.clone(), + appchain_registry_config: genesis_config.appchain_registry_config.clone(), funnel_node_registry_config: genesis_config.funnel_node_registry_config.clone(), }) } @@ -167,7 +167,7 @@ impl MainnetGenesisInfo { randomness_config_override: self.randomness_config_override.clone(), jwk_consensus_config_override: self.jwk_consensus_config_override.clone(), automation_registry_config: self.automation_registry_config.clone(), - microchain_registry_config: self.microchain_registry_config.clone(), + appchain_registry_config: self.appchain_registry_config.clone(), funnel_node_registry_config: self.funnel_node_registry_config.clone(), }, b"test".to_vec(), diff --git a/crates/aptos/src/genesis/mod.rs b/crates/aptos/src/genesis/mod.rs index a274012b582fb..679c72acc5739 100644 --- a/crates/aptos/src/genesis/mod.rs +++ b/crates/aptos/src/genesis/mod.rs @@ -260,7 +260,7 @@ pub fn fetch_mainnet_genesis_info(git_options: GitOptions) -> CliTypedResult CliTypedResult, } -impl MicrochainRegistryConfig { +impl AppchainRegistryConfig { pub fn new(reserved_ranges: Vec) -> Self { Self { reserved_ranges } } diff --git a/types/src/on_chain_config/mod.rs b/types/src/on_chain_config/mod.rs index d88651beb8010..f37454f35d6b1 100644 --- a/types/src/on_chain_config/mod.rs +++ b/types/src/on_chain_config/mod.rs @@ -32,7 +32,7 @@ mod execution_config; mod funnel_node_registry; mod gas_schedule; mod jwk_consensus_config; -mod microchain_registry; +mod appchain_registry; pub mod randomness_api_v0_config; mod randomness_config; mod timed_features; @@ -69,7 +69,7 @@ pub use self::{ jwk_consensus_config::{ ConfigV1 as JWKConsensusConfigV1, OIDCProvider, OnChainJWKConsensusConfig, }, - microchain_registry::{MicrochainRegistryConfig, ReservedRange}, + appchain_registry::{AppchainRegistryConfig, ReservedRange}, randomness_config::{ OnChainRandomnessConfig, RandomnessConfigMoveStruct, RandomnessConfigSeqNum, }, From 25152120241ae929a9c99bde1773bab6f740b31d Mon Sep 17 00:00:00 2001 From: vpanchal-supra Date: Tue, 2 Dec 2025 16:59:38 +0530 Subject: [PATCH 5/7] refactor: chain_id: u8 -> chain_id: 16 in `appchain_registry` --- .../supra-framework/doc/appchain_registry.md | 78 +++++++++---------- .../sources/appchain_registry.move | 50 ++++++------ .../tests/appchain_registry_tests.move | 8 +- .../src/on_chain_config/appchain_registry.rs | 21 +++-- .../on_chain_config/funnel_node_registry.rs | 4 +- 5 files changed, 79 insertions(+), 82 deletions(-) diff --git a/aptos-move/framework/supra-framework/doc/appchain_registry.md b/aptos-move/framework/supra-framework/doc/appchain_registry.md index f6c0d3e8715d4..2550051030d6b 100644 --- a/aptos-move/framework/supra-framework/doc/appchain_registry.md +++ b/aptos-move/framework/supra-framework/doc/appchain_registry.md @@ -78,13 +78,13 @@ Represents reserved chain ID range.
-start: u8 +start: u16
-end: u8 +end: u16
@@ -147,7 +147,7 @@ Global appchain registry resource.
-appchains: simple_map::SimpleMap<u8, appchain_registry::AppchainInfo> +appchains: simple_map::SimpleMap<u16, appchain_registry::AppchainInfo>
Map from chain ID to appchain info. @@ -181,7 +181,7 @@ Global appchain registry resource.
-chain_id: u8 +chain_id: u16
@@ -215,7 +215,7 @@ Global appchain registry resource.
-chain_id: u8 +chain_id: u16
@@ -243,7 +243,7 @@ Global appchain registry resource.
-chain_id: u8 +chain_id: u16
@@ -271,7 +271,7 @@ Global appchain registry resource.
-chain_id: u8 +chain_id: u16
@@ -449,7 +449,7 @@ supra_framework::supra_governance::reconfigure(&supra_framework); ``` -
public fun register_appchain(supra_framework: &signer, chain_id: u8, metadata_link: string::String)
+
public fun register_appchain(supra_framework: &signer, chain_id: u16, metadata_link: string::String)
 
@@ -460,7 +460,7 @@ supra_framework::supra_governance::reconfigure(&supra_framework);
public fun register_appchain(
     supra_framework: &signer,
-    chain_id: u8,
+    chain_id: u16,
     metadata_link: String,
 ) acquires AppchainRegistry {
     let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
@@ -514,7 +514,7 @@ supra_framework::supra_governance::reconfigure(&supra_framework);
 ```
 
 
-
public fun deactivate_appchain(supra_framework: &signer, chain_id: u8)
+
public fun deactivate_appchain(supra_framework: &signer, chain_id: u16)
 
@@ -525,7 +525,7 @@ supra_framework::supra_governance::reconfigure(&supra_framework);
public fun deactivate_appchain(
     supra_framework: &signer,
-    chain_id: u8,
+    chain_id: u16,
 ) acquires AppchainRegistry {
     let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
     assert_appchain_registered(&appchain_registry.appchains, &chain_id);
@@ -566,7 +566,7 @@ supra_framework::supra_governance::reconfigure(&supra_framework);
 ```
 
 
-
public fun reactivate_appchain(supra_framework: &signer, chain_id: u8)
+
public fun reactivate_appchain(supra_framework: &signer, chain_id: u16)
 
@@ -577,7 +577,7 @@ supra_framework::supra_governance::reconfigure(&supra_framework);
public fun reactivate_appchain(
     supra_framework: &signer,
-    chain_id: u8,
+    chain_id: u16,
 ) acquires AppchainRegistry {
     let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
     assert_appchain_registered(&appchain_registry.appchains, &chain_id);
@@ -604,7 +604,7 @@ supra_framework::supra_governance::reconfigure(&supra_framework);
 Updates metadata link of a registered appchain.
 
 
-
public fun update_appchain_metadata_link(supra_framework: &signer, chain_id: u8, new_metadata_link: string::String)
+
public fun update_appchain_metadata_link(supra_framework: &signer, chain_id: u16, new_metadata_link: string::String)
 
@@ -615,7 +615,7 @@ Updates metadata link of a registered appchain.
public fun update_appchain_metadata_link(
     supra_framework: &signer,
-    chain_id: u8,
+    chain_id: u16,
     new_metadata_link: String,
 ) acquires AppchainRegistry {
     let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
@@ -644,7 +644,7 @@ Updates metadata link of a registered appchain.
 Adds a reserved chain ID range.
 
 
-
public fun add_reserved_range(supra_framework: &signer, start: u8, end: u8)
+
public fun add_reserved_range(supra_framework: &signer, start: u16, end: u16)
 
@@ -655,8 +655,8 @@ Adds a reserved chain ID range.
public fun add_reserved_range(
     supra_framework: &signer,
-    start: u8,
-    end: u8,
+    start: u16,
+    end: u16,
 ) acquires AppchainRegistry {
     let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
     assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
@@ -677,7 +677,7 @@ Constructor to create an instance of the new_reserved_range(start: u8, end: u8): appchain_registry::ReservedRange
+
public fun new_reserved_range(start: u16, end: u16): appchain_registry::ReservedRange
 
@@ -687,8 +687,8 @@ This will be utilized in move-script to initialize the appchain registry with re
public fun new_reserved_range(
-    start: u8,
-    end: u8,
+    start: u16,
+    end: u16,
 ): ReservedRange {
     assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
     ReservedRange { start, end }
@@ -707,7 +707,7 @@ Get the state of a appchain.
 
 
 
#[view]
-public fun appchain_state(chain_id: u8): u8
+public fun appchain_state(chain_id: u16): u8
 
@@ -716,7 +716,7 @@ Get the state of a appchain. Implementation -
public fun appchain_state(chain_id: u8): u8 acquires AppchainRegistry {
+
public fun appchain_state(chain_id: u16): u8 acquires AppchainRegistry {
     let appchain_registry = borrow_global_appchain_registry();
     if (simple_map::contains_key(&appchain_registry.appchains, &chain_id)) {
         return simple_map::borrow(&appchain_registry.appchains, &chain_id).state;
@@ -738,7 +738,7 @@ Check if a appchain is active.
 
 
 
#[view]
-public fun is_appchain_active(chain_id: u8): bool
+public fun is_appchain_active(chain_id: u16): bool
 
@@ -747,7 +747,7 @@ Check if a appchain is active. Implementation -
public fun is_appchain_active(chain_id: u8): bool acquires AppchainRegistry {
+
public fun is_appchain_active(chain_id: u16): bool acquires AppchainRegistry {
     appchain_state(chain_id) == STATE_ACTIVE
 }
 
@@ -764,7 +764,7 @@ Get chain IDs of all appchain with Active state.
#[view]
-public fun active_appchains(): vector<u8>
+public fun active_appchains(): vector<u16>
 
@@ -773,12 +773,12 @@ Get chain IDs of all appchain with Active state. Implementation -
public fun active_appchains(): vector<u8> acquires AppchainRegistry {
+
public fun active_appchains(): vector<u16> acquires AppchainRegistry {
     let appchain_registry = borrow_global_appchain_registry();
     let appchains_chain_id = simple_map::keys(&appchain_registry.appchains);
     let appchains_info = simple_map::values(&appchain_registry.appchains);
-    let active_appchains_chain_id = vector::empty<u8>();
-    vector::zip_reverse<u8, AppchainInfo>(appchains_chain_id, appchains_info, |chain_id, appchain_info|{
+    let active_appchains_chain_id = vector::empty<u16>();
+    vector::zip_reverse<u16, AppchainInfo>(appchains_chain_id, appchains_info, |chain_id, appchain_info|{
         // New helper variable with explicit type annotation is required due to Move's lambda type inference
         // limitations. When I don't use this new variable with explicit type declaration, compiler throws error
         // and ask to infer the type.
@@ -803,7 +803,7 @@ Get appchain metadata link.
 
 
 
#[view]
-public fun appchain_metadata_link(chain_id: u8): string::String
+public fun appchain_metadata_link(chain_id: u16): string::String
 
@@ -812,7 +812,7 @@ Get appchain metadata link. Implementation -
public fun appchain_metadata_link(chain_id: u8): String acquires AppchainRegistry {
+
public fun appchain_metadata_link(chain_id: u16): String acquires AppchainRegistry {
     let appchain_registry = borrow_global_appchain_registry();
     assert_appchain_registered(&appchain_registry.appchains, &chain_id);
 
@@ -832,7 +832,7 @@ Get appchain info.
 
 
 
#[view]
-public fun appchain_info(chain_id: u8): (u8, string::String)
+public fun appchain_info(chain_id: u16): (u8, string::String)
 
@@ -841,7 +841,7 @@ Get appchain info. Implementation -
public fun appchain_info(chain_id: u8): (u8, String) acquires AppchainRegistry {
+
public fun appchain_info(chain_id: u16): (u8, String) acquires AppchainRegistry {
     let appchain_registry = borrow_global_appchain_registry();
     assert_appchain_registered(&appchain_registry.appchains, &chain_id);
 
@@ -862,7 +862,7 @@ Check if a chain ID falls within reserved ranges.
 
 
 
#[view]
-public fun is_chain_id_reserved(chain_id: u8): bool
+public fun is_chain_id_reserved(chain_id: u16): bool
 
@@ -871,7 +871,7 @@ Check if a chain ID falls within reserved ranges. Implementation -
public fun is_chain_id_reserved(chain_id: u8): bool acquires AppchainRegistry {
+
public fun is_chain_id_reserved(chain_id: u16): bool acquires AppchainRegistry {
     is_chain_id_reserved_internal(chain_id, &borrow_global_appchain_registry().reserved_ranges)
 }
 
@@ -939,7 +939,7 @@ Check if a chain ID falls within reserved ranges. -
fun assert_appchain_registered(appchains: &simple_map::SimpleMap<u8, appchain_registry::AppchainInfo>, chain_id: &u8)
+
fun assert_appchain_registered(appchains: &simple_map::SimpleMap<u16, appchain_registry::AppchainInfo>, chain_id: &u16)
 
@@ -948,7 +948,7 @@ Check if a chain ID falls within reserved ranges. Implementation -
inline fun assert_appchain_registered(appchains: &SimpleMap<u8, AppchainInfo>, chain_id: &u8) {
+
inline fun assert_appchain_registered(appchains: &SimpleMap<u16, AppchainInfo>, chain_id: &u16) {
     assert!(
         simple_map::contains_key(appchains, chain_id),
         error::not_found(EAPPCHAIN_NOT_REGISTERED)
@@ -966,7 +966,7 @@ Check if a chain ID falls within reserved ranges.
 
 
 
-
fun is_chain_id_reserved_internal(chain_id: u8, reserved_ranges: &vector<appchain_registry::ReservedRange>): bool
+
fun is_chain_id_reserved_internal(chain_id: u16, reserved_ranges: &vector<appchain_registry::ReservedRange>): bool
 
@@ -976,7 +976,7 @@ Check if a chain ID falls within reserved ranges.
fun is_chain_id_reserved_internal(
-    chain_id: u8,
+    chain_id: u16,
     reserved_ranges: &vector<ReservedRange>
 ): bool {
     let i = 0;
diff --git a/aptos-move/framework/supra-framework/sources/appchain_registry.move b/aptos-move/framework/supra-framework/sources/appchain_registry.move
index b5b29464b16f6..9dde50af2f166 100644
--- a/aptos-move/framework/supra-framework/sources/appchain_registry.move
+++ b/aptos-move/framework/supra-framework/sources/appchain_registry.move
@@ -62,8 +62,8 @@ module supra_framework::appchain_registry {
 
     /// Represents reserved chain ID range.
     struct ReservedRange has store, copy, drop {
-        start: u8,
-        end: u8
+        start: u16,
+        end: u16
     }
 
     /// Represents information about the registered appchain.
@@ -76,7 +76,7 @@ module supra_framework::appchain_registry {
     /// Global appchain registry resource.
     struct AppchainRegistry has key {
         /// Map from chain ID to appchain info.
-        appchains: SimpleMap,
+        appchains: SimpleMap,
         /// Reserved chain ID ranges.
         reserved_ranges: vector,
     }
@@ -84,23 +84,23 @@ module supra_framework::appchain_registry {
 
     #[event]
     struct AppchainRegistered has store, drop {
-        chain_id: u8,
+        chain_id: u16,
         metadata_link: String,
     }
 
     #[event]
     struct AppchainDeactivated has store, drop {
-        chain_id: u8,
+        chain_id: u16,
     }
 
     #[event]
     struct AppchainReactivated has store, drop {
-        chain_id: u8,
+        chain_id: u16,
     }
 
     #[event]
     struct AppchainMetadataLinkUpdated has store, drop {
-        chain_id: u8,
+        chain_id: u16,
         old_metadata_link: String,
         new_metadata_link: String,
     }
@@ -132,7 +132,7 @@ module supra_framework::appchain_registry {
     /// ```
     public fun register_appchain(
         supra_framework: &signer,
-        chain_id: u8,
+        chain_id: u16,
         metadata_link: String,
     ) acquires AppchainRegistry {
         let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
@@ -177,7 +177,7 @@ module supra_framework::appchain_registry {
     /// ```
     public fun deactivate_appchain(
         supra_framework: &signer,
-        chain_id: u8,
+        chain_id: u16,
     ) acquires AppchainRegistry {
         let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
         assert_appchain_registered(&appchain_registry.appchains, &chain_id);
@@ -209,7 +209,7 @@ module supra_framework::appchain_registry {
     /// ```
     public fun reactivate_appchain(
         supra_framework: &signer,
-        chain_id: u8,
+        chain_id: u16,
     ) acquires AppchainRegistry {
         let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
         assert_appchain_registered(&appchain_registry.appchains, &chain_id);
@@ -227,7 +227,7 @@ module supra_framework::appchain_registry {
     /// Updates metadata link of a registered appchain.
     public fun update_appchain_metadata_link(
         supra_framework: &signer,
-        chain_id: u8,
+        chain_id: u16,
         new_metadata_link: String,
     ) acquires AppchainRegistry {
         let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
@@ -247,8 +247,8 @@ module supra_framework::appchain_registry {
     /// Adds a reserved chain ID range.
     public fun add_reserved_range(
         supra_framework: &signer,
-        start: u8,
-        end: u8,
+        start: u16,
+        end: u16,
     ) acquires AppchainRegistry {
         let appchain_registry = borrow_global_mut_appchain_registry(supra_framework);
         assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
@@ -260,8 +260,8 @@ module supra_framework::appchain_registry {
     /// Constructor to create an instance of the `ReservedRange`.
     /// This will be utilized in move-script to initialize the appchain registry with reserved ranges.
     public fun new_reserved_range(
-        start: u8,
-        end: u8,
+        start: u16,
+        end: u16,
     ): ReservedRange {
         assert!(start <= end, error::invalid_argument(EINVALID_RANGE));
         ReservedRange { start, end }
@@ -270,7 +270,7 @@ module supra_framework::appchain_registry {
 
     #[view]
     /// Get the state of a appchain.
-    public fun appchain_state(chain_id: u8): u8 acquires AppchainRegistry {
+    public fun appchain_state(chain_id: u16): u8 acquires AppchainRegistry {
         let appchain_registry = borrow_global_appchain_registry();
         if (simple_map::contains_key(&appchain_registry.appchains, &chain_id)) {
             return simple_map::borrow(&appchain_registry.appchains, &chain_id).state;
@@ -281,18 +281,18 @@ module supra_framework::appchain_registry {
 
     #[view]
     /// Check if a appchain is active.
-    public fun is_appchain_active(chain_id: u8): bool acquires AppchainRegistry {
+    public fun is_appchain_active(chain_id: u16): bool acquires AppchainRegistry {
         appchain_state(chain_id) == STATE_ACTIVE
     }
 
     #[view]
     /// Get chain IDs of all appchain with `Active` state.
-    public fun active_appchains(): vector acquires AppchainRegistry {
+    public fun active_appchains(): vector acquires AppchainRegistry {
         let appchain_registry = borrow_global_appchain_registry();
         let appchains_chain_id = simple_map::keys(&appchain_registry.appchains);
         let appchains_info = simple_map::values(&appchain_registry.appchains);
-        let active_appchains_chain_id = vector::empty();
-        vector::zip_reverse(appchains_chain_id, appchains_info, |chain_id, appchain_info|{
+        let active_appchains_chain_id = vector::empty();
+        vector::zip_reverse(appchains_chain_id, appchains_info, |chain_id, appchain_info|{
             // New helper variable with explicit type annotation is required due to Move's lambda type inference
             // limitations. When I don't use this new variable with explicit type declaration, compiler throws error
             // and ask to infer the type.
@@ -306,7 +306,7 @@ module supra_framework::appchain_registry {
 
     #[view]
     /// Get appchain metadata link.
-    public fun appchain_metadata_link(chain_id: u8): String acquires AppchainRegistry {
+    public fun appchain_metadata_link(chain_id: u16): String acquires AppchainRegistry {
         let appchain_registry = borrow_global_appchain_registry();
         assert_appchain_registered(&appchain_registry.appchains, &chain_id);
 
@@ -315,7 +315,7 @@ module supra_framework::appchain_registry {
 
     #[view]
     /// Get appchain info.
-    public fun appchain_info(chain_id: u8): (u8, String) acquires AppchainRegistry {
+    public fun appchain_info(chain_id: u16): (u8, String) acquires AppchainRegistry {
         let appchain_registry = borrow_global_appchain_registry();
         assert_appchain_registered(&appchain_registry.appchains, &chain_id);
 
@@ -325,7 +325,7 @@ module supra_framework::appchain_registry {
 
     #[view]
     /// Check if a chain ID falls within reserved ranges.
-    public fun is_chain_id_reserved(chain_id: u8): bool acquires AppchainRegistry {
+    public fun is_chain_id_reserved(chain_id: u16): bool acquires AppchainRegistry {
         is_chain_id_reserved_internal(chain_id, &borrow_global_appchain_registry().reserved_ranges)
     }
 
@@ -343,7 +343,7 @@ module supra_framework::appchain_registry {
         borrow_global_mut(@supra_framework)
     }
 
-    inline fun assert_appchain_registered(appchains: &SimpleMap, chain_id: &u8) {
+    inline fun assert_appchain_registered(appchains: &SimpleMap, chain_id: &u16) {
         assert!(
             simple_map::contains_key(appchains, chain_id),
             error::not_found(EAPPCHAIN_NOT_REGISTERED)
@@ -352,7 +352,7 @@ module supra_framework::appchain_registry {
 
 
     fun is_chain_id_reserved_internal(
-        chain_id: u8,
+        chain_id: u16,
         reserved_ranges: &vector
     ): bool {
         let i = 0;
diff --git a/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move b/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move
index 768881a6af528..8833161b4fa7f 100644
--- a/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move
+++ b/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move
@@ -15,10 +15,10 @@ module supra_framework::appchain_registry_tests {
     const STATE_UNKNOWN: u8 = 2;
 
     // Test constants
-    const TEST_CHAIN_ID_1: u8 = 10;
-    const TEST_CHAIN_ID_2: u8 = 20;
-    const TEST_CHAIN_ID_3: u8 = 30;
-    const RESERVED_CHAIN_ID: u8 = 5;
+    const TEST_CHAIN_ID_1: u16 = 10;
+    const TEST_CHAIN_ID_2: u16 = 20;
+    const TEST_CHAIN_ID_3: u16 = 30;
+    const RESERVED_CHAIN_ID: u16 = 5;
 
 
     fun setup_test(): signer {
diff --git a/types/src/on_chain_config/appchain_registry.rs b/types/src/on_chain_config/appchain_registry.rs
index 5407f7f1b790d..6e213906cf95b 100644
--- a/types/src/on_chain_config/appchain_registry.rs
+++ b/types/src/on_chain_config/appchain_registry.rs
@@ -13,11 +13,8 @@ impl AppchainRegistryConfig {
     }
 
     pub fn serialize_into_move_values(&self) -> Vec> {
-        let reserved_ranges_vec_move_value = self
-            .reserved_ranges
-            .iter()
-            .map(MoveValue::from)
-            .collect::>();
+        let reserved_ranges_vec_move_value: Vec =
+            self.reserved_ranges.iter().map(MoveValue::from).collect();
         let arguments = vec![
             MoveValue::Signer(CORE_CODE_ADDRESS),
             MoveValue::Vector(reserved_ranges_vec_move_value),
@@ -28,15 +25,15 @@ impl AppchainRegistryConfig {
 
 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
 pub struct ReservedRange {
-    start: u8,
-    end: u8,
+    start: u16,
+    end: u16,
 }
 
 impl From<&ReservedRange> for MoveValue {
     fn from(value: &ReservedRange) -> MoveValue {
         MoveValue::Struct(MoveStruct::new(vec![
-            MoveValue::U8(value.start),
-            MoveValue::U8(value.end),
+            MoveValue::U16(value.start),
+            MoveValue::U16(value.end),
         ]))
     }
 }
@@ -53,10 +50,10 @@ impl Default for ReservedRange {
 impl ReservedRange {
     // Currently, default values are not finalized yet, however, by considering that our production
     // networks chain IDs falls between 0-10, according to me the current default values are best.
-    pub const DEFAULT_START: u8 = 0;
-    pub const DEFAULT_END: u8 = 10;
+    pub const DEFAULT_START: u16 = 0;
+    pub const DEFAULT_END: u16 = 10;
 
-    pub fn new(start: u8, end: u8) -> Self {
+    pub fn new(start: u16, end: u16) -> Self {
         Self { start, end }
     }
 }
diff --git a/types/src/on_chain_config/funnel_node_registry.rs b/types/src/on_chain_config/funnel_node_registry.rs
index 6ea4ea74fcf4b..f8efe4fda04f2 100644
--- a/types/src/on_chain_config/funnel_node_registry.rs
+++ b/types/src/on_chain_config/funnel_node_registry.rs
@@ -14,7 +14,7 @@ impl FunnelNodeRegistryConfig {
     }
 
     pub fn serialize_into_move_values(&self) -> Vec> {
-        let funnel_nodes_vec_move_value = self
+        let funnel_nodes_vec_move_value: Vec = self
             .funnel_nodes
             .iter()
             .map(|node_endpoint_url| {
@@ -22,7 +22,7 @@ impl FunnelNodeRegistryConfig {
                     node_endpoint_url.to_string().into_bytes(),
                 )]))
             })
-            .collect::>();
+            .collect();
         let arguments = vec![
             MoveValue::Signer(CORE_CODE_ADDRESS),
             MoveValue::Vector(funnel_nodes_vec_move_value),

From e910b0cf564995badad58a6d5ed9ab2437fed00a Mon Sep 17 00:00:00 2001
From: vpanchal-supra 
Date: Tue, 2 Dec 2025 18:33:48 +0530
Subject: [PATCH 6/7] feat: feature gated `appchain_registry` operations

---
 .../framework/move-stdlib/doc/features.md     |  2 +-
 .../supra-framework/doc/appchain_registry.md  | 15 +++++++++++
 .../sources/appchain_registry.move            |  9 ++++++-
 .../tests/appchain_registry_tests.move        | 26 +++++++++++++++++++
 4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md
index 4c6b8d80bfae9..6f5b75f1ae9d0 100644
--- a/aptos-move/framework/move-stdlib/doc/features.md
+++ b/aptos-move/framework/move-stdlib/doc/features.md
@@ -888,7 +888,7 @@ Lifetime: transient
 
 
 
-Whether Supra Appchain is enabled.
+Whether Supra Appchains are enabled.
 
 Lifetime: transient
 
diff --git a/aptos-move/framework/supra-framework/doc/appchain_registry.md b/aptos-move/framework/supra-framework/doc/appchain_registry.md
index 2550051030d6b..d214f0e1a7d69 100644
--- a/aptos-move/framework/supra-framework/doc/appchain_registry.md
+++ b/aptos-move/framework/supra-framework/doc/appchain_registry.md
@@ -53,6 +53,7 @@ c. reactivate_appchain
 
 
use 0x1::error;
 use 0x1::event;
+use 0x1::features;
 use 0x1::simple_map;
 use 0x1::string;
 use 0x1::system_addresses;
@@ -308,6 +309,16 @@ The provided range is invalid, start value must be less than or equal to end val
 
 
 
+
+
+Supra Appchains feature is not enabled.
+
+
+
const EAPPCHAINS_FEATURE_DISABLED: u64 = 8;
+
+ + + The appchain is already in the ACTIVE state and cannot be reactivated. @@ -404,6 +415,8 @@ Never registered as a appchain. Initializes the appchain registry. +Appchain registry initialization does not requires enabling SUPRA_APPCHAINS feature. +
public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector<appchain_registry::ReservedRange>)
 
@@ -896,6 +909,7 @@ Check if a chain ID falls within reserved ranges.
inline fun borrow_global_appchain_registry(): &AppchainRegistry acquires AppchainRegistry {
+    assert!(features::supra_appchains_enabled(), error::unavailable(EAPPCHAINS_FEATURE_DISABLED));
     assert!(exists<AppchainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
     borrow_global<AppchainRegistry>(@supra_framework)
 }
@@ -923,6 +937,7 @@ Check if a chain ID falls within reserved ranges.
 
inline fun borrow_global_mut_appchain_registry(
     supra_framework: &signer
 ): &mut AppchainRegistry acquires AppchainRegistry {
+    assert!(features::supra_appchains_enabled(), error::unavailable(EAPPCHAINS_FEATURE_DISABLED));
     system_addresses::assert_supra_framework(supra_framework);
     assert!(exists<AppchainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
     borrow_global_mut<AppchainRegistry>(@supra_framework)
diff --git a/aptos-move/framework/supra-framework/sources/appchain_registry.move b/aptos-move/framework/supra-framework/sources/appchain_registry.move
index 9dde50af2f166..76317eea53838 100644
--- a/aptos-move/framework/supra-framework/sources/appchain_registry.move
+++ b/aptos-move/framework/supra-framework/sources/appchain_registry.move
@@ -18,6 +18,7 @@
 ///     c. `reactivate_appchain`
 module supra_framework::appchain_registry {
     use std::error;
+    use std::features;
     use std::string::String;
     use std::vector;
 
@@ -52,6 +53,9 @@ module supra_framework::appchain_registry {
     /// The provided range is invalid, start value must be less than or equal to end value.
     const EINVALID_RANGE: u64 = 7;
 
+    /// Supra Appchains feature is not enabled.
+    const ESUPRA_APPCHAINS_FEATURE_DISABLED: u64 = 8;
+
 
     /// Registered as a appchain, but decommissioned from the Supra-L1.
     const STATE_INACTIVE: u8 = 0;
@@ -106,6 +110,8 @@ module supra_framework::appchain_registry {
     }
 
     /// Initializes the appchain registry.
+    ///
+    /// Appchain registry initialization does not require the `SUPRA_APPCHAINS` feature to be enabled.
     public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector) {
         system_addresses::assert_supra_framework(supra_framework);
 
@@ -329,8 +335,8 @@ module supra_framework::appchain_registry {
         is_chain_id_reserved_internal(chain_id, &borrow_global_appchain_registry().reserved_ranges)
     }
 
-
     inline fun borrow_global_appchain_registry(): &AppchainRegistry acquires AppchainRegistry {
+        assert!(features::supra_appchains_enabled(), error::unavailable(ESUPRA_APPCHAINS_FEATURE_DISABLED));
         assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
         borrow_global(@supra_framework)
     }
@@ -338,6 +344,7 @@ module supra_framework::appchain_registry {
     inline fun borrow_global_mut_appchain_registry(
         supra_framework: &signer
     ): &mut AppchainRegistry acquires AppchainRegistry {
+        assert!(features::supra_appchains_enabled(), error::unavailable(ESUPRA_APPCHAINS_FEATURE_DISABLED));
         system_addresses::assert_supra_framework(supra_framework);
         assert!(exists(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
         borrow_global_mut(@supra_framework)
diff --git a/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move b/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move
index 8833161b4fa7f..61e01bf7e28ac 100644
--- a/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move
+++ b/aptos-move/framework/supra-framework/tests/appchain_registry_tests.move
@@ -1,5 +1,6 @@
 #[test_only]
 module supra_framework::appchain_registry_tests {
+    use std::features;
     use std::string;
     use std::vector;
 
@@ -23,10 +24,19 @@ module supra_framework::appchain_registry_tests {
 
     fun setup_test(): signer {
         let supra_framework = account::create_account_for_test(@supra_framework);
+        enable_supra_appchain_feature(&supra_framework);
         appchain_registry::initialize(&supra_framework, vector::empty());
         supra_framework
     }
 
+    fun enable_supra_appchain_feature(supra_framework: &signer) {
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[features::get_supra_appchains_feature()],
+            vector[]
+        );
+    }
+
     fun create_metadata_link(suffix: vector): string::String {
         let base = b"https://temp.com/temp/";
         vector::append(&mut base, suffix);
@@ -45,6 +55,9 @@ module supra_framework::appchain_registry_tests {
                 appchain_registry::new_reserved_range(1, 10)
             ]
         );
+        // Although the Appchain registry can be initialized without the `SUPRA_APPCHAIN` feature enabled, but all other
+        // methods of `appchain_registry` module require that feature enabled.
+        enable_supra_appchain_feature(&supra_framework);
         assert!(appchain_registry::appchain_state(TEST_CHAIN_ID_1) == STATE_UNKNOWN, 1);
         assert!(appchain_registry::is_chain_id_reserved(6), 2)
     }
@@ -88,10 +101,23 @@ module supra_framework::appchain_registry_tests {
     }
 
 
+    #[test]
+    #[expected_failure(abort_code = 0xd0008, location = supra_framework::appchain_registry)]
+    fun test_register_appchain_without_feature_enable() {
+        let supra_framework = account::create_account_for_test(@supra_framework);
+        appchain_registry::initialize(&supra_framework, vector::empty());
+        appchain_registry::register_appchain(
+            &supra_framework,
+            TEST_CHAIN_ID_1,
+            create_metadata_link(b"chain1")
+        );
+    }
+
     #[test]
     #[expected_failure(abort_code = 0x60006, location = supra_framework::appchain_registry)]
     fun test_register_appchain_without_initialization() {
         let supra_framework = account::create_account_for_test(@supra_framework);
+        enable_supra_appchain_feature(&supra_framework);
         appchain_registry::register_appchain(
             &supra_framework,
             TEST_CHAIN_ID_1,

From 6be5d9ec0cfc38464e5ffea4b1cc44109a46c503 Mon Sep 17 00:00:00 2001
From: vpanchal-supra 
Date: Wed, 3 Dec 2025 15:29:33 +0530
Subject: [PATCH 7/7] fix: ensure `SUPRA_APPCHAINS` feature is by default
 disabled

---
 .../supra-framework/doc/appchain_registry.md  | 26 +++++++++----------
 types/src/on_chain_config/aptos_features.rs   |  1 -
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/aptos-move/framework/supra-framework/doc/appchain_registry.md b/aptos-move/framework/supra-framework/doc/appchain_registry.md
index d214f0e1a7d69..0d396808d5116 100644
--- a/aptos-move/framework/supra-framework/doc/appchain_registry.md
+++ b/aptos-move/framework/supra-framework/doc/appchain_registry.md
@@ -309,16 +309,6 @@ The provided range is invalid, start value must be less than or equal to end val
 
 
 
-
-
-Supra Appchains feature is not enabled.
-
-
-
const EAPPCHAINS_FEATURE_DISABLED: u64 = 8;
-
- - - The appchain is already in the ACTIVE state and cannot be reactivated. @@ -379,6 +369,16 @@ The + + +Supra Appchains feature is not enabled. + + +
const ESUPRA_APPCHAINS_FEATURE_DISABLED: u64 = 8;
+
+ + + Registered as a appchain and actively working. @@ -415,7 +415,7 @@ Never registered as a appchain. Initializes the appchain registry. -Appchain registry initialization does not requires enabling SUPRA_APPCHAINS feature. +Appchain registry initialization does not require the SUPRA_APPCHAINS feature to be enabled.
public(friend) fun initialize(supra_framework: &signer, reserved_ranges: vector<appchain_registry::ReservedRange>)
@@ -909,7 +909,7 @@ Check if a chain ID falls within reserved ranges.
 
 
 
inline fun borrow_global_appchain_registry(): &AppchainRegistry acquires AppchainRegistry {
-    assert!(features::supra_appchains_enabled(), error::unavailable(EAPPCHAINS_FEATURE_DISABLED));
+    assert!(features::supra_appchains_enabled(), error::unavailable(ESUPRA_APPCHAINS_FEATURE_DISABLED));
     assert!(exists<AppchainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
     borrow_global<AppchainRegistry>(@supra_framework)
 }
@@ -937,7 +937,7 @@ Check if a chain ID falls within reserved ranges.
 
inline fun borrow_global_mut_appchain_registry(
     supra_framework: &signer
 ): &mut AppchainRegistry acquires AppchainRegistry {
-    assert!(features::supra_appchains_enabled(), error::unavailable(EAPPCHAINS_FEATURE_DISABLED));
+    assert!(features::supra_appchains_enabled(), error::unavailable(ESUPRA_APPCHAINS_FEATURE_DISABLED));
     system_addresses::assert_supra_framework(supra_framework);
     assert!(exists<AppchainRegistry>(@supra_framework), error::not_found(EREGISTRY_NOT_INITIALIZED));
     borrow_global_mut<AppchainRegistry>(@supra_framework)
diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs
index 72dc7c68be297..0aa6667629782 100644
--- a/types/src/on_chain_config/aptos_features.rs
+++ b/types/src/on_chain_config/aptos_features.rs
@@ -170,7 +170,6 @@ impl FeatureFlag {
             FeatureFlag::SUPRA_COUNT_FAILED_PROPOSALS,
             FeatureFlag::SUPRA_DELEGATION_POOL_IDENTITY,
             FeatureFlag::SUPRA_AUTOMATION_V2,
-            FeatureFlag::SUPRA_APPCHAINS,
         ]
     }
 }